aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/DocBook/device-drivers.tmpl17
-rw-r--r--Documentation/DocBook/drm.tmpl126
-rw-r--r--Documentation/arm/Atmel/README124
-rw-r--r--Documentation/arm/Samsung-S3C24XX/DMA.txt46
-rw-r--r--Documentation/arm/sti/stih418-overview.txt20
-rw-r--r--Documentation/arm/sunxi/README1
-rw-r--r--Documentation/devicetree/bindings/arm/armada-38x.txt7
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-at91.txt17
-rw-r--r--Documentation/devicetree/bindings/arm/digicolor.txt6
-rw-r--r--Documentation/devicetree/bindings/arm/exynos/power_domain.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.txt20
-rw-r--r--Documentation/devicetree/bindings/arm/gic.txt8
-rw-r--r--Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt25
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek.txt4
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/rockchip.txt10
-rw-r--r--Documentation/devicetree/bindings/arm/rockchip/pmu-sram.txt16
-rw-r--r--Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt12
-rw-r--r--Documentation/devicetree/bindings/arm/samsung/pmu.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/sirf.txt6
-rw-r--r--Documentation/devicetree/bindings/arm/sti.txt4
-rw-r--r--Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt26
-rw-r--r--Documentation/devicetree/bindings/arm/versatile-sysreg.txt10
-rw-r--r--Documentation/devicetree/bindings/bus/mvebu-mbus.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/alphascale,acc.txt115
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt35
-rw-r--r--Documentation/devicetree/bindings/dma/img-mdc-dma.txt57
-rw-r--r--Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt3
-rw-r--r--Documentation/devicetree/bindings/dma/snps-dma.txt2
-rw-r--r--Documentation/devicetree/bindings/drm/atmel/hlcdc-dc.txt53
-rw-r--r--Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt50
-rw-r--r--Documentation/devicetree/bindings/drm/msm/hdmi.txt2
-rw-r--r--Documentation/devicetree/bindings/gpu/st,stih4xx.txt29
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt21
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt5
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt28
-rw-r--r--Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt6
-rw-r--r--Documentation/devicetree/bindings/media/s5p-mfc.txt4
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/renesas-memory-controllers.txt44
-rw-r--r--Documentation/devicetree/bindings/mfd/atmel-matrix.txt24
-rw-r--r--Documentation/devicetree/bindings/mfd/atmel-smc.txt19
-rw-r--r--Documentation/devicetree/bindings/mfd/da9063.txt93
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom-rpm.txt70
-rw-r--r--Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt40
-rw-r--r--Documentation/devicetree/bindings/mtd/atmel-nand.txt2
-rw-r--r--Documentation/devicetree/bindings/mtd/fsl-quadspi.txt2
-rw-r--r--Documentation/devicetree/bindings/mtd/gpmi-nand.txt2
-rw-r--r--Documentation/devicetree/bindings/mtd/hisi504-nand.txt47
-rw-r--r--Documentation/devicetree/bindings/mtd/mtd-physmap.txt5
-rw-r--r--Documentation/devicetree/bindings/panel/avic,tm070ddh03.txt7
-rw-r--r--Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt7
-rw-r--r--Documentation/devicetree/bindings/power/renesas,sysc-rmobile.txt99
-rw-r--r--Documentation/devicetree/bindings/pwm/img-pwm.txt24
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-sun4i.txt20
-rw-r--r--Documentation/devicetree/bindings/serial/mtk-uart.txt6
-rw-r--r--Documentation/devicetree/bindings/serial/of-serial.txt12
-rw-r--r--Documentation/devicetree/bindings/sound/atmel_ac97c.txt20
-rw-r--r--Documentation/devicetree/bindings/timer/digicolor-timer.txt18
-rw-r--r--Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt18
-rw-r--r--Documentation/devicetree/bindings/usb/atmel-usb.txt10
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt7
-rw-r--r--Documentation/devicetree/bindings/video/bridge/ps8622.txt31
-rw-r--r--Documentation/devicetree/bindings/video/bridge/ptn3460.txt (renamed from Documentation/devicetree/bindings/drm/bridge/ptn3460.txt)16
-rw-r--r--Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt46
-rw-r--r--Documentation/devicetree/bindings/video/exynos7-decon.txt68
-rw-r--r--Documentation/devicetree/bindings/video/exynos_dp.txt12
-rw-r--r--Documentation/devicetree/bindings/video/exynos_dsim.txt4
-rw-r--r--Documentation/devicetree/bindings/video/exynos_mixer.txt1
-rw-r--r--Documentation/devicetree/bindings/video/renesas,du.txt4
-rw-r--r--Documentation/devicetree/bindings/video/samsung-fimd.txt4
-rw-r--r--Documentation/devicetree/bindings/watchdog/gpio-wdt.txt5
-rw-r--r--Documentation/devicetree/bindings/watchdog/imgpdc-wdt.txt19
-rw-r--r--Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt12
-rw-r--r--Documentation/devicetree/bindings/watchdog/mtk-wdt.txt13
-rw-r--r--Documentation/dmaengine/provider.txt97
-rw-r--r--Documentation/filesystems/00-INDEX5
-rw-r--r--Documentation/filesystems/Locking3
-rw-r--r--Documentation/filesystems/dax.txt94
-rw-r--r--Documentation/filesystems/ext2.txt5
-rw-r--r--Documentation/filesystems/ext4.txt4
-rw-r--r--Documentation/filesystems/vfs.txt7
-rw-r--r--Documentation/filesystems/xip.txt71
-rw-r--r--Documentation/gdb-kernel-debugging.txt160
-rw-r--r--Documentation/ia64/paravirt_ops.txt137
-rw-r--r--Documentation/virtual/00-INDEX3
-rw-r--r--Documentation/virtual/paravirt_ops.txt32
-rw-r--r--MAINTAINERS71
-rw-r--r--Makefile5
-rw-r--r--arch/alpha/include/asm/uaccess.h86
-rw-r--r--arch/arc/boot/dts/abilis_tb10x.dtsi2
-rw-r--r--arch/arc/include/asm/pgtable.h3
-rw-r--r--arch/arc/include/asm/processor.h3
-rw-r--r--arch/arc/include/asm/serial.h23
-rw-r--r--arch/arc/kernel/devtree.c24
-rw-r--r--arch/arc/kernel/entry.S14
-rw-r--r--arch/arc/kernel/setup.c7
-rw-r--r--arch/arc/kernel/smp.c2
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/Kconfig.debug119
-rw-r--r--arch/arm/boot/dts/Makefile357
-rw-r--r--arch/arm/boot/dts/alphascale-asm9260-devkit.dts13
-rw-r--r--arch/arm/boot/dts/alphascale-asm9260.dtsi63
-rw-r--r--arch/arm/boot/dts/am4372.dtsi16
-rw-r--r--arch/arm/boot/dts/am437x-gp-evm.dts106
-rw-r--r--arch/arm/boot/dts/am437x-idk-evm.dts405
-rw-r--r--arch/arm/boot/dts/am437x-sk-evm.dts217
-rw-r--r--arch/arm/boot/dts/am43x-epos-evm.dts53
-rw-r--r--arch/arm/boot/dts/am57xx-beagle-x15.dts157
-rw-r--r--arch/arm/boot/dts/armada-370-db.dts40
-rw-r--r--arch/arm/boot/dts/armada-370-mirabox.dts40
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn102.dts41
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn104.dts41
-rw-r--r--arch/arm/boot/dts/armada-370-rd.dts40
-rw-r--r--arch/arm/boot/dts/armada-370-synology-ds213j.dts41
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi40
-rw-r--r--arch/arm/boot/dts/armada-370.dtsi40
-rw-r--r--arch/arm/boot/dts/armada-375-db.dts40
-rw-r--r--arch/arm/boot/dts/armada-375.dtsi42
-rw-r--r--arch/arm/boot/dts/armada-380.dtsi43
-rw-r--r--arch/arm/boot/dts/armada-385-db-ap.dts178
-rw-r--r--arch/arm/boot/dts/armada-385-rd.dts97
-rw-r--r--arch/arm/boot/dts/armada-385.dtsi43
-rw-r--r--arch/arm/boot/dts/armada-388-db.dts (renamed from arch/arm/boot/dts/armada-385-db.dts)49
-rw-r--r--arch/arm/boot/dts/armada-388-gp.dts414
-rw-r--r--arch/arm/boot/dts/armada-388-rd.dts132
-rw-r--r--arch/arm/boot/dts/armada-388.dtsi70
-rw-r--r--arch/arm/boot/dts/armada-38x.dtsi136
-rw-r--r--arch/arm/boot/dts/armada-xp-axpwifiap.dts46
-rw-r--r--arch/arm/boot/dts/armada-xp-db.dts40
-rw-r--r--arch/arm/boot/dts/armada-xp-gp.dts40
-rw-r--r--arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts41
-rw-r--r--arch/arm/boot/dts/armada-xp-matrix.dts40
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78230.dtsi40
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78260.dtsi40
-rw-r--r--arch/arm/boot/dts/armada-xp-mv78460.dtsi40
-rw-r--r--arch/arm/boot/dts/armada-xp-netgear-rn2120.dts41
-rw-r--r--arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts40
-rw-r--r--arch/arm/boot/dts/armada-xp-synology-ds414.dts41
-rw-r--r--arch/arm/boot/dts/armada-xp.dtsi40
-rw-r--r--arch/arm/boot/dts/at91rm9200.dtsi12
-rw-r--r--arch/arm/boot/dts/at91rm9200ek.dts4
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9261.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi33
-rw-r--r--arch/arm/boot/dts/at91sam9g20.dtsi9
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi7
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi12
-rw-r--r--arch/arm/boot/dts/at91sam9n12ek.dts2
-rw-r--r--arch/arm/boot/dts/at91sam9rl.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi5
-rw-r--r--arch/arm/boot/dts/at91sam9x5ek.dtsi9
-rw-r--r--arch/arm/boot/dts/at91sam9xe.dtsi60
-rw-r--r--arch/arm/boot/dts/atlas7-evb.dts110
-rw-r--r--arch/arm/boot/dts/atlas7.dtsi813
-rw-r--r--arch/arm/boot/dts/axp209.dtsi97
-rw-r--r--arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts68
-rw-r--r--arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts60
-rw-r--r--arch/arm/boot/dts/bcm4708-netgear-r6250.dts1
-rw-r--r--arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts1
-rw-r--r--arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts1
-rw-r--r--arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts68
-rw-r--r--arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts37
-rw-r--r--arch/arm/boot/dts/berlin2.dtsi2
-rw-r--r--arch/arm/boot/dts/berlin2cd.dtsi7
-rw-r--r--arch/arm/boot/dts/berlin2q.dtsi10
-rw-r--r--arch/arm/boot/dts/cx92755.dtsi113
-rw-r--r--arch/arm/boot/dts/cx92755_equinox.dts74
-rw-r--r--arch/arm/boot/dts/dm8168-evm.dts129
-rw-r--r--arch/arm/boot/dts/dm816x-clocks.dtsi250
-rw-r--r--arch/arm/boot/dts/dm816x.dtsi392
-rw-r--r--arch/arm/boot/dts/dra7-evm.dts31
-rw-r--r--arch/arm/boot/dts/dra7.dtsi2
-rw-r--r--arch/arm/boot/dts/dra72-evm.dts108
-rw-r--r--arch/arm/boot/dts/ethernut5.dts2
-rw-r--r--arch/arm/boot/dts/exynos3250-monk.dts63
-rw-r--r--arch/arm/boot/dts/exynos3250-rinato.dts133
-rw-r--r--arch/arm/boot/dts/exynos3250.dtsi106
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi134
-rw-r--r--arch/arm/boot/dts/exynos4210-trats.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210-universal_c210.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi9
-rw-r--r--arch/arm/boot/dts/exynos4412-odroid-common.dtsi1
-rw-r--r--arch/arm/boot/dts/exynos4412-trats2.dts212
-rw-r--r--arch/arm/boot/dts/exynos4415.dtsi34
-rw-r--r--arch/arm/boot/dts/exynos4x12.dtsi9
-rw-r--r--arch/arm/boot/dts/exynos5250-snow.dts16
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi12
-rw-r--r--arch/arm/boot/dts/exynos5420-peach-pit.dts100
-rw-r--r--arch/arm/boot/dts/exynos5420.dtsi27
-rw-r--r--arch/arm/boot/dts/exynos5422-odroidxu3.dts371
-rw-r--r--arch/arm/boot/dts/exynos5800-peach-pi.dts101
-rw-r--r--arch/arm/boot/dts/hip01-ca9x2.dts51
-rw-r--r--arch/arm/boot/dts/hip01.dtsi110
-rw-r--r--arch/arm/boot/dts/imx27-apf27dev.dts21
-rw-r--r--arch/arm/boot/dts/imx27.dtsi2
-rw-r--r--arch/arm/boot/dts/imx28-evk.dts1
-rw-r--r--arch/arm/boot/dts/imx51-apf51dev.dts14
-rw-r--r--arch/arm/boot/dts/imx53.dtsi11
-rw-r--r--arch/arm/boot/dts/imx6dl-udoo.dts18
-rw-r--r--arch/arm/boot/dts/imx6dl.dtsi2
-rw-r--r--arch/arm/boot/dts/imx6q-udoo.dts124
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabrelite.dtsi33
-rw-r--r--arch/arm/boot/dts/imx6qdl-udoo.dtsi134
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi5
-rw-r--r--arch/arm/boot/dts/imx6sx-sabreauto.dts146
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dts39
-rw-r--r--arch/arm/boot/dts/kirkwood-6192.dtsi2
-rw-r--r--arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts173
-rw-r--r--arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts8
-rw-r--r--arch/arm/boot/dts/kirkwood-pogo_e02.dts134
-rw-r--r--arch/arm/boot/dts/marco-evb.dts54
-rw-r--r--arch/arm/boot/dts/marco.dtsi757
-rw-r--r--arch/arm/boot/dts/mt6589-aquaris5.dts12
-rw-r--r--arch/arm/boot/dts/mt6589.dtsi52
-rw-r--r--arch/arm/boot/dts/mt6592.dtsi51
-rw-r--r--arch/arm/boot/dts/mt8127-moose.dts4
-rw-r--r--arch/arm/boot/dts/mt8127.dtsi52
-rw-r--r--arch/arm/boot/dts/mt8135-evbp1.dts4
-rw-r--r--arch/arm/boot/dts/mt8135.dtsi54
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3x.dtsi58
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3x30.dtsi3
-rw-r--r--arch/arm/boot/dts/omap3-gta04.dtsi99
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts3
-rw-r--r--arch/arm/boot/dts/omap3-n950-n9.dtsi5
-rw-r--r--arch/arm/boot/dts/omap3-sbc-t3517.dts4
-rw-r--r--arch/arm/boot/dts/omap3-sbc-t3530.dts10
-rw-r--r--arch/arm/boot/dts/omap3-sbc-t3730.dts5
-rw-r--r--arch/arm/boot/dts/qcom-apq8064-ifc6410.dts12
-rw-r--r--arch/arm/boot/dts/qcom-ipq8064.dtsi2
-rw-r--r--arch/arm/boot/dts/r7s72100-genmai.dts2
-rw-r--r--arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts2
-rw-r--r--arch/arm/boot/dts/r8a73a4-ape6evm.dts173
-rw-r--r--arch/arm/boot/dts/r8a73a4.dtsi10
-rw-r--r--arch/arm/boot/dts/r8a7740-armadillo800eva.dts4
-rw-r--r--arch/arm/boot/dts/r8a7740.dtsi115
-rw-r--r--arch/arm/boot/dts/r8a7779.dtsi39
-rw-r--r--arch/arm/boot/dts/r8a7790-lager.dts21
-rw-r--r--arch/arm/boot/dts/r8a7790.dtsi62
-rw-r--r--arch/arm/boot/dts/r8a7791-henninger.dts4
-rw-r--r--arch/arm/boot/dts/r8a7791-koelsch.dts23
-rw-r--r--arch/arm/boot/dts/r8a7791.dtsi69
-rw-r--r--arch/arm/boot/dts/r8a7794-alt.dts4
-rw-r--r--arch/arm/boot/dts/r8a7794.dtsi82
-rw-r--r--arch/arm/boot/dts/rk3066a-rayeager.dts468
-rw-r--r--arch/arm/boot/dts/rk3288-evb-act8846.dts27
-rw-r--r--arch/arm/boot/dts/rk3288-evb-rk808.dts54
-rw-r--r--arch/arm/boot/dts/rk3288-evb.dtsi25
-rw-r--r--arch/arm/boot/dts/rk3288-firefly-beta.dts71
-rw-r--r--arch/arm/boot/dts/rk3288-firefly.dts71
-rw-r--r--arch/arm/boot/dts/rk3288-firefly.dtsi490
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi111
-rw-r--r--arch/arm/boot/dts/s5pv210-aquila.dts1
-rw-r--r--arch/arm/boot/dts/s5pv210-goni.dts1
-rw-r--r--arch/arm/boot/dts/s5pv210-smdkv210.dts1
-rw-r--r--arch/arm/boot/dts/sama5d3.dtsi34
-rw-r--r--arch/arm/boot/dts/sama5d3xcm.dtsi1
-rw-r--r--arch/arm/boot/dts/sama5d3xmb.dtsi42
-rw-r--r--arch/arm/boot/dts/sama5d4.dtsi25
-rw-r--r--arch/arm/boot/dts/sh73a0-kzm9g-reference.dts6
-rw-r--r--arch/arm/boot/dts/sh73a0.dtsi376
-rw-r--r--arch/arm/boot/dts/spear13xx.dtsi4
-rw-r--r--arch/arm/boot/dts/stih407-b2120.dts3
-rw-r--r--arch/arm/boot/dts/stih407-family.dtsi53
-rw-r--r--arch/arm/boot/dts/stih407.dtsi151
-rw-r--r--arch/arm/boot/dts/stih410.dtsi138
-rw-r--r--arch/arm/boot/dts/stih418-b2199.dts78
-rw-r--r--arch/arm/boot/dts/stih418-clock.dtsi348
-rw-r--r--arch/arm/boot/dts/stih418.dtsi99
-rw-r--r--arch/arm/boot/dts/stihxxx-b2120.dtsi13
-rw-r--r--arch/arm/boot/dts/sun4i-a10-a1000.dts23
-rw-r--r--arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts10
-rw-r--r--arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts100
-rw-r--r--arch/arm/boot/dts/sun4i-a10-cubieboard.dts58
-rw-r--r--arch/arm/boot/dts/sun4i-a10-hackberry.dts21
-rw-r--r--arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts105
-rw-r--r--arch/arm/boot/dts/sun4i-a10-inet97fv2.dts8
-rw-r--r--arch/arm/boot/dts/sun4i-a10-marsboard.dts183
-rw-r--r--arch/arm/boot/dts/sun4i-a10-mini-xplus.dts11
-rw-r--r--arch/arm/boot/dts/sun4i-a10-mk802.dts109
-rw-r--r--arch/arm/boot/dts/sun4i-a10-mk802ii.dts113
-rw-r--r--arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts21
-rw-r--r--arch/arm/boot/dts/sun4i-a10-pcduino.dts68
-rw-r--r--arch/arm/boot/dts/sun4i-a10.dtsi204
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-mk802.dts125
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts72
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts25
-rw-r--r--arch/arm/boot/dts/sun5i-a10s.dtsi68
-rw-r--r--arch/arm/boot/dts/sun5i-a13-hsg-h702.dts59
-rw-r--r--arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts25
-rw-r--r--arch/arm/boot/dts/sun5i-a13-olinuxino.dts75
-rw-r--r--arch/arm/boot/dts/sun5i-a13.dtsi112
-rw-r--r--arch/arm/boot/dts/sun6i-a31-app4-evb1.dts13
-rw-r--r--arch/arm/boot/dts/sun6i-a31-colombus.dts21
-rw-r--r--arch/arm/boot/dts/sun6i-a31-hummingbird.dts185
-rw-r--r--arch/arm/boot/dts/sun6i-a31-m9.dts31
-rw-r--r--arch/arm/boot/dts/sun6i-a31.dtsi182
-rw-r--r--arch/arm/boot/dts/sun6i-a31s-cs908.dts104
-rw-r--r--arch/arm/boot/dts/sun6i-a31s.dtsi58
-rw-r--r--arch/arm/boot/dts/sun7i-a20-bananapi.dts28
-rw-r--r--arch/arm/boot/dts/sun7i-a20-bananapro.dts262
-rw-r--r--arch/arm/boot/dts/sun7i-a20-cubieboard2.dts101
-rw-r--r--arch/arm/boot/dts/sun7i-a20-cubietruck.dts125
-rw-r--r--arch/arm/boot/dts/sun7i-a20-hummingbird.dts38
-rw-r--r--arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts40
-rw-r--r--arch/arm/boot/dts/sun7i-a20-m3.dts18
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts24
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts24
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts79
-rw-r--r--arch/arm/boot/dts/sun7i-a20-pcduino3.dts21
-rw-r--r--arch/arm/boot/dts/sun7i-a20.dtsi347
-rw-r--r--arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts59
-rw-r--r--arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts33
-rw-r--r--arch/arm/boot/dts/sun8i-a23.dtsi100
-rw-r--r--arch/arm/boot/dts/sun9i-a80-optimus.dts112
-rw-r--r--arch/arm/boot/dts/sun9i-a80.dtsi192
-rw-r--r--arch/arm/boot/dts/sunxi-common-regulators.dtsi65
-rw-r--r--arch/arm/boot/dts/tegra124-jetson-tk1.dts7
-rw-r--r--arch/arm/boot/dts/tegra124-nyan-big.dts2
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi10
-rw-r--r--arch/arm/boot/dts/tegra30-cardhu.dtsi2
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi2
-rw-r--r--arch/arm/boot/dts/versatile-ab.dts5
-rw-r--r--arch/arm/boot/dts/vf-colibri-eval-v3.dtsi2
-rw-r--r--arch/arm/boot/dts/vf-colibri.dtsi3
-rw-r--r--arch/arm/boot/dts/vf500.dtsi23
-rw-r--r--arch/arm/boot/dts/vf610-twr.dts2
-rw-r--r--arch/arm/boot/dts/vfxxx.dtsi48
-rw-r--r--arch/arm/boot/dts/zynq-7000.dtsi32
-rw-r--r--arch/arm/boot/dts/zynq-parallella.dts2
-rw-r--r--arch/arm/boot/dts/zynq-zc702.dts224
-rw-r--r--arch/arm/boot/dts/zynq-zc706.dts194
-rw-r--r--arch/arm/boot/dts/zynq-zed.dts15
-rw-r--r--arch/arm/configs/at91_dt_defconfig10
-rw-r--r--arch/arm/configs/efm32_defconfig5
-rw-r--r--arch/arm/configs/exynos_defconfig11
-rw-r--r--arch/arm/configs/hisi_defconfig1
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig39
-rw-r--r--arch/arm/configs/keystone_defconfig1
-rw-r--r--arch/arm/configs/kzm9g_defconfig2
-rw-r--r--arch/arm/configs/lager_defconfig150
-rw-r--r--arch/arm/configs/multi_v7_defconfig21
-rw-r--r--arch/arm/configs/mvebu_v7_defconfig1
-rw-r--r--arch/arm/configs/omap2plus_defconfig127
-rw-r--r--arch/arm/configs/sama5_defconfig8
-rw-r--r--arch/arm/configs/shmobile_defconfig49
-rw-r--r--arch/arm/configs/sunxi_defconfig10
-rw-r--r--arch/arm/configs/tegra_defconfig2
-rw-r--r--arch/arm/include/asm/uaccess.h96
-rw-r--r--arch/arm/include/debug/at91.S (renamed from arch/arm/mach-at91/include/mach/debug-macro.S)19
-rw-r--r--arch/arm/include/debug/digicolor.S35
-rw-r--r--arch/arm/include/debug/msm.S6
-rw-r--r--arch/arm/include/debug/sirf.S30
-rw-r--r--arch/arm/mach-at91/Kconfig120
-rw-r--r--arch/arm/mach-at91/Makefile20
-rw-r--r--arch/arm/mach-at91/at91rm9200.c66
-rw-r--r--arch/arm/mach-at91/at91sam9.c87
-rw-r--r--arch/arm/mach-at91/at91sam9260.c61
-rw-r--r--arch/arm/mach-at91/at91sam9261.c42
-rw-r--r--arch/arm/mach-at91/at91sam9263.c40
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c40
-rw-r--r--arch/arm/mach-at91/at91sam9n12.c32
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c53
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c36
-rw-r--r--arch/arm/mach-at91/board-dt-rm9200.c43
-rw-r--r--arch/arm/mach-at91/board-dt-sam9.c36
-rw-r--r--arch/arm/mach-at91/generic.h26
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pio.h80
-rw-r--r--arch/arm/mach-at91/include/mach/at91_rtt.h35
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h52
-rw-r--r--arch/arm/mach-at91/include/mach/system_rev.h27
-rw-r--r--arch/arm/mach-at91/pm.c160
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S9
-rw-r--r--arch/arm/mach-at91/sama5.c (renamed from arch/arm/mach-at91/board-dt-sama5.c)46
-rw-r--r--arch/arm/mach-at91/sama5d3.c41
-rw-r--r--arch/arm/mach-at91/sama5d4.c64
-rw-r--r--arch/arm/mach-at91/setup.c115
-rw-r--r--arch/arm/mach-at91/soc.h77
-rw-r--r--arch/arm/mach-at91/sysirq_mask.c75
-rw-r--r--arch/arm/mach-bcm/platsmp-brcmstb.c85
-rw-r--r--arch/arm/mach-davinci/Makefile2
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c31
-rw-r--r--arch/arm/mach-davinci/cdce949.c295
-rw-r--r--arch/arm/mach-davinci/include/mach/cdce949.h19
-rw-r--r--arch/arm/mach-davinci/serial.c10
-rw-r--r--arch/arm/mach-digicolor/Kconfig7
-rw-r--r--arch/arm/mach-digicolor/Makefile1
-rw-r--r--arch/arm/mach-digicolor/digicolor.c18
-rw-r--r--arch/arm/mach-exynos/common.h4
-rw-r--r--arch/arm/mach-exynos/exynos.c44
-rw-r--r--arch/arm/mach-exynos/include/mach/dma.h26
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h3
-rw-r--r--arch/arm/mach-exynos/platsmp.c2
-rw-r--r--arch/arm/mach-exynos/pm.c136
-rw-r--r--arch/arm/mach-exynos/regs-pmu.h3
-rw-r--r--arch/arm/mach-exynos/regs-sys.h22
-rw-r--r--arch/arm/mach-exynos/suspend.c88
-rw-r--r--arch/arm/mach-hisi/Kconfig8
-rw-r--r--arch/arm/mach-hisi/core.h5
-rw-r--r--arch/arm/mach-hisi/headsmp.S2
-rw-r--r--arch/arm/mach-hisi/hisilicon.c10
-rw-r--r--arch/arm/mach-hisi/hotplug.c31
-rw-r--r--arch/arm/mach-hisi/platsmp.c56
-rw-r--r--arch/arm/mach-imx/Makefile3
-rw-r--r--arch/arm/mach-imx/clk-gate2.c23
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c2
-rw-r--r--arch/arm/mach-imx/clk-pllv3.c10
-rw-r--r--arch/arm/mach-imx/clk-vf610.c8
-rw-r--r--arch/arm/mach-imx/clk.h1
-rw-r--r--arch/arm/mach-imx/common.h4
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sx.c105
-rw-r--r--arch/arm/mach-imx/cpuidle.h5
-rw-r--r--arch/arm/mach-imx/gpc.c25
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6sx.c2
-rw-r--r--arch/arm/mach-imx/mach-vf610.c5
-rw-r--r--arch/arm/mach-imx/pm-imx6.c7
-rw-r--r--arch/arm/mach-mediatek/Kconfig22
-rw-r--r--arch/arm/mach-mvebu/coherency.c58
-rw-r--r--arch/arm/mach-mvebu/mvebu-soc-id.h18
-rw-r--r--arch/arm/mach-omap1/irq.c5
-rw-r--r--arch/arm/mach-omap1/timer32k.c5
-rw-r--r--arch/arm/mach-omap2/Kconfig12
-rw-r--r--arch/arm/mach-omap2/Makefile14
-rw-r--r--arch/arm/mach-omap2/am35xx-emac.c114
-rw-r--r--arch/arm/mach-omap2/am35xx-emac.h15
-rw-r--r--arch/arm/mach-omap2/am35xx.h46
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c150
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c373
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c335
-rw-r--r--arch/arm/mach-omap2/board-generic.c36
-rw-r--r--arch/arm/mach-omap2/cclock3xxx_data.c6
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c142
-rw-r--r--arch/arm/mach-omap2/clock.c3
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h11
-rw-r--r--arch/arm/mach-omap2/clockdomain.h1
-rw-r--r--arch/arm/mach-omap2/clockdomains81xx_data.c194
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c10
-rw-r--r--arch/arm/mach-omap2/cm2xxx.h2
-rw-r--r--arch/arm/mach-omap2/cm33xx.c21
-rw-r--r--arch/arm/mach-omap2/cm81xx.h61
-rw-r--r--arch/arm/mach-omap2/common.h11
-rw-r--r--arch/arm/mach-omap2/control.h4
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c20
-rw-r--r--arch/arm/mach-omap2/id.c2
-rw-r--r--arch/arm/mach-omap2/io.c66
-rw-r--r--arch/arm/mach-omap2/omap-pm-noop.c196
-rw-r--r--arch/arm/mach-omap2/omap-pm.h192
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c238
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h17
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c33
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_43xx_data.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_7xx_data.c5
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_81xx_data.c1136
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c35
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c1
-rw-r--r--arch/arm/mach-omap2/pmu.c5
-rw-r--r--arch/arm/mach-omap2/powerdomain.c82
-rw-r--r--arch/arm/mach-omap2/powerdomain.h5
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h1
-rw-r--r--arch/arm/mach-omap2/prm44xx_54xx.h1
-rw-r--r--arch/arm/mach-omap2/prm_common.c4
-rw-r--r--arch/arm/mach-omap2/soc.h4
-rw-r--r--arch/arm/mach-omap2/ti81xx-restart.c34
-rw-r--r--arch/arm/mach-omap2/timer.c2
-rw-r--r--arch/arm/mach-omap2/usb-musb.c12
-rw-r--r--arch/arm/mach-omap2/usb.h2
-rw-r--r--arch/arm/mach-omap2/voltage.c110
-rw-r--r--arch/arm/mach-omap2/voltage.h13
-rw-r--r--arch/arm/mach-prima2/Kconfig22
-rw-r--r--arch/arm/mach-prima2/Makefile1
-rw-r--r--arch/arm/mach-prima2/common.c22
-rw-r--r--arch/arm/mach-prima2/common.h15
-rw-r--r--arch/arm/mach-prima2/lluart.c35
-rw-r--r--arch/arm/mach-prima2/platsmp.c52
-rw-r--r--arch/arm/mach-prima2/rstc.c41
-rw-r--r--arch/arm/mach-prima2/rtciobrg.c1
-rw-r--r--arch/arm/mach-pxa/Kconfig6
-rw-r--r--arch/arm/mach-pxa/corgi.c3
-rw-r--r--arch/arm/mach-pxa/devices.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c2
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h10
-rw-r--r--arch/arm/mach-pxa/poodle.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c2
-rw-r--r--arch/arm/mach-qcom/Kconfig3
-rw-r--r--arch/arm/mach-qcom/scm-boot.c10
-rw-r--r--arch/arm/mach-qcom/scm-boot.h4
-rw-r--r--arch/arm/mach-qcom/scm.c85
-rw-r--r--arch/arm/mach-realview/realview_eb.c3
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c2
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c2
-rw-r--r--arch/arm/mach-realview/realview_pba8.c2
-rw-r--r--arch/arm/mach-realview/realview_pbx.c2
-rw-r--r--arch/arm/mach-rockchip/Kconfig1
-rw-r--r--arch/arm/mach-rockchip/Makefile1
-rw-r--r--arch/arm/mach-rockchip/pm.c260
-rw-r--r--arch/arm/mach-rockchip/pm.h99
-rw-r--r--arch/arm/mach-rockchip/rockchip.c4
-rw-r--r--arch/arm/mach-rockchip/sleep.S73
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig42
-rw-r--r--arch/arm/mach-s3c24xx/Makefile7
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2410.c182
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2412.c150
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2440.c193
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2443.c179
-rw-r--r--arch/arm/mach-s3c24xx/dma.c1465
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/dma.h159
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h15
-rw-r--r--arch/arm/mach-shmobile/Kconfig28
-rw-r--r--arch/arm/mach-shmobile/Makefile3
-rw-r--r--arch/arm/mach-shmobile/Makefile.boot1
-rw-r--r--arch/arm/mach-shmobile/board-lager-reference.c39
-rw-r--r--arch/arm/mach-shmobile/board-lager.c840
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7790.c459
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c10
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c14
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c314
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.h3
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c11
-rw-r--r--arch/arm/mach-shmobile/r8a7790.h28
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c2
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7790.c284
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c4
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c7
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c2
-rw-r--r--arch/arm/mach-sti/board-dt.c1
-rw-r--r--arch/arm/mach-sunxi/platsmp.c2
-rw-r--r--arch/arm/mach-sunxi/sunxi.c11
-rw-r--r--arch/arm/mach-tegra/Kconfig4
-rw-r--r--arch/arm/mach-versatile/core.c37
-rw-r--r--arch/arm/mach-zynq/Kconfig2
-rw-r--r--arch/arm/mach-zynq/common.c2
-rw-r--r--arch/arm/mach-zynq/pm.c2
-rw-r--r--arch/arm/mach-zynq/slcr.c35
-rw-r--r--arch/arm/plat-iop/pmu.c2
-rw-r--r--arch/arm/plat-omap/dma.c8
-rw-r--r--arch/arm/plat-samsung/Kconfig15
-rw-r--r--arch/arm/plat-samsung/Makefile6
-rw-r--r--arch/arm/plat-samsung/cpu.c4
-rw-r--r--arch/arm/plat-samsung/dma-ops.c146
-rw-r--r--arch/arm/plat-samsung/dma.c84
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-core.h22
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-ops.h69
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-pl330.h121
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-s3c24xx.h73
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h130
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-dma.h151
-rw-r--r--arch/arm/plat-samsung/s3c-dma-ops.c146
-rw-r--r--arch/arm64/Kconfig54
-rw-r--r--arch/arm64/boot/dts/Makefile3
-rw-r--r--arch/arm64/boot/dts/exynos/Makefile5
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7-espresso.dts84
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi588
-rw-r--r--arch/arm64/boot/dts/exynos/exynos7.dtsi530
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile5
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts65
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi163
-rw-r--r--arch/arm64/boot/dts/mediatek/Makefile5
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-evb.dts38
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173.dtsi168
-rw-r--r--arch/arm64/configs/defconfig3
-rw-r--r--arch/arm64/include/asm/uaccess.h4
-rw-r--r--arch/avr32/include/asm/uaccess.h24
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c2
-rw-r--r--arch/blackfin/include/asm/uaccess.h32
-rw-r--r--arch/frv/include/asm/segment.h2
-rw-r--r--arch/ia64/include/asm/uaccess.h11
-rw-r--r--arch/m32r/include/asm/uaccess.h88
-rw-r--r--arch/m68k/68360/commproc.c8
-rw-r--r--arch/m68k/68360/config.c13
-rw-r--r--arch/m68k/include/asm/commproc.h24
-rw-r--r--arch/m68k/include/asm/segment.h2
-rw-r--r--arch/m68k/include/asm/uaccess_mm.h40
-rw-r--r--arch/metag/include/asm/uaccess.h25
-rw-r--r--arch/mips/include/asm/mach-jz4740/jz4740_nand.h2
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c11
-rw-r--r--arch/mn10300/unit-asb2305/pci-iomap.c35
-rw-r--r--arch/nios2/Kconfig9
-rw-r--r--arch/nios2/Kconfig.debug11
-rw-r--r--arch/nios2/boot/Makefile7
-rw-r--r--arch/nios2/boot/compressed/Makefile19
-rw-r--r--arch/nios2/boot/compressed/console.c125
-rw-r--r--arch/nios2/boot/compressed/head.S117
-rw-r--r--arch/nios2/boot/compressed/misc.c187
-rw-r--r--arch/nios2/boot/compressed/vmlinux.lds.S58
-rw-r--r--arch/nios2/boot/compressed/vmlinux.scr (renamed from arch/arm/mach-at91/include/mach/memory.h)24
-rw-r--r--arch/nios2/configs/3c120_defconfig1
-rw-r--r--arch/nios2/include/asm/kgdb.h93
-rw-r--r--arch/nios2/include/asm/processor.h3
-rw-r--r--arch/nios2/include/asm/prom.h22
-rw-r--r--arch/nios2/kernel/Makefile2
-rw-r--r--arch/nios2/kernel/early_printk.c118
-rw-r--r--arch/nios2/kernel/entry.S12
-rw-r--r--arch/nios2/kernel/kgdb.c171
-rw-r--r--arch/nios2/kernel/prom.c52
-rw-r--r--arch/nios2/kernel/setup.c4
-rw-r--r--arch/nios2/mm/fault.c37
-rw-r--r--arch/openrisc/include/asm/uaccess.h4
-rw-r--r--arch/parisc/Kconfig4
-rw-r--r--arch/parisc/Makefile1
-rw-r--r--arch/parisc/hpux/Makefile5
-rw-r--r--arch/parisc/hpux/entry_hpux.S546
-rw-r--r--arch/parisc/hpux/fs.c192
-rw-r--r--arch/parisc/hpux/gate.S107
-rw-r--r--arch/parisc/hpux/ioctl.c72
-rw-r--r--arch/parisc/hpux/sys_hpux.c963
-rw-r--r--arch/parisc/hpux/wrappers.S250
-rw-r--r--arch/parisc/include/asm/processor.h2
-rw-r--r--arch/parisc/include/asm/uaccess.h116
-rw-r--r--arch/parisc/include/uapi/asm/unistd.h481
-rw-r--r--arch/parisc/kernel/entry.S20
-rw-r--r--arch/parisc/kernel/process.c15
-rw-r--r--arch/parisc/kernel/signal.c32
-rw-r--r--arch/parisc/kernel/smp.c3
-rw-r--r--arch/parisc/kernel/syscall_table.S1
-rw-r--r--arch/parisc/mm/init.c72
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc32.h9
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h5
-rw-r--r--arch/powerpc/include/asm/pgtable.h1
-rw-r--r--arch/powerpc/include/asm/pte-40x.h1
-rw-r--r--arch/powerpc/include/asm/pte-44x.h5
-rw-r--r--arch/powerpc/include/asm/pte-8xx.h1
-rw-r--r--arch/powerpc/include/asm/pte-book3e.h1
-rw-r--r--arch/powerpc/include/asm/pte-fsl-booke.h3
-rw-r--r--arch/powerpc/include/asm/pte-hash32.h1
-rw-r--r--arch/powerpc/include/asm/pte-hash64.h1
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c2
-rw-r--r--arch/powerpc/mm/pgtable_64.c2
-rw-r--r--arch/s390/include/asm/pci_io.h1
-rw-r--r--arch/s390/pci/pci.c34
-rw-r--r--arch/sh/include/asm/segment.h2
-rw-r--r--arch/sh/include/asm/uaccess.h4
-rw-r--r--arch/sh/include/asm/uaccess_64.h8
-rw-r--r--arch/sparc/include/asm/uaccess_32.h339
-rw-r--r--arch/sparc/include/asm/uaccess_64.h222
-rw-r--r--arch/x86/include/asm/lguest_hcall.h1
-rw-r--r--arch/x86/include/asm/mmu.h2
-rw-r--r--arch/x86/include/asm/mmu_context.h33
-rw-r--r--arch/x86/include/asm/paravirt.h6
-rw-r--r--arch/x86/include/asm/processor.h33
-rw-r--r--arch/x86/include/asm/special_insns.h6
-rw-r--r--arch/x86/include/asm/tlbflush.h77
-rw-r--r--arch/x86/include/asm/uaccess.h2
-rw-r--r--arch/x86/include/asm/virtext.h5
-rw-r--r--arch/x86/kernel/acpi/sleep.c2
-rw-r--r--arch/x86/kernel/cpu/common.c17
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c8
-rw-r--r--arch/x86/kernel/cpu/mcheck/p5.c3
-rw-r--r--arch/x86/kernel/cpu/mcheck/winchip.c3
-rw-r--r--arch/x86/kernel/cpu/mtrr/cyrix.c6
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c6
-rw-r--r--arch/x86/kernel/cpu/perf_event.c76
-rw-r--r--arch/x86/kernel/cpu/perf_event.h2
-rw-r--r--arch/x86/kernel/head32.c1
-rw-r--r--arch/x86/kernel/head64.c2
-rw-r--r--arch/x86/kernel/i387.c3
-rw-r--r--arch/x86/kernel/process.c5
-rw-r--r--arch/x86/kernel/process_32.c2
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kernel/setup.c2
-rw-r--r--arch/x86/kernel/xsave.c3
-rw-r--r--arch/x86/kvm/svm.c2
-rw-r--r--arch/x86/kvm/vmx.c10
-rw-r--r--arch/x86/lguest/boot.c173
-rw-r--r--arch/x86/mm/fault.c2
-rw-r--r--arch/x86/mm/init.c13
-rw-r--r--arch/x86/mm/tlb.c3
-rw-r--r--arch/x86/power/cpu.c11
-rw-r--r--arch/x86/realmode/init.c2
-rw-r--r--arch/x86/xen/enlighten.c4
-rw-r--r--arch/xtensa/include/asm/uaccess.h90
-rw-r--r--drivers/acpi/processor_idle.c48
-rw-r--r--drivers/block/Kconfig13
-rw-r--r--drivers/block/brd.c14
-rw-r--r--drivers/block/virtio_blk.c12
-rw-r--r--drivers/bus/mvebu-mbus.c286
-rw-r--r--drivers/char/agp/agp.h5
-rw-r--r--drivers/char/agp/generic.c11
-rw-r--r--drivers/char/agp/intel-gtt.c14
-rw-r--r--drivers/char/tpm/tpm-interface.c6
-rw-r--r--drivers/char/tpm/tpm.h5
-rw-r--r--drivers/char/tpm/tpm2-cmd.c59
-rw-r--r--drivers/char/tpm/tpm_crb.c20
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c20
-rw-r--r--drivers/char/tpm/tpm_tis.c37
-rw-r--r--drivers/char/virtio_console.c5
-rw-r--r--drivers/clk/at91/pmc.c9
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c23
-rw-r--r--drivers/clk/shmobile/Makefile1
-rw-r--r--drivers/clk/shmobile/clk-sh73a0.c218
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c1
-rw-r--r--drivers/clocksource/Kconfig20
-rw-r--r--drivers/clocksource/Makefile7
-rw-r--r--drivers/clocksource/asm9260_timer.c220
-rw-r--r--drivers/clocksource/rockchip_timer.c180
-rw-r--r--drivers/clocksource/timer-atlas7.c (renamed from drivers/clocksource/timer-marco.c)15
-rw-r--r--drivers/clocksource/timer-digicolor.c199
-rw-r--r--drivers/clocksource/versatile.c4
-rw-r--r--drivers/cpuidle/Kconfig.arm1
-rw-r--r--drivers/cpuidle/cpuidle-exynos.c76
-rw-r--r--drivers/cpuidle/cpuidle.c94
-rw-r--r--drivers/crypto/ux500/cryp/cryp_core.c4
-rw-r--r--drivers/crypto/ux500/hash/hash_core.c2
-rw-r--r--drivers/dma/Kconfig11
-rw-r--r--drivers/dma/Makefile3
-rw-r--r--drivers/dma/amba-pl08x.c156
-rw-r--r--drivers/dma/at_hdmac.c130
-rw-r--r--drivers/dma/at_hdmac_regs.h3
-rw-r--r--drivers/dma/at_xdmac.c186
-rw-r--r--drivers/dma/bcm2835-dma.c46
-rw-r--r--drivers/dma/coh901318.c153
-rw-r--r--drivers/dma/cppi41.c30
-rw-r--r--drivers/dma/dma-jz4740.c20
-rw-r--r--drivers/dma/dmaengine.c84
-rw-r--r--drivers/dma/dmatest.c35
-rw-r--r--drivers/dma/dw/core.c101
-rw-r--r--drivers/dma/dw/platform.c4
-rw-r--r--drivers/dma/dw/regs.h4
-rw-r--r--drivers/dma/edma.c73
-rw-r--r--drivers/dma/ep93xx_dma.c43
-rw-r--r--drivers/dma/fsl-edma.c123
-rw-r--r--drivers/dma/fsldma.c97
-rw-r--r--drivers/dma/fsldma.h4
-rw-r--r--drivers/dma/img-mdc-dma.c1011
-rw-r--r--drivers/dma/imx-dma.c108
-rw-r--r--drivers/dma/imx-sdma.c150
-rw-r--r--drivers/dma/intel_mid_dma.c25
-rw-r--r--drivers/dma/ioat/dma_v3.c25
-rw-r--r--drivers/dma/ioat/hw.h5
-rw-r--r--drivers/dma/ioat/pci.c5
-rw-r--r--drivers/dma/ipu/ipu_idmac.c96
-rw-r--r--drivers/dma/k3dma.c203
-rw-r--r--drivers/dma/mmp_pdma.c109
-rw-r--r--drivers/dma/mmp_tdma.c85
-rw-r--r--drivers/dma/moxart-dma.c25
-rw-r--r--drivers/dma/mpc512x_dma.c111
-rw-r--r--drivers/dma/mv_xor.c9
-rw-r--r--drivers/dma/mxs-dma.c65
-rw-r--r--drivers/dma/nbpfaxi.c112
-rw-r--r--drivers/dma/of-dma.c4
-rw-r--r--drivers/dma/omap-dma.c69
-rw-r--r--drivers/dma/pch_dma.c8
-rw-r--r--drivers/dma/pl330.c230
-rw-r--r--drivers/dma/qcom_bam_dma.c85
-rw-r--r--drivers/dma/s3c24xx-dma.c73
-rw-r--r--drivers/dma/sa11x0-dma.c157
-rw-r--r--drivers/dma/sh/Kconfig14
-rw-r--r--drivers/dma/sh/Makefile1
-rw-r--r--drivers/dma/sh/rcar-dmac.c1770
-rw-r--r--drivers/dma/sh/rcar-hpbdma.c6
-rw-r--r--drivers/dma/sh/shdma-base.c72
-rw-r--r--drivers/dma/sh/shdmac.c23
-rw-r--r--drivers/dma/sirf-dma.c59
-rw-r--r--drivers/dma/ste_dma40.c63
-rw-r--r--drivers/dma/sun6i-dma.c160
-rw-r--r--drivers/dma/tegra20-apb-dma.c42
-rw-r--r--drivers/dma/timb_dma.c8
-rw-r--r--drivers/dma/txx9dmac.c9
-rw-r--r--drivers/dma/xilinx/xilinx_vdma.c29
-rw-r--r--drivers/firewire/core-transaction.c4
-rw-r--r--drivers/firewire/ohci.c5
-rw-r--r--drivers/firewire/sbp2.c11
-rw-r--r--drivers/gpu/Makefile5
-rw-r--r--drivers/gpu/drm/Kconfig6
-rw-r--r--drivers/gpu/drm/Makefile3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/Makefile7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/cik_regs.h13
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c39
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device.c243
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c420
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h53
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c135
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c64
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c4
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c111
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h40
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c44
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c56
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_module.c6
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c321
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c450
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c33
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c32
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h65
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process.c40
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c34
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c155
-rw-r--r--drivers/gpu/drm/amd/include/cik_structs.h293
-rw-r--r--drivers/gpu/drm/amd/include/kgd_kfd_interface.h49
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c5
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c21
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/Kconfig11
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/Makefile7
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c406
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c579
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h213
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.c667
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.h398
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c319
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c856
-rw-r--r--drivers/gpu/drm/bochs/bochs_fbdev.c14
-rw-r--r--drivers/gpu/drm/bochs/bochs_kms.c5
-rw-r--r--drivers/gpu/drm/bridge/Kconfig8
-rw-r--r--drivers/gpu/drm/bridge/Makefile1
-rw-r--r--drivers/gpu/drm/bridge/dw_hdmi.c (renamed from drivers/gpu/drm/imx/imx-hdmi.c)717
-rw-r--r--drivers/gpu/drm/bridge/dw_hdmi.h (renamed from drivers/gpu/drm/imx/imx-hdmi.h)4
-rw-r--r--drivers/gpu/drm/bridge/ptn3460.c310
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c12
-rw-r--r--drivers/gpu/drm/drm_atomic.c751
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c321
-rw-r--r--drivers/gpu/drm/drm_bridge.c91
-rw-r--r--drivers/gpu/drm/drm_cache.c13
-rw-r--r--drivers/gpu/drm/drm_crtc.c651
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c2
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h6
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c31
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c2
-rw-r--r--drivers/gpu/drm/drm_fops.c89
-rw-r--r--drivers/gpu/drm/drm_info.c24
-rw-r--r--drivers/gpu/drm/drm_internal.h1
-rw-r--r--drivers/gpu/drm/drm_ioctl.c13
-rw-r--r--drivers/gpu/drm/drm_irq.c22
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c6
-rw-r--r--drivers/gpu/drm/drm_modes.c183
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c42
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c97
-rw-r--r--drivers/gpu/drm/drm_sysfs.c132
-rw-r--r--drivers/gpu/drm/exynos/Kconfig25
-rw-r--r--drivers/gpu/drm/exynos/Makefile4
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c990
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c67
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.h1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c247
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.h8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h78
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c14
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c192
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c152
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.h18
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c132
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c165
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c22
-rw-r--r--drivers/gpu/drm/i2c/adv7511.c3
-rw-r--r--drivers/gpu/drm/i915/Kconfig2
-rw-r--r--drivers/gpu/drm/i915/Makefile5
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.c131
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c442
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c45
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c24
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h432
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c672
-rw-r--r--drivers/gpu/drm/i915/i915_gem_batch_pool.c137
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c114
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c11
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c145
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c170
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h35
-rw-r--r--drivers/gpu/drm/i915/i915_gem_render_state.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_userptr.c20
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c93
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c161
-rw-r--r--drivers/gpu/drm/i915/i915_params.c14
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h410
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c2
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c133
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h69
-rw-r--r--drivers/gpu/drm/i915/intel_atomic.c237
-rw-r--r--drivers/gpu/drm/i915/intel_atomic_plane.c246
-rw-r--r--drivers/gpu/drm/i915/intel_audio.c2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c45
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h25
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c19
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c130
-rw-r--r--drivers/gpu/drm/i915/intel_display.c2171
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c276
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c19
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h201
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.c835
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.h75
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_cmd.c437
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_cmd.h78
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_panel_vbt.c322
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_pll.c12
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c23
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c701
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c15
-rw-r--r--drivers/gpu/drm/i915/intel_fifo_underrun.c2
-rw-r--r--drivers/gpu/drm/i915/intel_frontbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c51
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c385
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.h43
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c19
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c46
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c16
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c1083
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c308
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen6.c25
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen7.c25
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen8.c25
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen9.c25
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c289
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h37
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c17
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c34
-rw-r--r--drivers/gpu/drm/i915/intel_sideband.c30
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c394
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c13
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c1148
-rw-r--r--drivers/gpu/drm/imx/Kconfig3
-rw-r--r--drivers/gpu/drm/imx/Makefile2
-rw-r--r--drivers/gpu/drm/imx/dw_hdmi-imx.c258
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c87
-rw-r--r--drivers/gpu/drm/imx/imx-drm.h2
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c8
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c28
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c78
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c7
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c12
-rw-r--r--drivers/gpu/drm/msm/Kconfig1
-rw-r--r--drivers/gpu/drm/msm/Makefile9
-rw-r--r--drivers/gpu/drm/msm/adreno/a2xx.xml.h6
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx.xml.h248
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx.xml.h420
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_common.xml.h6
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h41
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.xml.h11
-rw-r--r--drivers/gpu/drm/msm/dsi/mmss_cc.xml.h11
-rw-r--r--drivers/gpu/drm/msm/dsi/sfpb.xml.h11
-rw-r--r--drivers/gpu/drm/msm/edp/edp.c208
-rw-r--r--drivers/gpu/drm/msm/edp/edp.h85
-rw-r--r--drivers/gpu/drm/msm/edp/edp.xml.h292
-rw-r--r--drivers/gpu/drm/msm/edp/edp_aux.c268
-rw-r--r--drivers/gpu/drm/msm/edp/edp_bridge.c120
-rw-r--r--drivers/gpu/drm/msm/edp/edp_connector.c161
-rw-r--r--drivers/gpu/drm/msm/edp/edp_ctrl.c1373
-rw-r--r--drivers/gpu/drm/msm/edp/edp_phy.c106
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c145
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.h9
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.xml.h106
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c14
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_connector.c4
-rw-r--r--drivers/gpu/drm/msm/hdmi/qfprom.xml.h11
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h55
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c65
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c119
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c34
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h19
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c154
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c104
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h245
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c230
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c127
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c56
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h19
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c216
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c5
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp_common.xml.h28
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp_format.c108
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp_kms.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp_kms.h24
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c50
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c13
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h14
-rw-r--r--drivers/gpu/drm/msm/msm_fb.c4
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c13
-rw-r--r--drivers/gpu/drm/msm/msm_kms.h5
-rw-r--r--drivers/gpu/drm/nouveau/Kbuild66
-rw-r--r--drivers/gpu/drm/nouveau/Kconfig2
-rw-r--r--drivers/gpu/drm/nouveau/Makefile400
-rw-r--r--drivers/gpu/drm/nouveau/core/core/gpuobj.c323
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c172
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/copy/nve0.c176
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/acpi.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv50.c475
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nvc0.c357
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nve0.c324
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/priv.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.h252
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/priv.h48
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h30
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h36
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h18
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h202
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv20.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv50.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h270
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h26
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c70
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c96
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c162
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c71
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h91
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nv50.h46
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/client.h57
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h184
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/engctx.h54
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/engine.h57
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/enum.h24
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/gpuobj.h71
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/handle.h34
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/ioctl.h6
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/mm.h40
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/namedb.h56
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/option.h20
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/parent.h62
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/ramht.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/bsp.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/copy.h13
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/crypt.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/disp.h36
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/falcon.h83
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/fifo.h126
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/graph.h86
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/mpeg.h63
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/perfmon.h38
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/ppp.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/software.h51
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/vp.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/xtensa.h38
l---------drivers/gpu/drm/nouveau/core/include/nvif/class.h1
l---------drivers/gpu/drm/nouveau/core/include/nvif/event.h1
l---------drivers/gpu/drm/nouveau/core/include/nvif/ioctl.h1
l---------drivers/gpu/drm/nouveau/core/include/nvif/unpack.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bar.h37
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios.h35
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/M0205.h32
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/M0209.h30
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h29
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h28
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/disp.h48
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h35
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h12
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h26
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h14
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h25
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h27
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bus.h53
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h166
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/devinit.h35
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h159
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fuse.h30
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/gpio.h47
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/i2c.h136
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ibus.h35
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/instmem.h52
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ltc.h35
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/mc.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/mxm.h37
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/pwr.h56
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/therm.h83
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/timer.h64
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/vm.h135
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/volt.h61
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/base.c149
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c220
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/priv.h32
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h20
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pll.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h40
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h55
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h33
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/priv.h76
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fuse/priv.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h67
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h34
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h89
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h40
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/priv.h56
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h22
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/priv.h38
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h22
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/base.c272
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c201
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/priv.h44
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/priv.h159
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/base.c483
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h19
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/Kbuild (renamed from drivers/gpu/drm/nouveau/dispnv04/Makefile)0
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/dac.c22
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/dfp.c6
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/disp.c20
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/disp.h6
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/hw.c24
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/hw.h4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvnv04.c8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvnv17.c10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/class.h (renamed from drivers/gpu/drm/nouveau/nvif/class.h)23
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/client.h (renamed from drivers/gpu/drm/nouveau/nvif/client.h)6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/device.h61
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/driver.h (renamed from drivers/gpu/drm/nouveau/nvif/driver.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/event.h (renamed from drivers/gpu/drm/nouveau/nvif/event.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/ioctl.h (renamed from drivers/gpu/drm/nouveau/nvif/ioctl.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/list.h (renamed from drivers/gpu/drm/nouveau/nvif/list.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/notify.h (renamed from drivers/gpu/drm/nouveau/nvif/notify.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/object.h (renamed from drivers/gpu/drm/nouveau/nvif/object.h)2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/os.h (renamed from drivers/gpu/drm/nouveau/core/os.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/unpack.h (renamed from drivers/gpu/drm/nouveau/nvif/unpack.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/client.h55
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/debug.h (renamed from drivers/gpu/drm/nouveau/core/include/core/debug.h)6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/device.h101
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h62
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h51
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/engine.h56
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/enum.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/event.h (renamed from drivers/gpu/drm/nouveau/core/include/core/event.h)27
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h64
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/handle.h34
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h7
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/mm.h40
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h53
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/notify.h (renamed from drivers/gpu/drm/nouveau/core/include/core/notify.h)5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/object.h (renamed from drivers/gpu/drm/nouveau/core/include/core/object.h)109
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/option.h17
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/os.h4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/parent.h58
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/printk.h (renamed from drivers/gpu/drm/nouveau/core/include/core/printk.h)13
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h20
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h (renamed from drivers/gpu/drm/nouveau/core/include/core/subdev.h)55
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h13
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/device.h (renamed from drivers/gpu/drm/nouveau/core/include/engine/device.h)3
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h26
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h81
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h126
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h86
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h62
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h7
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h7
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h34
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h50
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h35
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h33
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0203.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h)12
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h29
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h27
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bit.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h)4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bmp.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h)10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h27
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h)10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h26
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h)16
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h39
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h31
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/extdev.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h)9
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/fan.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/fan.h)4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h)10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/i2c.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h)10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/image.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h)4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/init.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h)8
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pcir.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h)6
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h)18
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pll.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h)10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h)12
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h)8
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/therm.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h)15
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h11
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h21
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h23
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/xpio.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h)5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h50
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h161
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h154
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h28
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h44
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h135
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h32
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h48
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h31
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h28
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h104
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h34
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h53
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h79
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h61
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/vga.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/vga.h)0
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h58
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c24
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_agp.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c126
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.h13
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c22
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c102
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c69
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c44
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c33
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hwmon.c98
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_nvif.c24
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_platform.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_platform.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_reg.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sgdma.c17
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sysfs.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c66
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c165
-rw-r--r--drivers/gpu/drm/nouveau/nv84_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvif/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvif/client.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvif/device.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvif/device.h62
-rw-r--r--drivers/gpu/drm/nouveau/nvif/notify.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvif/object.c8
l---------drivers/gpu/drm/nouveau/nvif/os.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/Kbuild17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/client.c (renamed from drivers/gpu/drm/nouveau/core/core/client.c)93
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/engctx.c (renamed from drivers/gpu/drm/nouveau/core/core/engctx.c)130
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/engine.c (renamed from drivers/gpu/drm/nouveau/core/core/engine.c)35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/enum.c (renamed from drivers/gpu/drm/nouveau/core/core/enum.c)14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/event.c (renamed from drivers/gpu/drm/nouveau/core/core/event.c)3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c316
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/handle.c (renamed from drivers/gpu/drm/nouveau/core/core/handle.c)97
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/ioctl.c (renamed from drivers/gpu/drm/nouveau/core/core/ioctl.c)170
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/mm.c (renamed from drivers/gpu/drm/nouveau/core/core/mm.c)71
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/namedb.c (renamed from drivers/gpu/drm/nouveau/core/core/namedb.c)108
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/notify.c (renamed from drivers/gpu/drm/nouveau/core/core/notify.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/object.c (renamed from drivers/gpu/drm/nouveau/core/core/object.c)106
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/option.c (renamed from drivers/gpu/drm/nouveau/core/core/option.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/parent.c (renamed from drivers/gpu/drm/nouveau/core/core/parent.c)56
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/printk.c (renamed from drivers/gpu/drm/nouveau/core/core/printk.c)35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/ramht.c (renamed from drivers/gpu/drm/nouveau/core/core/ramht.c)46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/subdev.c (renamed from drivers/gpu/drm/nouveau/core/core/subdev.c)60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/Kbuild19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/bsp/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c (renamed from drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c)63
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/com.fuc (renamed from drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc)58
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c166
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c173
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c (renamed from drivers/gpu/drm/nouveau/core/engine/copy/nva3.c)112
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/cipher/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c (renamed from drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c)136
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/acpi.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/acpi.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/acpi.h8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/base.c)287
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/ctrl.c)66
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c358
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c326
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/gm100.c)97
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/nv04.c)32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/nv10.c)90
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/nv20.c)52
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/nv30.c)62
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c (renamed from drivers/gpu/drm/nouveau/core/engine/device/nv40.c)208
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c478
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/base.c)84
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/conn.c)49
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h (renamed from drivers/gpu/drm/nouveau/core/engine/disp/conn.h)28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c)10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/dport.c)30
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h (renamed from drivers/gpu/drm/nouveau/core/engine/disp/dport.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nv84.c)72
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nv94.c)69
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c)289
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nve0.c)96
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c)76
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/gm107.c)64
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gm204.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/gm204.c)65
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nva0.c)56
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nva3.c)54
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf110.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c)12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c)10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c)8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf110.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c)8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/hdminve0.c)8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv04.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nv04.c)60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/nv50.c)260
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h226
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/outp.c)53
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h (renamed from drivers/gpu/drm/nouveau/core/engine/disp/outp.h)31
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c)53
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h (renamed from drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h)21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c)42
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h42
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c)74
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf110.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c)63
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm204.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c)31
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c)10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/vga.c (renamed from drivers/gpu/drm/nouveau/core/engine/disp/vga.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/Kbuild5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/base.c (renamed from drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c)45
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c)57
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/gf110.c (renamed from drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c)57
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/nv04.c (renamed from drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c)44
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/nv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c)32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/priv.h28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/falcon.c (renamed from drivers/gpu/drm/nouveau/core/engine/falcon.c)51
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/base.c)115
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c)328
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c)506
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c)537
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv108.c)17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c)17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c)170
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv04.h)39
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c)77
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c)87
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c)101
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c)223
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c)330
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h199
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c)73
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c)175
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c)101
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c)186
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c)177
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c)244
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c)185
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxgk110b.c)55
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c)177
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c)49
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c)138
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c)69
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctx.h)38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c)324
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/com.fuc (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc)2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc)2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc)2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5 (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/macros.fuc (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/os.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c)633
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h250
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c)101
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c)115
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c)107
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c)131
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c)129
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nve4.c)193
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c)171
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/gk110b.c)97
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv108.c)163
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c)35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/gm107.c)207
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv04.c)742
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv10.c)432
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv20.c)191
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv25.c)114
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c)80
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv30.c)130
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv34.c)118
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv35.c)116
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv40.c)249
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv40.h)16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/graph/nv50.c)326
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/regs.h (renamed from drivers/gpu/drm/nouveau/core/engine/graph/regs.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/Kbuild5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c (renamed from drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c)62
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c (renamed from drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c)111
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h (renamed from drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h)6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c (renamed from drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c)35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c (renamed from drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c)78
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c)91
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c (renamed from drivers/gpu/drm/nouveau/core/engine/vp/nv98.c)83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c)83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c (renamed from drivers/gpu/drm/nouveau/core/engine/vp/nve0.c)83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msppp/Kbuild2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c (renamed from drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c)83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c)83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c (renamed from drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c)85
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c)83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c (renamed from drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c)83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/Kbuild9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c (renamed from drivers/gpu/drm/nouveau/core/engine/perfmon/base.c)205
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/daemon.c (renamed from drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c)31
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/g84.c65
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c)108
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.h15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/gk104.c148
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c57
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/gt215.c (renamed from drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c)69
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c (renamed from drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c)85
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.h24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/nv50.c57
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h90
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/g98.fuc0s (renamed from drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc)104
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/g98.fuc0s.h (renamed from drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h)54
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c (renamed from drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c)113
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sw/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.c (renamed from drivers/gpu/drm/nouveau/core/engine/software/nvc0.c)92
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.c (renamed from drivers/gpu/drm/nouveau/core/engine/software/nv04.c)97
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.c (renamed from drivers/gpu/drm/nouveau/core/engine/software/nv10.c)86
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c (renamed from drivers/gpu/drm/nouveau/core/engine/software/nv50.c)153
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.h45
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/vp/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c (renamed from drivers/gpu/drm/nouveau/core/engine/vp/nv84.c)63
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c (renamed from drivers/gpu/drm/nouveau/core/engine/xtensa.c)70
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c144
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c219
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bar/gk20a.c)26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c)136
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h30
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild37
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0203.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0205.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/M0205.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0209.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/M0209.c)14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/P0260.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c)12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/base.c)91
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/bit.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/bit.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/boost.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/boost.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/conn.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/conn.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/cstep.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/dcb.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c)21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/disp.c)35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/dp.c)22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/fan.c)8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/gpio.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c)10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/i2c.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c)14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/image.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/image.c)5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/init.c)194
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/mxm.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/mxm.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/npde.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/npde.c)5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/pcir.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c)5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/perf.c)18
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/pll.c)19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/priv.h)10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/ramcfg.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c)40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c)7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowrom.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/therm.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/therm.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/timing.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/vmap.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/volt.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/xpio.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bios/xpio.c)10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/Kbuild6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/g94.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c)17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c)26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h (renamed from drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h)24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.h21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv31.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c)21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/base.c)204
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c)132
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c)142
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c)114
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c)153
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.h18
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/mcp77.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c)90
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c)54
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c)87
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c)88
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.h28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/pll.h11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/pllgt215.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c)8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/pllnv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/seq.h (renamed from drivers/gpu/drm/nouveau/core/subdev/clock/seq.h)3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/base.c)43
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c)22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c)28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c)51
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c)22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gt215.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c)44
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c)28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c)64
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.h22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv05.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c)16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv10.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c)16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv1a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c)10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv20.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c)14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c)39
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/priv.h34
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild45
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/base.c)58
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c)60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c)21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c)29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/gm107.c)19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/mcp77.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/mcp89.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c)26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.h53
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c)19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c)17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c)29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c)19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.h14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c)19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c)98
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h31
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h74
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h)40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c)178
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c)241
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c)33
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramgm107.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c)202
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c)46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c)24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c)25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c)41
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c)21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c)21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c)21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c)111
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h)3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/regsnv04.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/fb/regsnv04.h)5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c)3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c)3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fuse/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fuse/base.c)25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fuse/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fuse/gf100.c)29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fuse/gm107.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fuse/gm107.c)24
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fuse/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/fuse/g80.c)41
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fuse/priv.h7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/gpio/base.c)118
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c (renamed from drivers/gpu/drm/nouveau/core/subdev/gpio/nv94.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf110.c (renamed from drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c)33
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c)29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c (renamed from drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h64
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c)70
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/base.c)300
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bit.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c)35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/g94.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c)89
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gf110.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c)72
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gf117.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c)17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm204.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c)60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c)60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv4e.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c)60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c)58
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv50.h32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/pad.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/pad.h)32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/padnv94.c)35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm204.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c)19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padnv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/padnv04.c)5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/port.h (renamed from drivers/gpu/drm/nouveau/core/subdev/i2c/port.h)6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/priv.h87
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ibus/nvc0.c)47
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c)53
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c)25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/instmem/base.c)75
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c)97
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c)51
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c)66
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h54
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ltc/base.c)30
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c)40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c)7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c)19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h (renamed from drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h)46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/base.c)72
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c)29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c)39
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/gk20a.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c)25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c)13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c)11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c)25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c480
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c)95
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c)70
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c (renamed from drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c)74
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c (renamed from drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c)80
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c)97
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mxm/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mxm/base.c)49
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mxm/mxms.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c)20
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mxm/mxms.h22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mxm/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c)40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c268
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/arith.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/arith.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3 (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf110.fuc4 (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf110.fuc4.h (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5 (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3 (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h)4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/i2c_.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/i2c_.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/idle.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/os.h (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc)0
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf110.c (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/gk104.c)62
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c)27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c229
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c (renamed from drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c)37
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c200
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h43
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/base.c)199
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/fan.c)89
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/fannil.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/fannil.c)15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c)40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c)52
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c)144
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf110.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c)66
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/gm107.c)40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c)51
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/ic.c)22
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c)53
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c)49
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h153
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c (renamed from drivers/gpu/drm/nouveau/core/subdev/therm/temp.c)139
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/Kbuild3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/timer/base.c)23
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/timer/gk20a.c)9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c)48
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.h (renamed from drivers/gpu/drm/nouveau/core/subdev/timer/nv04.h)14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/priv.h (renamed from drivers/gpu/drm/nouveau/core/subdev/timer/priv.h)2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/volt/base.c)65
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c (renamed from drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c)36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/gpio.c (renamed from drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c)16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c)21
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c10
-rw-r--r--drivers/gpu/drm/panel/Kconfig2
-rw-r--r--drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c33
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c63
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c22
-rw-r--r--drivers/gpu/drm/radeon/Makefile8
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c4
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c29
-rw-r--r--drivers/gpu/drm/radeon/btc_dpm.c2
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.c57
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.h1
-rw-r--r--drivers/gpu/drm/radeon/ci_smc.c2
-rw-r--r--drivers/gpu/drm/radeon/cik.c66
-rw-r--r--drivers/gpu/drm/radeon/cik_reg.h167
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c29
-rw-r--r--drivers/gpu/drm/radeon/cypress_dpm.c2
-rw-r--r--drivers/gpu/drm/radeon/dce3_1_afmt.c264
-rw-r--r--drivers/gpu/drm/radeon/dce6_afmt.c218
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c7
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c76
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c478
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h15
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h1
-rw-r--r--drivers/gpu/drm/radeon/kv_dpm.c19
-rw-r--r--drivers/gpu/drm/radeon/ni.c18
-rw-r--r--drivers/gpu/drm/radeon/ni_dpm.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c7
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c399
-rw-r--r--drivers/gpu/drm/radeon/radeon.h15
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c36
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h21
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c766
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.h84
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c31
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_kfd.c283
-rw-r--r--drivers/gpu/drm/radeon/radeon_kfd.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c135
-rw-r--r--drivers/gpu/drm/radeon/rs600.c7
-rw-r--r--drivers/gpu/drm/radeon/rs690.c7
-rw-r--r--drivers/gpu/drm/radeon/rv770.c5
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.c4
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.h2
-rw-r--r--drivers/gpu/drm/radeon/si.c5
-rw-r--r--drivers/gpu/drm/radeon/si_dpm.c75
-rw-r--r--drivers/gpu/drm/radeon/si_dpm.h1
-rw-r--r--drivers/gpu/drm/radeon/sid.h10
-rw-r--r--drivers/gpu/drm/radeon/sumo_dpm.c4
-rw-r--r--drivers/gpu/drm/radeon/sumo_dpm.h3
-rw-r--r--drivers/gpu/drm/radeon/trinity_dpm.c2
-rw-r--r--drivers/gpu/drm/rcar-du/Kconfig2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c95
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.h1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c6
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.h2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_encoder.c34
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.c21
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c18
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c15
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c20
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_regs.h5
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vgacon.c1
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig12
-rw-r--r--drivers/gpu/drm/rockchip/Makefile2
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c341
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c1
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.c9
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c1
-rw-r--r--drivers/gpu/drm/shmobile/Kconfig4
-rw-r--r--drivers/gpu/drm/sti/Kconfig3
-rw-r--r--drivers/gpu/drm/sti/Makefile4
-rw-r--r--drivers/gpu/drm/sti/sti_awg_utils.c182
-rw-r--r--drivers/gpu/drm/sti/sti_awg_utils.h34
-rw-r--r--drivers/gpu/drm/sti/sti_drm_crtc.c6
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c560
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c11
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c11
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c190
-rw-r--r--drivers/gpu/drm/sti/sti_hqvdp.c2
-rw-r--r--drivers/gpu/drm/sti/sti_tvout.c118
-rw-r--r--drivers/gpu/drm/tegra/dc.c954
-rw-r--r--drivers/gpu/drm/tegra/drm.c140
-rw-r--r--drivers/gpu/drm/tegra/drm.h91
-rw-r--r--drivers/gpu/drm/tegra/dsi.c578
-rw-r--r--drivers/gpu/drm/tegra/fb.c25
-rw-r--r--drivers/gpu/drm/tegra/gem.c39
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c327
-rw-r--r--drivers/gpu/drm/tegra/mipi-phy.c25
-rw-r--r--drivers/gpu/drm/tegra/output.c168
-rw-r--r--drivers/gpu/drm/tegra/rgb.c218
-rw-r--r--drivers/gpu/drm/tegra/sor.c759
-rw-r--r--drivers/gpu/drm/tilcdc/Kconfig2
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c22
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c9
-rw-r--r--drivers/gpu/drm/udl/udl_transfer.c39
-rw-r--r--drivers/gpu/host1x/bus.c201
-rw-r--r--drivers/gpu/host1x/bus.h4
-rw-r--r--drivers/gpu/host1x/dev.c6
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c4
-rw-r--r--drivers/gpu/ipu-v3/ipu-dc.c30
-rw-r--r--drivers/gpu/ipu-v3/ipu-di.c121
-rw-r--r--drivers/idle/intel_idle.c179
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c35
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-digicolor.c120
-rw-r--r--drivers/irqchip/irq-gic-common.c18
-rw-r--r--drivers/irqchip/irq-gic-common.h2
-rw-r--r--drivers/irqchip/irq-gic-v3.c8
-rw-r--r--drivers/irqchip/irq-gic.c9
-rw-r--r--drivers/irqchip/irq-hip04.c9
-rw-r--r--drivers/irqchip/irq-mips-gic.c44
-rw-r--r--drivers/irqchip/irq-mtk-sysirq.c18
-rw-r--r--drivers/irqchip/irq-omap-intc.c22
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c50
-rw-r--r--drivers/lguest/Makefile3
-rw-r--r--drivers/lguest/core.c29
-rw-r--r--drivers/lguest/hypercalls.c7
-rw-r--r--drivers/lguest/lg.h26
-rw-r--r--drivers/lguest/lguest_device.c540
-rw-r--r--drivers/lguest/lguest_user.c221
-rw-r--r--drivers/lguest/page_tables.c75
-rw-r--r--drivers/lguest/x86/core.c203
-rw-r--r--drivers/md/raid1.c3
-rw-r--r--drivers/md/raid10.c3
-rw-r--r--drivers/md/raid5.c3
-rw-r--r--drivers/mfd/88pm860x-core.c2
-rw-r--r--drivers/mfd/Kconfig39
-rw-r--r--drivers/mfd/Makefile4
-rw-r--r--drivers/mfd/da9063-core.c2
-rw-r--r--drivers/mfd/da9063-i2c.c9
-rw-r--r--drivers/mfd/da9150-core.c413
-rw-r--r--drivers/mfd/davinci_voicecodec.c2
-rw-r--r--drivers/mfd/db8500-prcmu.c9
-rw-r--r--drivers/mfd/dln2.c71
-rw-r--r--drivers/mfd/hi6421-pmic-core.c2
-rw-r--r--drivers/mfd/intel_soc_pmic_core.c3
-rw-r--r--drivers/mfd/intel_soc_pmic_core.h2
-rw-r--r--drivers/mfd/intel_soc_pmic_crc.c2
-rw-r--r--drivers/mfd/lm3533-core.c2
-rw-r--r--drivers/mfd/lpc_sch.c1
-rw-r--r--drivers/mfd/max77686.c29
-rw-r--r--drivers/mfd/mc13xxx-i2c.c2
-rw-r--r--drivers/mfd/mc13xxx-spi.c2
-rw-r--r--drivers/mfd/omap-usb-host.c10
-rw-r--r--drivers/mfd/pcf50633-core.c2
-rw-r--r--drivers/mfd/qcom_rpm.c581
-rw-r--r--drivers/mfd/retu-mfd.c2
-rw-r--r--drivers/mfd/rt5033.c142
-rw-r--r--drivers/mfd/rtsx_usb.c18
-rw-r--r--drivers/mfd/smsc-ece1099.c2
-rw-r--r--drivers/mfd/sun6i-prcm.c14
-rw-r--r--drivers/mfd/tps65217.c2
-rw-r--r--drivers/mfd/tps65218.c2
-rw-r--r--drivers/mfd/twl-core.c8
-rw-r--r--drivers/mfd/twl6040.c4
-rw-r--r--drivers/mfd/wm8994-core.c6
-rw-r--r--drivers/mtd/bcm47xxpart.c43
-rw-r--r--drivers/mtd/chips/map_ram.c1
-rw-r--r--drivers/mtd/chips/map_rom.c13
-rw-r--r--drivers/mtd/devices/st_spi_fsm.c137
-rw-r--r--drivers/mtd/maps/physmap_of.c10
-rw-r--r--drivers/mtd/mtdblock.c10
-rw-r--r--drivers/mtd/mtdconcat.c3
-rw-r--r--drivers/mtd/mtdcore.c28
-rw-r--r--drivers/mtd/nand/Kconfig7
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/ams-delta.c6
-rw-r--r--drivers/mtd/nand/atmel_nand.c31
-rw-r--r--drivers/mtd/nand/denali.c40
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c9
-rw-r--r--drivers/mtd/nand/hisi504_nand.c891
-rw-r--r--drivers/mtd/nand/jz4740_nand.c29
-rw-r--r--drivers/mtd/nand/nand_base.c31
-rw-r--r--drivers/mtd/nand/nandsim.c7
-rw-r--r--drivers/mtd/nand/omap2.c31
-rw-r--r--drivers/mtd/nand/sunxi_nand.c2
-rw-r--r--drivers/mtd/nftlmount.c18
-rw-r--r--drivers/mtd/spi-nor/fsl-quadspi.c93
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c63
-rw-r--r--drivers/net/arcnet/com20020-pci.c21
-rw-r--r--drivers/net/ethernet/3com/3c589_cs.c7
-rw-r--r--drivers/net/ethernet/agere/et131x.c6
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c2
-rw-r--r--drivers/net/ethernet/broadcom/b44.c2
-rw-r--r--drivers/net/ethernet/broadcom/bgmac.c7
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c9
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c1
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h11
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c34
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c19
-rw-r--r--drivers/net/ethernet/sun/sunvnet.c23
-rw-r--r--drivers/net/ipvlan/ipvlan.h2
-rw-r--r--drivers/net/phy/micrel.c28
-rw-r--r--drivers/net/usb/hso.c2
-rw-r--r--drivers/net/usb/r8152.c59
-rw-r--r--drivers/net/virtio_net.c6
-rw-r--r--drivers/net/vxlan.c38
-rw-r--r--drivers/net/wireless/b43/main.c4
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c2
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c5
-rw-r--r--drivers/of/of_pci.c1
-rw-r--r--drivers/of/platform.c1
-rw-r--r--drivers/pcmcia/Kconfig1
-rw-r--r--drivers/pwm/Kconfig24
-rw-r--r--drivers/pwm/Makefile2
-rw-r--r--drivers/pwm/core.c2
-rw-r--r--drivers/pwm/pwm-atmel-hlcdc.c6
-rw-r--r--drivers/pwm/pwm-img.c249
-rw-r--r--drivers/pwm/pwm-sti.c30
-rw-r--r--drivers/pwm/pwm-sun4i.c366
-rw-r--r--drivers/pwm/pwm-tegra.c2
-rw-r--r--drivers/rapidio/devices/tsi721_dma.c8
-rw-r--r--drivers/regulator/qcom_rpm-regulator.c1
-rw-r--r--drivers/rtc/Kconfig118
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-ds1685.c2252
-rw-r--r--drivers/rtc/rtc-isl12022.c3
-rw-r--r--drivers/rtc/rtc-isl12057.c3
-rw-r--r--drivers/scsi/csiostor/csio_init.c9
-rw-r--r--drivers/scsi/virtio_scsi.c6
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c1
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra30.c9
-rw-r--r--drivers/soc/tegra/pmc.c124
-rw-r--r--drivers/soc/ti/Makefile3
-rw-r--r--drivers/soc/ti/knav_qmss_acc.c2
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c9
-rw-r--r--drivers/spi/spi-bcm53xx.c2
-rw-r--r--drivers/ssb/driver_gige.c2
-rw-r--r--drivers/staging/iio/light/isl29028.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/dcache.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_internal.h1
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_lib.c42
-rw-r--r--drivers/usb/gadget/udc/Kconfig1
-rw-r--r--drivers/usb/gadget/udc/at91_udc.c525
-rw-r--r--drivers/usb/gadget/udc/at91_udc.h9
-rw-r--r--drivers/usb/gadget/udc/atmel_usba_udc.c15
-rw-r--r--drivers/usb/host/bcma-hcd.c2
-rw-r--r--drivers/usb/host/ssb-hcd.c2
-rw-r--r--drivers/vhost/net.c11
-rw-r--r--drivers/virtio/Kconfig24
-rw-r--r--drivers/virtio/Makefile3
-rw-r--r--drivers/virtio/virtio.c5
-rw-r--r--drivers/virtio/virtio_balloon.c9
-rw-r--r--drivers/virtio/virtio_mmio.c131
-rw-r--r--drivers/virtio/virtio_pci_common.c94
-rw-r--r--drivers/virtio/virtio_pci_common.h43
-rw-r--r--drivers/virtio/virtio_pci_legacy.c76
-rw-r--r--drivers/virtio/virtio_pci_modern.c695
-rw-r--r--drivers/virtio/virtio_ring.c9
-rw-r--r--drivers/watchdog/Kconfig25
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c21
-rw-r--r--drivers/watchdog/da9063_wdt.c32
-rw-r--r--drivers/watchdog/dw_wdt.c32
-rw-r--r--drivers/watchdog/gpio_wdt.c37
-rw-r--r--drivers/watchdog/hpwdt.c2
-rw-r--r--drivers/watchdog/imgpdc_wdt.c289
-rw-r--r--drivers/watchdog/imx2_wdt.c4
-rw-r--r--drivers/watchdog/it87_wdt.c6
-rw-r--r--drivers/watchdog/jz4740_wdt.c10
-rw-r--r--drivers/watchdog/mtk_wdt.c251
-rw-r--r--drivers/watchdog/omap_wdt.c2
-rw-r--r--drivers/watchdog/retu_wdt.c2
-rw-r--r--drivers/watchdog/rt2880_wdt.c9
-rw-r--r--drivers/watchdog/twl4030_wdt.c2
-rw-r--r--drivers/watchdog/w83627hf_wdt.c14
-rw-r--r--fs/Kconfig22
-rw-r--r--fs/Kconfig.binfmt7
-rw-r--r--fs/Makefile2
-rw-r--r--fs/affs/affs.h2
-rw-r--r--fs/affs/amigaffs.c13
-rw-r--r--fs/affs/bitmap.c1
-rw-r--r--fs/affs/dir.c11
-rw-r--r--fs/affs/file.c49
-rw-r--r--fs/affs/inode.c7
-rw-r--r--fs/affs/namei.c47
-rw-r--r--fs/affs/super.c69
-rw-r--r--fs/befs/linuxvfs.c6
-rw-r--r--fs/binfmt_som.c299
-rw-r--r--fs/coda/dir.c138
-rw-r--r--fs/dax.c534
-rw-r--r--fs/dcache.c149
-rw-r--r--fs/debugfs/inode.c291
-rw-r--r--fs/eventfd.c12
-rw-r--r--fs/exec.c10
-rw-r--r--fs/exofs/inode.c1
-rw-r--r--fs/ext2/Kconfig11
-rw-r--r--fs/ext2/Makefile1
-rw-r--r--fs/ext2/ext2.h10
-rw-r--r--fs/ext2/file.c44
-rw-r--r--fs/ext2/inode.c38
-rw-r--r--fs/ext2/namei.c13
-rw-r--r--fs/ext2/super.c53
-rw-r--r--fs/ext2/xip.c86
-rw-r--r--fs/ext2/xip.h26
-rw-r--r--fs/ext4/ext4.h6
-rw-r--r--fs/ext4/file.c49
-rw-r--r--fs/ext4/indirect.c18
-rw-r--r--fs/ext4/inode.c159
-rw-r--r--fs/ext4/namei.c10
-rw-r--r--fs/ext4/super.c49
-rw-r--r--fs/fat/inode.c2
-rw-r--r--fs/fs-writeback.c62
-rw-r--r--fs/fs_pin.c96
-rw-r--r--fs/gfs2/file.c4
-rw-r--r--fs/inode.c106
-rw-r--r--fs/internal.h2
-rw-r--r--fs/jffs2/compr_rubin.c5
-rw-r--r--fs/jffs2/scan.c5
-rw-r--r--fs/jfs/file.c2
-rw-r--r--fs/libfs.c2
-rw-r--r--fs/mount.h4
-rw-r--r--fs/namei.c143
-rw-r--r--fs/namespace.c44
-rw-r--r--fs/ncpfs/dir.c98
-rw-r--r--fs/ncpfs/ncp_fs_i.h1
-rw-r--r--fs/ncpfs/ncplib_kernel.h30
-rw-r--r--fs/nfsd/nfsfh.h2
-rw-r--r--fs/nfsd/pnfs.h5
-rw-r--r--fs/ocfs2/aops.c242
-rw-r--r--fs/ocfs2/file.c76
-rw-r--r--fs/ocfs2/file.h9
-rw-r--r--fs/ocfs2/inode.c2
-rw-r--r--fs/ocfs2/inode.h2
-rw-r--r--fs/ocfs2/journal.c110
-rw-r--r--fs/ocfs2/journal.h5
-rw-r--r--fs/ocfs2/namei.c284
-rw-r--r--fs/ocfs2/namei.h8
-rw-r--r--fs/ocfs2/ocfs2.h23
-rw-r--r--fs/ocfs2/ocfs2_fs.h14
-rw-r--r--fs/ocfs2/super.c2
-rw-r--r--fs/open.c15
-rw-r--r--fs/proc/generic.c25
-rw-r--r--fs/proc/vmcore.c8
-rw-r--r--fs/proc_namespace.c1
-rw-r--r--fs/read_write.c46
-rw-r--r--fs/reiserfs/inode.c2
-rw-r--r--fs/splice.c23
-rw-r--r--fs/super.c4
-rw-r--r--fs/sync.c8
-rw-r--r--fs/ufs/super.c8
-rw-r--r--include/asm-generic/pci_iomap.h10
-rw-r--r--include/drm/bridge/dw_hdmi.h61
-rw-r--r--include/drm/bridge/ptn3460.h8
-rw-r--r--include/drm/drmP.h8
-rw-r--r--include/drm/drm_atomic.h13
-rw-r--r--include/drm/drm_atomic_helper.h43
-rw-r--r--include/drm/drm_crtc.h120
-rw-r--r--include/drm/drm_crtc_helper.h59
-rw-r--r--include/drm/drm_dp_helper.h1
-rw-r--r--include/drm/drm_fb_helper.h2
-rw-r--r--include/drm/drm_modes.h11
-rw-r--r--include/drm/drm_plane_helper.h5
-rw-r--r--include/dt-bindings/clock/exynos5420.h6
-rw-r--r--include/dt-bindings/clock/r8a7790-clock.h1
-rw-r--r--include/dt-bindings/clock/r8a7791-clock.h2
-rw-r--r--include/dt-bindings/clock/r8a7794-clock.h17
-rw-r--r--include/dt-bindings/clock/rk3288-cru.h4
-rw-r--r--include/dt-bindings/clock/sh73a0-clock.h79
-rw-r--r--include/dt-bindings/clock/stih418-clks.h34
-rw-r--r--include/dt-bindings/clock/vf610-clock.h3
-rw-r--r--include/dt-bindings/dma/sun4i-a10.h56
-rw-r--r--include/dt-bindings/mfd/qcom-rpm.h154
-rw-r--r--include/dt-bindings/pinctrl/omap.h1
-rw-r--r--include/dt-bindings/pinctrl/sun4i-a10.h62
-rw-r--r--include/linux/audit.h3
-rw-r--r--include/linux/backing-dev.h1
-rw-r--r--include/linux/bcm47xx_wdt.h1
-rw-r--r--include/linux/cpuidle.h13
-rw-r--r--include/linux/dcache.h3
-rw-r--r--include/linux/debugfs.h18
-rw-r--r--include/linux/dmaengine.h120
-rw-r--r--include/linux/fs.h56
-rw-r--r--include/linux/fs_pin.h25
-rw-r--r--include/linux/host1x.h18
-rw-r--r--include/linux/irqchip/irq-omap-intc.h2
-rw-r--r--include/linux/kexec.h22
-rw-r--r--include/linux/lguest_launcher.h61
-rw-r--r--include/linux/lockref.h3
-rw-r--r--include/linux/mfd/axp20x.h43
-rw-r--r--include/linux/mfd/da9063/core.h1
-rw-r--r--include/linux/mfd/da9150/core.h68
-rw-r--r--include/linux/mfd/da9150/registers.h1155
-rw-r--r--include/linux/mfd/max77686-private.h1
-rw-r--r--include/linux/mfd/max77686.h28
-rw-r--r--include/linux/mfd/qcom_rpm.h13
-rw-r--r--include/linux/mfd/rt5033-private.h260
-rw-r--r--include/linux/mfd/rt5033.h62
-rw-r--r--include/linux/mfd/syscon/atmel-matrix.h117
-rw-r--r--include/linux/mfd/syscon/atmel-smc.h173
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/mod_devicetable.h4
-rw-r--r--include/linux/mtd/mtd.h1
-rw-r--r--include/linux/mtd/spi-nor.h7
-rw-r--r--include/linux/netdevice.h62
-rw-r--r--include/linux/perf_event.h7
-rw-r--r--include/linux/pid_namespace.h4
-rw-r--r--include/linux/platform_data/cpuidle-exynos.h20
-rw-r--r--include/linux/platform_data/dma-dw.h6
-rw-r--r--include/linux/platform_data/dma-mmp_tdma.h7
-rw-r--r--include/linux/rbtree.h2
-rw-r--r--include/linux/rmap.h2
-rw-r--r--include/linux/rtc/ds1685.h375
-rw-r--r--include/linux/skbuff.h32
-rw-r--r--include/linux/suspend.h16
-rw-r--r--include/linux/tick.h6
-rw-r--r--include/linux/uio.h4
-rw-r--r--include/linux/virtio_mmio.h44
-rw-r--r--include/net/checksum.h5
-rw-r--r--include/net/vxlan.h4
-rw-r--r--include/soc/tegra/fuse.h1
-rw-r--r--include/soc/tegra/pm.h2
-rw-r--r--include/trace/events/ext4.h30
-rw-r--r--include/trace/events/writeback.h60
-rw-r--r--include/uapi/drm/drm.h8
-rw-r--r--include/uapi/drm/drm_fourcc.h3
-rw-r--r--include/uapi/drm/drm_mode.h38
-rw-r--r--include/uapi/drm/i915_drm.h30
-rw-r--r--include/uapi/linux/Kbuild1
-rw-r--r--include/uapi/linux/fou.h1
-rw-r--r--include/uapi/linux/fs.h4
-rw-r--r--include/uapi/linux/if_link.h1
-rw-r--r--include/uapi/linux/kexec.h6
-rw-r--r--include/uapi/linux/som.h154
-rw-r--r--include/uapi/linux/virtio_balloon.h3
-rw-r--r--include/uapi/linux/virtio_blk.h17
-rw-r--r--include/uapi/linux/virtio_config.h2
-rw-r--r--include/uapi/linux/virtio_net.h42
-rw-r--r--include/uapi/linux/virtio_pci.h93
-rw-r--r--include/video/exynos7_decon.h349
-rw-r--r--include/video/imx-ipu-v3.h21
-rw-r--r--ipc/sem.c2
-rw-r--r--kernel/acct.c94
-rw-r--r--kernel/audit.h17
-rw-r--r--kernel/auditsc.c176
-rw-r--r--kernel/events/core.c14
-rw-r--r--kernel/irq/manage.c3
-rw-r--r--kernel/kexec.c23
-rw-r--r--kernel/module.c9
-rw-r--r--kernel/power/suspend.c43
-rw-r--r--kernel/ptrace.c1
-rw-r--r--kernel/sched/idle.c16
-rw-r--r--kernel/seccomp.c4
-rw-r--r--kernel/signal.c4
-rw-r--r--kernel/time/tick-common.c50
-rw-r--r--kernel/time/timekeeping.c48
-rw-r--r--kernel/time/timekeeping.h2
-rw-r--r--lib/Kconfig2
-rw-r--r--lib/Kconfig.debug11
-rw-r--r--lib/lockref.c36
-rw-r--r--lib/pci_iomap.c35
-rw-r--r--mm/Makefile1
-rw-r--r--mm/backing-dev.c10
-rw-r--r--mm/fadvise.c6
-rw-r--r--mm/filemap.c25
-rw-r--r--mm/filemap_xip.c478
-rw-r--r--mm/iov_iter.c17
-rw-r--r--mm/madvise.c2
-rw-r--r--mm/memory.c42
-rw-r--r--mm/page_io.c9
-rw-r--r--net/9p/trans_virtio.c6
-rw-r--r--net/bridge/br_netfilter.c7
-rw-r--r--net/core/dev.c3
-rw-r--r--net/core/filter.c2
-rw-r--r--net/core/pktgen.c2
-rw-r--r--net/core/rtnetlink.c9
-rw-r--r--net/dsa/slave.c9
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/fou.c42
-rw-r--r--net/ipv4/tcp_fastopen.c32
-rw-r--r--net/ipv4/udp_offload.c13
-rw-r--r--net/ipv6/ip6_flowlabel.c4
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/udp_offload.c6
-rw-r--r--net/netfilter/nft_compat.c63
-rw-r--r--net/netfilter/nft_lookup.c1
-rw-r--r--net/openvswitch/flow.c2
-rw-r--r--net/openvswitch/flow_netlink.c4
-rw-r--r--net/rds/cong.c16
-rw-r--r--samples/seccomp/bpf-fancy.c4
-rw-r--r--samples/seccomp/bpf-helper.c6
-rw-r--r--scripts/Makefile1
-rwxr-xr-xscripts/diffconfig1
-rw-r--r--scripts/gdb/Makefile1
-rw-r--r--scripts/gdb/linux/.gitignore2
-rw-r--r--scripts/gdb/linux/Makefile11
-rw-r--r--scripts/gdb/linux/cpus.py135
-rw-r--r--scripts/gdb/linux/dmesg.py65
-rw-r--r--scripts/gdb/linux/modules.py103
-rw-r--r--scripts/gdb/linux/symbols.py177
-rw-r--r--scripts/gdb/linux/tasks.py100
-rw-r--r--scripts/gdb/linux/utils.py156
-rw-r--r--scripts/gdb/vmlinux-gdb.py30
-rw-r--r--security/commoncap.c6
-rw-r--r--security/keys/request_key.c1
-rw-r--r--security/selinux/selinuxfs.c52
-rw-r--r--security/smack/smack_lsm.c16
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c2
-rw-r--r--tools/lguest/Makefile8
-rw-r--r--tools/lguest/lguest.c2016
2269 files changed, 98349 insertions, 57232 deletions
diff --git a/.gitignore b/.gitignore
index 9ac91060ea64..acb6afe6b7a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,7 @@ Module.symvers
/TAGS
/linux
/vmlinux
+/vmlinux-gdb.py
/vmlinuz
/System.map
/Module.markers
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index f2130586ef5d..faf09d4a0ea8 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -190,23 +190,6 @@ X!Edrivers/pnp/system.c
!Idrivers/message/fusion/mptfc.c
!Idrivers/message/fusion/mptlan.c
</sect1>
- <sect1><title>I2O message devices</title>
-!Iinclude/linux/i2o.h
-!Idrivers/message/i2o/core.h
-!Edrivers/message/i2o/iop.c
-!Idrivers/message/i2o/iop.c
-!Idrivers/message/i2o/config-osm.c
-!Edrivers/message/i2o/exec-osm.c
-!Idrivers/message/i2o/exec-osm.c
-!Idrivers/message/i2o/bus-osm.c
-!Edrivers/message/i2o/device.c
-!Idrivers/message/i2o/device.c
-!Idrivers/message/i2o/driver.c
-!Idrivers/message/i2o/pci.c
-!Idrivers/message/i2o/i2o_block.c
-!Idrivers/message/i2o/i2o_scsi.c
-!Idrivers/message/i2o/i2o_proc.c
- </sect1>
</chapter>
<chapter id="snddev">
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 4b592ffbafee..03f1985a4bd1 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -239,6 +239,14 @@
Driver supports dedicated render nodes.
</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term>DRIVER_ATOMIC</term>
+ <listitem><para>
+ Driver supports atomic properties. In this case the driver
+ must implement appropriate obj->atomic_get_property() vfuncs
+ for any modeset objects with driver specific properties.
+ </para></listitem>
+ </varlistentry>
</variablelist>
</sect3>
<sect3>
@@ -1377,7 +1385,7 @@ int max_width, max_height;</synopsis>
<itemizedlist>
<listitem>
DRM_PLANE_TYPE_PRIMARY represents a "main" plane for a CRTC. Primary
- planes are the planes operated upon by by CRTC modesetting and flipping
+ planes are the planes operated upon by CRTC modesetting and flipping
operations described in <xref linkend="drm-kms-crtcops"/>.
</listitem>
<listitem>
@@ -2362,6 +2370,7 @@ void intel_crt_init(struct drm_device *dev)
</sect2>
<sect2>
<title>Modeset Helper Functions Reference</title>
+!Iinclude/drm/drm_crtc_helper.h
!Edrivers/gpu/drm/drm_crtc_helper.c
!Pdrivers/gpu/drm/drm_crtc_helper.c overview
</sect2>
@@ -2564,8 +2573,8 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >Description/Restrictions</td>
</tr>
<tr>
- <td rowspan="25" valign="top" >DRM</td>
- <td rowspan="4" valign="top" >Generic</td>
+ <td rowspan="36" valign="top" >DRM</td>
+ <td rowspan="5" valign="top" >Connector</td>
<td valign="top" >“EDID”</td>
<td valign="top" >BLOB | IMMUTABLE</td>
<td valign="top" >0</td>
@@ -2594,7 +2603,14 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >Contains tiling information for a connector.</td>
</tr>
<tr>
- <td rowspan="1" valign="top" >Plane</td>
+ <td valign="top" >“CRTC_ID”</td>
+ <td valign="top" >OBJECT</td>
+ <td valign="top" >DRM_MODE_OBJECT_CRTC</td>
+ <td valign="top" >Connector</td>
+ <td valign="top" >CRTC that connector is attached to (atomic)</td>
+ </tr>
+ <tr>
+ <td rowspan="11" valign="top" >Plane</td>
<td valign="top" >“type”</td>
<td valign="top" >ENUM | IMMUTABLE</td>
<td valign="top" >{ "Overlay", "Primary", "Cursor" }</td>
@@ -2602,6 +2618,76 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >Plane type</td>
</tr>
<tr>
+ <td valign="top" >“SRC_X”</td>
+ <td valign="top" >RANGE</td>
+ <td valign="top" >Min=0, Max=UINT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout source x coordinate in 16.16 fixed point (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“SRC_Y”</td>
+ <td valign="top" >RANGE</td>
+ <td valign="top" >Min=0, Max=UINT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout source y coordinate in 16.16 fixed point (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“SRC_W”</td>
+ <td valign="top" >RANGE</td>
+ <td valign="top" >Min=0, Max=UINT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout source width in 16.16 fixed point (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“SRC_H”</td>
+ <td valign="top" >RANGE</td>
+ <td valign="top" >Min=0, Max=UINT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout source height in 16.16 fixed point (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“CRTC_X”</td>
+ <td valign="top" >SIGNED_RANGE</td>
+ <td valign="top" >Min=INT_MIN, Max=INT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout CRTC (destination) x coordinate (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“CRTC_Y”</td>
+ <td valign="top" >SIGNED_RANGE</td>
+ <td valign="top" >Min=INT_MIN, Max=INT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout CRTC (destination) y coordinate (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“CRTC_W”</td>
+ <td valign="top" >RANGE</td>
+ <td valign="top" >Min=0, Max=UINT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout CRTC (destination) width (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“CRTC_H”</td>
+ <td valign="top" >RANGE</td>
+ <td valign="top" >Min=0, Max=UINT_MAX</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout CRTC (destination) height (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“FB_ID”</td>
+ <td valign="top" >OBJECT</td>
+ <td valign="top" >DRM_MODE_OBJECT_FB</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Scanout framebuffer (atomic)</td>
+ </tr>
+ <tr>
+ <td valign="top" >“CRTC_ID”</td>
+ <td valign="top" >OBJECT</td>
+ <td valign="top" >DRM_MODE_OBJECT_CRTC</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >CRTC that plane is attached to (atomic)</td>
+ </tr>
+ <tr>
<td rowspan="2" valign="top" >DVI-I</td>
<td valign="top" >“subconnector”</td>
<td valign="top" >ENUM</td>
@@ -3883,6 +3969,7 @@ int num_ioctls;</synopsis>
<title>Runtime Power Management</title>
!Pdrivers/gpu/drm/i915/intel_runtime_pm.c runtime pm
!Idrivers/gpu/drm/i915/intel_runtime_pm.c
+!Idrivers/gpu/drm/i915/intel_uncore.c
</sect2>
<sect2>
<title>Interrupt Handling</title>
@@ -3932,6 +4019,11 @@ int num_ioctls;</synopsis>
</para>
</sect2>
<sect2>
+ <title>Atomic Plane Helpers</title>
+!Pdrivers/gpu/drm/i915/intel_atomic_plane.c atomic plane helpers
+!Idrivers/gpu/drm/i915/intel_atomic_plane.c
+ </sect2>
+ <sect2>
<title>Output Probing</title>
<para>
This section covers output probing and related infrastructure like the
@@ -3951,6 +4043,11 @@ int num_ioctls;</synopsis>
!Idrivers/gpu/drm/i915/intel_psr.c
</sect2>
<sect2>
+ <title>Frame Buffer Compression (FBC)</title>
+!Pdrivers/gpu/drm/i915/intel_fbc.c Frame Buffer Compression (FBC)
+!Idrivers/gpu/drm/i915/intel_fbc.c
+ </sect2>
+ <sect2>
<title>DPIO</title>
!Pdrivers/gpu/drm/i915/i915_reg.h DPIO
<table id="dpiox2">
@@ -4054,10 +4151,31 @@ int num_ioctls;</synopsis>
!Idrivers/gpu/drm/i915/i915_cmd_parser.c
</sect2>
<sect2>
+ <title>Batchbuffer Pools</title>
+!Pdrivers/gpu/drm/i915/i915_gem_batch_pool.c batch pool
+!Idrivers/gpu/drm/i915/i915_gem_batch_pool.c
+ </sect2>
+ <sect2>
<title>Logical Rings, Logical Ring Contexts and Execlists</title>
!Pdrivers/gpu/drm/i915/intel_lrc.c Logical Rings, Logical Ring Contexts and Execlists
!Idrivers/gpu/drm/i915/intel_lrc.c
</sect2>
+ <sect2>
+ <title>Global GTT views</title>
+!Pdrivers/gpu/drm/i915/i915_gem_gtt.c Global GTT views
+!Idrivers/gpu/drm/i915/i915_gem_gtt.c
+ </sect2>
+ <sect2>
+ <title>Buffer Object Eviction</title>
+ <para>
+ This section documents the interface function for evicting buffer
+ objects to make space available in the virtual gpu address spaces.
+ Note that this is mostly orthogonal to shrinking buffer objects
+ caches, which has the goal to make main memory (shared with the gpu
+ through the unified memory architecture) available.
+ </para>
+!Idrivers/gpu/drm/i915/i915_gem_evict.c
+ </sect2>
</sect1>
<sect1>
diff --git a/Documentation/arm/Atmel/README b/Documentation/arm/Atmel/README
new file mode 100644
index 000000000000..c53a19b4aab2
--- /dev/null
+++ b/Documentation/arm/Atmel/README
@@ -0,0 +1,124 @@
+ARM Atmel SoCs (aka AT91)
+=========================
+
+
+Introduction
+------------
+This document gives useful information about the ARM Atmel SoCs that are
+currently supported in Linux Mainline (you know, the one on kernel.org).
+
+It is important to note that the Atmel | SMART ARM-based MPU product line is
+historically named "AT91" or "at91" throughout the Linux kernel development
+process even if this product prefix has completely disappeared from the
+official Atmel product name. Anyway, files, directories, git trees,
+git branches/tags and email subject always contain this "at91" sub-string.
+
+
+AT91 SoCs
+---------
+Documentation and detailled datasheet for each product are available on
+the Atmel website: http://www.atmel.com.
+
+ Flavors:
+ * ARM 920 based SoC
+ - at91rm9200
+ + Datasheet
+ http://www.atmel.com/Images/doc1768.pdf
+
+ * ARM 926 based SoCs
+ - at91sam9260
+ + Datasheet
+ http://www.atmel.com/Images/doc6221.pdf
+
+ - at91sam9xe
+ + Datasheet
+ http://www.atmel.com/Images/Atmel-6254-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9XE_Datasheet.pdf
+
+ - at91sam9261
+ + Datasheet
+ http://www.atmel.com/Images/doc6062.pdf
+
+ - at91sam9263
+ + Datasheet
+ http://www.atmel.com/Images/Atmel_6249_32-bit-ARM926EJ-S-Microcontroller_SAM9263_Datasheet.pdf
+
+ - at91sam9rl
+ + Datasheet
+ http://www.atmel.com/Images/doc6289.pdf
+
+ - at91sam9g20
+ + Datasheet
+ http://www.atmel.com/Images/doc6384.pdf
+
+ - at91sam9g45 family
+ - at91sam9g45
+ - at91sam9g46
+ - at91sam9m10
+ - at91sam9m11 (device superset)
+ + Datasheet
+ http://www.atmel.com/Images/Atmel-6437-32-bit-ARM926-Embedded-Microprocessor-SAM9M11_Datasheet.pdf
+
+ - at91sam9x5 family (aka "The 5 series")
+ - at91sam9g15
+ - at91sam9g25
+ - at91sam9g35
+ - at91sam9x25
+ - at91sam9x35
+ + Datasheet (can be considered as covering the whole family)
+ http://www.atmel.com/Images/Atmel_11055_32-bit-ARM926EJ-S-Microcontroller_SAM9X35_Datasheet.pdf
+
+ - at91sam9n12
+ + Datasheet
+ http://www.atmel.com/Images/Atmel_11063_32-bit-ARM926EJ-S-Microcontroller_SAM9N12CN11CN12_Datasheet.pdf
+
+ * ARM Cortex-A5 based SoCs
+ - sama5d3 family
+ - sama5d31
+ - sama5d33
+ - sama5d34
+ - sama5d35
+ - sama5d36 (device superset)
+ + Datasheet
+ http://www.atmel.com/Images/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet.pdf
+
+ * ARM Cortex-A5 + NEON based SoCs
+ - sama5d4 family
+ - sama5d41
+ - sama5d42
+ - sama5d43
+ - sama5d44 (device superset)
+ + Datasheet
+ http://www.atmel.com/Images/Atmel-11238-32-bit-Cortex-A5-Microcontroller-SAMA5D4_Datasheet.pdf
+
+
+Linux kernel information
+------------------------
+Linux kernel mach directory: arch/arm/mach-at91
+MAINTAINERS entry is: "ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES"
+
+
+Device Tree for AT91 SoCs and boards
+------------------------------------
+All AT91 SoCs are converted to Device Tree. Since Linux 3.19, these products
+must use this method to boot the Linux kernel.
+
+Work In Progress statement:
+Device Tree files and Device Tree bindings that apply to AT91 SoCs and boards are
+considered as "Unstable". To be completely clear, any at91 binding can change at
+any time. So, be sure to use a Device Tree Binary and a Kernel Image generated from
+the same source tree.
+Please refer to the Documentation/devicetree/bindings/ABI.txt file for a
+definition of a "Stable" binding/ABI.
+This statement will be removed by AT91 MAINTAINERS when appropriate.
+
+Naming conventions and best practice:
+- SoCs Device Tree Source Include files are named after the official name of
+ the product (at91sam9g20.dtsi or sama5d33.dtsi for instance).
+- Device Tree Source Include files (.dtsi) are used to collect common nodes that can be
+ shared across SoCs or boards (sama5d3.dtsi or at91sam9x5cm.dtsi for instance).
+ When collecting nodes for a particular peripheral or topic, the identifier have to
+ be placed at the end of the file name, separated with a "_" (at91sam9x5_can.dtsi
+ or sama5d3_gmac.dtsi for example).
+- board Device Tree Source files (.dts) are prefixed by the string "at91-" so
+ that they can be identified easily. Note that some files are historical exceptions
+ to this rule (sama5d3[13456]ek.dts, usb_a9g20.dts or animeo_ip.dts for example).
diff --git a/Documentation/arm/Samsung-S3C24XX/DMA.txt b/Documentation/arm/Samsung-S3C24XX/DMA.txt
deleted file mode 100644
index 3ed82383efea..000000000000
--- a/Documentation/arm/Samsung-S3C24XX/DMA.txt
+++ /dev/null
@@ -1,46 +0,0 @@
- S3C2410 DMA
- ===========
-
-Introduction
-------------
-
- The kernel provides an interface to manage DMA transfers
- using the DMA channels in the CPU, so that the central
- duty of managing channel mappings, and programming the
- channel generators is in one place.
-
-
-DMA Channel Ordering
---------------------
-
- Many of the range do not have connections for the DMA
- channels to all sources, which means that some devices
- have a restricted number of channels that can be used.
-
- To allow flexibility for each CPU type and board, the
- DMA code can be given a DMA ordering structure which
- allows the order of channel search to be specified, as
- well as allowing the prohibition of certain claims.
-
- struct s3c24xx_dma_order has a list of channels, and
- each channel within has a slot for a list of DMA
- channel numbers. The slots are searched in order for
- the presence of a DMA channel number with DMA_CH_VALID
- or-ed in.
-
- If the order has the flag DMA_CH_NEVER set, then after
- checking the channel list, the system will return no
- found channel, thus denying the request.
-
- A board support file can call s3c24xx_dma_order_set()
- to register a complete ordering set. The routine will
- copy the data, so the original can be discarded with
- __initdata.
-
-
-Authour
--------
-
-Ben Dooks,
-Copyright (c) 2007 Ben Dooks, Simtec Electronics
-Licensed under the GPL v2
diff --git a/Documentation/arm/sti/stih418-overview.txt b/Documentation/arm/sti/stih418-overview.txt
new file mode 100644
index 000000000000..1cd8fc80646d
--- /dev/null
+++ b/Documentation/arm/sti/stih418-overview.txt
@@ -0,0 +1,20 @@
+ STiH418 Overview
+ ================
+
+Introduction
+------------
+
+ The STiH418 is the new generation of SoC for UHDp60 set-top boxes
+ and server/connected client application for satellite, cable, terrestrial
+ and IP-STB markets.
+
+ Features
+ - ARM Cortex-A9 1.5 GHz quad core CPU (28nm)
+ - SATA2, USB 3.0, PCIe, Gbit Ethernet
+ - HEVC L5.1 Main 10
+ - VP9
+
+ Document Author
+ ---------------
+
+ Maxime Coquelin <maxime.coquelin@st.com>, (c) 2015 ST Microelectronics
diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README
index e68d163df33d..1fe2d7fd4108 100644
--- a/Documentation/arm/sunxi/README
+++ b/Documentation/arm/sunxi/README
@@ -50,7 +50,6 @@ SunXi family
http://dl.linux-sunxi.org/A31/A3x_release_document/A31/IC/A31%20user%20manual%20V1.1%2020130630.pdf
- Allwinner A31s (sun6i)
- + Not Supported
+ Datasheet
http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20datasheet%20V1.3%2020131106.pdf
+ User Manual
diff --git a/Documentation/devicetree/bindings/arm/armada-38x.txt b/Documentation/devicetree/bindings/arm/armada-38x.txt
index ad9f8ed4d9bd..202953f1887e 100644
--- a/Documentation/devicetree/bindings/arm/armada-38x.txt
+++ b/Documentation/devicetree/bindings/arm/armada-38x.txt
@@ -15,6 +15,13 @@ Required root node property:
compatible: must contain "marvell,armada385"
+In addition, boards using the Marvell Armada 388 SoC shall have the
+following property before the previous one:
+
+Required root node property:
+
+compatible: must contain "marvell,armada388"
+
Example:
compatible = "marvell,a385-rd", "marvell,armada385", "marvell,armada380";
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index 562cda9d86d9..ad319f84f560 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -24,6 +24,7 @@ compatible: must be one of:
o "atmel,at91sam9g45"
o "atmel,at91sam9n12"
o "atmel,at91sam9rl"
+ o "atmel,at91sam9xe"
* "atmel,sama5" for SoCs using a Cortex-A5, shall be extended with the specific
SoC family:
o "atmel,sama5d3" shall be extended with the specific SoC compatible:
@@ -136,3 +137,19 @@ Example:
compatible = "atmel,at91sam9260-rstc";
reg = <0xfffffd00 0x10>;
};
+
+Special Function Registers (SFR)
+
+Special Function Registers (SFR) manage specific aspects of the integrated
+memory, bridge implementations, processor and other functionality not controlled
+elsewhere.
+
+required properties:
+- compatible: Should be "atmel,<chip>-sfr", "syscon".
+ <chip> can be "sama5d3" or "sama5d4".
+- reg: Should contain registers location and length
+
+ sfr@f0038000 {
+ compatible = "atmel,sama5d3-sfr", "syscon";
+ reg = <0xf0038000 0x60>;
+ };
diff --git a/Documentation/devicetree/bindings/arm/digicolor.txt b/Documentation/devicetree/bindings/arm/digicolor.txt
new file mode 100644
index 000000000000..658553f40b23
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/digicolor.txt
@@ -0,0 +1,6 @@
+Conexant Digicolor Platforms Device Tree Bindings
+
+Each device tree must specify which Conexant Digicolor SoC it uses.
+Must be the following compatible string:
+
+ cnxt,cx92755
diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index abde1ea8a119..f4445e5a2bbb 100644
--- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
+++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
@@ -23,7 +23,7 @@ Optional Properties:
devices in this power domain. Maximum of 4 pairs (N = 0 to 3)
are supported currently.
-Node of a device using power domains must have a samsung,power-domain property
+Node of a device using power domains must have a power-domains property
defined with a phandle to respective power domain.
Example:
diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index 4e8b7df7fc62..a5462b6b3c30 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -75,6 +75,18 @@ i.MX6q generic board
Required root node properties:
- compatible = "fsl,imx6q";
+Freescale Vybrid Platform Device Tree Bindings
+----------------------------------------------
+
+For the Vybrid SoC familiy all variants with DDR controller are supported,
+which is the VF5xx and VF6xx series. Out of historical reasons, in most
+places the kernel uses vf610 to refer to the whole familiy.
+
+Required root node compatible property (one of them):
+ - compatible = "fsl,vf500";
+ - compatible = "fsl,vf510";
+ - compatible = "fsl,vf600";
+ - compatible = "fsl,vf610";
Freescale LS1021A Platform Device Tree Bindings
------------------------------------------------
@@ -112,3 +124,11 @@ Example:
compatible = "fsl,ls1021a-dcfg";
reg = <0x0 0x1ee0000 0x0 0x10000>;
};
+
+Freescale LS2085A SoC Device Tree Bindings
+------------------------------------------
+
+LS2085A ARMv8 based Simulator model
+Required root node properties:
+ - compatible = "fsl,ls2085a-simu", "fsl,ls2085a";
+
diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
index 8112d0c3675a..c97484b73e72 100644
--- a/Documentation/devicetree/bindings/arm/gic.txt
+++ b/Documentation/devicetree/bindings/arm/gic.txt
@@ -32,12 +32,16 @@ Main node required properties:
The 3rd cell is the flags, encoded as follows:
bits[3:0] trigger type and level flags.
1 = low-to-high edge triggered
- 2 = high-to-low edge triggered
+ 2 = high-to-low edge triggered (invalid for SPIs)
4 = active high level-sensitive
- 8 = active low level-sensitive
+ 8 = active low level-sensitive (invalid for SPIs).
bits[15:8] PPI interrupt cpu mask. Each bit corresponds to each of
the 8 possible cpus attached to the GIC. A bit set to '1' indicated
the interrupt is wired to that CPU. Only valid for PPI interrupts.
+ Also note that the configurability of PPI interrupts is IMPLEMENTATION
+ DEFINED and as such not guaranteed to be present (most SoC available
+ in 2014 seem to ignore the setting of this flag and use the hardware
+ default value).
- reg : Specifies base physical address(s) and size of the GIC registers. The
first region is the GIC distributor register base and size. The 2nd region is
diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index f717c7b48603..35b1bd49cfa1 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -9,6 +9,10 @@ HiP04 D01 Board
Required root node properties:
- compatible = "hisilicon,hip04-d01";
+HiP01 ca9x2 Board
+Required root node properties:
+ - compatible = "hisilicon,hip01-ca9x2";
+
Hisilicon system controller
@@ -37,6 +41,27 @@ Example:
};
-----------------------------------------------------------------------
+Hisilicon HiP01 system controller
+
+Required properties:
+- compatible : "hisilicon,hip01-sysctrl"
+- reg : Register address and size
+
+The HiP01 system controller is mostly compatible with hisilicon
+system controller,but it has some specific control registers for
+HIP01 SoC family, such as slave core boot, and also some same
+registers located at different offset.
+
+Example:
+
+ /* for hip01-ca9x2 */
+ sysctrl: system-controller@10000000 {
+ compatible = "hisilicon,hip01-sysctrl", "hisilicon,sysctrl";
+ reg = <0x10000000 0x1000>;
+ reboot-offset = <0x4>;
+ };
+
+-----------------------------------------------------------------------
Hisilicon CPU controller
Required properties:
diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt
index 3be40139cfbb..dd7550a29db6 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek.txt
@@ -9,6 +9,7 @@ compatible: Must contain one of
"mediatek,mt6592"
"mediatek,mt8127"
"mediatek,mt8135"
+ "mediatek,mt8173"
Supported boards:
@@ -25,3 +26,6 @@ Supported boards:
- MTK mt8135 tablet EVB:
Required root node properties:
- compatible = "mediatek,mt8135-evbp1", "mediatek,mt8135";
+- MTK mt8173 tablet EVB:
+ Required root node properties:
+ - compatible = "mediatek,mt8173-evb", "mediatek,mt8173";
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
index d680b07ec6e8..4f5a5352ccd8 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sysirq.txt
@@ -5,8 +5,10 @@ interrupt.
Required properties:
- compatible: should be one of:
+ "mediatek,mt8173-sysirq"
"mediatek,mt8135-sysirq"
"mediatek,mt8127-sysirq"
+ "mediatek,mt6592-sysirq"
"mediatek,mt6589-sysirq"
"mediatek,mt6582-sysirq"
"mediatek,mt6577-sysirq"
diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index eaa3d1a0eb05..6809e4e51ed2 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -9,6 +9,16 @@ Rockchip platforms device tree bindings
Required root node properties:
- compatible = "mundoreader,bq-curie2", "rockchip,rk3066a";
+- ChipSPARK Rayeager PX2 board:
+ Required root node properties:
+ - compatible = "chipspark,rayeager-px2", "rockchip,rk3066a";
+
- Radxa Rock board:
Required root node properties:
- compatible = "radxa,rock", "rockchip,rk3188";
+
+- Firefly Firefly-RK3288 board:
+ Required root node properties:
+ - compatible = "firefly,firefly-rk3288", "rockchip,rk3288";
+ or
+ - compatible = "firefly,firefly-rk3288-beta", "rockchip,rk3288";
diff --git a/Documentation/devicetree/bindings/arm/rockchip/pmu-sram.txt b/Documentation/devicetree/bindings/arm/rockchip/pmu-sram.txt
new file mode 100644
index 000000000000..6b42fda306ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/rockchip/pmu-sram.txt
@@ -0,0 +1,16 @@
+Rockchip SRAM for pmu:
+------------------------------
+
+The sram of pmu is used to store the function of resume from maskrom(the 1st
+level loader). This is a common use of the "pmu-sram" because it keeps power
+even in low power states in the system.
+
+Required node properties:
+- compatible : should be "rockchip,rk3288-pmu-sram"
+- reg : physical base address and the size of the registers window
+
+Example:
+ sram@ff720000 {
+ compatible = "rockchip,rk3288-pmu-sram", "mmio-sram";
+ reg = <0xff720000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt
new file mode 100644
index 000000000000..85c5dfd4a720
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/samsung/exynos-chipid.txt
@@ -0,0 +1,12 @@
+SAMSUNG Exynos SoCs Chipid driver.
+
+Required properties:
+- compatible : Should at least contain "samsung,exynos4210-chipid".
+
+- reg: offset and length of the register set
+
+Example:
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
index 1e1979b229ff..67b211381f2b 100644
--- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -10,6 +10,7 @@ Properties:
- "samsung,exynos5260-pmu" - for Exynos5260 SoC.
- "samsung,exynos5410-pmu" - for Exynos5410 SoC,
- "samsung,exynos5420-pmu" - for Exynos5420 SoC.
+ - "samsung,exynos7-pmu" - for Exynos7 SoC.
second value must be always "syscon".
- reg : offset and length of the register set.
diff --git a/Documentation/devicetree/bindings/arm/sirf.txt b/Documentation/devicetree/bindings/arm/sirf.txt
index c6ba6d3c747f..7b28ee6fee91 100644
--- a/Documentation/devicetree/bindings/arm/sirf.txt
+++ b/Documentation/devicetree/bindings/arm/sirf.txt
@@ -3,7 +3,9 @@ CSR SiRFprimaII and SiRFmarco device tree bindings.
Required root node properties:
- compatible:
+ - "sirf,atlas6-cb" : atlas6 "cb" evaluation board
+ - "sirf,atlas6" : atlas6 device based board
+ - "sirf,atlas7-cb" : atlas7 "cb" evaluation board
+ - "sirf,atlas7" : atlas7 device based board
- "sirf,prima2-cb" : prima2 "cb" evaluation board
- - "sirf,marco-cb" : marco "cb" evaluation board
- "sirf,prima2" : prima2 device based board
- - "sirf,marco" : marco device based board
diff --git a/Documentation/devicetree/bindings/arm/sti.txt b/Documentation/devicetree/bindings/arm/sti.txt
index 92f16c78bb69..d70ec358736c 100644
--- a/Documentation/devicetree/bindings/arm/sti.txt
+++ b/Documentation/devicetree/bindings/arm/sti.txt
@@ -13,3 +13,7 @@ Boards with the ST STiH407 SoC shall have the following properties:
Required root node property:
compatible = "st,stih407";
+Boards with the ST STiH418 SoC shall have the following properties:
+Required root node property:
+compatible = "st,stih418";
+
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
index dd75b972ee37..02c27004d4a8 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
@@ -51,6 +51,23 @@ Required properties when nvidia,suspend-mode=<0>:
sleep mode, the warm boot code will restore some PLLs, clocks and then
bring up CPU0 for resuming the system.
+Hardware-triggered thermal reset:
+On Tegra30, Tegra114 and Tegra124, if the 'i2c-thermtrip' subnode exists,
+hardware-triggered thermal reset will be enabled.
+
+Required properties for hardware-triggered thermal reset (inside 'i2c-thermtrip'):
+- nvidia,i2c-controller-id : ID of I2C controller to send poweroff command to. Valid values are
+ described in section 9.2.148 "APBDEV_PMC_SCRATCH53_0" of the
+ Tegra K1 Technical Reference Manual.
+- nvidia,bus-addr : Bus address of the PMU on the I2C bus
+- nvidia,reg-addr : I2C register address to write poweroff command to
+- nvidia,reg-data : Poweroff command to write to PMU
+
+Optional properties for hardware-triggered thermal reset (inside 'i2c-thermtrip'):
+- nvidia,pinmux-id : Pinmux used by the hardware when issuing poweroff command.
+ Defaults to 0. Valid values are described in section 12.5.2
+ "Pinmux Support" of the Tegra4 Technical Reference Manual.
+
Example:
/ SoC dts including file
@@ -73,6 +90,15 @@ pmc@7000f400 {
/ Tegra board dts file
{
...
+ pmc@7000f400 {
+ i2c-thermtrip {
+ nvidia,i2c-controller-id = <4>;
+ nvidia,bus-addr = <0x40>;
+ nvidia,reg-addr = <0x36>;
+ nvidia,reg-data = <0x2>;
+ };
+ };
+ ...
clocks {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/arm/versatile-sysreg.txt b/Documentation/devicetree/bindings/arm/versatile-sysreg.txt
new file mode 100644
index 000000000000..a4f15262d717
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/versatile-sysreg.txt
@@ -0,0 +1,10 @@
+ARM Versatile system registers
+--------------------------------------
+
+This is a system control registers block, providing multiple low level
+platform functions like board detection and identification, software
+interrupt generation, MMC and NOR Flash control etc.
+
+Required node properties:
+- compatible value : = "arm,versatile-sysreg", "syscon"
+- reg : physical base address and the size of the registers window
diff --git a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt
index 5e16c3ccb061..fa6cde41b460 100644
--- a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt
+++ b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt
@@ -6,8 +6,8 @@ Required properties:
- compatible: Should be set to one of the following:
marvell,armada370-mbus
marvell,armadaxp-mbus
- marvell,armada370-mbus
- marvell,armadaxp-mbus
+ marvell,armada375-mbus
+ marvell,armada380-mbus
marvell,kirkwood-mbus
marvell,dove-mbus
marvell,orion5x-88f5281-mbus
diff --git a/Documentation/devicetree/bindings/clock/alphascale,acc.txt b/Documentation/devicetree/bindings/clock/alphascale,acc.txt
new file mode 100644
index 000000000000..62e67e883e76
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/alphascale,acc.txt
@@ -0,0 +1,115 @@
+Alphascale Clock Controller
+
+The ACC (Alphascale Clock Controller) is responsible of choising proper
+clock source, setting deviders and clock gates.
+
+Required properties for the ACC node:
+ - compatible: must be "alphascale,asm9260-clock-controller"
+ - reg: must contain the ACC register base and size
+ - #clock-cells : shall be set to 1.
+
+Simple one-cell clock specifier format is used, where the only cell is used
+as an index of the clock inside the provider.
+It is encouraged to use dt-binding for clock index definitions. SoC specific
+dt-binding should be included to the device tree descriptor. For example
+Alphascale ASM9260:
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+This binding contains two types of clock providers:
+ _AHB_ - AHB gate;
+ _SYS_ - adjustable clock source. Not all peripheral have _SYS_ clock provider.
+All clock specific details can be found in the SoC documentation.
+CLKID_AHB_ROM 0
+CLKID_AHB_RAM 1
+CLKID_AHB_GPIO 2
+CLKID_AHB_MAC 3
+CLKID_AHB_EMI 4
+CLKID_AHB_USB0 5
+CLKID_AHB_USB1 6
+CLKID_AHB_DMA0 7
+CLKID_AHB_DMA1 8
+CLKID_AHB_UART0 9
+CLKID_AHB_UART1 10
+CLKID_AHB_UART2 11
+CLKID_AHB_UART3 12
+CLKID_AHB_UART4 13
+CLKID_AHB_UART5 14
+CLKID_AHB_UART6 15
+CLKID_AHB_UART7 16
+CLKID_AHB_UART8 17
+CLKID_AHB_UART9 18
+CLKID_AHB_I2S0 19
+CLKID_AHB_I2C0 20
+CLKID_AHB_I2C1 21
+CLKID_AHB_SSP0 22
+CLKID_AHB_IOCONFIG 23
+CLKID_AHB_WDT 24
+CLKID_AHB_CAN0 25
+CLKID_AHB_CAN1 26
+CLKID_AHB_MPWM 27
+CLKID_AHB_SPI0 28
+CLKID_AHB_SPI1 29
+CLKID_AHB_QEI 30
+CLKID_AHB_QUADSPI0 31
+CLKID_AHB_CAMIF 32
+CLKID_AHB_LCDIF 33
+CLKID_AHB_TIMER0 34
+CLKID_AHB_TIMER1 35
+CLKID_AHB_TIMER2 36
+CLKID_AHB_TIMER3 37
+CLKID_AHB_IRQ 38
+CLKID_AHB_RTC 39
+CLKID_AHB_NAND 40
+CLKID_AHB_ADC0 41
+CLKID_AHB_LED 42
+CLKID_AHB_DAC0 43
+CLKID_AHB_LCD 44
+CLKID_AHB_I2S1 45
+CLKID_AHB_MAC1 46
+
+CLKID_SYS_CPU 47
+CLKID_SYS_AHB 48
+CLKID_SYS_I2S0M 49
+CLKID_SYS_I2S0S 50
+CLKID_SYS_I2S1M 51
+CLKID_SYS_I2S1S 52
+CLKID_SYS_UART0 53
+CLKID_SYS_UART1 54
+CLKID_SYS_UART2 55
+CLKID_SYS_UART3 56
+CLKID_SYS_UART4 56
+CLKID_SYS_UART5 57
+CLKID_SYS_UART6 58
+CLKID_SYS_UART7 59
+CLKID_SYS_UART8 60
+CLKID_SYS_UART9 61
+CLKID_SYS_SPI0 62
+CLKID_SYS_SPI1 63
+CLKID_SYS_QUADSPI 64
+CLKID_SYS_SSP0 65
+CLKID_SYS_NAND 66
+CLKID_SYS_TRACE 67
+CLKID_SYS_CAMM 68
+CLKID_SYS_WDT 69
+CLKID_SYS_CLKOUT 70
+CLKID_SYS_MAC 71
+CLKID_SYS_LCD 72
+CLKID_SYS_ADCANA 73
+
+Example of clock consumer with _SYS_ and _AHB_ sinks.
+uart4: serial@80010000 {
+ compatible = "alphascale,asm9260-uart";
+ reg = <0x80010000 0x4000>;
+ clocks = <&acc CLKID_SYS_UART4>, <&acc CLKID_AHB_UART4>;
+ interrupts = <19>;
+ status = "disabled";
+};
+
+Clock consumer with only one, _AHB_ sink.
+timer0: timer@80088000 {
+ compatible = "alphascale,asm9260-timer";
+ reg = <0x80088000 0x4000>;
+ clocks = <&acc CLKID_AHB_TIMER0>;
+ interrupts = <29>;
+};
+
diff --git a/Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt
new file mode 100644
index 000000000000..a8978ec94831
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,sh73a0-cpg-clocks.txt
@@ -0,0 +1,35 @@
+These bindings should be considered EXPERIMENTAL for now.
+
+* Renesas SH73A0 Clock Pulse Generator (CPG)
+
+The CPG generates core clocks for the SH73A0 SoC. It includes four PLLs
+and several fixed ratio dividers.
+
+Required Properties:
+
+ - compatible: Must be "renesas,sh73a0-cpg-clocks"
+
+ - reg: Base address and length of the memory resource used by the CPG
+
+ - clocks: Reference to the parent clocks ("extal1" and "extal2")
+
+ - #clock-cells: Must be 1
+
+ - clock-output-names: The names of the clocks. Supported clocks are "main",
+ "pll0", "pll1", "pll2", "pll3", "dsi0phy", "dsi1phy", "zg", "m3", "b",
+ "m1", "m2", "z", "zx", and "hp".
+
+
+Example
+-------
+
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,sh73a0-cpg-clocks";
+ reg = <0 0xe6150000 0 0x10000>;
+ clocks = <&extal1_clk>, <&extal2_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll2",
+ "pll3", "dsi0phy", "dsi1phy",
+ "zg", "m3", "b", "m1", "m2",
+ "z", "zx", "hp";
+ };
diff --git a/Documentation/devicetree/bindings/dma/img-mdc-dma.txt b/Documentation/devicetree/bindings/dma/img-mdc-dma.txt
new file mode 100644
index 000000000000..28c1341db346
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/img-mdc-dma.txt
@@ -0,0 +1,57 @@
+* IMG Multi-threaded DMA Controller (MDC)
+
+Required properties:
+- compatible: Must be "img,pistachio-mdc-dma".
+- reg: Must contain the base address and length of the MDC registers.
+- interrupts: Must contain all the per-channel DMA interrupts.
+- clocks: Must contain an entry for each entry in clock-names.
+ See ../clock/clock-bindings.txt for details.
+- clock-names: Must include the following entries:
+ - sys: MDC system interface clock.
+- img,cr-periph: Must contain a phandle to the peripheral control syscon
+ node which contains the DMA request to channel mapping registers.
+- img,max-burst-multiplier: Must be the maximum supported burst size multiplier.
+ The maximum burst size is this value multiplied by the hardware-reported bus
+ width.
+- #dma-cells: Must be 3:
+ - The first cell is the peripheral's DMA request line.
+ - The second cell is a bitmap specifying to which channels the DMA request
+ line may be mapped (i.e. bit N set indicates channel N is usable).
+ - The third cell is the thread ID to be used by the channel.
+
+Optional properties:
+- dma-channels: Number of supported DMA channels, up to 32. If not specified
+ the number reported by the hardware is used.
+
+Example:
+
+mdc: dma-controller@18143000 {
+ compatible = "img,pistachio-mdc-dma";
+ reg = <0x18143000 0x1000>;
+ interrupts = <GIC_SHARED 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 36 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 37 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SHARED 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&system_clk>;
+ clock-names = "sys";
+
+ img,max-burst-multiplier = <16>;
+ img,cr-periph = <&cr_periph>;
+
+ #dma-cells = <3>;
+};
+
+spi@18100f00 {
+ ...
+ dmas = <&mdc 9 0xffffffff 0>, <&mdc 10 0xffffffff 0>;
+ dma-names = "tx", "rx";
+ ...
+};
diff --git a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
index f7e21b1c2a05..09daeef1ff22 100644
--- a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
+++ b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt
@@ -5,9 +5,6 @@ controller instances named DMAC capable of serving multiple clients. Channels
can be dedicated to specific clients or shared between a large number of
clients.
-DMA clients are connected to the DMAC ports referenced by an 8-bit identifier
-called MID/RID.
-
Each DMA client is connected to one dedicated port of the DMAC, identified by
an 8-bit port number called the MID/RID. A DMA controller can thus serve up to
256 clients in total. When the number of hardware channels is lower than the
diff --git a/Documentation/devicetree/bindings/dma/snps-dma.txt b/Documentation/devicetree/bindings/dma/snps-dma.txt
index d58675ea1abf..c261598164a7 100644
--- a/Documentation/devicetree/bindings/dma/snps-dma.txt
+++ b/Documentation/devicetree/bindings/dma/snps-dma.txt
@@ -38,7 +38,7 @@ Example:
chan_allocation_order = <1>;
chan_priority = <1>;
block_size = <0xfff>;
- data_width = <3 3 0 0>;
+ data_width = <3 3>;
};
DMA clients connected to the Designware DMA controller must use the format
diff --git a/Documentation/devicetree/bindings/drm/atmel/hlcdc-dc.txt b/Documentation/devicetree/bindings/drm/atmel/hlcdc-dc.txt
new file mode 100644
index 000000000000..ebc1a914bda3
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/atmel/hlcdc-dc.txt
@@ -0,0 +1,53 @@
+Device-Tree bindings for Atmel's HLCDC (High LCD Controller) DRM driver
+
+The Atmel HLCDC Display Controller is subdevice of the HLCDC MFD device.
+See ../mfd/atmel-hlcdc.txt for more details.
+
+Required properties:
+ - compatible: value should be "atmel,hlcdc-display-controller"
+ - pinctrl-names: the pin control state names. Should contain "default".
+ - pinctrl-0: should contain the default pinctrl states.
+ - #address-cells: should be set to 1.
+ - #size-cells: should be set to 0.
+
+Required children nodes:
+ Children nodes are encoding available output ports and their connections
+ to external devices using the OF graph reprensentation (see ../graph.txt).
+ At least one port node is required.
+
+Example:
+
+ hlcdc: hlcdc@f0030000 {
+ compatible = "atmel,sama5d3-hlcdc";
+ reg = <0xf0030000 0x2000>;
+ interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>;
+ clock-names = "periph_clk","sys_clk", "slow_clk";
+ status = "disabled";
+
+ hlcdc-display-controller {
+ compatible = "atmel,hlcdc-display-controller";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ hlcdc_panel_output: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&panel_input>;
+ };
+ };
+ };
+
+ hlcdc_pwm: hlcdc-pwm {
+ compatible = "atmel,hlcdc-pwm";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcd_pwm>;
+ #pwm-cells = <3>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
new file mode 100644
index 000000000000..a905c1413558
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
@@ -0,0 +1,50 @@
+DesignWare HDMI bridge bindings
+
+Required properties:
+- compatible: platform specific such as:
+ * "snps,dw-hdmi-tx"
+ * "fsl,imx6q-hdmi"
+ * "fsl,imx6dl-hdmi"
+ * "rockchip,rk3288-dw-hdmi"
+- reg: Physical base address and length of the controller's registers.
+- interrupts: The HDMI interrupt number
+- clocks, clock-names : must have the phandles to the HDMI iahb and isfr clocks,
+ as described in Documentation/devicetree/bindings/clock/clock-bindings.txt,
+ the clocks are soc specific, the clock-names should be "iahb", "isfr"
+-port@[X]: SoC specific port nodes with endpoint definitions as defined
+ in Documentation/devicetree/bindings/media/video-interfaces.txt,
+ please refer to the SoC specific binding document:
+ * Documentation/devicetree/bindings/drm/imx/hdmi.txt
+ * Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
+
+Optional properties
+- reg-io-width: the width of the reg:1,4, default set to 1 if not present
+- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+- clocks, clock-names: phandle to the HDMI CEC clock, name should be "cec"
+
+Example:
+ hdmi: hdmi@0120000 {
+ compatible = "fsl,imx6q-hdmi";
+ reg = <0x00120000 0x9000>;
+ interrupts = <0 115 0x04>;
+ gpr = <&gpr>;
+ clocks = <&clks 123>, <&clks 124>;
+ clock-names = "iahb", "isfr";
+ ddc-i2c-bus = <&i2c2>;
+
+ port@0 {
+ reg = <0>;
+
+ hdmi_mux_0: endpoint {
+ remote-endpoint = <&ipu1_di0_hdmi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ hdmi_mux_1: endpoint {
+ remote-endpoint = <&ipu1_di1_hdmi>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/drm/msm/hdmi.txt b/Documentation/devicetree/bindings/drm/msm/hdmi.txt
index aca917fe2ba7..a29a55f3d937 100644
--- a/Documentation/devicetree/bindings/drm/msm/hdmi.txt
+++ b/Documentation/devicetree/bindings/drm/msm/hdmi.txt
@@ -2,6 +2,8 @@ Qualcomm adreno/snapdragon hdmi output
Required properties:
- compatible: one of the following
+ * "qcom,hdmi-tx-8084"
+ * "qcom,hdmi-tx-8074"
* "qcom,hdmi-tx-8660"
* "qcom,hdmi-tx-8960"
- reg: Physical base address and length of the controller's registers
diff --git a/Documentation/devicetree/bindings/gpu/st,stih4xx.txt b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
index c99eb34e640b..6b1d75f1a529 100644
--- a/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
+++ b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
@@ -83,6 +83,22 @@ sti-hda:
- clock-names: names of the clocks listed in clocks property in the same
order.
+sti-dvo:
+ Required properties:
+ must be a child of sti-tvout
+ - compatible: "st,stih<chip>-dvo"
+ - reg: Physical base address of the IP registers and length of memory mapped region.
+ - reg-names: names of the mapped memory regions listed in regs property in
+ the same order.
+ - clocks: from common clock binding: handle hardware IP needed clocks, the
+ number of clocks may depend of the SoC type.
+ See ../clocks/clock-bindings.txt for details.
+ - clock-names: names of the clocks listed in clocks property in the same
+ order.
+ - pinctrl-0: pin control handle
+ - pinctrl-name: names of the pin control to use
+ - sti,panel: phandle of the panel connected to the DVO output
+
sti-hqvdp:
must be a child of sti-display-subsystem
Required properties:
@@ -198,6 +214,19 @@ Example:
clock-names = "pix", "hddac";
clocks = <&clockgen_c_vcc CLK_S_PIX_HD>, <&clockgen_c_vcc CLK_S_HDDAC>;
};
+
+ sti-dvo@8d00400 {
+ compatible = "st,stih407-dvo";
+ reg = <0x8d00400 0x200>;
+ reg-names = "dvo-reg";
+ clock-names = "dvo_pix", "dvo",
+ "main_parent", "aux_parent";
+ clocks = <&clk_s_d2_flexgen CLK_PIX_DVO>, <&clk_s_d2_flexgen CLK_DVO>,
+ <&clk_s_d2_quadfs 0>, <&clk_s_d2_quadfs 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dvo>;
+ sti,panel = <&panel_dvo>;
+ };
};
sti-hqvdp@9c000000 {
diff --git a/Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt
new file mode 100644
index 000000000000..42d41ec84c7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/digicolor-ic.txt
@@ -0,0 +1,21 @@
+Conexant Digicolor Interrupt Controller
+
+Required properties:
+
+- compatible : should be "cnxt,cx92755-ic"
+- reg : Specifies base physical address and size of the interrupt controller
+ registers (IC) area
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source. The value shall be 1.
+- syscon: A phandle to the syscon node describing UC registers
+
+Example:
+
+ intc: interrupt-controller@f0000040 {
+ compatible = "cnxt,cx92755-ic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xf0000040 0x40>;
+ syscon = <&uc_regs>;
+ };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
index c73acd060093..4f7946ae8adc 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
@@ -9,6 +9,11 @@ Required properties:
- "renesas,intc-irqpin-r8a7778" (R-Car M1A)
- "renesas,intc-irqpin-r8a7779" (R-Car H1)
- "renesas,intc-irqpin-sh73a0" (SH-Mobile AG5)
+
+- reg: Base address and length of each register bank used by the external
+ IRQ pins driven by the interrupt controller hardware module. The base
+ addresses, length and number of required register banks varies with soctype.
+
- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
interrupts.txt in this directory
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt
new file mode 100644
index 000000000000..38ce5d037722
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,omap-intc-irq.txt
@@ -0,0 +1,28 @@
+Omap2/3 intc controller
+
+On TI omap2 and 3 the intc interrupt controller can provide
+96 or 128 IRQ signals to the ARM host depending on the SoC.
+
+Required Properties:
+- compatible: should be one of
+ "ti,omap2-intc"
+ "ti,omap3-intc"
+ "ti,dm814-intc"
+ "ti,dm816-intc"
+ "ti,am33xx-intc"
+
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode interrupt
+ source, should be 1 for intc
+- interrupts: interrupt reference to primary interrupt controller
+
+Please refer to interrupts.txt in this directory for details of the common
+Interrupt Controllers bindings used by client devices.
+
+Example:
+ intc: interrupt-controller@48200000 {
+ compatible = "ti,omap3-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x48200000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt
index 6fa4c737af23..729543c47046 100644
--- a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt
+++ b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt
@@ -45,7 +45,7 @@ Required properties:
Exynos4 SoCs, there needs no "master" clock.
Exynos5 SoCs, some System MMUs must have "master" clocks.
- clocks: Required if the System MMU is needed to gate its clock.
-- samsung,power-domain: Required if the System MMU is needed to gate its power.
+- power-domains: Required if the System MMU is needed to gate its power.
Please refer to the following document:
Documentation/devicetree/bindings/arm/exynos/power_domain.txt
@@ -54,7 +54,7 @@ Examples:
compatible = "samsung,exynos5-gsc";
reg = <0x13e00000 0x1000>;
interrupts = <0 85 0>;
- samsung,power-domain = <&pd_gsc>;
+ power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL0>;
clock-names = "gscl";
};
@@ -66,5 +66,5 @@ Examples:
interrupts = <2 0>;
clock-names = "sysmmu", "master";
clocks = <&clock CLK_SMMU_GSCL0>, <&clock CLK_GSCL0>;
- samsung,power-domain = <&pd_gsc>;
+ power-domains = <&pd_gsc>;
};
diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt
index 3e3c5f349570..2d5787eac91a 100644
--- a/Documentation/devicetree/bindings/media/s5p-mfc.txt
+++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
@@ -28,7 +28,7 @@ Required properties:
for DMA contiguous memory allocation and its size.
Optional properties:
- - samsung,power-domain : power-domain property defined with a phandle
+ - power-domains : power-domain property defined with a phandle
to respective power domain.
Example:
@@ -38,7 +38,7 @@ mfc: codec@13400000 {
compatible = "samsung,mfc-v5";
reg = <0x13400000 0x10000>;
interrupts = <0 94 0>;
- samsung,power-domain = <&pd_mfc>;
+ power-domains = <&pd_mfc>;
clocks = <&clock 273>;
clock-names = "mfc";
};
diff --git a/Documentation/devicetree/bindings/memory-controllers/renesas-memory-controllers.txt b/Documentation/devicetree/bindings/memory-controllers/renesas-memory-controllers.txt
new file mode 100644
index 000000000000..c64b7925cd09
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/renesas-memory-controllers.txt
@@ -0,0 +1,44 @@
+DT bindings for Renesas R-Mobile and SH-Mobile memory controllers
+=================================================================
+
+Renesas R-Mobile and SH-Mobile SoCs contain one or more memory controllers.
+These memory controllers differ from one SoC variant to another, and are called
+by different names ("DDR Bus Controller (DBSC)", "DDR3 Bus State Controller
+(DBSC3)", "SDRAM Bus State Controller (SBSC)").
+
+Currently memory controller device nodes are used only to reference PM
+domains, and prevent these PM domains from being powered down, which would
+crash the system.
+
+As there exist no actual drivers for these controllers yet, these bindings
+should be considered EXPERIMENTAL for now.
+
+Required properties:
+ - compatible: Must be one of the following SoC-specific values:
+ - "renesas,dbsc-r8a73a4" (R-Mobile APE6)
+ - "renesas,dbsc3-r8a7740" (R-Mobile A1)
+ - "renesas,sbsc-sh73a0" (SH-Mobile AG5)
+ - reg: Must contain the base address and length of the memory controller's
+ registers.
+
+Optional properties:
+ - interrupts: Must contain a list of interrupt specifiers for memory
+ controller interrupts, if available.
+ - interrupts-names: Must contain a list of interrupt names corresponding to
+ the interrupts in the interrupts property, if available.
+ Valid interrupt names are:
+ - "sec" (secure interrupt)
+ - "temp" (normal (temperature) interrupt)
+ - power-domains: Must contain a reference to the PM domain that the memory
+ controller belongs to, if available.
+
+Example:
+
+ sbsc1: memory-controller@fe400000 {
+ compatible = "renesas,sbsc-sh73a0";
+ reg = <0xfe400000 0x400>;
+ interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>,
+ <0 36 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sec", "temp";
+ power-domains = <&pd_a4bc0>;
+ };
diff --git a/Documentation/devicetree/bindings/mfd/atmel-matrix.txt b/Documentation/devicetree/bindings/mfd/atmel-matrix.txt
new file mode 100644
index 000000000000..e3ef50ca02a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel-matrix.txt
@@ -0,0 +1,24 @@
+* Device tree bindings for Atmel Bus Matrix
+
+The Bus Matrix registers are used to configure Atmel SoCs internal bus
+behavior (master/slave priorities, undefined burst length type, ...)
+
+Required properties:
+- compatible: Should be one of the following
+ "atmel,at91sam9260-matrix", "syscon"
+ "atmel,at91sam9261-matrix", "syscon"
+ "atmel,at91sam9263-matrix", "syscon"
+ "atmel,at91sam9rl-matrix", "syscon"
+ "atmel,at91sam9g45-matrix", "syscon"
+ "atmel,at91sam9n12-matrix", "syscon"
+ "atmel,at91sam9x5-matrix", "syscon"
+ "atmel,sama5d3-matrix", "syscon"
+- reg: Contains offset/length value of the Bus Matrix
+ memory region.
+
+Example:
+
+matrix: matrix@ffffec00 {
+ compatible = "atmel,sama5d3-matrix", "syscon";
+ reg = <0xffffec00 0x200>;
+};
diff --git a/Documentation/devicetree/bindings/mfd/atmel-smc.txt b/Documentation/devicetree/bindings/mfd/atmel-smc.txt
new file mode 100644
index 000000000000..26eeed373934
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel-smc.txt
@@ -0,0 +1,19 @@
+* Device tree bindings for Atmel SMC (Static Memory Controller)
+
+The SMC registers are used to configure Atmel EBI (External Bus Interface)
+to interface with standard memory devices (NAND, NOR, SRAM or specialized
+devices like FPGAs).
+
+Required properties:
+- compatible: Should be one of the following
+ "atmel,at91sam9260-smc", "syscon"
+ "atmel,sama5d3-smc", "syscon"
+- reg: Contains offset/length value of the SMC memory
+ region.
+
+Example:
+
+smc: smc@ffffc000 {
+ compatible = "atmel,sama5d3-smc", "syscon";
+ reg = <0xffffc000 0x1000>;
+};
diff --git a/Documentation/devicetree/bindings/mfd/da9063.txt b/Documentation/devicetree/bindings/mfd/da9063.txt
new file mode 100644
index 000000000000..42c6fa6f1c9a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/da9063.txt
@@ -0,0 +1,93 @@
+* Dialog DA9063 Power Management Integrated Circuit (PMIC)
+
+DA9093 consists of a large and varied group of sub-devices (I2C Only):
+
+Device Supply Names Description
+------ ------------ -----------
+da9063-regulator : : LDOs & BUCKs
+da9063-rtc : : Real-Time Clock
+da9063-watchdog : : Watchdog
+
+======
+
+Required properties:
+
+- compatible : Should be "dlg,da9063"
+- reg : Specifies the I2C slave address (this defaults to 0x58 but it can be
+ modified to match the chip's OTP settings).
+- interrupt-parent : Specifies the reference to the interrupt controller for
+ the DA9063.
+- interrupts : IRQ line information.
+- interrupt-controller
+
+Sub-nodes:
+
+- regulators : This node defines the settings for the LDOs and BUCKs. The
+ DA9063 regulators are bound using their names listed below:
+
+ bcore1 : BUCK CORE1
+ bcore2 : BUCK CORE2
+ bpro : BUCK PRO
+ bmem : BUCK MEM
+ bio : BUCK IO
+ bperi : BUCK PERI
+ ldo1 : LDO_1
+ ldo2 : LDO_2
+ ldo3 : LDO_3
+ ldo4 : LDO_4
+ ldo5 : LDO_5
+ ldo6 : LDO_6
+ ldo7 : LDO_7
+ ldo8 : LDO_8
+ ldo9 : LDO_9
+ ldo10 : LDO_10
+ ldo11 : LDO_11
+
+ The component follows the standard regulator framework and the bindings
+ details of individual regulator device can be found in:
+ Documentation/devicetree/bindings/regulator/regulator.txt
+
+- rtc : This node defines settings for the Real-Time Clock associated with
+ the DA9063. There are currently no entries in this binding, however
+ compatible = "dlg,da9063-rtc" should be added if a node is created.
+
+- watchdog : This node defines settings for the Watchdog timer associated
+ with the DA9063. There are currently no entries in this binding, however
+ compatible = "dlg,da9063-watchdog" should be added if a node is created.
+
+
+Example:
+
+ pmic0: da9063@58 {
+ compatible = "dlg,da9063"
+ reg = <0x58>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+
+ rtc {
+ compatible = "dlg,da9063-rtc";
+ };
+
+ wdt {
+ compatible = "dlg,da9063-watchdog";
+ };
+
+ regulators {
+ DA9063_BCORE1: bcore1 {
+ regulator-name = "BCORE1";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1570000>;
+ regulator-min-microamp = <500000>;
+ regulator-max-microamp = <2000000>;
+ regulator-boot-on;
+ };
+ DA9063_LDO11: ldo11 {
+ regulator-name = "LDO_11";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <3600000>;
+ regulator-boot-on;
+ };
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
new file mode 100644
index 000000000000..85e31980017a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
@@ -0,0 +1,70 @@
+Qualcomm Resource Power Manager (RPM)
+
+This driver is used to interface with the Resource Power Manager (RPM) found in
+various Qualcomm platforms. The RPM allows each component in the system to vote
+for state of the system resources, such as clocks, regulators and bus
+frequencies.
+
+- compatible:
+ Usage: required
+ Value type: <string>
+ Definition: must be one of:
+ "qcom,rpm-apq8064"
+ "qcom,rpm-msm8660"
+ "qcom,rpm-msm8960"
+
+- reg:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: base address and size of the RPM's message ram
+
+- interrupts:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: three entries specifying the RPM's:
+ 1. acknowledgement interrupt
+ 2. error interrupt
+ 3. wakeup interrupt
+
+- interrupt-names:
+ Usage: required
+ Value type: <string-array>
+ Definition: must be the three strings "ack", "err" and "wakeup", in order
+
+- #address-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 1
+
+- #size-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 0
+
+- qcom,ipc:
+ Usage: required
+ Value type: <prop-encoded-array>
+
+ Definition: three entries specifying the outgoing ipc bit used for
+ signaling the RPM:
+ - phandle to a syscon node representing the apcs registers
+ - u32 representing offset to the register within the syscon
+ - u32 representing the ipc bit within the register
+
+
+= EXAMPLE
+
+ #include <dt-bindings/mfd/qcom-rpm.h>
+
+ rpm@108000 {
+ compatible = "qcom,rpm-msm8960";
+ reg = <0x108000 0x1000>;
+ qcom,ipc = <&apcs 0x8 2>;
+
+ interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
+ interrupt-names = "ack", "err", "wakeup";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
new file mode 100644
index 000000000000..c7a26ca8da12
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
@@ -0,0 +1,40 @@
+* Freescale Management Complex
+
+The Freescale Management Complex (fsl-mc) is a hardware resource
+manager that manages specialized hardware objects used in
+network-oriented packet processing applications. After the fsl-mc
+block is enabled, pools of hardware resources are available, such as
+queues, buffer pools, I/O interfaces. These resources are building
+blocks that can be used to create functional hardware objects/devices
+such as network interfaces, crypto accelerator instances, L2 switches,
+etc.
+
+Required properties:
+
+ - compatible
+ Value type: <string>
+ Definition: Must be "fsl,qoriq-mc". A Freescale Management Complex
+ compatible with this binding must have Block Revision
+ Registers BRR1 and BRR2 at offset 0x0BF8 and 0x0BFC in
+ the MC control register region.
+
+ - reg
+ Value type: <prop-encoded-array>
+ Definition: A standard property. Specifies one or two regions
+ defining the MC's registers:
+
+ -the first region is the command portal for the
+ this machine and must always be present
+
+ -the second region is the MC control registers. This
+ region may not be present in some scenarios, such
+ as in the device tree presented to a virtual machine.
+
+Example:
+
+ fsl_mc: fsl-mc@80c000000 {
+ compatible = "fsl,qoriq-mc";
+ reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
+ <0x00000000 0x08340000 0 0x40000>; /* MC control reg */
+ };
+
diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
index 1fe6dde98499..7d4c8eb775a5 100644
--- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
@@ -1,7 +1,7 @@
Atmel NAND flash
Required properties:
-- compatible : "atmel,at91rm9200-nand".
+- compatible : should be "atmel,at91rm9200-nand" or "atmel,sama5d4-nand".
- reg : should specify localbus address and size used for the chip,
and hardware ECC controller if available.
If the hardware ECC is PMECC, it should contain address and size for
diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
index 823d13412195..4461dc71cb10 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt
@@ -1,7 +1,7 @@
* Freescale Quad Serial Peripheral Interface(QuadSPI)
Required properties:
- - compatible : Should be "fsl,vf610-qspi"
+ - compatible : Should be "fsl,vf610-qspi" or "fsl,imx6sx-qspi"
- reg : the first contains the register location and length,
the second contains the memory mapping address and length
- reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory"
diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index a011fdf61dbf..d02acaff3c35 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -1,7 +1,7 @@
* Freescale General-Purpose Media Interface (GPMI)
The GPMI nand controller provides an interface to control the
-NAND flash chips. We support only one NAND chip now.
+NAND flash chips.
Required properties:
- compatible : should be "fsl,<chip>-gpmi-nand"
diff --git a/Documentation/devicetree/bindings/mtd/hisi504-nand.txt b/Documentation/devicetree/bindings/mtd/hisi504-nand.txt
new file mode 100644
index 000000000000..2e35f0662912
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/hisi504-nand.txt
@@ -0,0 +1,47 @@
+Hisilicon Hip04 Soc NAND controller DT binding
+
+Required properties:
+
+- compatible: Should be "hisilicon,504-nfc".
+- reg: The first contains base physical address and size of
+ NAND controller's registers. The second contains base
+ physical address and size of NAND controller's buffer.
+- interrupts: Interrupt number for nfc.
+- nand-bus-width: See nand.txt.
+- nand-ecc-mode: Support none and hw ecc mode.
+- #address-cells: Partition address, should be set 1.
+- #size-cells: Partition size, should be set 1.
+
+Optional properties:
+
+- nand-ecc-strength: Number of bits to correct per ECC step.
+- nand-ecc-step-size: Number of data bytes covered by a single ECC step.
+
+The following ECC strength and step size are currently supported:
+
+ - nand-ecc-strength = <16>, nand-ecc-step-size = <1024>
+
+Flash chip may optionally contain additional sub-nodes describing partitions of
+the address space. See partition.txt for more detail.
+
+Example:
+
+ nand: nand@4020000 {
+ compatible = "hisilicon,504-nfc";
+ reg = <0x4020000 0x10000>, <0x5000000 0x1000>;
+ interrupts = <0 379 4>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-ecc-strength = <16>;
+ nand-ecc-step-size = <1024>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "nand_text";
+ reg = <0x00000000 0x00400000>;
+ };
+
+ ...
+
+ };
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
index 6b9f680cb579..4a0a48bf4ecb 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
@@ -36,6 +36,11 @@ are defined:
- vendor-id : Contains the flash chip's vendor id (1 byte).
- device-id : Contains the flash chip's device id (1 byte).
+For ROM compatible devices (and ROM fallback from cfi-flash), the following
+additional (optional) property is defined:
+
+ - erase-size : The chip's physical erase block size in bytes.
+
The device tree may optionally contain sub-nodes describing partitions of the
address space. See partition.txt for more detail.
diff --git a/Documentation/devicetree/bindings/panel/avic,tm070ddh03.txt b/Documentation/devicetree/bindings/panel/avic,tm070ddh03.txt
new file mode 100644
index 000000000000..b6f2f3e8f44e
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/avic,tm070ddh03.txt
@@ -0,0 +1,7 @@
+Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
+
+Required properties:
+- compatible: should be "avic,tm070ddh03"
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt b/Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt
new file mode 100644
index 000000000000..24b0b624434b
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt
@@ -0,0 +1,7 @@
+GiantPlus GPG48273QS5 4.3" (480x272) WQVGA TFT LCD panel
+
+Required properties:
+- compatible: should be "giantplus,gpg48273qs5"
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/power/renesas,sysc-rmobile.txt b/Documentation/devicetree/bindings/power/renesas,sysc-rmobile.txt
new file mode 100644
index 000000000000..cc3b1f0a9b1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/renesas,sysc-rmobile.txt
@@ -0,0 +1,99 @@
+DT bindings for the Renesas R-Mobile System Controller
+
+== System Controller Node ==
+
+The R-Mobile System Controller provides the following functions:
+ - Boot mode management,
+ - Reset generation,
+ - Power management.
+
+Required properties:
+- compatible: Should be "renesas,sysc-<soctype>", "renesas,sysc-rmobile" as
+ fallback.
+ Examples with soctypes are:
+ - "renesas,sysc-r8a7740" (R-Mobile A1)
+ - "renesas,sysc-sh73a0" (SH-Mobile AG5)
+- reg: Two address start and address range blocks for the device:
+ - The first block refers to the normally accessible registers,
+ - the second block refers to the registers protected by the HPB
+ semaphore.
+
+Optional nodes:
+- pm-domains: This node contains a hierarchy of PM domain nodes, which should
+ match the Power Area Hierarchy in the Power Domain Specifications section of
+ the device's datasheet.
+
+
+== PM Domain Nodes ==
+
+Each of the PM domain nodes represents a PM domain, as documented by the
+generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
+
+The nodes should be named by the real power area names, and thus their names
+should be unique.
+
+Required properties:
+ - #power-domain-cells: Must be 0.
+
+Optional properties:
+- reg: If the PM domain is not always-on, this property must contain the bit
+ index number for the corresponding power area in the various Power
+ Control and Status Registers. The parent's node must contain the
+ following two properties:
+ - #address-cells: Must be 1,
+ - #size-cells: Must be 0.
+ If the PM domain is always-on, this property must be omitted.
+
+
+Example:
+
+This shows a subset of the r8a7740 PM domain hierarchy, containing the
+C5 "always-on" domain, 2 of its subdomains (A4S and A4SU), and the A3SP domain,
+which is a subdomain of A4S.
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,sysc-r8a7740", "renesas,sysc-rmobile";
+ reg = <0xe6180000 0x8000>, <0xe6188000 0x8000>;
+
+ pm-domains {
+ pd_c5: c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a4s: a4s@10 {
+ reg = <10>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3sp: a3sp@11 {
+ reg = <11>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4su: a4su@20 {
+ reg = <20>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ };
+
+
+== PM Domain Consumers ==
+
+Hardware blocks belonging to a PM domain should contain a "power-domains"
+property that is a phandle pointing to the corresponding PM domain node.
+
+Example:
+
+ tpu: pwm@e6600000 {
+ compatible = "renesas,tpu-r8a7740", "renesas,tpu";
+ reg = <0xe6600000 0x100>;
+ clocks = <&mstp3_clks R8A7740_CLK_TPU0>;
+ power-domains = <&pd_a3sp>;
+ #pwm-cells = <3>;
+ };
diff --git a/Documentation/devicetree/bindings/pwm/img-pwm.txt b/Documentation/devicetree/bindings/pwm/img-pwm.txt
new file mode 100644
index 000000000000..fade5f26fcac
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/img-pwm.txt
@@ -0,0 +1,24 @@
+*Imagination Technologies PWM DAC driver
+
+Required properties:
+ - compatible: Should be "img,pistachio-pwm"
+ - reg: Should contain physical base address and length of pwm registers.
+ - clocks: Must contain an entry for each entry in clock-names.
+ See ../clock/clock-bindings.txt for details.
+ - clock-names: Must include the following entries.
+ - pwm: PWM operating clock.
+ - sys: PWM system interface clock.
+ - #pwm-cells: Should be 2. See pwm.txt in this directory for the
+ description of the cells format.
+ - img,cr-periph: Must contain a phandle to the peripheral control
+ syscon node which contains PWM control registers.
+
+Example:
+ pwm: pwm@18101300 {
+ compatible = "img,pistachio-pwm";
+ reg = <0x18101300 0x100>;
+ clocks = <&pwm_clk>, <&system_clk>;
+ clock-names = "pwm", "sys";
+ #pwm-cells = <2>;
+ img,cr-periph = <&cr_periph>;
+ };
diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
new file mode 100644
index 000000000000..ae0273e19506
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -0,0 +1,20 @@
+Allwinner sun4i and sun7i SoC PWM controller
+
+Required properties:
+ - compatible: should be one of:
+ - "allwinner,sun4i-a10-pwm"
+ - "allwinner,sun7i-a20-pwm"
+ - reg: physical base address and length of the controller's registers
+ - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
+ the cells format.
+ - clocks: From common clock binding, handle to the parent clock.
+
+Example:
+
+ pwm: pwm@01c20e00 {
+ compatible = "allwinner,sun7i-a20-pwm";
+ reg = <0x01c20e00 0xc>;
+ clocks = <&osc24M>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index 48358a33ea7d..44152261e5c5 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -2,9 +2,13 @@
Required properties:
- compatible should contain:
+ * "mediatek,mt8135-uart" for MT8135 compatible UARTS
+ * "mediatek,mt8127-uart" for MT8127 compatible UARTS
+ * "mediatek,mt8173-uart" for MT8173 compatible UARTS
* "mediatek,mt6589-uart" for MT6589 compatible UARTS
* "mediatek,mt6582-uart" for MT6582 compatible UARTS
- * "mediatek,mt6577-uart" for all compatible UARTS (MT6589, MT6582, MT6577)
+ * "mediatek,mt6577-uart" for all compatible UARTS (MT8173, MT6589, MT6582,
+ MT6577)
- reg: The base address of the UART register bank.
diff --git a/Documentation/devicetree/bindings/serial/of-serial.txt b/Documentation/devicetree/bindings/serial/of-serial.txt
index bea60ef6cdc5..91d5ab0e60fc 100644
--- a/Documentation/devicetree/bindings/serial/of-serial.txt
+++ b/Documentation/devicetree/bindings/serial/of-serial.txt
@@ -19,6 +19,7 @@ Required properties:
- "altr,16550-FIFO64"
- "altr,16550-FIFO128"
- "fsl,16550-FIFO64"
+ - "fsl,ns16550"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
@@ -43,6 +44,17 @@ Optional properties:
driver is allowed to detect support for the capability even without this
property.
+Note:
+* fsl,ns16550:
+ ------------
+ Freescale DUART is very similar to the PC16552D (and to a
+ pair of NS16550A), albeit with some nonstandard behavior such as
+ erratum A-004737 (relating to incorrect BRK handling).
+
+ Represents a single port that is compatible with the DUART found
+ on many Freescale chips (examples include mpc8349, mpc8548,
+ mpc8641d, p4080 and ls2085a).
+
Example:
uart@80230000 {
diff --git a/Documentation/devicetree/bindings/sound/atmel_ac97c.txt b/Documentation/devicetree/bindings/sound/atmel_ac97c.txt
new file mode 100644
index 000000000000..b151bd902ce3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel_ac97c.txt
@@ -0,0 +1,20 @@
+* Atmel AC97 controller
+
+Required properties:
+ - compatible: "atmel,at91sam9263-ac97c"
+ - reg: Address and length of the register set for the device
+ - interrupts: Should contain AC97 interrupt
+ - ac97-gpios: Please refer to soc-ac97link.txt, only ac97-reset is used
+Optional properties:
+ - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
+
+Example:
+sound@fffa0000 {
+ compatible = "atmel,at91sam9263-ac97c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ac97>;
+ reg = <0xfffa0000 0x4000>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 5>;
+
+ ac97-gpios = <&pioB 0 0 &pioB 2 0 &pioC 29 GPIO_ACTIVE_LOW>;
+};
diff --git a/Documentation/devicetree/bindings/timer/digicolor-timer.txt b/Documentation/devicetree/bindings/timer/digicolor-timer.txt
new file mode 100644
index 000000000000..d1b659bbc29f
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/digicolor-timer.txt
@@ -0,0 +1,18 @@
+Conexant Digicolor SoCs Timer Controller
+
+Required properties:
+
+- compatible : should be "cnxt,cx92755-timer"
+- reg : Specifies base physical address and size of the "Agent Communication"
+ timer registers
+- interrupts : Contains 8 interrupts, one for each timer
+- clocks: phandle to the main clock
+
+Example:
+
+ timer@f0000fc0 {
+ compatible = "cnxt,cx92755-timer";
+ reg = <0xf0000fc0 0x40>;
+ interrupts = <19>, <31>, <34>, <35>, <52>, <53>, <54>, <55>;
+ clocks = <&main_clk>;
+ };
diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt
new file mode 100644
index 000000000000..87f0b0042bae
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt
@@ -0,0 +1,18 @@
+Rockchip rk3288 timer
+
+Required properties:
+- compatible: shall be "rockchip,rk3288-timer"
+- reg: base address of the timer register starting with TIMERS CONTROL register
+- interrupts: should contain the interrupts for Timer0
+- clocks : must contain an entry for each entry in clock-names
+- clock-names : must include the following entries:
+ "timer", "pclk"
+
+Example:
+ timer: timer@ff810000 {
+ compatible = "rockchip,rk3288-timer";
+ reg = <0xff810000 0x20>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>, <&cru PCLK_TIMER>;
+ clock-names = "timer", "pclk";
+ };
diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
index 38fee0f66c12..e180d56c75db 100644
--- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
+++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt
@@ -33,9 +33,17 @@ usb1: ehci@00800000 {
AT91 USB device controller
Required properties:
- - compatible: Should be "atmel,at91rm9200-udc"
+ - compatible: Should be one of the following
+ "atmel,at91rm9200-udc"
+ "atmel,at91sam9260-udc"
+ "atmel,at91sam9261-udc"
+ "atmel,at91sam9263-udc"
- reg: Address and length of the register set for the device
- interrupts: Should contain macb interrupt
+ - clocks: Should reference the peripheral and the AHB clocks
+ - clock-names: Should contains two strings
+ "pclk" for the peripheral clock
+ "hclk" for the AHB clock
Optional properties:
- atmel,vbus-gpio: If present, specifies a gpio that needs to be
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index cba613f8aa4f..389ca1347a77 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -12,6 +12,7 @@ adh AD Holdings Plc.
adi Analog Devices, Inc.
aeroflexgaisler Aeroflex Gaisler AB
allwinner Allwinner Technology Co., Ltd.
+alphascale AlphaScale Integrated Circuits Systems, Inc.
altr Altera Corp.
amcc Applied Micro Circuits Corporation (APM, formally AMCC)
amd Advanced Micro Devices (AMD), Inc.
@@ -25,6 +26,7 @@ asahi-kasei Asahi Kasei Corp.
atmel Atmel Corporation
auo AU Optronics Corporation
avago Avago Technologies
+avic Shanghai AVIC Optoelectronics Co., Ltd.
bosch Bosch Sensortec GmbH
brcm Broadcom Corporation
buffalo Buffalo, Inc.
@@ -33,9 +35,11 @@ capella Capella Microsystems, Inc
cavium Cavium, Inc.
cdns Cadence Design Systems Inc.
chipidea Chipidea, Inc
+chipspark ChipSPARK
chrp Common Hardware Reference Platform
chunghwa Chunghwa Picture Tubes Ltd.
cirrus Cirrus Logic, Inc.
+cloudengines Cloud Engines, Inc.
cnm Chips&Media, Inc.
cnxt Conexant Systems, Inc.
cortina Cortina Systems, Inc.
@@ -64,10 +68,12 @@ everest Everest Semiconductor Co. Ltd.
everspin Everspin Technologies, Inc.
excito Excito
fcs Fairchild Semiconductor
+firefly Firefly
fsl Freescale Semiconductor
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
geniatech Geniatech, Inc.
+giantplus Giantplus Technology Co., Ltd.
globalscale Globalscale Technologies, Inc.
gmt Global Mixed-mode Technology, Inc.
google Google, Inc.
@@ -126,6 +132,7 @@ onnn ON Semiconductor Corp.
opencores OpenCores.org
ovti OmniVision Technologies
panasonic Panasonic Corporation
+parade Parade Technologies Inc.
pericom Pericom Technology Inc.
phytec PHYTEC Messtechnik GmbH
picochip Picochip Ltd
diff --git a/Documentation/devicetree/bindings/video/bridge/ps8622.txt b/Documentation/devicetree/bindings/video/bridge/ps8622.txt
new file mode 100644
index 000000000000..c989c3807f2b
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/bridge/ps8622.txt
@@ -0,0 +1,31 @@
+ps8622-bridge bindings
+
+Required properties:
+ - compatible: "parade,ps8622" or "parade,ps8625"
+ - reg: first i2c address of the bridge
+ - sleep-gpios: OF device-tree gpio specification for PD_ pin.
+ - reset-gpios: OF device-tree gpio specification for RST_ pin.
+
+Optional properties:
+ - lane-count: number of DP lanes to use
+ - use-external-pwm: backlight will be controlled by an external PWM
+ - video interfaces: Device node can contain video interface port
+ nodes for panel according to [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example:
+ lvds-bridge@48 {
+ compatible = "parade,ps8622";
+ reg = <0x48>;
+ sleep-gpios = <&gpc3 6 1 0 0>;
+ reset-gpios = <&gpc3 1 1 0 0>;
+ lane-count = <1>;
+ ports {
+ port@0 {
+ bridge_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/drm/bridge/ptn3460.txt b/Documentation/devicetree/bindings/video/bridge/ptn3460.txt
index 52b93b2c6748..361971ba104d 100644
--- a/Documentation/devicetree/bindings/drm/bridge/ptn3460.txt
+++ b/Documentation/devicetree/bindings/video/bridge/ptn3460.txt
@@ -3,8 +3,8 @@ ptn3460 bridge bindings
Required properties:
- compatible: "nxp,ptn3460"
- reg: i2c address of the bridge
- - powerdown-gpio: OF device-tree gpio specification
- - reset-gpio: OF device-tree gpio specification
+ - powerdown-gpio: OF device-tree gpio specification for PD_N pin.
+ - reset-gpio: OF device-tree gpio specification for RST_N pin.
- edid-emulation: The EDID emulation entry to use
+-------+------------+------------------+
| Value | Resolution | Description |
@@ -17,6 +17,11 @@ Required properties:
| 6 | 1600x900 | ChiMei M215HGE |
+-------+------------+------------------+
+ - video interfaces: Device node can contain video interface port
+ nodes for panel according to [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
Example:
lvds-bridge@20 {
compatible = "nxp,ptn3460";
@@ -24,4 +29,11 @@ Example:
powerdown-gpio = <&gpy2 5 1 0 0>;
reset-gpio = <&gpx1 5 1 0 0>;
edid-emulation = <5>;
+ ports {
+ port@0 {
+ bridge_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
};
diff --git a/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
new file mode 100644
index 000000000000..668091f27674
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt
@@ -0,0 +1,46 @@
+Rockchip specific extensions to the Synopsys Designware HDMI
+================================
+
+Required properties:
+- compatible: "rockchip,rk3288-dw-hdmi";
+- reg: Physical base address and length of the controller's registers.
+- clocks: phandle to hdmi iahb and isfr clocks.
+- clock-names: should be "iahb" "isfr"
+- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
+- interrupts: HDMI interrupt number
+- ports: contain a port node with endpoint definitions as defined in
+ Documentation/devicetree/bindings/media/video-interfaces.txt. For
+ vopb,set the reg = <0> and set the reg = <1> for vopl.
+- reg-io-width: the width of the reg:1,4, the value should be 4 on
+ rk3288 platform
+
+Optional properties
+- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+- clocks, clock-names: phandle to the HDMI CEC clock, name should be "cec"
+
+Example:
+hdmi: hdmi@ff980000 {
+ compatible = "rockchip,rk3288-dw-hdmi";
+ reg = <0xff980000 0x20000>;
+ reg-io-width = <4>;
+ ddc-i2c-bus = <&i2c5>;
+ rockchip,grf = <&grf>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
+ clock-names = "iahb", "isfr";
+ status = "disabled";
+ ports {
+ hdmi_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ hdmi_in_vopb: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vopb_out_hdmi>;
+ };
+ hdmi_in_vopl: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&vopl_out_hdmi>;
+ };
+ };
+ };
+};
diff --git a/Documentation/devicetree/bindings/video/exynos7-decon.txt b/Documentation/devicetree/bindings/video/exynos7-decon.txt
new file mode 100644
index 000000000000..f5f9c8d4a55a
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/exynos7-decon.txt
@@ -0,0 +1,68 @@
+Device-Tree bindings for Samsung Exynos7 SoC display controller (DECON)
+
+DECON (Display and Enhancement Controller) is the Display Controller for the
+Exynos7 series of SoCs which transfers the image data from a video memory
+buffer to an external LCD interface.
+
+Required properties:
+- compatible: value should be "samsung,exynos7-decon";
+
+- reg: physical base address and length of the DECON registers set.
+
+- interrupt-parent: should be the phandle of the decon controller's
+ parent interrupt controller.
+
+- interrupts: should contain a list of all DECON IP block interrupts in the
+ order: FIFO Level, VSYNC, LCD_SYSTEM. The interrupt specifier
+ format depends on the interrupt controller used.
+
+- interrupt-names: should contain the interrupt names: "fifo", "vsync",
+ "lcd_sys", in the same order as they were listed in the interrupts
+ property.
+
+- pinctrl-0: pin control group to be used for this controller.
+
+- pinctrl-names: must contain a "default" entry.
+
+- clocks: must include clock specifiers corresponding to entries in the
+ clock-names property.
+
+- clock-names: list of clock names sorted in the same order as the clocks
+ property. Must contain "pclk_decon0", "aclk_decon0",
+ "decon0_eclk", "decon0_vclk".
+- i80-if-timings: timing configuration for lcd i80 interface support.
+
+Optional Properties:
+- samsung,power-domain: a phandle to DECON power domain node.
+- display-timings: timing settings for DECON, as described in document [1].
+ Can be used in case timings cannot be provided otherwise
+ or to override timings provided by the panel.
+
+[1]: Documentation/devicetree/bindings/video/display-timing.txt
+
+Example:
+
+SoC specific DT entry:
+
+ decon@13930000 {
+ compatible = "samsung,exynos7-decon";
+ interrupt-parent = <&combiner>;
+ reg = <0x13930000 0x1000>;
+ interrupt-names = "lcd_sys", "vsync", "fifo";
+ interrupts = <0 188 0>, <0 189 0>, <0 190 0>;
+ clocks = <&clock_disp PCLK_DECON_INT>,
+ <&clock_disp ACLK_DECON_INT>,
+ <&clock_disp SCLK_DECON_INT_ECLK>,
+ <&clock_disp SCLK_DECON_INT_EXTCLKPLL>;
+ clock-names = "pclk_decon0", "aclk_decon0", "decon0_eclk",
+ "decon0_vclk";
+ status = "disabled";
+ };
+
+Board specific DT entry:
+
+ decon@13930000 {
+ pinctrl-0 = <&lcd_clk &pwm1_out>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 53dbccfa80ca..7a3a9cdb86ab 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -66,6 +66,10 @@ Optional properties for dp-controller:
Hotplug detect GPIO.
Indicates which GPIO should be used for hotplug
detection
+ -video interfaces: Device node can contain video interface port
+ nodes according to [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
Example:
@@ -105,4 +109,12 @@ Board Specific portion:
vsync-len = <6>;
};
};
+
+ ports {
+ port@0 {
+ dp_out: endpoint {
+ remote-endpoint = <&bridge_in>;
+ };
+ };
+ };
};
diff --git a/Documentation/devicetree/bindings/video/exynos_dsim.txt b/Documentation/devicetree/bindings/video/exynos_dsim.txt
index ca2b4aacd9af..802aa7ef64e5 100644
--- a/Documentation/devicetree/bindings/video/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dsim.txt
@@ -21,7 +21,7 @@ Required properties:
according to DSI host bindings (see MIPI DSI bindings [1])
Optional properties:
- - samsung,power-domain: a phandle to DSIM power domain node
+ - power-domains: a phandle to DSIM power domain node
Child nodes:
Should contain DSI peripheral nodes (see MIPI DSI bindings [1]).
@@ -53,7 +53,7 @@ Example:
phy-names = "dsim";
vddcore-supply = <&vusb_reg>;
vddio-supply = <&vmipi_reg>;
- samsung,power-domain = <&pd_lcd0>;
+ power-domains = <&pd_lcd0>;
#address-cells = <1>;
#size-cells = <0>;
samsung,pll-clock-frequency = <24000000>;
diff --git a/Documentation/devicetree/bindings/video/exynos_mixer.txt b/Documentation/devicetree/bindings/video/exynos_mixer.txt
index 08b394b1edbf..3e38128f866b 100644
--- a/Documentation/devicetree/bindings/video/exynos_mixer.txt
+++ b/Documentation/devicetree/bindings/video/exynos_mixer.txt
@@ -15,6 +15,7 @@ Required properties:
a) mixer: Gate of Mixer IP bus clock.
b) sclk_hdmi: HDMI Special clock, one of the two possible inputs of
mixer mux.
+ c) hdmi: Gate of HDMI IP bus clock, needed together with sclk_hdmi.
Example:
diff --git a/Documentation/devicetree/bindings/video/renesas,du.txt b/Documentation/devicetree/bindings/video/renesas,du.txt
index 5102830f2760..c902323928f7 100644
--- a/Documentation/devicetree/bindings/video/renesas,du.txt
+++ b/Documentation/devicetree/bindings/video/renesas,du.txt
@@ -26,6 +26,10 @@ Required Properties:
per LVDS encoder. The functional clocks must be named "du.x" with "x"
being the channel numerical index. The LVDS clocks must be named
"lvds.x" with "x" being the LVDS encoder numerical index.
+ - In addition to the functional and encoder clocks, all DU versions also
+ support externally supplied pixel clocks. Those clocks are optional.
+ When supplied they must be named "dclkin.x" with "x" being the input
+ clock numerical index.
Required nodes:
diff --git a/Documentation/devicetree/bindings/video/samsung-fimd.txt b/Documentation/devicetree/bindings/video/samsung-fimd.txt
index cf1af6371021..a8bbbde03e79 100644
--- a/Documentation/devicetree/bindings/video/samsung-fimd.txt
+++ b/Documentation/devicetree/bindings/video/samsung-fimd.txt
@@ -38,7 +38,7 @@ Required properties:
property. Must contain "sclk_fimd" and "fimd".
Optional Properties:
-- samsung,power-domain: a phandle to FIMD power domain node.
+- power-domains: a phandle to FIMD power domain node.
- samsung,invert-vden: video enable signal is inverted
- samsung,invert-vclk: video clock signal is inverted
- display-timings: timing settings for FIMD, as described in document [1].
@@ -97,7 +97,7 @@ SoC specific DT entry:
interrupts = <11 0>, <11 1>, <11 2>;
clocks = <&clock 140>, <&clock 283>;
clock-names = "sclk_fimd", "fimd";
- samsung,power-domain = <&pd_lcd0>;
+ power-domains = <&pd_lcd0>;
status = "disabled";
};
diff --git a/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt b/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt
index 37afec194949..198794963786 100644
--- a/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt
@@ -13,6 +13,11 @@ Required Properties:
by the GPIO flags.
- hw_margin_ms: Maximum time to reset watchdog circuit (milliseconds).
+Optional Properties:
+- always-running: If the watchdog timer cannot be disabled, add this flag to
+ have the driver keep toggling the signal without a client. It will only cease
+ to toggle the signal when the device is open and the timeout elapsed.
+
Example:
watchdog: watchdog {
/* ADM706 */
diff --git a/Documentation/devicetree/bindings/watchdog/imgpdc-wdt.txt b/Documentation/devicetree/bindings/watchdog/imgpdc-wdt.txt
new file mode 100644
index 000000000000..b2fa11fd43de
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/imgpdc-wdt.txt
@@ -0,0 +1,19 @@
+*ImgTec PowerDown Controller (PDC) Watchdog Timer (WDT)
+
+Required properties:
+- compatible : Should be "img,pdc-wdt"
+- reg : Should contain WDT registers location and length
+- clocks: Must contain an entry for each entry in clock-names.
+- clock-names: Should contain "wdt" and "sys"; the watchdog counter
+ clock and register interface clock respectively.
+- interrupts : Should contain WDT interrupt
+
+Examples:
+
+watchdog@18102100 {
+ compatible = "img,pdc-wdt";
+ reg = <0x18102100 0x100>;
+ clocks = <&pdc_wdt_clk>, <&sys_clk>;
+ clock-names = "wdt", "sys";
+ interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt b/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
new file mode 100644
index 000000000000..e27763ef0049
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
@@ -0,0 +1,12 @@
+Ingenic Watchdog Timer (WDT) Controller for JZ4740
+
+Required properties:
+compatible: "ingenic,jz4740-watchdog"
+reg: Register address and length for watchdog registers
+
+Example:
+
+watchdog: jz4740-watchdog@0x10002000 {
+ compatible = "ingenic,jz4740-watchdog";
+ reg = <0x10002000 0x100>;
+};
diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
new file mode 100644
index 000000000000..af9eb5b8a253
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -0,0 +1,13 @@
+Mediatek SoCs Watchdog timer
+
+Required properties:
+
+- compatible : should be "mediatek,mt6589-wdt"
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+wdt: watchdog@010000000 {
+ compatible = "mediatek,mt6589-wdt";
+ reg = <0x10000000 0x18>;
+};
diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt
index 766658ccf235..05d2280190f1 100644
--- a/Documentation/dmaengine/provider.txt
+++ b/Documentation/dmaengine/provider.txt
@@ -113,6 +113,31 @@ need to initialize a few fields in there:
* channels: should be initialized as a list using the
INIT_LIST_HEAD macro for example
+ * src_addr_widths:
+ - should contain a bitmask of the supported source transfer width
+
+ * dst_addr_widths:
+ - should contain a bitmask of the supported destination transfer
+ width
+
+ * directions:
+ - should contain a bitmask of the supported slave directions
+ (i.e. excluding mem2mem transfers)
+
+ * residue_granularity:
+ - Granularity of the transfer residue reported to dma_set_residue.
+ - This can be either:
+ + Descriptor
+ -> Your device doesn't support any kind of residue
+ reporting. The framework will only know that a particular
+ transaction descriptor is done.
+ + Segment
+ -> Your device is able to report which chunks have been
+ transferred
+ + Burst
+ -> Your device is able to report which burst have been
+ transferred
+
* dev: should hold the pointer to the struct device associated
to your current driver instance.
@@ -274,48 +299,36 @@ supported.
account the current period.
- This function can be called in an interrupt context.
- * device_control
- - Used by client drivers to control and configure the channel it
- has a handle on.
- - Called with a command and an argument
- + The command is one of the values listed by the enum
- dma_ctrl_cmd. The valid commands are:
- + DMA_PAUSE
- + Pauses a transfer on the channel
- + This command should operate synchronously on the channel,
- pausing right away the work of the given channel
- + DMA_RESUME
- + Restarts a transfer on the channel
- + This command should operate synchronously on the channel,
- resuming right away the work of the given channel
- + DMA_TERMINATE_ALL
- + Aborts all the pending and ongoing transfers on the
- channel
- + This command should operate synchronously on the channel,
- terminating right away all the channels
- + DMA_SLAVE_CONFIG
- + Reconfigures the channel with passed configuration
- + This command should NOT perform synchronously, or on any
- currently queued transfers, but only on subsequent ones
- + In this case, the function will receive a
- dma_slave_config structure pointer as an argument, that
- will detail which configuration to use.
- + Even though that structure contains a direction field,
- this field is deprecated in favor of the direction
- argument given to the prep_* functions
- + FSLDMA_EXTERNAL_START
- + TODO: Why does that even exist?
- + The argument is an opaque unsigned long. This actually is a
- pointer to a struct dma_slave_config that should be used only
- in the DMA_SLAVE_CONFIG.
-
- * device_slave_caps
- - Called through the framework by client drivers in order to have
- an idea of what are the properties of the channel allocated to
- them.
- - Such properties are the buswidth, available directions, etc.
- - Required for every generic layer doing DMA transfers, such as
- ASoC.
+ * device_config
+ - Reconfigures the channel with the configuration given as
+ argument
+ - This command should NOT perform synchronously, or on any
+ currently queued transfers, but only on subsequent ones
+ - In this case, the function will receive a dma_slave_config
+ structure pointer as an argument, that will detail which
+ configuration to use.
+ - Even though that structure contains a direction field, this
+ field is deprecated in favor of the direction argument given to
+ the prep_* functions
+ - This call is mandatory for slave operations only. This should NOT be
+ set or expected to be set for memcpy operations.
+ If a driver support both, it should use this call for slave
+ operations only and not for memcpy ones.
+
+ * device_pause
+ - Pauses a transfer on the channel
+ - This command should operate synchronously on the channel,
+ pausing right away the work of the given channel
+
+ * device_resume
+ - Resumes a transfer on the channel
+ - This command should operate synchronously on the channel,
+ pausing right away the work of the given channel
+
+ * device_terminate_all
+ - Aborts all the pending and ongoing transfers on the channel
+ - This command should operate synchronously on the channel,
+ terminating right away all the channels
Misc notes (stuff that should be documented, but don't really know
where to put them)
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index ac28149aede4..9922939e7d99 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -34,6 +34,9 @@ configfs/
- directory containing configfs documentation and example code.
cramfs.txt
- info on the cram filesystem for small storage (ROMs etc).
+dax.txt
+ - info on avoiding the page cache for files stored on CPU-addressable
+ storage devices.
debugfs.txt
- info on the debugfs filesystem.
devpts.txt
@@ -154,5 +157,3 @@ xfs-self-describing-metadata.txt
- info on XFS Self Describing Metadata.
xfs.txt
- info and mount options for the XFS filesystem.
-xip.txt
- - info on execute-in-place for file mappings.
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index b30753cbf431..2ca3d17eee56 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -199,8 +199,6 @@ prototypes:
int (*releasepage) (struct page *, int);
void (*freepage)(struct page *);
int (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset);
- int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **,
- unsigned long *);
int (*migratepage)(struct address_space *, struct page *, struct page *);
int (*launder_page)(struct page *);
int (*is_partially_uptodate)(struct page *, unsigned long, unsigned long);
@@ -225,7 +223,6 @@ invalidatepage: yes
releasepage: yes
freepage: yes
direct_IO:
-get_xip_mem: maybe
migratepage: yes (both)
launder_page: yes
is_partially_uptodate: yes
diff --git a/Documentation/filesystems/dax.txt b/Documentation/filesystems/dax.txt
new file mode 100644
index 000000000000..baf41118660d
--- /dev/null
+++ b/Documentation/filesystems/dax.txt
@@ -0,0 +1,94 @@
+Direct Access for files
+-----------------------
+
+Motivation
+----------
+
+The page cache is usually used to buffer reads and writes to files.
+It is also used to provide the pages which are mapped into userspace
+by a call to mmap.
+
+For block devices that are memory-like, the page cache pages would be
+unnecessary copies of the original storage. The DAX code removes the
+extra copy by performing reads and writes directly to the storage device.
+For file mappings, the storage device is mapped directly into userspace.
+
+
+Usage
+-----
+
+If you have a block device which supports DAX, you can make a filesystem
+on it as usual. When mounting it, use the -o dax option manually
+or add 'dax' to the options in /etc/fstab.
+
+
+Implementation Tips for Block Driver Writers
+--------------------------------------------
+
+To support DAX in your block driver, implement the 'direct_access'
+block device operation. It is used to translate the sector number
+(expressed in units of 512-byte sectors) to a page frame number (pfn)
+that identifies the physical page for the memory. It also returns a
+kernel virtual address that can be used to access the memory.
+
+The direct_access method takes a 'size' parameter that indicates the
+number of bytes being requested. The function should return the number
+of bytes that can be contiguously accessed at that offset. It may also
+return a negative errno if an error occurs.
+
+In order to support this method, the storage must be byte-accessible by
+the CPU at all times. If your device uses paging techniques to expose
+a large amount of memory through a smaller window, then you cannot
+implement direct_access. Equally, if your device can occasionally
+stall the CPU for an extended period, you should also not attempt to
+implement direct_access.
+
+These block devices may be used for inspiration:
+- axonram: Axon DDR2 device driver
+- brd: RAM backed block device driver
+- dcssblk: s390 dcss block device driver
+
+
+Implementation Tips for Filesystem Writers
+------------------------------------------
+
+Filesystem support consists of
+- adding support to mark inodes as being DAX by setting the S_DAX flag in
+ i_flags
+- implementing the direct_IO address space operation, and calling
+ dax_do_io() instead of blockdev_direct_IO() if S_DAX is set
+- implementing an mmap file operation for DAX files which sets the
+ VM_MIXEDMAP flag on the VMA, and setting the vm_ops to include handlers
+ for fault and page_mkwrite (which should probably call dax_fault() and
+ dax_mkwrite(), passing the appropriate get_block() callback)
+- calling dax_truncate_page() instead of block_truncate_page() for DAX files
+- calling dax_zero_page_range() instead of zero_user() for DAX files
+- ensuring that there is sufficient locking between reads, writes,
+ truncates and page faults
+
+The get_block() callback passed to the DAX functions may return
+uninitialised extents. If it does, it must ensure that simultaneous
+calls to get_block() (for example by a page-fault racing with a read()
+or a write()) work correctly.
+
+These filesystems may be used for inspiration:
+- ext2: the second extended filesystem, see Documentation/filesystems/ext2.txt
+- ext4: the fourth extended filesystem, see Documentation/filesystems/ext4.txt
+
+
+Shortcomings
+------------
+
+Even if the kernel or its modules are stored on a filesystem that supports
+DAX on a block device that supports DAX, they will still be copied into RAM.
+
+The DAX code does not work correctly on architectures which have virtually
+mapped caches such as ARM, MIPS and SPARC.
+
+Calling get_user_pages() on a range of user memory that has been mmaped
+from a DAX file will fail as there are no 'struct page' to describe
+those pages. This problem is being worked on. That means that O_DIRECT
+reads/writes to those memory ranges from a non-DAX file will fail (note
+that O_DIRECT reads/writes _of a DAX file_ do work, it is the memory
+that is being accessed that is key here). Other things that will not
+work include RDMA, sendfile() and splice().
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
index 67639f905f10..b9714569e472 100644
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -20,6 +20,9 @@ minixdf Makes `df' act like Minix.
check=none, nocheck (*) Don't do extra checking of bitmaps on mount
(check=normal and check=strict options removed)
+dax Use direct access (no page cache). See
+ Documentation/filesystems/dax.txt.
+
debug Extra debugging information is sent to the
kernel syslog. Useful for developers.
@@ -56,8 +59,6 @@ noacl Don't support POSIX ACLs.
nobh Do not attach buffer_heads to file pagecache.
-xip Use execute in place (no caching) if possible
-
grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2.
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 919a3293aaa4..6c0108eb0137 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -386,6 +386,10 @@ max_dir_size_kb=n This limits the size of directories so that any
i_version Enable 64-bit inode version support. This option is
off by default.
+dax Use direct access (no page cache). See
+ Documentation/filesystems/dax.txt. Note that
+ this option is incompatible with data=journal.
+
Data Mode
=========
There are 3 different data modes:
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 43ce0507ee25..966b22829f3b 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -591,8 +591,6 @@ struct address_space_operations {
int (*releasepage) (struct page *, int);
void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset);
- struct page* (*get_xip_page)(struct address_space *, sector_t,
- int);
/* migrate the contents of a page to the specified target */
int (*migratepage) (struct page *, struct page *);
int (*launder_page) (struct page *);
@@ -748,11 +746,6 @@ struct address_space_operations {
and transfer data directly between the storage and the
application's address space.
- get_xip_page: called by the VM to translate a block number to a page.
- The page is valid until the corresponding filesystem is unmounted.
- Filesystems that want to use execute-in-place (XIP) need to implement
- it. An example implementation can be found in fs/ext2/xip.c.
-
migrate_page: This is used to compact the physical memory usage.
If the VM wants to relocate a page (maybe off a memory card
that is signalling imminent failure) it will pass a new page
diff --git a/Documentation/filesystems/xip.txt b/Documentation/filesystems/xip.txt
deleted file mode 100644
index b77472949ede..000000000000
--- a/Documentation/filesystems/xip.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-Execute-in-place for file mappings
-----------------------------------
-
-Motivation
-----------
-File mappings are performed by mapping page cache pages to userspace. In
-addition, read&write type file operations also transfer data from/to the page
-cache.
-
-For memory backed storage devices that use the block device interface, the page
-cache pages are in fact copies of the original storage. Various approaches
-exist to work around the need for an extra copy. The ramdisk driver for example
-does read the data into the page cache, keeps a reference, and discards the
-original data behind later on.
-
-Execute-in-place solves this issue the other way around: instead of keeping
-data in the page cache, the need to have a page cache copy is eliminated
-completely. With execute-in-place, read&write type operations are performed
-directly from/to the memory backed storage device. For file mappings, the
-storage device itself is mapped directly into userspace.
-
-This implementation was initially written for shared memory segments between
-different virtual machines on s390 hardware to allow multiple machines to
-share the same binaries and libraries.
-
-Implementation
---------------
-Execute-in-place is implemented in three steps: block device operation,
-address space operation, and file operations.
-
-A block device operation named direct_access is used to translate the
-block device sector number to a page frame number (pfn) that identifies
-the physical page for the memory. It also returns a kernel virtual
-address that can be used to access the memory.
-
-The direct_access method takes a 'size' parameter that indicates the
-number of bytes being requested. The function should return the number
-of bytes that can be contiguously accessed at that offset. It may also
-return a negative errno if an error occurs.
-
-The block device operation is optional, these block devices support it as of
-today:
-- dcssblk: s390 dcss block device driver
-
-An address space operation named get_xip_mem is used to retrieve references
-to a page frame number and a kernel address. To obtain these values a reference
-to an address_space is provided. This function assigns values to the kmem and
-pfn parameters. The third argument indicates whether the function should allocate
-blocks if needed.
-
-This address space operation is mutually exclusive with readpage&writepage that
-do page cache read/write operations.
-The following filesystems support it as of today:
-- ext2: the second extended filesystem, see Documentation/filesystems/ext2.txt
-
-A set of file operations that do utilize get_xip_page can be found in
-mm/filemap_xip.c . The following file operation implementations are provided:
-- aio_read/aio_write
-- readv/writev
-- sendfile
-
-The generic file operations do_sync_read/do_sync_write can be used to implement
-classic synchronous IO calls.
-
-Shortcomings
-------------
-This implementation is limited to storage devices that are cpu addressable at
-all times (no highmem or such). It works well on rom/ram, but enhancements are
-needed to make it work with flash in read+write mode.
-Putting the Linux kernel and/or its modules on a xip filesystem does not mean
-they are not copied.
diff --git a/Documentation/gdb-kernel-debugging.txt b/Documentation/gdb-kernel-debugging.txt
new file mode 100644
index 000000000000..7050ce8794b9
--- /dev/null
+++ b/Documentation/gdb-kernel-debugging.txt
@@ -0,0 +1,160 @@
+Debugging kernel and modules via gdb
+====================================
+
+The kernel debugger kgdb, hypervisors like QEMU or JTAG-based hardware
+interfaces allow to debug the Linux kernel and its modules during runtime
+using gdb. Gdb comes with a powerful scripting interface for python. The
+kernel provides a collection of helper scripts that can simplify typical
+kernel debugging steps. This is a short tutorial about how to enable and use
+them. It focuses on QEMU/KVM virtual machines as target, but the examples can
+be transferred to the other gdb stubs as well.
+
+
+Requirements
+------------
+
+ o gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true
+ for distributions)
+
+
+Setup
+-----
+
+ o Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and
+ www.qemu.org for more details). For cross-development,
+ http://landley.net/aboriginal/bin keeps a pool of machine images and
+ toolchains that can be helpful to start from.
+
+ o Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave
+ CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports
+ CONFIG_FRAME_POINTER, keep it enabled.
+
+ o Install that kernel on the guest.
+
+ Alternatively, QEMU allows to boot the kernel directly using -kernel,
+ -append, -initrd command line switches. This is generally only useful if
+ you do not depend on modules. See QEMU documentation for more details on
+ this mode.
+
+ o Enable the gdb stub of QEMU/KVM, either
+ - at VM startup time by appending "-s" to the QEMU command line
+ or
+ - during runtime by issuing "gdbserver" from the QEMU monitor
+ console
+
+ o cd /path/to/linux-build
+
+ o Start gdb: gdb vmlinux
+
+ Note: Some distros may restrict auto-loading of gdb scripts to known safe
+ directories. In case gdb reports to refuse loading vmlinux-gdb.py, add
+
+ add-auto-load-safe-path /path/to/linux-build
+
+ to ~/.gdbinit. See gdb help for more details.
+
+ o Attach to the booted guest:
+ (gdb) target remote :1234
+
+
+Examples of using the Linux-provided gdb helpers
+------------------------------------------------
+
+ o Load module (and main kernel) symbols:
+ (gdb) lx-symbols
+ loading vmlinux
+ scanning for modules in /home/user/linux/build
+ loading @0xffffffffa0020000: /home/user/linux/build/net/netfilter/xt_tcpudp.ko
+ loading @0xffffffffa0016000: /home/user/linux/build/net/netfilter/xt_pkttype.ko
+ loading @0xffffffffa0002000: /home/user/linux/build/net/netfilter/xt_limit.ko
+ loading @0xffffffffa00ca000: /home/user/linux/build/net/packet/af_packet.ko
+ loading @0xffffffffa003c000: /home/user/linux/build/fs/fuse/fuse.ko
+ ...
+ loading @0xffffffffa0000000: /home/user/linux/build/drivers/ata/ata_generic.ko
+
+ o Set a breakpoint on some not yet loaded module function, e.g.:
+ (gdb) b btrfs_init_sysfs
+ Function "btrfs_init_sysfs" not defined.
+ Make breakpoint pending on future shared library load? (y or [n]) y
+ Breakpoint 1 (btrfs_init_sysfs) pending.
+
+ o Continue the target
+ (gdb) c
+
+ o Load the module on the target and watch the symbols being loaded as well as
+ the breakpoint hit:
+ loading @0xffffffffa0034000: /home/user/linux/build/lib/libcrc32c.ko
+ loading @0xffffffffa0050000: /home/user/linux/build/lib/lzo/lzo_compress.ko
+ loading @0xffffffffa006e000: /home/user/linux/build/lib/zlib_deflate/zlib_deflate.ko
+ loading @0xffffffffa01b1000: /home/user/linux/build/fs/btrfs/btrfs.ko
+
+ Breakpoint 1, btrfs_init_sysfs () at /home/user/linux/fs/btrfs/sysfs.c:36
+ 36 btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
+
+ o Dump the log buffer of the target kernel:
+ (gdb) lx-dmesg
+ [ 0.000000] Initializing cgroup subsys cpuset
+ [ 0.000000] Initializing cgroup subsys cpu
+ [ 0.000000] Linux version 3.8.0-rc4-dbg+ (...
+ [ 0.000000] Command line: root=/dev/sda2 resume=/dev/sda1 vga=0x314
+ [ 0.000000] e820: BIOS-provided physical RAM map:
+ [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
+ [ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
+ ....
+
+ o Examine fields of the current task struct:
+ (gdb) p $lx_current().pid
+ $1 = 4998
+ (gdb) p $lx_current().comm
+ $2 = "modprobe\000\000\000\000\000\000\000"
+
+ o Make use of the per-cpu function for the current or a specified CPU:
+ (gdb) p $lx_per_cpu("runqueues").nr_running
+ $3 = 1
+ (gdb) p $lx_per_cpu("runqueues", 2).nr_running
+ $4 = 0
+
+ o Dig into hrtimers using the container_of helper:
+ (gdb) set $next = $lx_per_cpu("hrtimer_bases").clock_base[0].active.next
+ (gdb) p *$container_of($next, "struct hrtimer", "node")
+ $5 = {
+ node = {
+ node = {
+ __rb_parent_color = 18446612133355256072,
+ rb_right = 0x0 <irq_stack_union>,
+ rb_left = 0x0 <irq_stack_union>
+ },
+ expires = {
+ tv64 = 1835268000000
+ }
+ },
+ _softexpires = {
+ tv64 = 1835268000000
+ },
+ function = 0xffffffff81078232 <tick_sched_timer>,
+ base = 0xffff88003fd0d6f0,
+ state = 1,
+ start_pid = 0,
+ start_site = 0xffffffff81055c1f <hrtimer_start_range_ns+20>,
+ start_comm = "swapper/2\000\000\000\000\000\000"
+ }
+
+
+List of commands and functions
+------------------------------
+
+The number of commands and convenience functions may evolve over the time,
+this is just a snapshot of the initial version:
+
+ (gdb) apropos lx
+ function lx_current -- Return current task
+ function lx_module -- Find module by name and return the module variable
+ function lx_per_cpu -- Return per-cpu variable
+ function lx_task_by_pid -- Find Linux task by PID and return the task_struct variable
+ function lx_thread_info -- Calculate Linux thread_info from task variable
+ lx-dmesg -- Print Linux kernel log buffer
+ lx-lsmod -- List currently loaded modules
+ lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules
+
+Detailed help can be obtained via "help <command-name>" for commands and "help
+function <function-name>" for convenience functions.
diff --git a/Documentation/ia64/paravirt_ops.txt b/Documentation/ia64/paravirt_ops.txt
deleted file mode 100644
index 39ded02ec33f..000000000000
--- a/Documentation/ia64/paravirt_ops.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-Paravirt_ops on IA64
-====================
- 21 May 2008, Isaku Yamahata <yamahata@valinux.co.jp>
-
-
-Introduction
-------------
-The aim of this documentation is to help with maintainability and/or to
-encourage people to use paravirt_ops/IA64.
-
-paravirt_ops (pv_ops in short) is a way for virtualization support of
-Linux kernel on x86. Several ways for virtualization support were
-proposed, paravirt_ops is the winner.
-On the other hand, now there are also several IA64 virtualization
-technologies like kvm/IA64, xen/IA64 and many other academic IA64
-hypervisors so that it is good to add generic virtualization
-infrastructure on Linux/IA64.
-
-
-What is paravirt_ops?
----------------------
-It has been developed on x86 as virtualization support via API, not ABI.
-It allows each hypervisor to override operations which are important for
-hypervisors at API level. And it allows a single kernel binary to run on
-all supported execution environments including native machine.
-Essentially paravirt_ops is a set of function pointers which represent
-operations corresponding to low level sensitive instructions and high
-level functionalities in various area. But one significant difference
-from usual function pointer table is that it allows optimization with
-binary patch. It is because some of these operations are very
-performance sensitive and indirect call overhead is not negligible.
-With binary patch, indirect C function call can be transformed into
-direct C function call or in-place execution to eliminate the overhead.
-
-Thus, operations of paravirt_ops are classified into three categories.
-- simple indirect call
- These operations correspond to high level functionality so that the
- overhead of indirect call isn't very important.
-
-- indirect call which allows optimization with binary patch
- Usually these operations correspond to low level instructions. They
- are called frequently and performance critical. So the overhead is
- very important.
-
-- a set of macros for hand written assembly code
- Hand written assembly codes (.S files) also need paravirtualization
- because they include sensitive instructions or some of code paths in
- them are very performance critical.
-
-
-The relation to the IA64 machine vector
----------------------------------------
-Linux/IA64 has the IA64 machine vector functionality which allows the
-kernel to switch implementations (e.g. initialization, ipi, dma api...)
-depending on executing platform.
-We can replace some implementations very easily defining a new machine
-vector. Thus another approach for virtualization support would be
-enhancing the machine vector functionality.
-But paravirt_ops approach was taken because
-- virtualization support needs wider support than machine vector does.
- e.g. low level instruction paravirtualization. It must be
- initialized very early before platform detection.
-
-- virtualization support needs more functionality like binary patch.
- Probably the calling overhead might not be very large compared to the
- emulation overhead of virtualization. However in the native case, the
- overhead should be eliminated completely.
- A single kernel binary should run on each environment including native,
- and the overhead of paravirt_ops on native environment should be as
- small as possible.
-
-- for full virtualization technology, e.g. KVM/IA64 or
- Xen/IA64 HVM domain, the result would be
- (the emulated platform machine vector. probably dig) + (pv_ops).
- This means that the virtualization support layer should be under
- the machine vector layer.
-
-Possibly it might be better to move some function pointers from
-paravirt_ops to machine vector. In fact, Xen domU case utilizes both
-pv_ops and machine vector.
-
-
-IA64 paravirt_ops
------------------
-In this section, the concrete paravirt_ops will be discussed.
-Because of the architecture difference between ia64 and x86, the
-resulting set of functions is very different from x86 pv_ops.
-
-- C function pointer tables
-They are not very performance critical so that simple C indirect
-function call is acceptable. The following structures are defined at
-this moment. For details see linux/include/asm-ia64/paravirt.h
- - struct pv_info
- This structure describes the execution environment.
- - struct pv_init_ops
- This structure describes the various initialization hooks.
- - struct pv_iosapic_ops
- This structure describes hooks to iosapic operations.
- - struct pv_irq_ops
- This structure describes hooks to irq related operations
- - struct pv_time_op
- This structure describes hooks to steal time accounting.
-
-- a set of indirect calls which need optimization
-Currently this class of functions correspond to a subset of IA64
-intrinsics. At this moment the optimization with binary patch isn't
-implemented yet.
-struct pv_cpu_op is defined. For details see
-linux/include/asm-ia64/paravirt_privop.h
-Mostly they correspond to ia64 intrinsics 1-to-1.
-Caveat: Now they are defined as C indirect function pointers, but in
-order to support binary patch optimization, they will be changed
-using GCC extended inline assembly code.
-
-- a set of macros for hand written assembly code (.S files)
-For maintenance purpose, the taken approach for .S files is single
-source code and compile multiple times with different macros definitions.
-Each pv_ops instance must define those macros to compile.
-The important thing here is that sensitive, but non-privileged
-instructions must be paravirtualized and that some privileged
-instructions also need paravirtualization for reasonable performance.
-Developers who modify .S files must be aware of that. At this moment
-an easy checker is implemented to detect paravirtualization breakage.
-But it doesn't cover all the cases.
-
-Sometimes this set of macros is called pv_cpu_asm_op. But there is no
-corresponding structure in the source code.
-Those macros mostly 1:1 correspond to a subset of privileged
-instructions. See linux/include/asm-ia64/native/inst.h.
-And some functions written in assembly also need to be overrided so
-that each pv_ops instance have to define some macros. Again see
-linux/include/asm-ia64/native/inst.h.
-
-
-Those structures must be initialized very early before start_kernel.
-Probably initialized in head.S using multi entry point or some other trick.
-For native case implementation see linux/arch/ia64/kernel/paravirt.c.
diff --git a/Documentation/virtual/00-INDEX b/Documentation/virtual/00-INDEX
index e952d30bbf0f..af0d23968ee7 100644
--- a/Documentation/virtual/00-INDEX
+++ b/Documentation/virtual/00-INDEX
@@ -2,6 +2,9 @@ Virtualization support in the Linux kernel.
00-INDEX
- this file.
+
+paravirt_ops.txt
+ - Describes the Linux kernel pv_ops to support different hypervisors
kvm/
- Kernel Virtual Machine. See also http://linux-kvm.org
uml/
diff --git a/Documentation/virtual/paravirt_ops.txt b/Documentation/virtual/paravirt_ops.txt
new file mode 100644
index 000000000000..d4881c00e339
--- /dev/null
+++ b/Documentation/virtual/paravirt_ops.txt
@@ -0,0 +1,32 @@
+Paravirt_ops
+============
+
+Linux provides support for different hypervisor virtualization technologies.
+Historically different binary kernels would be required in order to support
+different hypervisors, this restriction was removed with pv_ops.
+Linux pv_ops is a virtualization API which enables support for different
+hypervisors. It allows each hypervisor to override critical operations and
+allows a single kernel binary to run on all supported execution environments
+including native machine -- without any hypervisors.
+
+pv_ops provides a set of function pointers which represent operations
+corresponding to low level critical instructions and high level
+functionalities in various areas. pv-ops allows for optimizations at run
+time by enabling binary patching of the low-ops critical operations
+at boot time.
+
+pv_ops operations are classified into three categories:
+
+- simple indirect call
+ These operations correspond to high level functionality where it is
+ known that the overhead of indirect call isn't very important.
+
+- indirect call which allows optimization with binary patch
+ Usually these operations correspond to low level critical instructions. They
+ are called frequently and are performance critical. The overhead is
+ very important.
+
+- a set of macros for hand written assembly code
+ Hand written assembly codes (.S files) also need paravirtualization
+ because they include sensitive instructions or some of code paths in
+ them are very performance critical.
diff --git a/MAINTAINERS b/MAINTAINERS
index 348f5c16ef50..1921ed58d1a0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -34,7 +34,7 @@ trivial patch so apply some common sense.
generalized kernel feature ready for next time.
PLEASE check your patch with the automated style checker
- (scripts/checkpatch.pl) to catch trival style violations.
+ (scripts/checkpatch.pl) to catch trivial style violations.
See Documentation/CodingStyle for guidance here.
PLEASE CC: the maintainers and mailing lists that are generated
@@ -630,6 +630,8 @@ L: dri-devel@lists.freedesktop.org
T: git git://people.freedesktop.org/~gabbayo/linux.git
S: Supported
F: drivers/gpu/drm/amd/amdkfd/
+F: drivers/gpu/drm/amd/include/cik_structs.h
+F: drivers/gpu/drm/amd/include/kgd_kfd_interface.h
F: drivers/gpu/drm/radeon/radeon_kfd.c
F: drivers/gpu/drm/radeon/radeon_kfd.h
F: include/uapi/linux/kfd_ioctl.h
@@ -893,6 +895,7 @@ F: arch/arm/boot/dts/at91*.dts
F: arch/arm/boot/dts/at91*.dtsi
F: arch/arm/boot/dts/sama*.dts
F: arch/arm/boot/dts/sama*.dtsi
+F: arch/arm/include/debug/at91.S
ARM/ATMEL AT91 Clock Support
M: Boris Brezillon <boris.brezillon@free-electrons.com>
@@ -974,7 +977,7 @@ S: Maintained
F: arch/arm/mach-prima2/
F: drivers/clk/sirf/
F: drivers/clocksource/timer-prima2.c
-F: drivers/clocksource/timer-marco.c
+F: drivers/clocksource/timer-atlas7.c
N: [^a-z]sirf
ARM/EBSA110 MACHINE SUPPORT
@@ -1307,10 +1310,13 @@ S: Maintained
ARM/QUALCOMM SUPPORT
M: Kumar Gala <galak@codeaurora.org>
+M: Andy Gross <agross@codeaurora.org>
M: David Brown <davidb@codeaurora.org>
L: linux-arm-msm@vger.kernel.org
+L: linux-soc@vger.kernel.org
S: Maintained
F: arch/arm/mach-qcom/
+F: drivers/soc/qcom/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
ARM/RADISYS ENP2611 MACHINE SUPPORT
@@ -1412,7 +1418,6 @@ F: arch/arm/configs/ape6evm_defconfig
F: arch/arm/configs/armadillo800eva_defconfig
F: arch/arm/configs/bockw_defconfig
F: arch/arm/configs/kzm9g_defconfig
-F: arch/arm/configs/lager_defconfig
F: arch/arm/configs/mackerel_defconfig
F: arch/arm/configs/marzen_defconfig
F: arch/arm/configs/shmobile_defconfig
@@ -2142,7 +2147,7 @@ F: arch/arm/boot/dts/bcm470*
BROADCOM BCM63XX ARM ARCHITECTURE
M: Florian Fainelli <f.fainelli@gmail.com>
L: linux-arm-kernel@lists.infradead.org
-T: git git://git.github.com/brcm/linux.git
+T: git git://github.com/broadcom/arm-bcm63xx.git
S: Maintained
F: arch/arm/mach-bcm/bcm63xx.c
F: arch/arm/include/debug/bcm63xx.S
@@ -2159,6 +2164,7 @@ M: Brian Norris <computersforpeace@gmail.com>
M: Gregory Fong <gregory.0xf0@gmail.com>
M: Florian Fainelli <f.fainelli@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+T: git git://github.com/broadcom/stblinux.git
S: Maintained
F: arch/arm/mach-bcm/*brcmstb*
F: arch/arm/boot/dts/bcm7*.dts*
@@ -2168,6 +2174,7 @@ BROADCOM BMIPS MIPS ARCHITECTURE
M: Kevin Cernekee <cernekee@gmail.com>
M: Florian Fainelli <f.fainelli@gmail.com>
L: linux-mips@linux-mips.org
+T: git git://github.com/broadcom/stblinux.git
S: Maintained
F: arch/mips/bmips/*
F: arch/mips/include/asm/mach-bmips/*
@@ -2210,7 +2217,7 @@ M: Ray Jui <rjui@broadcom.com>
M: Scott Branden <sbranden@broadcom.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: bcm-kernel-feedback-list@broadcom.com
-T: git git://git.github.com/brcm/linux.git
+T: git git://github.com/broadcom/cygnus-linux.git
S: Maintained
N: iproc
N: cygnus
@@ -2963,6 +2970,12 @@ S: Supported
F: drivers/input/touchscreen/cyttsp*
F: include/linux/input/cyttsp.h
+DALLAS/MAXIM DS1685-FAMILY REAL TIME CLOCK
+M: Joshua Kinard <kumba@gentoo.org>
+S: Maintained
+F: drivers/rtc/rtc-ds1685.c
+F: include/linux/rtc/ds1685.h
+
DAMA SLAVE for AX.25
M: Joerg Reuter <jreuter@yaina.de>
W: http://yaina.de/jreuter/
@@ -3151,6 +3164,12 @@ L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/busses/i2c-diolan-u2c.c
+DIRECT ACCESS (DAX)
+M: Matthew Wilcox <willy@linux.intel.com>
+L: linux-fsdevel@vger.kernel.org
+S: Supported
+F: fs/dax.c
+
DIRECTORY NOTIFICATION (DNOTIFY)
M: Eric Paris <eparis@parisplace.org>
S: Maintained
@@ -4073,6 +4092,12 @@ S: Maintained
F: include/linux/platform_data/video-imxfb.h
F: drivers/video/fbdev/imxfb.c
+FREESCALE QUAD SPI DRIVER
+M: Han Xu <han.xu@freescale.com>
+L: linux-mtd@lists.infradead.org
+S: Maintained
+F: drivers/mtd/spi-nor/fsl-quadspi.c
+
FREESCALE SOC FS_ENET DRIVER
M: Pantelis Antoniou <pantelis.antoniou@gmail.com>
M: Vitaly Bordug <vbordug@ru.mvista.com>
@@ -4213,6 +4238,11 @@ W: http://www.icp-vortex.com/
S: Supported
F: drivers/scsi/gdt*
+GDB KERNEL DEBUGGING HELPER SCRIPTS
+M: Jan Kiszka <jan.kiszka@siemens.com>
+S: Supported
+F: scripts/gdb/
+
GEMTEK FM RADIO RECEIVER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -6210,6 +6240,26 @@ S: Supported
F: drivers/power/max14577_charger.c
F: drivers/power/max77693_charger.c
+MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
+M: Chanwoo Choi <cw00.choi@samsung.com>
+M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+L: linux-kernel@vger.kernel.org
+S: Supported
+F: drivers/*/max14577.c
+F: drivers/*/max77686.c
+F: drivers/*/max77693.c
+F: drivers/extcon/extcon-max14577.c
+F: drivers/extcon/extcon-max77693.c
+F: drivers/rtc/rtc-max77686.c
+F: drivers/clk/clk-max77686.c
+F: Documentation/devicetree/bindings/mfd/max14577.txt
+F: Documentation/devicetree/bindings/mfd/max77686.txt
+F: Documentation/devicetree/bindings/mfd/max77693.txt
+F: Documentation/devicetree/bindings/clock/maxim,max77686.txt
+F: include/linux/mfd/max14577*.h
+F: include/linux/mfd/max77686*.h
+F: include/linux/mfd/max77693*.h
+
MAXIRADIO FM RADIO RECEIVER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -6837,7 +6887,7 @@ F: drivers/scsi/nsp32*
NIOS2 ARCHITECTURE
M: Ley Foon Tan <lftan@altera.com>
L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
-T: git git://git.rocketboards.org/linux-socfpga.git
+T: git git://git.rocketboards.org/linux-socfpga-next.git
S: Maintained
F: arch/nios2/
@@ -7010,6 +7060,12 @@ L: linux-omap@vger.kernel.org
S: Maintained
F: arch/arm/mach-omap2/omap_hwmod.*
+OMAP HWMOD DATA
+M: Paul Walmsley <paul@pwsan.com>
+L: linux-omap@vger.kernel.org
+S: Maintained
+F: arch/arm/mach-omap2/omap_hwmod*data*
+
OMAP HWMOD DATA FOR OMAP4-BASED DEVICES
M: Benoît Cousson <bcousson@baylibre.com>
L: linux-omap@vger.kernel.org
@@ -7246,7 +7302,7 @@ M: Alok Kataria <akataria@vmware.com>
M: Rusty Russell <rusty@rustcorp.com.au>
L: virtualization@lists.linux-foundation.org
S: Supported
-F: Documentation/ia64/paravirt_ops.txt
+F: Documentation/virtual/paravirt_ops.txt
F: arch/*/kernel/paravirt*
F: arch/*/include/asm/paravirt.h
@@ -8447,6 +8503,7 @@ SYNOPSYS DESIGNWARE DMAC DRIVER
M: Viresh Kumar <viresh.linux@gmail.com>
M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
S: Maintained
+F: include/linux/dma/dw.h
F: include/linux/platform_data/dma-dw.h
F: drivers/dma/dw/
diff --git a/Makefile b/Makefile
index 33cb15efd257..dd8796caa239 100644
--- a/Makefile
+++ b/Makefile
@@ -927,6 +927,9 @@ endif
ifdef CONFIG_BUILD_DOCSRC
$(Q)$(MAKE) $(build)=Documentation
endif
+ifdef CONFIG_GDB_SCRIPTS
+ $(Q)ln -fsn `cd $(srctree) && /bin/pwd`/scripts/gdb/vmlinux-gdb.py
+endif
+$(call if_changed,link-vmlinux)
# The actual objects are generated when descending,
@@ -1181,7 +1184,7 @@ MRPROPER_FILES += .config .config.old .version .old_version $(version_h) \
Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
signing_key.priv signing_key.x509 x509.genkey \
extra_certificates signing_key.x509.keyid \
- signing_key.x509.signer
+ signing_key.x509.signer vmlinux-gdb.py
# clean - Delete most, but leave enough to build external modules
#
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h
index 766fdfde2b7a..9b0d40093c9a 100644
--- a/arch/alpha/include/asm/uaccess.h
+++ b/arch/alpha/include/asm/uaccess.h
@@ -27,7 +27,7 @@
#define get_ds() (KERNEL_DS)
#define set_fs(x) (current_thread_info()->addr_limit = (x))
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
/*
* Is a address valid? This does a straightforward calculation rather
@@ -39,13 +39,13 @@
* - AND "addr+size" doesn't have any high-bits set
* - OR we are in kernel mode.
*/
-#define __access_ok(addr,size,segment) \
+#define __access_ok(addr, size, segment) \
(((segment).seg & (addr | size | (addr+size))) == 0)
-#define access_ok(type,addr,size) \
+#define access_ok(type, addr, size) \
({ \
__chk_user_ptr(addr); \
- __access_ok(((unsigned long)(addr)),(size),get_fs()); \
+ __access_ok(((unsigned long)(addr)), (size), get_fs()); \
})
/*
@@ -60,20 +60,20 @@
* (a) re-use the arguments for side effects (sizeof/typeof is ok)
* (b) require any knowledge of processes at this stage
*/
-#define put_user(x,ptr) \
- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)),get_fs())
-#define get_user(x,ptr) \
- __get_user_check((x),(ptr),sizeof(*(ptr)),get_fs())
+#define put_user(x, ptr) \
+ __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), get_fs())
+#define get_user(x, ptr) \
+ __get_user_check((x), (ptr), sizeof(*(ptr)), get_fs())
/*
* The "__xxx" versions do not do address space checking, useful when
* doing multiple accesses to the same area (the programmer has to do the
* checks by hand with "access_ok()")
*/
-#define __put_user(x,ptr) \
- __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-#define __get_user(x,ptr) \
- __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+ __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+#define __get_user(x, ptr) \
+ __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
/*
* The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to
@@ -84,7 +84,7 @@
extern void __get_user_unknown(void);
-#define __get_user_nocheck(x,ptr,size) \
+#define __get_user_nocheck(x, ptr, size) \
({ \
long __gu_err = 0; \
unsigned long __gu_val; \
@@ -96,16 +96,16 @@ extern void __get_user_unknown(void);
case 8: __get_user_64(ptr); break; \
default: __get_user_unknown(); break; \
} \
- (x) = (__typeof__(*(ptr))) __gu_val; \
+ (x) = (__force __typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
-#define __get_user_check(x,ptr,size,segment) \
+#define __get_user_check(x, ptr, size, segment) \
({ \
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
- if (__access_ok((unsigned long)__gu_addr,size,segment)) { \
+ if (__access_ok((unsigned long)__gu_addr, size, segment)) { \
__gu_err = 0; \
switch (size) { \
case 1: __get_user_8(__gu_addr); break; \
@@ -115,7 +115,7 @@ extern void __get_user_unknown(void);
default: __get_user_unknown(); break; \
} \
} \
- (x) = (__typeof__(*(ptr))) __gu_val; \
+ (x) = (__force __typeof__(*(ptr))) __gu_val; \
__gu_err; \
})
@@ -201,31 +201,31 @@ struct __large_struct { unsigned long buf[100]; };
extern void __put_user_unknown(void);
-#define __put_user_nocheck(x,ptr,size) \
+#define __put_user_nocheck(x, ptr, size) \
({ \
long __pu_err = 0; \
__chk_user_ptr(ptr); \
switch (size) { \
- case 1: __put_user_8(x,ptr); break; \
- case 2: __put_user_16(x,ptr); break; \
- case 4: __put_user_32(x,ptr); break; \
- case 8: __put_user_64(x,ptr); break; \
+ case 1: __put_user_8(x, ptr); break; \
+ case 2: __put_user_16(x, ptr); break; \
+ case 4: __put_user_32(x, ptr); break; \
+ case 8: __put_user_64(x, ptr); break; \
default: __put_user_unknown(); break; \
} \
__pu_err; \
})
-#define __put_user_check(x,ptr,size,segment) \
+#define __put_user_check(x, ptr, size, segment) \
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
- if (__access_ok((unsigned long)__pu_addr,size,segment)) { \
+ if (__access_ok((unsigned long)__pu_addr, size, segment)) { \
__pu_err = 0; \
switch (size) { \
- case 1: __put_user_8(x,__pu_addr); break; \
- case 2: __put_user_16(x,__pu_addr); break; \
- case 4: __put_user_32(x,__pu_addr); break; \
- case 8: __put_user_64(x,__pu_addr); break; \
+ case 1: __put_user_8(x, __pu_addr); break; \
+ case 2: __put_user_16(x, __pu_addr); break; \
+ case 4: __put_user_32(x, __pu_addr); break; \
+ case 8: __put_user_64(x, __pu_addr); break; \
default: __put_user_unknown(); break; \
} \
} \
@@ -237,7 +237,7 @@ extern void __put_user_unknown(void);
* instead of writing: this is because they do not write to
* any memory gcc knows about, so there are no aliasing issues
*/
-#define __put_user_64(x,addr) \
+#define __put_user_64(x, addr) \
__asm__ __volatile__("1: stq %r2,%1\n" \
"2:\n" \
".section __ex_table,\"a\"\n" \
@@ -247,7 +247,7 @@ __asm__ __volatile__("1: stq %r2,%1\n" \
: "=r"(__pu_err) \
: "m" (__m(addr)), "rJ" (x), "0"(__pu_err))
-#define __put_user_32(x,addr) \
+#define __put_user_32(x, addr) \
__asm__ __volatile__("1: stl %r2,%1\n" \
"2:\n" \
".section __ex_table,\"a\"\n" \
@@ -260,7 +260,7 @@ __asm__ __volatile__("1: stl %r2,%1\n" \
#ifdef __alpha_bwx__
/* Those lucky bastards with ev56 and later CPUs can do byte/word moves. */
-#define __put_user_16(x,addr) \
+#define __put_user_16(x, addr) \
__asm__ __volatile__("1: stw %r2,%1\n" \
"2:\n" \
".section __ex_table,\"a\"\n" \
@@ -270,7 +270,7 @@ __asm__ __volatile__("1: stw %r2,%1\n" \
: "=r"(__pu_err) \
: "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
-#define __put_user_8(x,addr) \
+#define __put_user_8(x, addr) \
__asm__ __volatile__("1: stb %r2,%1\n" \
"2:\n" \
".section __ex_table,\"a\"\n" \
@@ -283,7 +283,7 @@ __asm__ __volatile__("1: stb %r2,%1\n" \
/* Unfortunately, we can't get an unaligned access trap for the sub-word
write, so we have to do a general unaligned operation. */
-#define __put_user_16(x,addr) \
+#define __put_user_16(x, addr) \
{ \
long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4; \
__asm__ __volatile__( \
@@ -308,13 +308,13 @@ __asm__ __volatile__("1: stb %r2,%1\n" \
" .long 4b - .\n" \
" lda $31, 5b-4b(%0)\n" \
".previous" \
- : "=r"(__pu_err), "=&r"(__pu_tmp1), \
- "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \
+ : "=r"(__pu_err), "=&r"(__pu_tmp1), \
+ "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \
"=&r"(__pu_tmp4) \
: "r"(addr), "r"((unsigned long)(x)), "0"(__pu_err)); \
}
-#define __put_user_8(x,addr) \
+#define __put_user_8(x, addr) \
{ \
long __pu_tmp1, __pu_tmp2; \
__asm__ __volatile__( \
@@ -330,7 +330,7 @@ __asm__ __volatile__("1: stb %r2,%1\n" \
" .long 2b - .\n" \
" lda $31, 3b-2b(%0)\n" \
".previous" \
- : "=r"(__pu_err), \
+ : "=r"(__pu_err), \
"=&r"(__pu_tmp1), "=&r"(__pu_tmp2) \
: "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \
}
@@ -366,7 +366,7 @@ __copy_tofrom_user_nocheck(void *to, const void *from, long len)
: "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to)
: __module_address(__copy_user)
"0" (__cu_len), "1" (__cu_from), "2" (__cu_to)
- : "$1","$2","$3","$4","$5","$28","memory");
+ : "$1", "$2", "$3", "$4", "$5", "$28", "memory");
return __cu_len;
}
@@ -379,15 +379,15 @@ __copy_tofrom_user(void *to, const void *from, long len, const void __user *vali
return len;
}
-#define __copy_to_user(to,from,n) \
+#define __copy_to_user(to, from, n) \
({ \
__chk_user_ptr(to); \
- __copy_tofrom_user_nocheck((__force void *)(to),(from),(n)); \
+ __copy_tofrom_user_nocheck((__force void *)(to), (from), (n)); \
})
-#define __copy_from_user(to,from,n) \
+#define __copy_from_user(to, from, n) \
({ \
__chk_user_ptr(from); \
- __copy_tofrom_user_nocheck((to),(__force void *)(from),(n)); \
+ __copy_tofrom_user_nocheck((to), (__force void *)(from), (n)); \
})
#define __copy_to_user_inatomic __copy_to_user
@@ -418,7 +418,7 @@ __clear_user(void __user *to, long len)
: "=r"(__cl_len), "=r"(__cl_to)
: __module_address(__do_clear_user)
"0"(__cl_len), "1"(__cl_to)
- : "$1","$2","$3","$4","$5","$28","memory");
+ : "$1", "$2", "$3", "$4", "$5", "$28", "memory");
return __cl_len;
}
diff --git a/arch/arc/boot/dts/abilis_tb10x.dtsi b/arch/arc/boot/dts/abilis_tb10x.dtsi
index a098d7c05e96..cfb5052239a1 100644
--- a/arch/arc/boot/dts/abilis_tb10x.dtsi
+++ b/arch/arc/boot/dts/abilis_tb10x.dtsi
@@ -112,7 +112,7 @@
chan_allocation_order = <0>;
chan_priority = <1>;
block_size = <0x7ff>;
- data_width = <2 0 0 0>;
+ data_width = <2>;
clocks = <&ahb_clk>;
clock-names = "hclk";
};
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index ffed3b2cf313..9615fe1701c6 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -257,7 +257,8 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
#define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0)
#define pte_page(x) (mem_map + \
- (unsigned long)(((pte_val(x) - PAGE_OFFSET) >> PAGE_SHIFT)))
+ (unsigned long)(((pte_val(x) - CONFIG_LINUX_LINK_BASE) >> \
+ PAGE_SHIFT)))
#define mk_pte(page, pgprot) \
({ \
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 210fe97464c3..4e547296831d 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -56,9 +56,6 @@ unsigned long thread_saved_pc(struct task_struct *t);
/* Free all resources held by a thread */
#define release_thread(thread) do { } while (0)
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
-
/*
* A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
* get optimised away by gcc
diff --git a/arch/arc/include/asm/serial.h b/arch/arc/include/asm/serial.h
index 602b0970a764..744a6ae15754 100644
--- a/arch/arc/include/asm/serial.h
+++ b/arch/arc/include/asm/serial.h
@@ -10,26 +10,13 @@
#define _ASM_ARC_SERIAL_H
/*
- * early-8250 requires BASE_BAUD to be defined and includes this header.
- * We put in a typical value:
- * (core clk / 16) - i.e. UART samples 16 times per sec.
- * Athough in multi-platform-image this might not work, specially if the
- * clk driving the UART is different.
- * We can't use DeviceTree as this is typically for early serial.
+ * early 8250 (now earlycon) requires BASE_BAUD to be defined in this header.
+ * However to still determine it dynamically (for multi-platform images)
+ * we do this in a helper by parsing the FDT early
*/
-#include <asm/clk.h>
+extern unsigned int __init arc_early_base_baud(void);
-#define BASE_BAUD (arc_get_core_freq() / 16)
-
-/*
- * This is definitely going to break early 8250 consoles on multi-platform
- * images but hey, it won't add any code complexity for a debug feature of
- * one broken driver.
- */
-#ifdef CONFIG_ARC_PLAT_TB10X
-#undef BASE_BAUD
-#define BASE_BAUD (arc_get_core_freq() / 16 / 3)
-#endif
+#define BASE_BAUD arc_early_base_baud()
#endif /* _ASM_ARC_SERIAL_H */
diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c
index fffdb5e41b20..e32b54abff51 100644
--- a/arch/arc/kernel/devtree.c
+++ b/arch/arc/kernel/devtree.c
@@ -17,6 +17,28 @@
#include <asm/clk.h>
#include <asm/mach_desc.h>
+#ifdef CONFIG_SERIAL_EARLYCON
+
+static unsigned int __initdata arc_base_baud;
+
+unsigned int __init arc_early_base_baud(void)
+{
+ return arc_base_baud/16;
+}
+
+static void __init arc_set_early_base_baud(unsigned long dt_root)
+{
+ unsigned int core_clk = arc_get_core_freq();
+
+ if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x"))
+ arc_base_baud = core_clk/3;
+ else
+ arc_base_baud = core_clk;
+}
+#else
+#define arc_set_early_base_baud(dt_root)
+#endif
+
static const void * __init arch_get_next_mach(const char *const **match)
{
static const struct machine_desc *mdesc = __arch_info_begin;
@@ -56,5 +78,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt)
if (clk)
arc_set_core_freq(of_read_ulong(clk, len/4));
+ arc_set_early_base_baud(dt_root);
+
return mdesc;
}
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 83a046a7cd06..d868289c5a26 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -736,16 +736,20 @@ ENTRY(ret_from_fork)
; put last task in scheduler queue
bl @schedule_tail
- ; If kernel thread, jump to its entry-point
ld r9, [sp, PT_status32]
brne r9, 0, 1f
- jl.d [r14]
- mov r0, r13 ; arg to payload
+ jl.d [r14] ; kernel thread entry point
+ mov r0, r13 ; (see PF_KTHREAD block in copy_thread)
1:
- ; special case of kernel_thread entry point returning back due to
- ; kernel_execve() - pretend return from syscall to ret to userland
+ ; Return to user space
+ ; 1. Any forked task (Reach here via BRne above)
+ ; 2. First ever init task (Reach here via return from JL above)
+ ; This is the historic "kernel_execve" use-case, to return to init
+ ; user mode, in a round about way since that is always done from
+ ; a kernel thread which is executed via JL above but always returns
+ ; out whenever kernel_execve (now inline do_fork()) is involved
b ret_from_exception
END(ret_from_fork)
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 252bf603db9c..900f68a70088 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -412,6 +412,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
char *str;
int cpu_id = ptr_to_cpu(v);
+ if (!cpu_online(cpu_id)) {
+ seq_printf(m, "processor [%d]\t: Offline\n", cpu_id);
+ goto done;
+ }
+
str = (char *)__get_free_page(GFP_TEMPORARY);
if (!str)
goto done;
@@ -429,7 +434,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
free_page((unsigned long)str);
done:
- seq_printf(m, "\n\n");
+ seq_printf(m, "\n");
return 0;
}
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 20ebb602ea2f..6a400b1b0b62 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -221,7 +221,7 @@ static void ipi_send_msg_one(int cpu, enum ipi_msg_type msg)
* and read back old value
*/
do {
- new = old = *ipi_data_ptr;
+ new = old = ACCESS_ONCE(*ipi_data_ptr);
new |= 1U << msg;
} while (cmpxchg(ipi_data_ptr, old, new) != old);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0850fc0f9658..9f1f09a2bc9b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -860,6 +860,8 @@ source "arch/arm/mach-cns3xxx/Kconfig"
source "arch/arm/mach-davinci/Kconfig"
+source "arch/arm/mach-digicolor/Kconfig"
+
source "arch/arm/mach-dove/Kconfig"
source "arch/arm/mach-ep93xx/Kconfig"
@@ -1493,7 +1495,7 @@ config ARM_PSCI
# selected platforms.
config ARCH_NR_GPIO
int
- default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
+ default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
default 416 if ARCH_SUNXI
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index a324ecdfeb21..970de7518341 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -115,16 +115,22 @@ choice
0x80024000 | 0xf0024000 | UART9
config AT91_DEBUG_LL_DBGU0
- bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
- depends on HAVE_AT91_DBGU0
+ bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10, 9rl, 9x5, 9n12"
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_AT91RM9200 || SOC_AT91SAM9
config AT91_DEBUG_LL_DBGU1
- bool "Kernel low-level debugging on 9263 and 9g45"
- depends on HAVE_AT91_DBGU1
+ bool "Kernel low-level debugging on 9263, 9g45 and sama5d3"
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_AT91SAM9 || SOC_SAMA5
config AT91_DEBUG_LL_DBGU2
bool "Kernel low-level debugging on sama5d4"
- depends on HAVE_AT91_DBGU2
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_SAMA5
config DEBUG_BCM2835
bool "Kernel low-level debugging on BCM2835 PL011 UART"
@@ -241,6 +247,13 @@ choice
Say Y here if you want the debug print routines to direct
their output to the serial port in the DC21285 (Footbridge).
+ config DEBUG_DIGICOLOR_UA0
+ bool "Kernel low-level debugging messages via Digicolor UA0"
+ depends on ARCH_DIGICOLOR
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the UA0 serial port in the CX92755.
+
config DEBUG_FOOTBRIDGE_COM1
bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
depends on FOOTBRIDGE
@@ -272,6 +285,14 @@ choice
Say Y here if you want the debug print routines to direct
their output to the UART on Highbank based devices.
+ config DEBUG_HIP01_UART
+ bool "Hisilicon Hip01 Debug UART"
+ depends on ARCH_HIP01
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on HIP01 UART.
+
config DEBUG_HIP04_UART
bool "Hisilicon HiP04 Debug UART"
depends on ARCH_HIP04
@@ -434,7 +455,7 @@ choice
Say Y here if you want the debug print routines to direct
their output to the serial port on MSM devices.
- ARCH DEBUG_UART_PHYS DEBUG_UART_BASE #
+ ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT #
MSM7X00A, QSD8X50 0xa9a00000 0xe1000000 UART1
MSM7X00A, QSD8X50 0xa9b00000 0xe1000000 UART2
MSM7X00A, QSD8X50 0xa9c00000 0xe1000000 UART3
@@ -453,7 +474,8 @@ choice
Say Y here if you want the debug print routines to direct
their output to the serial port on Qualcomm devices.
- ARCH DEBUG_UART_PHYS DEBUG_UART_BASE
+ ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT
+ APQ8064 0x16640000 0xf0040000
APQ8084 0xf995e000 0xfa75e000
MSM8X60 0x19c40000 0xf0040000
MSM8960 0x16440000 0xf0040000
@@ -462,13 +484,13 @@ choice
Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
options based on your needs.
- config DEBUG_MVEBU_UART
- bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)"
+ config DEBUG_MVEBU_UART0
+ bool "Kernel low-level debugging messages via MVEBU UART0 (old bootloaders)"
depends on ARCH_MVEBU
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
- on MVEBU based platforms.
+ on MVEBU based platforms on UART0.
This option should be used with the old bootloaders
that left the internal registers mapped at
@@ -481,13 +503,28 @@ choice
when u-boot hands over to the kernel, the system
silently crashes, with no serial output at all.
- config DEBUG_MVEBU_UART_ALTERNATE
- bool "Kernel low-level debugging messages via MVEBU UART (new bootloaders)"
+ config DEBUG_MVEBU_UART0_ALTERNATE
+ bool "Kernel low-level debugging messages via MVEBU UART0 (new bootloaders)"
+ depends on ARCH_MVEBU
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on MVEBU based platforms on UART0.
+
+ This option should be used with the new bootloaders
+ that remap the internal registers at 0xf1000000.
+
+ If the wrong DEBUG_MVEBU_UART* option is selected,
+ when u-boot hands over to the kernel, the system
+ silently crashes, with no serial output at all.
+
+ config DEBUG_MVEBU_UART1_ALTERNATE
+ bool "Kernel low-level debugging messages via MVEBU UART1 (new bootloaders)"
depends on ARCH_MVEBU
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
- on MVEBU based platforms.
+ on MVEBU based platforms on UART1.
This option should be used with the new bootloaders
that remap the internal registers at 0xf1000000.
@@ -978,16 +1015,28 @@ choice
config DEBUG_SIRFPRIMA2_UART1
bool "Kernel low-level debugging messages via SiRFprimaII UART1"
depends on ARCH_PRIMA2
+ select DEBUG_SIRFSOC_UART
help
Say Y here if you want the debug print routines to direct
their output to the uart1 port on SiRFprimaII devices.
- config DEBUG_SIRFMARCO_UART1
- bool "Kernel low-level debugging messages via SiRFmarco UART1"
- depends on ARCH_MARCO
+ config DEBUG_SIRFATLAS7_UART0
+ bool "Kernel low-level debugging messages via SiRFatlas7 UART0"
+ depends on ARCH_ATLAS7
+ select DEBUG_SIRFSOC_UART
help
Say Y here if you want the debug print routines to direct
- their output to the uart1 port on SiRFmarco devices.
+ their output to the uart0 port on SiRFATLAS7 devices.The uart0
+ is used on SiRFATLAS7 as a extra debug port.sometimes an extra
+ debug port can be very useful.
+
+ config DEBUG_SIRFATLAS7_UART1
+ bool "Kernel low-level debugging messages via SiRFatlas7 UART1"
+ depends on ARCH_ATLAS7
+ select DEBUG_SIRFSOC_UART
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the uart1 port on SiRFATLAS7 devices.
config STIH41X_DEBUG_ASC2
bool "Use StiH415/416 ASC2 UART for low-level debug"
@@ -1035,7 +1084,7 @@ choice
for Mediatek mt6589 based platforms on UART0.
config DEBUG_MT8127_UART0
- bool "Mediatek mt8127 UART0"
+ bool "Mediatek mt8127/mt6592 UART0"
depends on ARCH_MEDIATEK
select DEBUG_UART_8250
help
@@ -1162,6 +1211,10 @@ choice
endchoice
+config DEBUG_AT91_UART
+ bool
+ depends on ARCH_AT91
+
config DEBUG_EXYNOS_UART
bool
@@ -1214,10 +1267,15 @@ config DEBUG_STI_UART
bool
depends on ARCH_STI
+config DEBUG_SIRFSOC_UART
+ bool
+ depends on ARCH_SIRF
+
config DEBUG_LL_INCLUDE
string
default "debug/sa1100.S" if DEBUG_SA1100
default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
+ default "debug/at91.S" if DEBUG_AT91_UART
default "debug/asm9260.S" if DEBUG_ASM9260_UART
default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2
default "debug/meson.S" if DEBUG_MESON_UARTAO
@@ -1250,7 +1308,7 @@ config DEBUG_LL_INCLUDE
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART
default "debug/s5pv210.S" if DEBUG_S5PV210_UART
- default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
+ default "debug/sirf.S" if DEBUG_SIRFSOC_UART
default "debug/sti.S" if DEBUG_STI_UART
default "debug/tegra.S" if DEBUG_TEGRA_UART
default "debug/ux500.S" if DEBUG_UX500_UART
@@ -1259,6 +1317,7 @@ config DEBUG_LL_INCLUDE
default "debug/vt8500.S" if DEBUG_VT8500_UART0
default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
default "debug/bcm63xx.S" if DEBUG_UART_BCM63XX
+ default "debug/digicolor.S" if DEBUG_DIGICOLOR_UA0
default "mach/debug-macro.S"
# Compatibility options for PL01x
@@ -1302,7 +1361,10 @@ config DEBUG_UART_PHYS
default 0x11009000 if DEBUG_MT8135_UART3
default 0x16000000 if ARCH_INTEGRATOR
default 0x18000300 if DEBUG_BCM_5301X
+ default 0x18010000 if DEBUG_SIRFATLAS7_UART0
+ default 0x18020000 if DEBUG_SIRFATLAS7_UART1
default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
+ default 0x20001000 if DEBUG_HIP01_UART
default 0x20060000 if DEBUG_RK29_UART0
default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
@@ -1327,12 +1389,13 @@ config DEBUG_UART_PHYS
default 0x808c0000 if ARCH_EP93XX
default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
default 0xa9a00000 if DEBUG_MSM_UART
+ default 0xb0060000 if DEBUG_SIRFPRIMA2_UART1
default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX
default 0xc0013000 if DEBUG_U300_UART
default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
default 0xc8000003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
default 0xd0000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
- default 0xd0012000 if DEBUG_MVEBU_UART
+ default 0xd0012000 if DEBUG_MVEBU_UART0
default 0xc81004c0 if DEBUG_MESON_UARTAO
default 0xd4017000 if DEBUG_MMP_UART2
default 0xd4018000 if DEBUG_MMP_UART3
@@ -1346,7 +1409,8 @@ config DEBUG_UART_PHYS
default 0xe8008000 if DEBUG_R7S72100_SCIF2
default 0xf0000be0 if ARCH_EBSA110
default 0xf040ab00 if DEBUG_BRCMSTB_UART
- default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
+ default 0xf1012000 if DEBUG_MVEBU_UART0_ALTERNATE
+ default 0xf1012100 if DEBUG_MVEBU_UART1_ALTERNATE
default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \
ARCH_ORION5X
default 0xf7fc9000 if DEBUG_BERLIN_UART
@@ -1375,7 +1439,8 @@ config DEBUG_UART_PHYS
DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
- DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
+ DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
config DEBUG_UART_VIRT
hex "Virtual base address of debug UART"
@@ -1433,8 +1498,12 @@ config DEBUG_UART_VIRT
default 0xfeb30c00 if DEBUG_KEYSTONE_UART0
default 0xfeb31000 if DEBUG_KEYSTONE_UART1
default 0xfec02000 if DEBUG_SOCFPGA_UART
- default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE
+ default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
+ default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
+ default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0
+ default 0xfec20000 if DEBUG_SIRFATLAS7_UART1
+ default 0xfec60000 if DEBUG_SIRFPRIMA2_UART1
default 0xfec90000 if DEBUG_RK32_UART2
default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1
default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2
@@ -1453,12 +1522,14 @@ config DEBUG_UART_VIRT
default 0xfefb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
default 0xfefff700 if ARCH_IOP33X
default 0xff003000 if DEBUG_U300_UART
+ default 0xffd01000 if DEBUG_HIP01_UART
default DEBUG_UART_PHYS if !MMU
depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
DEBUG_MSM_UART || DEBUG_NETX_UART || \
DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
- DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
+ DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
config DEBUG_UART_8250_SHIFT
int "Register offset shift for the 8250 debug UART"
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 91bd5bd62857..a1c776b8dcec 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1,83 +1,91 @@
ifeq ($(CONFIG_OF),y)
+dtb-$(CONFIG_MACH_ASM9260) += \
+ alphascale-asm9260-devkit.dtb
# Keep at91 dtb files sorted alphabetically for each SoC
-# rm9200
-dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += mpa1600.dtb
-# sam9260
-dtb-$(CONFIG_ARCH_AT91) += animeo_ip.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91-qil_a9260.dtb
-dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb
-dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb
-dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb
-dtb-$(CONFIG_ARCH_AT91) += tny_a9260.dtb
-dtb-$(CONFIG_ARCH_AT91) += usb_a9260.dtb
-# sam9261
-dtb-$(CONFIG_ARCH_AT91) += at91sam9261ek.dtb
-# sam9263
-dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb
-dtb-$(CONFIG_ARCH_AT91) += usb_a9263.dtb
-# sam9g20
-dtb-$(CONFIG_ARCH_AT91) += at91-foxg20.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek_2mmc.dtb
-dtb-$(CONFIG_ARCH_AT91) += kizbox.dtb
-dtb-$(CONFIG_ARCH_AT91) += tny_a9g20.dtb
-dtb-$(CONFIG_ARCH_AT91) += usb_a9g20.dtb
-dtb-$(CONFIG_ARCH_AT91) += usb_a9g20_lpw.dtb
-# sam9g45
-dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb
-# sam9n12
-dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb
-# sam9rl
-dtb-$(CONFIG_ARCH_AT91) += at91sam9rlek.dtb
-# sam9x5
-dtb-$(CONFIG_ARCH_AT91) += at91-ariag25.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91-cosino_mega2560.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
-# sama5d3
-dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained.dtb
-dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb
-dtb-$(CONFIG_ARCH_AT91) += sama5d36ek.dtb
-# sama5d4
-dtb-$(CONFIG_ARCH_AT91) += at91-sama5d4ek.dtb
-
-dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
-dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb
-dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
-dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b-plus.dtb
+dtb-$(CONFIG_SOC_SAM_V4_V5) += \
+ at91rm9200ek.dtb \
+ mpa1600.dtb \
+ animeo_ip.dtb \
+ at91-qil_a9260.dtb \
+ aks-cdu.dtb \
+ ethernut5.dtb \
+ evk-pro3.dtb \
+ tny_a9260.dtb \
+ usb_a9260.dtb \
+ at91sam9261ek.dtb \
+ at91sam9263ek.dtb \
+ tny_a9263.dtb \
+ usb_a9263.dtb \
+ at91-foxg20.dtb \
+ at91sam9g20ek.dtb \
+ at91sam9g20ek_2mmc.dtb \
+ kizbox.dtb \
+ tny_a9g20.dtb \
+ usb_a9g20.dtb \
+ usb_a9g20_lpw.dtb \
+ at91sam9m10g45ek.dtb \
+ pm9g45.dtb \
+ at91sam9n12ek.dtb \
+ at91sam9rlek.dtb \
+ at91-ariag25.dtb \
+ at91-cosino_mega2560.dtb \
+ at91sam9g15ek.dtb \
+ at91sam9g25ek.dtb \
+ at91sam9g35ek.dtb \
+ at91sam9x25ek.dtb \
+ at91sam9x35ek.dtb
+dtb-$(CONFIG_SOC_SAM_V7) += \
+ at91-sama5d3_xplained.dtb \
+ sama5d31ek.dtb \
+ sama5d33ek.dtb \
+ sama5d34ek.dtb \
+ sama5d35ek.dtb \
+ sama5d36ek.dtb \
+ at91-sama5d4ek.dtb
+dtb-$(CONFIG_ARCH_ATLAS6) += \
+ atlas6-evb.dtb
+dtb-$(CONFIG_ARCH_ATLAS7) += \
+ atlas7-evb.dtb
+dtb-$(CONFIG_ARCH_AXXIA) += \
+ axm5516-amarillo.dtb
+dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2835-rpi-b.dtb \
+ bcm2835-rpi-b-plus.dtb
dtb-$(CONFIG_ARCH_BCM_5301X) += \
bcm4708-buffalo-wzr-1750dhp.dtb \
+ bcm4708-luxul-xwc-1000.dtb \
bcm4708-netgear-r6250.dtb \
bcm4708-netgear-r6300-v2.dtb \
bcm47081-asus-rt-n18u.dtb \
- bcm47081-buffalo-wzr-600dhp2.dtb
-dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb
-dtb-$(CONFIG_ARCH_BCM_CYGNUS) += bcm911360_entphn.dtb \
+ bcm47081-buffalo-wzr-600dhp2.dtb \
+ bcm47081-buffalo-wzr-900dhp.dtb
+dtb-$(CONFIG_ARCH_BCM_63XX) += \
+ bcm963138dvt.dtb
+dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
+ bcm911360_entphn.dtb \
bcm911360k.dtb \
bcm958300k.dtb
-dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
+dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
+ bcm28155-ap.dtb \
bcm21664-garnet.dtb
dtb-$(CONFIG_ARCH_BERLIN) += \
- berlin2-sony-nsz-gs7.dtb \
- berlin2cd-google-chromecast.dtb \
+ berlin2-sony-nsz-gs7.dtb \
+ berlin2cd-google-chromecast.dtb \
berlin2q-marvell-dmp.dtb
dtb-$(CONFIG_ARCH_BRCMSTB) += \
bcm7445-bcm97445svmb.dtb
-dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \
+dtb-$(CONFIG_ARCH_DAVINCI) += \
+ da850-enbw-cmc.dtb \
da850-evm.dtb
-dtb-$(CONFIG_ARCH_EFM32) += efm32gg-dk3750.dtb
-dtb-$(CONFIG_ARCH_EXYNOS) += exynos3250-monk.dtb \
- exynos3250-rinato.dtb \
+dtb-$(CONFIG_ARCH_DIGICOLOR) += \
+ cx92755_equinox.dtb
+dtb-$(CONFIG_ARCH_EFM32) += \
+ efm32gg-dk3750.dtb
+dtb-$(CONFIG_ARCH_EXYNOS3) += \
+ exynos3250-monk.dtb \
+ exynos3250-rinato.dtb
+dtb-$(CONFIG_ARCH_EXYNOS4) += \
exynos4210-origen.dtb \
exynos4210-smdkv310.dtb \
exynos4210-trats.dtb \
@@ -88,7 +96,8 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos3250-monk.dtb \
exynos4412-origen.dtb \
exynos4412-smdk4412.dtb \
exynos4412-tiny4412.dtb \
- exynos4412-trats2.dtb \
+ exynos4412-trats2.dtb
+dtb-$(CONFIG_ARCH_EXYNOS5) += \
exynos5250-arndale.dtb \
exynos5250-smdk5250.dtb \
exynos5250-snow.dtb \
@@ -98,20 +107,31 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos3250-monk.dtb \
exynos5420-arndale-octa.dtb \
exynos5420-peach-pit.dtb \
exynos5420-smdk5420.dtb \
+ exynos5422-odroidxu3.dtb \
exynos5440-sd5v1.dtb \
exynos5440-ssdk5440.dtb \
exynos5800-peach-pi.dtb
-dtb-$(CONFIG_ARCH_HI3xxx) += hi3620-hi4511.dtb
-dtb-$(CONFIG_ARCH_HIX5HD2) += hisi-x5hd2-dkb.dtb
-dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
+dtb-$(CONFIG_ARCH_HI3xxx) += \
+ hi3620-hi4511.dtb
+dtb-$(CONFIG_ARCH_HIX5HD2) += \
+ hisi-x5hd2-dkb.dtb
+dtb-$(CONFIG_ARCH_HIGHBANK) += \
+ highbank.dtb \
ecx-2000.dtb
-dtb-$(CONFIG_ARCH_HIP04) += hip04-d01.dtb
-dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
+dtb-$(CONFIG_ARCH_HIP01) += \
+ hip01-ca9x2.dtb
+dtb-$(CONFIG_ARCH_HIP04) += \
+ hip04-d01.dtb
+dtb-$(CONFIG_ARCH_INTEGRATOR) += \
+ integratorap.dtb \
integratorcp.dtb
-dtb-$(CONFIG_ARCH_KEYSTONE) += k2hk-evm.dtb \
+dtb-$(CONFIG_ARCH_KEYSTONE) += \
+ k2hk-evm.dtb \
k2l-evm.dtb \
k2e-evm.dtb
-dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
+dtb-$(CONFIG_MACH_KIRKWOOD) += \
+ kirkwood-b3.dtb \
+ kirkwood-blackarmor-nas220.dtb \
kirkwood-cloudbox.dtb \
kirkwood-d2net.dtb \
kirkwood-db-88f6281.dtb \
@@ -160,6 +180,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-openrd-base.dtb \
kirkwood-openrd-client.dtb \
kirkwood-openrd-ultimate.dtb \
+ kirkwood-pogo_e02.dtb \
kirkwood-rd88f6192.dtb \
kirkwood-rd88f6281-z0.dtb \
kirkwood-rd88f6281-a.dtb \
@@ -174,37 +195,47 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-ts219-6282.dtb \
kirkwood-ts419-6281.dtb \
kirkwood-ts419-6282.dtb
-dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
-dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
-dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
-dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
+dtb-$(CONFIG_ARCH_LPC32XX) += \
+ ea3250.dtb phy3250.dtb
+dtb-$(CONFIG_MACH_MESON6) += \
+ meson6-atv1200.dtb
+dtb-$(CONFIG_ARCH_MMP) += \
+ pxa168-aspenite.dtb \
pxa910-dkb.dtb \
mmp2-brownstone.dtb
-dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
-dtb-$(CONFIG_ARCH_MXC) += \
+dtb-$(CONFIG_ARCH_MOXART) += \
+ moxart-uc7112lx.dtb
+dtb-$(CONFIG_SOC_IMX1) += \
imx1-ads.dtb \
- imx1-apf9328.dtb \
+ imx1-apf9328.dtb
+dtb-$(CONFIG_SOC_IMX25) += \
imx25-eukrea-mbimxsd25-baseboard.dtb \
imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dtb \
imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dtb \
imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dtb \
imx25-karo-tx25.dtb \
- imx25-pdk.dtb \
+ imx25-pdk.dtb
+dtb-$(CONFIG_SOC_IMX31) += \
imx27-apf27.dtb \
imx27-apf27dev.dtb \
imx27-eukrea-mbimxsd27-baseboard.dtb \
imx27-pdk.dtb \
imx27-phytec-phycore-rdk.dtb \
- imx27-phytec-phycard-s-rdk.dtb \
- imx31-bug.dtb \
+ imx27-phytec-phycard-s-rdk.dtb
+dtb-$(CONFIG_SOC_IMX31) += \
+ imx31-bug.dtb
+dtb-$(CONFIG_SOC_IMX35) += \
imx35-eukrea-mbimxsd35-baseboard.dtb \
- imx35-pdk.dtb \
- imx50-evk.dtb \
+ imx35-pdk.dtb
+dtb-$(CONFIG_SOC_IMX50) += \
+ imx50-evk.dtb
+dtb-$(CONFIG_SOC_IMX51) += \
imx51-apf51.dtb \
imx51-apf51dev.dtb \
imx51-babbage.dtb \
imx51-digi-connectcore-jsk.dtb \
- imx51-eukrea-mbimxsd51-baseboard.dtb \
+ imx51-eukrea-mbimxsd51-baseboard.dtb
+dtb-$(CONFIG_SOC_IMX53) += \
imx53-ard.dtb \
imx53-m53evk.dtb \
imx53-mba53.dtb \
@@ -213,7 +244,8 @@ dtb-$(CONFIG_ARCH_MXC) += \
imx53-smd.dtb \
imx53-tx53-x03x.dtb \
imx53-tx53-x13x.dtb \
- imx53-voipac-bsb.dtb \
+ imx53-voipac-bsb.dtb
+dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-aristainetos_4.dtb \
imx6dl-aristainetos_7.dtb \
imx6dl-cubox-i.dtb \
@@ -234,6 +266,7 @@ dtb-$(CONFIG_ARCH_MXC) += \
imx6dl-tx6dl-comtft.dtb \
imx6dl-tx6u-801x.dtb \
imx6dl-tx6u-811x.dtb \
+ imx6dl-udoo.dtb \
imx6dl-wandboard.dtb \
imx6dl-wandboard-revb1.dtb \
imx6q-arm2.dtb \
@@ -257,23 +290,29 @@ dtb-$(CONFIG_ARCH_MXC) += \
imx6q-sabresd.dtb \
imx6q-sbc6x.dtb \
imx6q-tbs2910.dtb \
- imx6q-udoo.dtb \
- imx6q-wandboard.dtb \
- imx6q-wandboard-revb1.dtb \
imx6q-tx6q-1010.dtb \
imx6q-tx6q-1010-comtft.dtb \
imx6q-tx6q-1020.dtb \
imx6q-tx6q-1020-comtft.dtb \
imx6q-tx6q-1110.dtb \
- imx6sl-evk.dtb \
- imx6sx-sdb.dtb \
+ imx6q-udoo.dtb \
+ imx6q-wandboard.dtb \
+ imx6q-wandboard-revb1.dtb
+dtb-$(CONFIG_SOC_IMX6SL) += \
+ imx6sl-evk.dtb
+dtb-$(CONFIG_SOC_IMX6SX) += \
+ imx6sx-sabreauto.dtb \
+ imx6sx-sdb.dtb
+dtb-$(CONFIG_SOC_LS1021A) += \
ls1021a-qds.dtb \
- ls1021a-twr.dtb \
+ ls1021a-twr.dtb
+dtb-$(CONFIG_SOC_VF610) += \
vf500-colibri-eval-v3.dtb \
vf610-colibri-eval-v3.dtb \
vf610-cosmic.dtb \
vf610-twr.dtb
-dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
+dtb-$(CONFIG_ARCH_MXS) += \
+ imx23-evk.dtb \
imx23-olinuxino.dtb \
imx23-stmp378x_devb.dtb \
imx28-apf28.dtb \
@@ -294,17 +333,21 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
imx28-m28evk.dtb \
imx28-sps1.dtb \
imx28-tx28.dtb
-dtb-$(CONFIG_ARCH_NOMADIK) += ste-nomadik-s8815.dtb \
+dtb-$(CONFIG_ARCH_NOMADIK) += \
+ ste-nomadik-s8815.dtb \
ste-nomadik-nhk15.dtb
-dtb-$(CONFIG_ARCH_NSPIRE) += nspire-cx.dtb \
+dtb-$(CONFIG_ARCH_NSPIRE) += \
+ nspire-cx.dtb \
nspire-tp.dtb \
nspire-clp.dtb
-dtb-$(CONFIG_ARCH_OMAP2) += omap2420-h4.dtb \
+dtb-$(CONFIG_ARCH_OMAP2) += \
+ omap2420-h4.dtb \
omap2420-n800.dtb \
omap2420-n810.dtb \
omap2420-n810-wimax.dtb \
omap2430-sdp.dtb
-dtb-$(CONFIG_ARCH_OMAP3) += am3517-craneboard.dtb \
+dtb-$(CONFIG_ARCH_OMAP3) += \
+ am3517-craneboard.dtb \
am3517-evm.dtb \
am3517_mt_ventoux.dtb \
omap3430-sdp.dtb \
@@ -348,7 +391,10 @@ dtb-$(CONFIG_ARCH_OMAP3) += am3517-craneboard.dtb \
omap3-sbc-t3730.dtb \
omap3-thunder.dtb \
omap3-zoom3.dtb
-dtb-$(CONFIG_SOC_AM33XX) += am335x-base0033.dtb \
+dtb-$(CONFIG_SOC_TI81XX) += \
+ dm8168-evm.dtb
+dtb-$(CONFIG_SOC_AM33XX) += \
+ am335x-base0033.dtb \
am335x-bone.dtb \
am335x-boneblack.dtb \
am335x-evm.dtb \
@@ -356,7 +402,8 @@ dtb-$(CONFIG_SOC_AM33XX) += am335x-base0033.dtb \
am335x-nano.dtb \
am335x-pepper.dtb \
am335x-lxm.dtb
-dtb-$(CONFIG_ARCH_OMAP4) += omap4-duovero-parlor.dtb \
+dtb-$(CONFIG_ARCH_OMAP4) += \
+ omap4-duovero-parlor.dtb \
omap4-panda.dtb \
omap4-panda-a4.dtb \
omap4-panda-es.dtb \
@@ -364,20 +411,26 @@ dtb-$(CONFIG_ARCH_OMAP4) += omap4-duovero-parlor.dtb \
omap4-sdp-es23plus.dtb \
omap4-var-dvk-om44.dtb \
omap4-var-stk-om44.dtb
-dtb-$(CONFIG_SOC_AM43XX) += am43x-epos-evm.dtb \
+dtb-$(CONFIG_SOC_AM43XX) += \
+ am43x-epos-evm.dtb \
am437x-sk-evm.dtb \
+ am437x-idk-evm.dtb \
am437x-gp-evm.dtb
-dtb-$(CONFIG_SOC_OMAP5) += omap5-cm-t54.dtb \
+dtb-$(CONFIG_SOC_OMAP5) += \
+ omap5-cm-t54.dtb \
omap5-sbc-t54.dtb \
omap5-uevm.dtb
-dtb-$(CONFIG_SOC_DRA7XX) += dra7-evm.dtb \
+dtb-$(CONFIG_SOC_DRA7XX) += \
+ dra7-evm.dtb \
am57xx-beagle-x15.dtb \
dra72-evm.dtb
-dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-d2-network.dtb \
+dtb-$(CONFIG_ARCH_ORION5X) += \
+ orion5x-lacie-d2-network.dtb \
orion5x-lacie-ethernet-disk-mini-v2.dtb \
orion5x-maxtor-shared-storage-2.dtb \
orion5x-rd88f5182-nas.dtb
-dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
+dtb-$(CONFIG_ARCH_PRIMA2) += \
+ prima2-evb.dtb
dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8064-cm-qs600.dtb \
qcom-apq8064-ifc6410.dtb \
@@ -388,17 +441,24 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-msm8660-surf.dtb \
qcom-msm8960-cdp.dtb \
qcom-msm8974-sony-xperia-honami.dtb
-dtb-$(CONFIG_ARCH_REALVIEW) += arm-realview-pb1176.dtb
+dtb-$(CONFIG_ARCH_REALVIEW) += \
+ arm-realview-pb1176.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3066a-bqcurie2.dtb \
rk3066a-marsboard.dtb \
+ rk3066a-rayeager.dtb \
rk3188-radxarock.dtb \
rk3288-evb-act8846.dtb \
- rk3288-evb-rk808.dtb
-dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb
-dtb-$(CONFIG_ARCH_S3C64XX) += s3c6410-mini6410.dtb \
+ rk3288-evb-rk808.dtb \
+ rk3288-firefly-beta.dtb \
+ rk3288-firefly.dtb
+dtb-$(CONFIG_ARCH_S3C24XX) += \
+ s3c2416-smdk2416.dtb
+dtb-$(CONFIG_ARCH_S3C64XX) += \
+ s3c6410-mini6410.dtb \
s3c6410-smdk6410.dtb
-dtb-$(CONFIG_ARCH_S5PV210) += s5pv210-aquila.dtb \
+dtb-$(CONFIG_ARCH_S5PV210) += \
+ s5pv210-aquila.dtb \
s5pv210-goni.dtb \
s5pv210-smdkc110.dtb \
s5pv210-smdkv210.dtb \
@@ -410,48 +470,61 @@ dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += \
r8a7778-bockw.dtb \
r8a7778-bockw-reference.dtb \
r8a7779-marzen.dtb \
- r8a7790-lager.dtb \
sh7372-mackerel.dtb \
sh73a0-kzm9g.dtb \
sh73a0-kzm9g-reference.dtb
-dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d.dtb \
+dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
+ emev2-kzm9d.dtb \
r7s72100-genmai.dtb \
+ r8a73a4-ape6evm.dtb \
r8a7740-armadillo800eva.dtb \
r8a7779-marzen.dtb \
r8a7790-lager.dtb \
r8a7791-henninger.dtb \
r8a7791-koelsch.dtb \
r8a7794-alt.dtb
-dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_arria5_socdk.dtb \
+dtb-$(CONFIG_ARCH_SOCFPGA) += \
+ socfpga_arria5_socdk.dtb \
socfpga_arria10_socdk.dtb \
socfpga_cyclone5_socdk.dtb \
socfpga_cyclone5_sockit.dtb \
socfpga_cyclone5_socrates.dtb \
socfpga_vt.dtb
-dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
+dtb-$(CONFIG_ARCH_SPEAR13XX) += \
+ spear1310-evb.dtb \
spear1340-evb.dtb
-dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
+dtb-$(CONFIG_ARCH_SPEAR3XX) += \
+ spear300-evb.dtb \
spear310-evb.dtb \
spear320-evb.dtb \
spear320-hmi.dtb
-dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
-dtb-$(CONFIG_ARCH_STI)+= stih407-b2120.dtb \
+dtb-$(CONFIG_ARCH_SPEAR6XX) += \
+ spear600-evb.dtb
+dtb-$(CONFIG_ARCH_STI) += \
+ stih407-b2120.dtb \
stih410-b2120.dtb \
stih415-b2000.dtb \
stih415-b2020.dtb \
stih416-b2000.dtb \
stih416-b2020.dtb \
- stih416-b2020e.dtb
+ stih416-b2020e.dtb \
+ stih418-b2199.dtb
dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-a1000.dtb \
sun4i-a10-ba10-tvbox.dtb \
+ sun4i-a10-chuwi-v7-cw0825.dtb \
sun4i-a10-cubieboard.dtb \
+ sun4i-a10-marsboard.dtb \
sun4i-a10-mini-xplus.dtb \
+ sun4i-a10-mk802.dtb \
+ sun4i-a10-mk802ii.dtb \
sun4i-a10-hackberry.dtb \
+ sun4i-a10-hyundai-a7hd.dtb \
sun4i-a10-inet97fv2.dtb \
sun4i-a10-olinuxino-lime.dtb \
sun4i-a10-pcduino.dtb
dtb-$(CONFIG_MACH_SUN5I) += \
+ sun5i-a10s-mk802.dtb \
sun5i-a10s-olinuxino-micro.dtb \
sun5i-a10s-r7-tv-dongle.dtb \
sun5i-a13-hsg-h702.dtb \
@@ -461,9 +534,11 @@ dtb-$(CONFIG_MACH_SUN6I) += \
sun6i-a31-app4-evb1.dtb \
sun6i-a31-colombus.dtb \
sun6i-a31-hummingbird.dtb \
- sun6i-a31-m9.dtb
+ sun6i-a31-m9.dtb \
+ sun6i-a31s-cs908.dtb
dtb-$(CONFIG_MACH_SUN7I) += \
sun7i-a20-bananapi.dtb \
+ sun7i-a20-bananapro.dtb \
sun7i-a20-cubieboard2.dtb \
sun7i-a20-cubietruck.dtb \
sun7i-a20-hummingbird.dtb \
@@ -474,10 +549,12 @@ dtb-$(CONFIG_MACH_SUN7I) += \
sun7i-a20-olinuxino-micro.dtb \
sun7i-a20-pcduino3.dtb
dtb-$(CONFIG_MACH_SUN8I) += \
- sun8i-a23-ippo-q8h-v5.dtb
+ sun8i-a23-ippo-q8h-v5.dtb \
+ sun8i-a23-ippo-q8h-v1.2.dtb
dtb-$(CONFIG_MACH_SUN9I) += \
sun9i-a80-optimus.dtb
-dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
+dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
+ tegra20-harmony.dtb \
tegra20-iris-512.dtb \
tegra20-medcom-wide.dtb \
tegra20-paz00.dtb \
@@ -486,34 +563,43 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
tegra20-tec.dtb \
tegra20-trimslice.dtb \
tegra20-ventana.dtb \
- tegra20-whistler.dtb \
+ tegra20-whistler.dtb
+dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += \
tegra30-apalis-eval.dtb \
tegra30-beaver.dtb \
tegra30-cardhu-a02.dtb \
tegra30-cardhu-a04.dtb \
- tegra30-colibri-eval-v3.dtb \
+ tegra30-colibri-eval-v3.dtb
+dtb-$(CONFIG_ARCH_TEGRA_114_SOC) += \
tegra114-dalmore.dtb \
tegra114-roth.dtb \
- tegra114-tn7.dtb \
+ tegra114-tn7.dtb
+dtb-$(CONFIG_ARCH_TEGRA_124_SOC) += \
tegra124-jetson-tk1.dtb \
tegra124-nyan-big.dtb \
tegra124-venice2.dtb
-dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb
-dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
+dtb-$(CONFIG_ARCH_U300) += \
+ ste-u300.dtb
+dtb-$(CONFIG_ARCH_U8500) += \
+ ste-snowball.dtb \
ste-hrefprev60-stuib.dtb \
ste-hrefprev60-tvk.dtb \
ste-hrefv60plus-stuib.dtb \
ste-hrefv60plus-tvk.dtb \
ste-ccu8540.dtb \
ste-ccu9540.dtb
-dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
+dtb-$(CONFIG_ARCH_VERSATILE) += \
+ versatile-ab.dtb \
versatile-pb.dtb
-dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
+dtb-$(CONFIG_ARCH_VEXPRESS) += \
+ vexpress-v2p-ca5s.dtb \
vexpress-v2p-ca9.dtb \
vexpress-v2p-ca15-tc1.dtb \
vexpress-v2p-ca15_a7.dtb
-dtb-$(CONFIG_ARCH_VIRT) += xenvm-4.2.dtb
-dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
+dtb-$(CONFIG_ARCH_VIRT) += \
+ xenvm-4.2.dtb
+dtb-$(CONFIG_ARCH_VT8500) += \
+ vt8500-bv07.dtb \
wm8505-ref.dtb \
wm8650-mid.dtb \
wm8750-apc8750.dtb \
@@ -534,8 +620,10 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
dtb-$(CONFIG_MACH_ARMADA_375) += \
armada-375-db.dtb
dtb-$(CONFIG_MACH_ARMADA_38X) += \
- armada-385-db.dtb \
- armada-385-rd.dtb
+ armada-385-db-ap.dtb \
+ armada-388-db.dtb \
+ armada-388-gp.dtb \
+ armada-388-rd.dtb
dtb-$(CONFIG_MACH_ARMADA_XP) += \
armada-xp-axpwifiap.dtb \
armada-xp-db.dtb \
@@ -545,17 +633,18 @@ dtb-$(CONFIG_MACH_ARMADA_XP) += \
armada-xp-netgear-rn2120.dtb \
armada-xp-openblocks-ax3-4.dtb \
armada-xp-synology-ds414.dtb
-dtb-$(CONFIG_MACH_DOVE) += dove-cm-a510.dtb \
+dtb-$(CONFIG_MACH_DOVE) += \
+ dove-cm-a510.dtb \
dove-cubox.dtb \
dove-cubox-es.dtb \
dove-d2plug.dtb \
dove-d3plug.dtb \
dove-dove-db.dtb
-dtb-$(CONFIG_ARCH_MEDIATEK) += mt6589-aquaris5.dtb \
+dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt6589-aquaris5.dtb \
mt6592-evb.dtb \
mt8127-moose.dtb \
mt8135-evbp1.dtb
-
endif
always := $(dtb-y)
diff --git a/arch/arm/boot/dts/alphascale-asm9260-devkit.dts b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
new file mode 100644
index 000000000000..c77e2c902fb6
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260-devkit.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+/dts-v1/;
+#include "alphascale-asm9260.dtsi"
+
+/ {
+ model = "Alphascale asm9260 Development Kit";
+ compatible = "alphascale,asm9260devkit", "alphascale,asm9260";
+};
diff --git a/arch/arm/boot/dts/alphascale-asm9260.dtsi b/arch/arm/boot/dts/alphascale-asm9260.dtsi
new file mode 100644
index 000000000000..907fc7bfc418
--- /dev/null
+++ b/arch/arm/boot/dts/alphascale-asm9260.dtsi
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * Licensed under the X11 license or the GPL v2 (or later)
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/alphascale,asm9260.h>
+
+/ {
+ interrupt-parent = <&icoll>;
+
+ memory {
+ device_type = "memory";
+ reg = <0x20000000 0x2000000>;
+ };
+
+ cpus {
+ #address-cells = <0>;
+ #size-cells = <0>;
+
+ cpu {
+ compatible = "arm,arm926ej-s";
+ device_type = "cpu";
+ clocks = <&acc CLKID_SYS_CPU>;
+ };
+ };
+
+ osc24m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-accuracy = <30000>;
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ acc: clock-controller@80040000 {
+ compatible = "alphascale,asm9260-clock-controller";
+ #clock-cells = <1>;
+ clocks = <&osc24m>;
+ reg = <0x80040000 0x204>;
+ };
+
+ icoll: interrupt-controller@80054000 {
+ compatible = "alphascale,asm9260-icoll";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x80054000 0x200>;
+ };
+
+ timer0: timer@80088000 {
+ compatible = "alphascale,asm9260-timer";
+ reg = <0x80088000 0x4000>;
+ clocks = <&acc CLKID_AHB_TIMER0>;
+ interrupts = <29>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index b62a1cd776cd..1943fc333e7c 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -948,6 +948,22 @@
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
+
+ vpfe0: vpfe@48326000 {
+ compatible = "ti,am437x-vpfe";
+ reg = <0x48326000 0x2000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "vpfe0";
+ status = "disabled";
+ };
+
+ vpfe1: vpfe@48328000 {
+ compatible = "ti,am437x-vpfe";
+ reg = <0x48328000 0x2000>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+ ti,hwmods = "vpfe1";
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
index 7eaae4cf9f89..f84d9715a4a9 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -268,6 +268,78 @@
0x184 (PIN_INPUT_PULLUP | MUX_MODE2) /* uart1_txd.d_can1_rx */
>;
};
+
+ vpfe0_pins_default: vpfe0_pins_default {
+ pinctrl-single,pins = <
+ 0x1B0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_hd mode 0*/
+ 0x1B4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_vd mode 0*/
+ 0x1C0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_pclk mode 0*/
+ 0x1C4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data8 mode 0*/
+ 0x1C8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data9 mode 0*/
+ 0x208 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data0 mode 0*/
+ 0x20C (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data1 mode 0*/
+ 0x210 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data2 mode 0*/
+ 0x214 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data3 mode 0*/
+ 0x218 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data4 mode 0*/
+ 0x21C (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data5 mode 0*/
+ 0x220 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data6 mode 0*/
+ 0x224 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data7 mode 0*/
+ >;
+ };
+
+ vpfe0_pins_sleep: vpfe0_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1B0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_hd mode 0*/
+ 0x1B4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_vd mode 0*/
+ 0x1C0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_pclk mode 0*/
+ 0x1C4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data8 mode 0*/
+ 0x1C8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data9 mode 0*/
+ 0x208 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data0 mode 0*/
+ 0x20C (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data1 mode 0*/
+ 0x210 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data2 mode 0*/
+ 0x214 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data3 mode 0*/
+ 0x218 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data4 mode 0*/
+ 0x21C (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data5 mode 0*/
+ 0x220 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data6 mode 0*/
+ 0x224 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam0_data7 mode 0*/
+ >;
+ };
+
+ vpfe1_pins_default: vpfe1_pins_default {
+ pinctrl-single,pins = <
+ 0x1CC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data9 mode 0*/
+ 0x1D0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data8 mode 0*/
+ 0x1D4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_hd mode 0*/
+ 0x1D8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_vd mode 0*/
+ 0x1DC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_pclk mode 0*/
+ 0x1E8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data0 mode 0*/
+ 0x1EC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data1 mode 0*/
+ 0x1F0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data2 mode 0*/
+ 0x1F4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data3 mode 0*/
+ 0x1F8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data4 mode 0*/
+ 0x1FC (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data5 mode 0*/
+ 0x200 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data6 mode 0*/
+ 0x204 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data7 mode 0*/
+ >;
+ };
+
+ vpfe1_pins_sleep: vpfe1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1CC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data9 mode 0*/
+ 0x1D0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data8 mode 0*/
+ 0x1D4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_hd mode 0*/
+ 0x1D8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_vd mode 0*/
+ 0x1DC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_pclk mode 0*/
+ 0x1E8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data0 mode 0*/
+ 0x1EC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data1 mode 0*/
+ 0x1F0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data2 mode 0*/
+ 0x1F4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data3 mode 0*/
+ 0x1F8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data4 mode 0*/
+ 0x1FC (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data5 mode 0*/
+ 0x200 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data6 mode 0*/
+ 0x204 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7) /* cam1_data7 mode 0*/
+ >;
+ };
};
&i2c0 {
@@ -545,3 +617,37 @@
pinctrl-0 = <&dcan1_default>;
status = "okay";
};
+
+&vpfe0 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe0_pins_default>;
+ pinctrl-1 = <&vpfe0_pins_sleep>;
+
+ port {
+ vpfe0_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
+
+&vpfe1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe1_pins_default>;
+ pinctrl-1 = <&vpfe1_pins_sleep>;
+
+ port {
+ vpfe1_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts
new file mode 100644
index 000000000000..f9a17e2ca8cb
--- /dev/null
+++ b/arch/arm/boot/dts/am437x-idk-evm.dts
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "am4372.dtsi"
+#include <dt-bindings/pinctrl/am43xx.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "TI AM437x Industrial Development Kit";
+ compatible = "ti,am437x-idk-evm","ti,am4372","ti,am43";
+
+ v24_0d: fixed-regulator-v24_0d {
+ compatible = "regulator-fixed";
+ regulator-name = "V24_0D";
+ regulator-min-microvolt = <24000000>;
+ regulator-max-microvolt = <24000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ v3_3d: fixed-regulator-v3_3d {
+ compatible = "regulator-fixed";
+ regulator-name = "V3_3D";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ vdd_corereg: fixed-regulator-vdd_corereg {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_COREREG";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ vdd_core: fixed-regulator-vdd_core {
+ compatible = "regulator-fixed";
+ regulator-name = "VDD_CORE";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_corereg>;
+ };
+
+ v1_8dreg: fixed-regulator-v1_8dreg{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_8DREG";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ v1_8d: fixed-regulator-v1_8d{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_8D";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v1_8dreg>;
+ };
+
+ v1_5dreg: fixed-regulator-v1_5dreg{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_5DREG";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v24_0d>;
+ };
+
+ v1_5d: fixed-regulator-v1_5d{
+ compatible = "regulator-fixed";
+ regulator-name = "V1_5D";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&v1_5dreg>;
+ };
+
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pins_default>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ switch@0 {
+ label = "power-button";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&am43xx_pinmux {
+ gpio_keys_pins_default: gpio_keys_pins_default {
+ pinctrl-single,pins = <
+ 0x1b8 (PIN_INPUT | MUX_MODE7) /* cam0_field.gpio4_2 */
+ >;
+ };
+
+ i2c0_pins_default: i2c0_pins_default {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ i2c0_pins_sleep: i2c0_pins_sleep {
+ pinctrl-single,pins = <
+ 0x188 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x18c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ i2c1_pins_default: i2c1_pins_default {
+ pinctrl-single,pins = <
+ 0x15c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ 0x158 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_d1.i2c1_sda */
+ >;
+ };
+
+ i2c1_pins_sleep: i2c1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x15c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_cs0.i2c1_scl */
+ 0x158 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* spi0_d1.i2c1_sda */
+ >;
+ };
+
+ mmc1_pins_default: pinmux_mmc1_pins_default {
+ pinctrl-single,pins = <
+ 0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ 0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
+ 0x1f0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ 0x1f4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ 0x1f8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ 0x1fc (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
+ >;
+ };
+
+ mmc1_pins_sleep: pinmux_mmc1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x100 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x104 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1f0 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1f4 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1f8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x1fc (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x160 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ ecap0_pins_default: backlight_pins_default {
+ pinctrl-single,pins = <
+ 0x164 (PIN_OUTPUT | MUX_MODE0) /* ecap0_in_pwm0_out.ecap0_in_pwm0_out */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */
+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd2 */
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd3 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ qspi_pins_default: qspi_pins_default {
+ pinctrl-single,pins = <
+ 0x7c (PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_csn0.qspi_csn */
+ 0x88 (PIN_OUTPUT | MUX_MODE2) /* gpmc_csn3.qspi_clk */
+ 0x90 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_advn_ale.qspi_d0 */
+ 0x94 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_oen_ren.qspi_d1 */
+ 0x98 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_wen.qspi_d2 */
+ 0x9c (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_be0n_cle.qspi_d3 */
+ >;
+ };
+
+ qspi_pins_sleep: qspi_pins_sleep{
+ pinctrl-single,pins = <
+ 0x7c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x88 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x98 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ 0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c0_pins_default>;
+ pinctrl-1 = <&i2c0_pins_default>;
+ clock-frequency = <400000>;
+
+ at24@50 {
+ compatible = "at24,24c256";
+ pagesize = <64>;
+ reg = <0x50>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&i2c1_pins_default>;
+ pinctrl-1 = <&i2c1_pins_default>;
+ clock-frequency = <400000>;
+
+ tps: tps62362@60 {
+ compatible = "ti,tps62362";
+ regulator-name = "VDD_MPU";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1330000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-high;
+ ti,vsel1-state-high;
+ vin-supply = <&v3_3d>;
+ };
+};
+
+&epwmss0 {
+ status = "okay";
+};
+
+&ecap0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pins_default>;
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio4 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&mmc1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&mmc1_pins_default>;
+ pinctrl-1 = <&mmc1_pins_sleep>;
+ vmmc-supply = <&v3_3d>;
+ bus-width = <4>;
+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+};
+
+&qspi {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&qspi_pins_default>;
+ pinctrl-1 = <&qspi_pins_sleep>;
+
+ spi-max-frequency = <48000000>;
+ m25p80@0 {
+ compatible = "mx66l51235l";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-cpol;
+ spi-cpha;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * MTD partition table. The ROM checks the first 512KiB for a
+ * valid file to boot(XIP).
+ */
+ partition@0 {
+ label = "QSPI.U_BOOT";
+ reg = <0x00000000 0x000080000>;
+ };
+ partition@1 {
+ label = "QSPI.U_BOOT.backup";
+ reg = <0x00080000 0x00080000>;
+ };
+ partition@2 {
+ label = "QSPI.U-BOOT-SPL_OS";
+ reg = <0x00100000 0x00010000>;
+ };
+ partition@3 {
+ label = "QSPI.U_BOOT_ENV";
+ reg = <0x00110000 0x00010000>;
+ };
+ partition@4 {
+ label = "QSPI.U-BOOT-ENV.backup";
+ reg = <0x00120000 0x00010000>;
+ };
+ partition@5 {
+ label = "QSPI.KERNEL";
+ reg = <0x00130000 0x0800000>;
+ };
+ partition@6 {
+ label = "QSPI.FILESYSTEM";
+ reg = <0x00930000 0x36D0000>;
+ };
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rgmii";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
+
+&cpu {
+ cpu0-supply = <&tps>;
+};
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts
index 53bbfc90b26a..832d24318f62 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -153,20 +153,26 @@
i2c0_pins: i2c0_pins {
pinctrl-single,pins = <
- 0x188 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
- 0x18c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ 0x188 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ 0x18c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* i2c0_scl.i2c0_scl */
>;
};
i2c1_pins: i2c1_pins {
pinctrl-single,pins = <
- 0x15c (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */
- 0x158 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) /* spi0_d1.i2c1_sda */
+ 0x15c (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_cs0.i2c1_scl */
+ 0x158 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE2) /* spi0_d1.i2c1_sda */
>;
};
mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = <
+ 0x0f0 (PIN_INPUT | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
+ 0x0f4 (PIN_INPUT | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
+ 0x0f8 (PIN_INPUT | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
+ 0x0fc (PIN_INPUT | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
+ 0x100 (PIN_INPUT | MUX_MODE0) /* mmc0_clk.mmc0_clk */
+ 0x104 (PIN_INPUT | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */
>;
};
@@ -184,35 +190,75 @@
>;
};
+ vpfe0_pins_default: vpfe0_pins_default {
+ pinctrl-single,pins = <
+ 0x1b0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_hd mode 0*/
+ 0x1b4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_vd mode 0*/
+ 0x1b8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_field mode 0*/
+ 0x1bc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_wen mode 0*/
+ 0x1c0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_pclk mode 0*/
+ 0x1c4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data8 mode 0*/
+ 0x1c8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data9 mode 0*/
+ 0x208 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data0 mode 0*/
+ 0x20c (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data1 mode 0*/
+ 0x210 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data2 mode 0*/
+ 0x214 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data3 mode 0*/
+ 0x218 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data4 mode 0*/
+ 0x21c (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data5 mode 0*/
+ 0x220 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data6 mode 0*/
+ 0x224 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam0_data7 mode 0*/
+ >;
+ };
+
+ vpfe0_pins_sleep: vpfe0_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1b0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1b4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1b8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1bc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1c0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1c4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1c8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x208 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x20c (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x210 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x214 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x218 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x21c (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x220 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x224 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ >;
+ };
+
cpsw_default: cpsw_default {
pinctrl-single,pins = <
/* Slave 1 */
- 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
- 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
- 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
- 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
- 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
- 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
- 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
- 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
- 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
- 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
- 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd2 */
- 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd3 */
+ 0x12c (PIN_OUTPUT | MUX_MODE2) /* mii1_txclk.rmii1_tclk */
+ 0x114 (PIN_OUTPUT | MUX_MODE2) /* mii1_txen.rgmii1_tctl */
+ 0x128 (PIN_OUTPUT | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */
+ 0x124 (PIN_OUTPUT | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */
+ 0x120 (PIN_OUTPUT | MUX_MODE2) /* mii1_txd0.rgmii1_td2 */
+ 0x11c (PIN_OUTPUT | MUX_MODE2) /* mii1_txd1.rgmii1_td3 */
+ 0x130 (PIN_INPUT | MUX_MODE2) /* mii1_rxclk.rmii1_rclk */
+ 0x118 (PIN_INPUT | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */
+ 0x140 (PIN_INPUT | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */
+ 0x13c (PIN_INPUT | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */
+ 0x138 (PIN_INPUT | MUX_MODE2) /* mii1_rxd0.rgmii1_rd2 */
+ 0x134 (PIN_INPUT | MUX_MODE2) /* mii1_rxd1.rgmii1_rd3 */
/* Slave 2 */
- 0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */
- 0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */
- 0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */
- 0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */
- 0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */
- 0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */
- 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */
- 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a1.rgmii2_rtcl */
- 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */
- 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */
- 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */
- 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */
+ 0x58 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a6.rgmii2_tclk */
+ 0x40 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a0.rgmii2_tctl */
+ 0x54 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a5.rgmii2_td0 */
+ 0x50 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a4.rgmii2_td1 */
+ 0x4c (PIN_OUTPUT | MUX_MODE2) /* gpmc_a3.rgmii2_td2 */
+ 0x48 (PIN_OUTPUT | MUX_MODE2) /* gpmc_a2.rgmii2_td3 */
+ 0x5c (PIN_INPUT | MUX_MODE2) /* gpmc_a7.rgmii2_rclk */
+ 0x44 (PIN_INPUT | MUX_MODE2) /* gpmc_a1.rgmii2_rtcl */
+ 0x6c (PIN_INPUT | MUX_MODE2) /* gpmc_a11.rgmii2_rd0 */
+ 0x68 (PIN_INPUT | MUX_MODE2) /* gpmc_a10.rgmii2_rd1 */
+ 0x64 (PIN_INPUT | MUX_MODE2) /* gpmc_a9.rgmii2_rd2 */
+ 0x60 (PIN_INPUT | MUX_MODE2) /* gpmc_a8.rgmii2_rd3 */
>;
};
@@ -251,8 +297,8 @@
davinci_mdio_default: davinci_mdio_default {
pinctrl-single,pins = <
/* MDIO */
- 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
- 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ 0x148 (PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ 0x14c (PIN_OUTPUT | MUX_MODE0) /* mdio_clk.mdio_clk */
>;
};
@@ -266,46 +312,46 @@
dss_pins: dss_pins {
pinctrl-single,pins = <
- 0x020 (PIN_OUTPUT_PULLUP | MUX_MODE1) /* gpmc ad 8 -> DSS DATA 23 */
- 0x024 (PIN_OUTPUT_PULLUP | MUX_MODE1)
- 0x028 (PIN_OUTPUT_PULLUP | MUX_MODE1)
- 0x02c (PIN_OUTPUT_PULLUP | MUX_MODE1)
- 0x030 (PIN_OUTPUT_PULLUP | MUX_MODE1)
- 0x034 (PIN_OUTPUT_PULLUP | MUX_MODE1)
- 0x038 (PIN_OUTPUT_PULLUP | MUX_MODE1)
- 0x03c (PIN_OUTPUT_PULLUP | MUX_MODE1) /* gpmc ad 15 -> DSS DATA 16 */
- 0x0a0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 0 */
- 0x0a4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0a8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0ac (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0b0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0b4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0b8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0bc (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0c0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0c4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0c8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0cc (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0d0 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0d4 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0d8 (PIN_OUTPUT_PULLUP | MUX_MODE0)
- 0x0dc (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS DATA 15 */
- 0x0e0 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS VSYNC */
- 0x0e4 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS HSYNC */
- 0x0e8 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS PCLK */
- 0x0ec (PIN_OUTPUT_PULLUP | MUX_MODE0) /* DSS AC BIAS EN */
+ 0x020 (PIN_OUTPUT | MUX_MODE1) /* gpmc ad 8 -> DSS DATA 23 */
+ 0x024 (PIN_OUTPUT | MUX_MODE1)
+ 0x028 (PIN_OUTPUT | MUX_MODE1)
+ 0x02c (PIN_OUTPUT | MUX_MODE1)
+ 0x030 (PIN_OUTPUT | MUX_MODE1)
+ 0x034 (PIN_OUTPUT | MUX_MODE1)
+ 0x038 (PIN_OUTPUT | MUX_MODE1)
+ 0x03c (PIN_OUTPUT | MUX_MODE1) /* gpmc ad 15 -> DSS DATA 16 */
+ 0x0a0 (PIN_OUTPUT | MUX_MODE0) /* DSS DATA 0 */
+ 0x0a4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0a8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0ac (PIN_OUTPUT | MUX_MODE0)
+ 0x0b0 (PIN_OUTPUT | MUX_MODE0)
+ 0x0b4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0b8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0bc (PIN_OUTPUT | MUX_MODE0)
+ 0x0c0 (PIN_OUTPUT | MUX_MODE0)
+ 0x0c4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0c8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0cc (PIN_OUTPUT | MUX_MODE0)
+ 0x0d0 (PIN_OUTPUT | MUX_MODE0)
+ 0x0d4 (PIN_OUTPUT | MUX_MODE0)
+ 0x0d8 (PIN_OUTPUT | MUX_MODE0)
+ 0x0dc (PIN_OUTPUT | MUX_MODE0) /* DSS DATA 15 */
+ 0x0e0 (PIN_OUTPUT | MUX_MODE0) /* DSS VSYNC */
+ 0x0e4 (PIN_OUTPUT | MUX_MODE0) /* DSS HSYNC */
+ 0x0e8 (PIN_OUTPUT | MUX_MODE0) /* DSS PCLK */
+ 0x0ec (PIN_OUTPUT | MUX_MODE0) /* DSS AC BIAS EN */
>;
};
qspi_pins: qspi_pins {
pinctrl-single,pins = <
- 0x7c (PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_csn0.qspi_csn */
- 0x88 (PIN_OUTPUT | MUX_MODE2) /* gpmc_csn3.qspi_clk */
- 0x90 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_advn_ale.qspi_d0 */
- 0x94 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_oen_ren.qspi_d1 */
- 0x98 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_wen.qspi_d2 */
- 0x9c (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_be0n_cle.qspi_d3 */
+ 0x7c (PIN_OUTPUT | MUX_MODE3) /* gpmc_csn0.qspi_csn */
+ 0x88 (PIN_OUTPUT | MUX_MODE2) /* gpmc_csn3.qspi_clk */
+ 0x90 (PIN_INPUT | MUX_MODE3) /* gpmc_advn_ale.qspi_d0 */
+ 0x94 (PIN_INPUT | MUX_MODE3) /* gpmc_oen_ren.qspi_d1 */
+ 0x98 (PIN_INPUT | MUX_MODE3) /* gpmc_wen.qspi_d2 */
+ 0x9c (PIN_INPUT | MUX_MODE3) /* gpmc_be0n_cle.qspi_d3 */
>;
};
@@ -323,6 +369,18 @@
0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpcm_ad7.gpio1_7 */
>;
};
+
+ usb1_pins: usb1_pins {
+ pinctrl-single,pins = <
+ 0x2c0 (PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
+ >;
+ };
+
+ usb2_pins: usb2_pins {
+ pinctrl-single,pins = <
+ 0x2c4 (PIN_OUTPUT | MUX_MODE0) /* usb0_drvvbus.usb0_drvvbus */
+ >;
+ };
};
&i2c0 {
@@ -386,6 +444,11 @@
regulator-always-on;
};
+ power-button {
+ compatible = "ti,tps65218-pwrbutton";
+ status = "okay";
+ interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
+ };
};
at24@50 {
@@ -479,6 +542,8 @@
&usb1 {
dr_mode = "peripheral";
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_pins>;
};
&usb2_phy2 {
@@ -488,6 +553,8 @@
&usb2 {
dr_mode = "host";
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_pins>;
};
&qspi {
@@ -610,3 +677,25 @@
&wdt {
status = "okay";
};
+
+&cpu {
+ cpu0-supply = <&dcdc2>;
+};
+
+&vpfe0 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe0_pins_default>;
+ pinctrl-1 = <&vpfe0_pins_sleep>;
+
+ /* Camera port */
+ port {
+ vpfe0_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts
index 662261d6b2ca..257c099c347e 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -243,6 +243,42 @@
0x08C (PIN_OUTPUT_PULLUP | MUX_MODE7)
>;
};
+
+ vpfe1_pins_default: vpfe1_pins_default {
+ pinctrl-single,pins = <
+ 0x1cc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data9 mode 0 */
+ 0x1d0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data8 mode 0 */
+ 0x1d4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_hd mode 0 */
+ 0x1d8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_vd mode 0 */
+ 0x1dc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_pclk mode 0 */
+ 0x1e8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data0 mode 0 */
+ 0x1ec (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data1 mode 0 */
+ 0x1f0 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data2 mode 0 */
+ 0x1f4 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data3 mode 0 */
+ 0x1f8 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data4 mode 0 */
+ 0x1fc (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data5 mode 0 */
+ 0x200 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data6 mode 0 */
+ 0x204 (PIN_INPUT_PULLUP | MUX_MODE0) /* cam1_data7 mode 0 */
+ >;
+ };
+
+ vpfe1_pins_sleep: vpfe1_pins_sleep {
+ pinctrl-single,pins = <
+ 0x1cc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1d0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1d4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1d8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1dc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1e8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1ec (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1f0 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1f4 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1f8 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x1fc (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x200 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ 0x204 (DS0_PULL_UP_DOWN_EN | INPUT_EN | MUX_MODE7)
+ >;
+ };
};
matrix_keypad: matrix_keypad@0 {
@@ -634,3 +670,20 @@
};
};
};
+
+&vpfe1 {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&vpfe1_pins_default>;
+ pinctrl-1 = <&vpfe1_pins_sleep>;
+
+ port {
+ vpfe1_ep: endpoint {
+ /* remote-endpoint = <&sensor>; add once we have it */
+ ti,am437x-vpfe-interface = <0>;
+ bus-width = <8>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts
index 49edbda68cd5..03750af3b49a 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
+++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
@@ -80,6 +80,28 @@
default-state = "off";
};
};
+
+ gpio_fan: gpio_fan {
+ /* Based on 5v 500mA AFB02505HHB */
+ compatible = "gpio-fan";
+ gpios = <&tps659038_gpio 1 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = <0 0>,
+ <13000 1>;
+ };
+
+ extcon_usb1: extcon_usb1 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio7 25 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&extcon_usb1_pins>;
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio7 24 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&extcon_usb2_pins>;
+ };
};
&dra7_pmx_core {
@@ -140,6 +162,86 @@
>;
};
+ cpsw_pins_default: cpsw_pins_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x250 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_tclk */
+ 0x254 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_tctl */
+ 0x258 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td3 */
+ 0x25c (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td2 */
+ 0x260 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td1 */
+ 0x264 (PIN_OUTPUT | MUX_MODE0) /* rgmii1_td0 */
+ 0x268 (PIN_INPUT | MUX_MODE0) /* rgmii1_rclk */
+ 0x26c (PIN_INPUT | MUX_MODE0) /* rgmii1_rctl */
+ 0x270 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd3 */
+ 0x274 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd2 */
+ 0x278 (PIN_INPUT | MUX_MODE0) /* rgmii1_rd1 */
+ 0x27c (PIN_INPUT | MUX_MODE0) /* rgmii1_rd0 */
+
+ /* Slave 2 */
+ 0x198 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_tclk */
+ 0x19c (PIN_OUTPUT | MUX_MODE3) /* rgmii2_tctl */
+ 0x1a0 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td3 */
+ 0x1a4 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td2 */
+ 0x1a8 (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td1 */
+ 0x1ac (PIN_OUTPUT | MUX_MODE3) /* rgmii2_td0 */
+ 0x1b0 (PIN_INPUT | MUX_MODE3) /* rgmii2_rclk */
+ 0x1b4 (PIN_INPUT | MUX_MODE3) /* rgmii2_rctl */
+ 0x1b8 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd3 */
+ 0x1bc (PIN_INPUT | MUX_MODE3) /* rgmii2_rd2 */
+ 0x1c0 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd1 */
+ 0x1c4 (PIN_INPUT | MUX_MODE3) /* rgmii2_rd0 */
+ >;
+
+ };
+
+ cpsw_pins_sleep: cpsw_pins_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ 0x250 (PIN_INPUT | MUX_MODE15)
+ 0x254 (PIN_INPUT | MUX_MODE15)
+ 0x258 (PIN_INPUT | MUX_MODE15)
+ 0x25c (PIN_INPUT | MUX_MODE15)
+ 0x260 (PIN_INPUT | MUX_MODE15)
+ 0x264 (PIN_INPUT | MUX_MODE15)
+ 0x268 (PIN_INPUT | MUX_MODE15)
+ 0x26c (PIN_INPUT | MUX_MODE15)
+ 0x270 (PIN_INPUT | MUX_MODE15)
+ 0x274 (PIN_INPUT | MUX_MODE15)
+ 0x278 (PIN_INPUT | MUX_MODE15)
+ 0x27c (PIN_INPUT | MUX_MODE15)
+
+ /* Slave 2 */
+ 0x198 (PIN_INPUT | MUX_MODE15)
+ 0x19c (PIN_INPUT | MUX_MODE15)
+ 0x1a0 (PIN_INPUT | MUX_MODE15)
+ 0x1a4 (PIN_INPUT | MUX_MODE15)
+ 0x1a8 (PIN_INPUT | MUX_MODE15)
+ 0x1ac (PIN_INPUT | MUX_MODE15)
+ 0x1b0 (PIN_INPUT | MUX_MODE15)
+ 0x1b4 (PIN_INPUT | MUX_MODE15)
+ 0x1b8 (PIN_INPUT | MUX_MODE15)
+ 0x1bc (PIN_INPUT | MUX_MODE15)
+ 0x1c0 (PIN_INPUT | MUX_MODE15)
+ 0x1c4 (PIN_INPUT | MUX_MODE15)
+ >;
+ };
+
+ davinci_mdio_pins_default: davinci_mdio_pins_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ 0x23c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_mclk */
+ 0x240 (PIN_INPUT_PULLUP | MUX_MODE0) /* mdio_d */
+ >;
+ };
+
+ davinci_mdio_pins_sleep: davinci_mdio_pins_sleep {
+ pinctrl-single,pins = <
+ 0x23c (PIN_INPUT | MUX_MODE15)
+ 0x240 (PIN_INPUT | MUX_MODE15)
+ >;
+ };
+
tps659038_pins_default: tps659038_pins_default {
pinctrl-single,pins = <
0x418 (PIN_INPUT_PULLUP | MUX_MODE14) /* wakeup0.gpio1_0 */
@@ -164,6 +266,17 @@
>;
};
+ extcon_usb1_pins: extcon_usb1_pins {
+ pinctrl-single,pins = <
+ 0x3ec (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_rtsn.gpio7_25 */
+ >;
+ };
+
+ extcon_usb2_pins: extcon_usb2_pins {
+ pinctrl-single,pins = <
+ 0x3e8 (PIN_INPUT_PULLUP | MUX_MODE14) /* uart1_ctsn.gpio7_24 */
+ >;
+ };
};
&i2c1 {
@@ -314,6 +427,12 @@
wakeup-source;
ti,palmas-long-press-seconds = <12>;
};
+
+ tps659038_gpio: tps659038_gpio {
+ compatible = "ti,palmas-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
};
tmp102: tmp102@48 {
@@ -365,6 +484,32 @@
pinctrl-0 = <&uart3_pins_default>;
};
+&mac {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_pins_default>;
+ pinctrl-1 = <&cpsw_pins_sleep>;
+ dual_emac;
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <2>;
+ phy-mode = "rgmii";
+ dual_emac_res_vlan = <2>;
+};
+
+&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_pins_default>;
+ pinctrl-1 = <&davinci_mdio_pins_sleep>;
+};
+
&mmc1 {
status = "okay";
@@ -403,3 +548,15 @@
pinctrl-names = "default";
pinctrl-0 = <&usb1_pins>;
};
+
+&omap_dwc3_1 {
+ extcon = <&extcon_usb1>;
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
+
+&usb2 {
+ dr_mode = "peripheral";
+};
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index 70b1943a86b1..e993c46bd472 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -8,9 +8,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index e1b0eb6b091f..b10ceb488efe 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -3,9 +3,43 @@
*
* Gregory CLEMENT <gregory.clement@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
index 1c83b7ce0982..3f8cc3845a5e 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -3,10 +3,43 @@
*
* Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
index 5fbfe02964dc..99eb8a014ac6 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -3,10 +3,43 @@
*
* Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index 394308951ed9..6ae36a38beb2 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -6,9 +6,43 @@
*
* Copyright (C) 2013 Florian Fainelli <florian@openwrt.org>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Note: this Device Tree assumes that the bootloader has remapped the
* internal registers to 0xf1000000 (instead of the default
diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
index 70fecde76ccb..59f74e66963f 100644
--- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts
+++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
@@ -3,10 +3,43 @@
*
* Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Note: this Device Tree assumes that the bootloader has remapped the
* internal registers to 0xf1000000 (instead of the old 0xd0000000).
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 1af428602748..8a322ad57e5f 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -8,9 +8,43 @@
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
* Ben Dooks <ben.dooks@codethink.co.uk>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* This file contains the definitions that are common to the Armada
* 370 and Armada XP SoC.
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index fdb3c12a6139..27397f151def 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -7,9 +7,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Contains definitions specific to the Armada 370 SoC that are not
* common to all Armada SoCs.
diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts
index 929ae00b4063..0440891425c0 100644
--- a/arch/arm/boot/dts/armada-375-db.dts
+++ b/arch/arm/boot/dts/armada-375-db.dts
@@ -7,9 +7,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
index 50096d3427eb..ba3c57e0af72 100644
--- a/arch/arm/boot/dts/armada-375.dtsi
+++ b/arch/arm/boot/dts/armada-375.dtsi
@@ -6,9 +6,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
#include "skeleton.dtsi"
@@ -63,7 +97,7 @@
};
soc {
- compatible = "marvell,armada375-mbus", "marvell,armada370-mbus", "simple-bus";
+ compatible = "marvell,armada375-mbus", "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
controller = <&mbusc>;
diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi
index 4173a8ab34e7..5102d19cc8f4 100644
--- a/arch/arm/boot/dts/armada-380.dtsi
+++ b/arch/arm/boot/dts/armada-380.dtsi
@@ -7,9 +7,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
#include "armada-38x.dtsi"
@@ -32,9 +66,8 @@
soc {
internal-regs {
- pinctrl {
+ pinctrl@18000 {
compatible = "marvell,mv88f6810-pinctrl";
- reg = <0x18000 0x20>;
};
};
diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts
new file mode 100644
index 000000000000..57b9119fb3e0
--- /dev/null
+++ b/arch/arm/boot/dts/armada-385-db-ap.dts
@@ -0,0 +1,178 @@
+/*
+ * Device Tree file for Marvell Armada 385 Access Point Development board
+ * (DB-88F6820-AP)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Nadav Haklai <nadavh@marvell.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-385.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Marvell Armada 385 Access Point Development Board";
+ compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada38x";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>; /* 2GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi1: spi@10680 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <54000000>;
+ };
+ };
+
+ i2c0: i2c@11000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+
+ /*
+ * This bus is wired to two EEPROM
+ * sockets, one of which holding the
+ * board ID used by the bootloader.
+ * Erasing this EEPROM's content will
+ * brick the board.
+ * Use this bus with caution.
+ */
+ };
+
+ mdio@72004 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy1: ethernet-phy@4 {
+ reg = <4>;
+ };
+
+ phy2: ethernet-phy@6 {
+ reg = <6>;
+ };
+ };
+
+ /* UART0 is exposed through the JP8 connector */
+ uart0: serial@12000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+ };
+
+ /*
+ * UART1 is exposed through a FTDI chip
+ * wired to the mini-USB connector
+ */
+ uart1: serial@12100 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+ };
+
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy2>;
+ phy-mode = "sgmii";
+ };
+
+ ethernet@34000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "sgmii";
+ };
+
+ ethernet@70000 {
+ pinctrl-names = "default";
+
+ /*
+ * The Reference Clock 0 is used to
+ * provide a clock to the PHY
+ */
+ pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+
+ /*
+ * The three PCIe units are accessible through
+ * standard mini-PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+
+ pcie@3,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-385-rd.dts b/arch/arm/boot/dts/armada-385-rd.dts
deleted file mode 100644
index aaca2861dc87..000000000000
--- a/arch/arm/boot/dts/armada-385-rd.dts
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Device Tree file for Marvell Armada 385 Reference Design board
- * (RD-88F6820-AP)
- *
- * Copyright (C) 2014 Marvell
- *
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-/dts-v1/;
-#include "armada-385.dtsi"
-
-/ {
- model = "Marvell Armada 385 Reference Design";
- compatible = "marvell,a385-rd", "marvell,armada385", "marvell,armada380";
-
- chosen {
- bootargs = "console=ttyS0,115200 earlyprintk";
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>; /* 256 MB */
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
-
- internal-regs {
- spi@10600 {
- status = "okay";
-
- spi-flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,m25p128";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <108000000>;
- };
- };
-
- i2c@11000 {
- status = "okay";
- clock-frequency = <100000>;
- };
-
- serial@12000 {
- status = "okay";
- };
-
- ethernet@30000 {
- status = "okay";
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- };
-
- ethernet@70000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "rgmii-id";
- };
-
-
- mdio {
- phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
- };
-
- usb3@f0000 {
- status = "okay";
- };
- };
-
- pcie-controller {
- status = "okay";
- /*
- * One PCIe units is accessible through
- * standard PCIe slot on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
index 6283d7912f71..8e67d2c083dd 100644
--- a/arch/arm/boot/dts/armada-385.dtsi
+++ b/arch/arm/boot/dts/armada-385.dtsi
@@ -7,9 +7,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
#include "armada-38x.dtsi"
@@ -37,9 +71,8 @@
soc {
internal-regs {
- pinctrl {
+ pinctrl@18000 {
compatible = "marvell,mv88f6820-pinctrl";
- reg = <0x18000 0x20>;
};
};
diff --git a/arch/arm/boot/dts/armada-385-db.dts b/arch/arm/boot/dts/armada-388-db.dts
index 2aaa9d2ac284..16512efcd32c 100644
--- a/arch/arm/boot/dts/armada-385-db.dts
+++ b/arch/arm/boot/dts/armada-388-db.dts
@@ -1,22 +1,57 @@
/*
- * Device Tree file for Marvell Armada 385 evaluation board
+ * Device Tree file for Marvell Armada 388 evaluation board
* (DB-88F6820)
*
* Copyright (C) 2014 Marvell
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
-#include "armada-385.dtsi"
+#include "armada-388.dtsi"
/ {
model = "Marvell Armada 385 Development Board";
- compatible = "marvell,a385-db", "marvell,armada385", "marvell,armada380";
+ compatible = "marvell,a385-db", "marvell,armada388",
+ "marvell,armada385", "marvell,armada380";
chosen {
bootargs = "console=ttyS0,115200 earlyprintk";
@@ -74,7 +109,7 @@
phy-mode = "rgmii-id";
};
- mdio {
+ mdio@72004 {
phy0: ethernet-phy@0 {
reg = <0>;
};
diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts
new file mode 100644
index 000000000000..590b383db323
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388-gp.dts
@@ -0,0 +1,414 @@
+/*
+ * Device Tree file for Marvell Armada 385 development board
+ * (RD-88F6820-GP)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Marvell Armada 385 GP";
+ compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>; /* 2 GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi@10600 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <50000000>;
+ m25p,fast-read;
+ };
+ };
+
+ i2c@11000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+ clock-frequency = <100000>;
+ /*
+ * The EEPROM located at adresse 54 is needed
+ * for the boot - DO NOT ERASE IT -
+ */
+
+ expander0: pca9555@20 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pca0_pins>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x20>;
+ };
+
+ expander1: pca9555@21 {
+ compatible = "nxp,pca9555";
+ pinctrl-names = "default";
+ interrupt-parent = <&gpio0>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x21>;
+ };
+
+ };
+
+ serial@12000 {
+ /*
+ * Exported on the micro USB connector CON16
+ * through an FTDI
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+ };
+
+ /* GE1 CON15 */
+ ethernet@30000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ge1_rgmii_pins>;
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+ /* CON4 */
+ usb@50000 {
+ vcc-supply = <&reg_usb2_0_vbus>;
+ status = "okay";
+ };
+
+ /* GE0 CON1 */
+ ethernet@70000 {
+ pinctrl-names = "default";
+ /*
+ * The Reference Clock 0 is used to provide a
+ * clock to the PHY
+ */
+ pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+
+ mdio@72004 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ sata@a8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata0_pins>, <&sata1_pins>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata0: sata-port@0 {
+ reg = <0>;
+ target-supply = <&reg_5v_sata0>;
+ };
+
+ sata1: sata-port@1 {
+ reg = <1>;
+ target-supply = <&reg_5v_sata1>;
+ };
+ };
+
+ sata@e0000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata2_pins>, <&sata3_pins>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sata2: sata-port@0 {
+ reg = <0>;
+ target-supply = <&reg_5v_sata2>;
+ };
+
+ sata3: sata-port@1 {
+ reg = <1>;
+ target-supply = <&reg_5v_sata3>;
+ };
+ };
+
+ sdhci@d8000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhci_pins>;
+ cd-gpios = <&expander0 5 GPIO_ACTIVE_LOW>;
+ no-1-8-v;
+ wp-inverted;
+ bus-width = <8>;
+ status = "okay";
+ };
+
+ /* CON5 */
+ usb3@f0000 {
+ vcc-supply = <&reg_usb2_1_vbus>;
+ status = "okay";
+ };
+
+ /* CON7 */
+ usb3@f8000 {
+ vcc-supply = <&reg_usb3_vbus>;
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * One PCIe units is accessible through
+ * standard PCIe slot on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /*
+ * The two other PCIe units are accessible
+ * through mini PCIe slot on the board.
+ */
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+ pcie@3,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ gpio-fan {
+ compatible = "gpio-fan";
+ gpios = <&expander1 3 GPIO_ACTIVE_HIGH>;
+ gpio-fan,speed-map = < 0 0
+ 3000 1>;
+ };
+ };
+
+ reg_usb3_vbus: usb3-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb3-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander1 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_0_vbus: v5-vbus0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander1 14 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_1_vbus: v5-vbus1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_usb2_1_vbus: v5-vbus1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_sata0: pwr-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata0";
+ enable-active-high;
+ regulator-always-on;
+
+ };
+
+ reg_5v_sata0: v5-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata0>;
+ };
+
+ reg_12v_sata0: v12-sata0 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata0>;
+ };
+
+ reg_sata1: pwr-sata1 {
+ regulator-name = "pwr_en_sata1";
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata1: v5-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata1>;
+ };
+
+ reg_12v_sata1: v12-sata1 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata1";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata1>;
+ };
+
+ reg_sata2: pwr-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata2";
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata2: v5-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata2>;
+ };
+
+ reg_12v_sata2: v12-sata2 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata2";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata2>;
+ };
+
+ reg_sata3: pwr-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "pwr_en_sata3";
+ enable-active-high;
+ regulator-always-on;
+ gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_5v_sata3: v5-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "v5.0-sata3";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata3>;
+ };
+
+ reg_12v_sata3: v12-sata3 {
+ compatible = "regulator-fixed";
+ regulator-name = "v12.0-sata3";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ vin-supply = <&reg_sata3>;
+ };
+};
+
+&pinctrl {
+ pca0_pins: pca0_pins {
+ marvell,pins = "mpp18";
+ marvell,function = "gpio";
+ };
+};
diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts
new file mode 100644
index 000000000000..d99baac72081
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388-rd.dts
@@ -0,0 +1,132 @@
+/*
+ * Device Tree file for Marvell Armada 388 Reference Design board
+ * (RD-88F6820-AP)
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+
+/ {
+ model = "Marvell Armada 385 Reference Design";
+ compatible = "marvell,a385-rd", "marvell,armada388",
+ "marvell,armada385","marvell,armada380";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>; /* 256 MB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+ internal-regs {
+ spi@10600 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p128";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+ };
+
+ i2c@11000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ serial@12000 {
+ status = "okay";
+ };
+
+ ethernet@30000 {
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+ };
+
+ ethernet@70000 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "rgmii-id";
+ };
+
+
+ mdio@72004 {
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
+
+ usb3@f0000 {
+ status = "okay";
+ };
+ };
+
+ pcie-controller {
+ status = "okay";
+ /*
+ * One PCIe units is accessible through
+ * standard PCIe slot on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-388.dtsi b/arch/arm/boot/dts/armada-388.dtsi
new file mode 100644
index 000000000000..564fa5937e25
--- /dev/null
+++ b/arch/arm/boot/dts/armada-388.dtsi
@@ -0,0 +1,70 @@
+/*
+ * Device Tree Include file for Marvell Armada 388 SoC.
+ *
+ * Copyright (C) 2015 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * The main difference with the Armada 385 is that the 388 can handle two more
+ * SATA ports. So we can reuse the dtsi of the Armada 385, override the pinctrl
+ * property and the name of the SoC, and add the second SATA host which control
+ * the 2 other ports.
+ */
+
+#include "armada-385.dtsi"
+
+/ {
+ model = "Marvell Armada 388 family SoC";
+ compatible = "marvell,armada388", "marvell,armada385",
+ "marvell,armada380";
+
+ soc {
+ internal-regs {
+ pinctrl@18000 {
+ compatible = "marvell,mv88f6828-pinctrl";
+ };
+
+ sata@e0000 {
+ compatible = "marvell,armada-380-ahci";
+ reg = <0xe0000 0x2000>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gateclk 30>;
+ status = "disabled";
+ };
+
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index 2a9f4caac643..1dff30a81e24 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -7,9 +7,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
#include "skeleton.dtsi"
@@ -31,8 +65,7 @@
};
soc {
- compatible = "marvell,armada380-mbus", "marvell,armada370-mbus",
- "simple-bus";
+ compatible = "marvell,armada380-mbus", "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
controller = <&mbusc>;
@@ -173,7 +206,7 @@
status = "disabled";
};
- serial@12000 {
+ uart0: serial@12000 {
compatible = "snps,dw-apb-uart";
reg = <0x12000 0x100>;
reg-shift = <2>;
@@ -193,9 +226,94 @@
status = "disabled";
};
- pinctrl {
- compatible = "marvell,mv88f6820-pinctrl";
+ pinctrl: pinctrl@18000 {
reg = <0x18000 0x20>;
+
+ ge0_rgmii_pins: ge-rgmii-pins-0 {
+ marvell,pins = "mpp6", "mpp7", "mpp8",
+ "mpp9", "mpp10", "mpp11",
+ "mpp12", "mpp13", "mpp14",
+ "mpp15", "mpp16", "mpp17";
+ marvell,function = "ge0";
+ };
+
+ ge1_rgmii_pins: ge-rgmii-pins-1 {
+ marvell,pins = "mpp21", "mpp27", "mpp28",
+ "mpp29", "mpp30", "mpp31",
+ "mpp32", "mpp37", "mpp38",
+ "mpp39", "mpp40", "mpp41";
+ marvell,function = "ge1";
+ };
+
+ i2c0_pins: i2c-pins-0 {
+ marvell,pins = "mpp2", "mpp3";
+ marvell,function = "i2c0";
+ };
+
+ mdio_pins: mdio-pins {
+ marvell,pins = "mpp4", "mpp5";
+ marvell,function = "ge";
+ };
+
+ ref_clk0_pins: ref-clk-pins-0 {
+ marvell,pins = "mpp45";
+ marvell,function = "ref";
+ };
+
+ ref_clk1_pins: ref-clk-pins-1 {
+ marvell,pins = "mpp46";
+ marvell,function = "ref";
+ };
+
+ spi0_pins: spi-pins-0 {
+ marvell,pins = "mpp22", "mpp23", "mpp24",
+ "mpp25";
+ marvell,function = "spi0";
+ };
+
+ spi1_pins: spi-pins-1 {
+ marvell,pins = "mpp56", "mpp57", "mpp58",
+ "mpp59";
+ marvell,function = "spi1";
+ };
+
+ uart0_pins: uart-pins-0 {
+ marvell,pins = "mpp0", "mpp1";
+ marvell,function = "ua0";
+ };
+
+ uart1_pins: uart-pins-1 {
+ marvell,pins = "mpp19", "mpp20";
+ marvell,function = "ua1";
+ };
+
+ sdhci_pins: sdhci-pins {
+ marvell,pins = "mpp48", "mpp49", "mpp50",
+ "mpp52", "mpp53", "mpp54",
+ "mpp55", "mpp57", "mpp58",
+ "mpp59";
+ marvell,function = "sd0";
+ };
+
+ sata0_pins: sata-pins-0 {
+ marvell,pins = "mpp20";
+ marvell,function = "sata0";
+ };
+
+ sata1_pins: sata-pins-1 {
+ marvell,pins = "mpp19";
+ marvell,function = "sata1";
+ };
+
+ sata2_pins: sata-pins-2 {
+ marvell,pins = "mpp47";
+ marvell,function = "sata2";
+ };
+
+ sata3_pins: sata-pins-3 {
+ marvell,pins = "mpp44";
+ marvell,function = "sata3";
+ };
};
gpio0: gpio@18100 {
@@ -373,7 +491,7 @@
status = "disabled";
};
- mdio {
+ mdio@72004 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
diff --git a/arch/arm/boot/dts/armada-xp-axpwifiap.dts b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
index ca0200e20751..c1fbab243609 100644
--- a/arch/arm/boot/dts/armada-xp-axpwifiap.dts
+++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
@@ -3,16 +3,50 @@
*
* Note: this board is shipped with a new generation boot loader that
* remaps internal registers at 0xf1000000. Therefore, if earlyprintk
- * is used, the CONFIG_DEBUG_MVEBU_UART_ALTERNATE option should be
- * used.
+ * is used, the CONFIG_DEBUG_MVEBU_UART0_ALTERNATE option or the
+ * CONFIG_DEBUG_MVEBU_UART1_ALTERNATE option should be used.
*
* Copyright (C) 2013 Marvell
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
@@ -60,10 +94,12 @@
};
internal-regs {
+ /* UART0 */
serial@12000 {
status = "okay";
};
+ /* UART1 */
serial@12100 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index 42ddb2864365..48bdafe17526 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -8,9 +8,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Note: this Device Tree assumes that the bootloader has remapped the
* internal registers to 0xf1000000 (instead of the default
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index ea8673647494..206aebba01be 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -8,9 +8,43 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Note: this Device Tree assumes that the bootloader has remapped the
* internal registers to 0xf1000000 (instead of the default
diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
index a2ef93c1eb10..5fb3c8b687cf 100644
--- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
+++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
@@ -3,10 +3,43 @@
*
* Copyright (C) 2014, Benoit Masson <yahoo@perenite.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts
index 7e291e2ef4b3..56f958eb1ede 100644
--- a/arch/arm/boot/dts/armada-xp-matrix.dts
+++ b/arch/arm/boot/dts/armada-xp-matrix.dts
@@ -5,9 +5,43 @@
*
* Lior Amsalem <alior@marvell.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
index 281ccd24295c..6e6d0f04bf2b 100644
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -5,9 +5,43 @@
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Contains definitions specific to the Armada XP MV78230 SoC that are not
* common to all Armada XP SoCs.
diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
index d7a8d0b0f385..4a7cbed79b07 100644
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -5,9 +5,43 @@
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Contains definitions specific to the Armada XP MV78260 SoC that are not
* common to all Armada XP SoCs.
diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
index 9c40c130d11a..36ce63a96cc9 100644
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -5,9 +5,43 @@
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Contains definitions specific to the Armada XP MV78460 SoC that are not
* common to all Armada XP SoCs.
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
index fc8bdfcd2348..99cb9a8401b4 100644
--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -3,10 +3,43 @@
*
* Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index 6f6b0916df48..0c76d9f05fd0 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -5,9 +5,43 @@
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/armada-xp-synology-ds414.dts b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
index 749fdba5a642..e9fb225169aa 100644
--- a/arch/arm/boot/dts/armada-xp-synology-ds414.dts
+++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
@@ -3,10 +3,43 @@
*
* Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Note: this Device Tree assumes that the bootloader has remapped the
* internal registers to 0xf1000000 (instead of the old 0xd0000000).
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 62c3ba958b39..82917236a2fb 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -8,9 +8,43 @@
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
* Ben Dooks <ben.dooks@codethink.co.uk>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*
* Contains definitions specific to the Armada XP SoC that are not
* common to all Armada SoCs.
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index 6c97d4af61ee..21c2b504f977 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -66,6 +66,11 @@
};
};
+ sram: sram@00200000 {
+ compatible = "mmio-sram";
+ reg = <0x00200000 0x4000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -356,6 +361,13 @@
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
};
+ rtc: rtc@fffffe00 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffe00 0x40>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
tcb0: timer@fffa0000 {
compatible = "atmel,at91rm9200-tcb";
reg = <0xfffa0000 0x100>;
diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts
index 43eb779dd6f6..2a5d21247d7e 100644
--- a/arch/arm/boot/dts/at91rm9200ek.dts
+++ b/arch/arm/boot/dts/at91rm9200ek.dts
@@ -77,6 +77,10 @@
dbgu: serial@fffff200 {
status = "okay";
};
+
+ rtc: rtc@fffffe00 {
+ status = "okay";
+ };
};
usb0: ohci@00300000 {
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index dd1313cbc314..fff0ee69aab4 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -69,6 +69,11 @@
};
};
+ sram0: sram@002ff000 {
+ compatible = "mmio-sram";
+ reg = <0x002ff000 0x2000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
index cdb9ed612109..e247b0b5fdab 100644
--- a/arch/arm/boot/dts/at91sam9261.dtsi
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -60,6 +60,11 @@
};
};
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x28000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index e8c6c600a5b6..1f67bb4c144e 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -62,6 +62,16 @@
};
};
+ sram0: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x14000>;
+ };
+
+ sram1: sram@00500000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x4000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -294,7 +304,7 @@
reg = <17>;
};
- ac91_clk: ac97_clk {
+ ac97_clk: ac97_clk {
#clock-cells = <0>;
reg = <18>;
};
@@ -685,6 +695,16 @@
};
};
+ ac97 {
+ pinctrl_ac97: ac97-0 {
+ atmel,pins =
+ <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB12 periph A AC97FS pin */
+ AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB13 periph A AC97CK pin */
+ AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE /* PB14 periph A AC97TX pin */
+ AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB14 periph A AC97RX pin */
+ };
+ };
+
pioA: gpio@fffff200 {
compatible = "atmel,at91rm9200-gpio";
reg = <0xfffff200 0x200>;
@@ -813,6 +833,17 @@
status = "disabled";
};
+ ac97: sound@fffa0000 {
+ compatible = "atmel,at91sam9263-ac97c";
+ reg = <0xfffa0000 0x4000>;
+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ac97>;
+ clocks = <&ac97_clk>;
+ clock-names = "ac97_clk";
+ status = "disabled";
+ };
+
macb0: ethernet@fffbc000 {
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xfffbc000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
index a50ee587a7af..f59301618163 100644
--- a/arch/arm/boot/dts/at91sam9g20.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -16,6 +16,15 @@
reg = <0x20000000 0x08000000>;
};
+ sram0: sram@002ff000 {
+ status = "disabled";
+ };
+
+ sram1: sram@002fc000 {
+ compatible = "mmio-sram";
+ reg = <0x002fc000 0x8000>;
+ };
+
ahb {
apb {
i2c0: i2c@fffac000 {
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 2a8da8a884b4..ee80aa9c0759 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -74,6 +74,11 @@
};
};
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x10000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -1287,7 +1292,6 @@
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00700000 0x100000>;
interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
- //TODO
clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck";
status = "disabled";
@@ -1297,7 +1301,6 @@
compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
reg = <0x00800000 0x100000>;
interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
- //TODO
clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
clock-names = "usb_clk", "ehci_clk", "hclk", "uhpck";
status = "disabled";
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 68eb9aded164..c2666a7cb5b1 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -64,6 +64,11 @@
};
};
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x8000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -893,6 +898,13 @@
status = "disabled";
};
+ rtc@fffffeb0 {
+ compatible = "atmel,at91rm9200-rtc";
+ reg = <0xfffffeb0 0x40>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ status = "disabled";
+ };
+
pwm0: pwm@f8034000 {
compatible = "atmel,at91sam9rl-pwm";
reg = <0xf8034000 0x300>;
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
index 13bb24ea971a..9575c0d895c9 100644
--- a/arch/arm/boot/dts/at91sam9n12ek.dts
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -54,7 +54,7 @@
status = "okay";
wm8904: codec@1a {
- compatible = "wm8904";
+ compatible = "wlf,wm8904";
reg = <0x1a>;
clocks = <&pck0>;
clock-names = "mclk";
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
index 72424371413e..40f645b8fe25 100644
--- a/arch/arm/boot/dts/at91sam9rl.dtsi
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -70,6 +70,11 @@
};
};
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x10000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index bbb3ba65165f..818dabdd8c0e 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -72,6 +72,11 @@
};
};
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x8000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
index 3a9f6fa4a36a..bd16bd360272 100644
--- a/arch/arm/boot/dts/at91sam9x5ek.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -53,6 +53,8 @@
};
usb2: gadget@f803c000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_board_usb2>;
atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
status = "okay";
};
@@ -80,6 +82,13 @@
<AT91_PIOD 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD14 gpio CD pin pull up and deglitch */
};
};
+
+ usb2 {
+ pinctrl_board_usb2: usb2-board {
+ atmel,pins =
+ <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PB16 gpio vbus sense, deglitch */
+ };
+ };
};
spi0: spi@f0000000 {
diff --git a/arch/arm/boot/dts/at91sam9xe.dtsi b/arch/arm/boot/dts/at91sam9xe.dtsi
new file mode 100644
index 000000000000..0278f63b2daf
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9xe.dtsi
@@ -0,0 +1,60 @@
+/*
+ * at91sam9xe.dtsi - Device Tree Include file for AT91SAM9XE family SoC
+ *
+ * Copyright (C) 2015 Atmel,
+ * 2015 Alexandre Belloni <alexandre.Belloni@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "at91sam9260.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9XE family SoC";
+ compatible = "atmel,at91sam9xe", "atmel,at91sam9260";
+
+ sram0: sram@002ff000 {
+ status = "disabled";
+ };
+
+ sram1: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x4000>;
+ };
+};
diff --git a/arch/arm/boot/dts/atlas7-evb.dts b/arch/arm/boot/dts/atlas7-evb.dts
new file mode 100644
index 000000000000..49cf59a95572
--- /dev/null
+++ b/arch/arm/boot/dts/atlas7-evb.dts
@@ -0,0 +1,110 @@
+/*
+ * DTS file for CSR SiRFatlas7 Evaluation Board
+ *
+ * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+/include/ "atlas7.dtsi"
+
+/ {
+ model = "CSR SiRFatlas7 Evaluation Board";
+ compatible = "sirf,atlas7-cb", "sirf,atlas7";
+
+ chosen {
+ bootargs = "console=ttySiRF1,115200 earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0x20000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ vpp_reserved: vpp_mem@5e800000 {
+ compatible = "sirf,reserved-memory";
+ reg = <0x5e800000 0x800000>;
+ };
+
+ nanddisk_reserved: nanddisk@46000000 {
+ reg = <0x46000000 0x200000>;
+ no-map;
+ };
+ };
+
+
+ noc {
+ mediam {
+ nand@17050000 {
+ memory-region = <&nanddisk_reserved>;
+ };
+ };
+
+ gnssm {
+ spi1: spi@18200000 {
+ status = "okay";
+ spiflash: macronix@0{
+ status = "okay";
+ compatible = "macronix,mx25l6405d";
+ reg = <0>;
+ spi-max-frequency = <37500000>;
+ spi-cpha;
+ spi-cpol;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partitions@0 {
+ label = "myspiboot";
+ reg = <0x0 0x800000>;
+ };
+ };
+ };
+ };
+
+ btm {
+ uart6: uart@11000000 {
+ status = "okay";
+ sirf,uart-has-rtscts;
+ };
+ };
+
+ disp-iobg {
+ vpp@13110000 {
+ memory-region = <&vpp_reserved>;
+ };
+ };
+
+ display0: display@0 {
+ compatible = "lvds-panel";
+ source = "lvds.0";
+
+ bl-gpios = <&gpio_1 63 0>;
+ data-lines = <24>;
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: timing0 {
+ clock-frequency = <60000000>;
+ hactive = <1024>;
+ vactive = <600>;
+ hfront-porch = <220>;
+ hback-porch = <100>;
+ hsync-len = <1>;
+ vback-porch = <10>;
+ vfront-porch = <25>;
+ vsync-len = <1>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/atlas7.dtsi b/arch/arm/boot/dts/atlas7.dtsi
new file mode 100644
index 000000000000..a753178abc85
--- /dev/null
+++ b/arch/arm/boot/dts/atlas7.dtsi
@@ -0,0 +1,813 @@
+/*
+ * DTS file for CSR SiRFatlas7 SoC
+ *
+ * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+/ {
+ compatible = "sirf,atlas7";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ serial6 = &uart6;
+ serial9 = &usp2;
+ };
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0>;
+ };
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <1>;
+ };
+ };
+
+ noc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10000000 0x10000000 0xc0000000>;
+
+ gic: interrupt-controller@10301000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x10301000 0x1000>,
+ <0x10302000 0x0100>;
+ };
+
+ pmu_regulator: pmu_regulator@10E30020 {
+ compatible = "sirf,atlas7-pmu-ldo";
+ reg = <0x10E30020 0x4>;
+ ldo: ldo {
+ regulator-name = "ldo";
+ };
+ };
+
+ atlas7_codec: atlas7_codec@10E30000 {
+ #sound-dai-cells = <0>;
+ compatible = "sirf,atlas7-codec";
+ reg = <0x10E30000 0x400>;
+ clocks = <&car 62>;
+ ldo-supply = <&ldo>;
+ };
+
+ atlas7_iacc: atlas7_iacc@10D01000 {
+ #sound-dai-cells = <0>;
+ compatible = "sirf,atlas7-iacc";
+ reg = <0x10D01000 0x100>;
+ dmas = <&dmac3 0>, <&dmac3 7>, <&dmac3 8>,
+ <&dmac3 3>, <&dmac3 9>;
+ dma-names = "rx", "tx0", "tx1", "tx2", "tx3";
+ clocks = <&car 62>;
+ };
+
+ ipc@13240000 {
+ compatible = "sirf,atlas7-ipc";
+ ranges = <0x13240000 0x13240000 0x00010000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ hwspinlock {
+ compatible = "sirf,hwspinlock";
+ reg = <0x13240000 0x00010000>;
+
+ num-spinlocks = <30>;
+ };
+
+ ns_m3_rproc@0 {
+ compatible = "sirf,ns2m30-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 123 0>;
+ };
+
+ ns_m3_rproc@1 {
+ compatible = "sirf,ns2m31-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 126 0>;
+ };
+
+ ns_kal_rproc@0 {
+ compatible = "sirf,ns2kal0-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 124 0>;
+ };
+
+ ns_kal_rproc@1 {
+ compatible = "sirf,ns2kal1-rproc";
+ reg = <0x13240000 0x00010000>;
+ interrupts = <0 127 0>;
+ };
+ };
+
+ pinctrl: ioc@18880000 {
+ compatible = "sirf,atlas7-ioc";
+ reg = <0x18880000 0x1000>,
+ <0x10E40000 0x1000>;
+ };
+
+ pmipc {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13240000 0x13240000 0x00010000>;
+ pmipc@0x13240000 {
+ compatible = "sirf,atlas7-pmipc";
+ reg = <0x13240000 0x00010000>;
+ };
+ };
+
+ dramfw {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10830000 0x10830000 0x18000>;
+ dramfw@10820000 {
+ compatible = "sirf,nocfw-dramfw";
+ reg = <0x10830000 0x18000>;
+ };
+ };
+
+ spramfw {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10250000 0x10250000 0x3000>;
+ spramfw@10820000 {
+ compatible = "sirf,nocfw-spramfw";
+ reg = <0x10250000 0x3000>;
+ };
+ };
+
+ cpum {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10200000 0x10200000 0x3000>;
+ cpum@10200000 {
+ compatible = "sirf,nocfw-cpum";
+ reg = <0x10200000 0x3000>;
+ };
+ };
+
+ cgum {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x18641000 0x18641000 0x3000>,
+ <0x18620000 0x18620000 0x1000>;
+
+ cgum@18641000 {
+ compatible = "sirf,nocfw-cgum";
+ reg = <0x18641000 0x3000>;
+ };
+
+ car: clock-controller@18620000 {
+ compatible = "sirf,atlas7-car";
+ reg = <0x18620000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+
+ gnssm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x18000000 0x18000000 0x0000ffff>,
+ <0x18010000 0x18010000 0x1000>,
+ <0x18020000 0x18020000 0x1000>,
+ <0x18030000 0x18030000 0x1000>,
+ <0x18040000 0x18040000 0x1000>,
+ <0x18050000 0x18050000 0x1000>,
+ <0x18060000 0x18060000 0x1000>,
+ <0x18100000 0x18100000 0x3000>,
+ <0x18250000 0x18250000 0x10000>,
+ <0x18200000 0x18200000 0x1000>;
+
+ dmac0: dma-controller@18000000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x18000000 0x1000>;
+ interrupts = <0 12 0>;
+ clocks = <&car 89>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+
+ gnssmfw@0x18100000 {
+ compatible = "sirf,nocfw-gnssm";
+ reg = <0x18100000 0x3000>;
+ };
+
+ uart0: uart@18010000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18010000 0x1000>;
+ interrupts = <0 17 0>;
+ clocks = <&car 90>;
+ fifosize = <128>;
+ dmas = <&dmac0 3>, <&dmac0 2>;
+ dma-names = "rx", "tx";
+ };
+
+ uart1: uart@18020000 {
+ cell-index = <1>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18020000 0x1000>;
+ interrupts = <0 18 0>;
+ clocks = <&car 88>;
+ fifosize = <32>;
+ };
+
+ uart2: uart@18030000 {
+ cell-index = <2>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18030000 0x1000>;
+ interrupts = <0 19 0>;
+ clocks = <&car 91>;
+ fifosize = <128>;
+ dmas = <&dmac0 6>, <&dmac0 7>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ uart3: uart@18040000 {
+ cell-index = <3>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18040000 0x1000>;
+ interrupts = <0 66 0>;
+ clocks = <&car 92>;
+ fifosize = <128>;
+ dmas = <&dmac0 4>, <&dmac0 5>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ uart4: uart@18050000 {
+ cell-index = <4>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18050000 0x1000>;
+ interrupts = <0 69 0>;
+ clocks = <&car 93>;
+ fifosize = <128>;
+ dmas = <&dmac0 0>, <&dmac0 1>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ uart5: uart@18060000 {
+ cell-index = <5>;
+ compatible = "sirf,atlas7-uart";
+ reg = <0x18060000 0x1000>;
+ interrupts = <0 71 0>;
+ clocks = <&car 94>;
+ fifosize = <128>;
+ dmas = <&dmac0 8>, <&dmac0 9>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ dspub@18250000 {
+ compatible = "dx,cc44p";
+ reg = <0x18250000 0x10000>;
+ interrupts = <0 27 0>;
+ };
+
+ spi1: spi@18200000 {
+ compatible = "sirf,prima2-spi";
+ reg = <0x18200000 0x1000>;
+ interrupts = <0 16 0>;
+ clocks = <&car 95>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac0 12>, <&dmac0 13>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+ };
+
+
+ gpum {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13000000 0x13000000 0x3000>;
+ gpum@0x13000000 {
+ compatible = "sirf,nocfw-gpum";
+ reg = <0x13000000 0x3000>;
+ };
+ };
+
+ mediam {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x16000000 0x16000000 0x00200000>,
+ <0x17020000 0x17020000 0x1000>,
+ <0x17030000 0x17030000 0x1000>,
+ <0x17040000 0x17040000 0x1000>,
+ <0x17050000 0x17050000 0x10000>,
+ <0x17060000 0x17060000 0x200>,
+ <0x17060200 0x17060200 0x100>,
+ <0x17070000 0x17070000 0x200>,
+ <0x17070200 0x17070200 0x100>,
+ <0x170A0000 0x170A0000 0x3000>;
+
+ mediam@170A0000 {
+ compatible = "sirf,nocfw-mediam";
+ reg = <0x170A0000 0x3000>;
+ };
+
+ gpio_0: gpio_mediam@17040000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,atlas7-gpio";
+ reg = <0x17040000 0x1000>;
+ interrupts = <0 13 0>, <0 14 0>;
+ clocks = <&car 107>;
+ clock-names = "gpio0_io";
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ nand@17050000 {
+ compatible = "sirf,atlas7-nand";
+ reg = <0x17050000 0x10000>;
+ interrupts = <0 41 0>;
+ clocks = <&car 108>, <&car 112>;
+ clock-names = "nand_io", "nand_nand";
+ };
+
+ sd0: sdhci@16000000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x16000000 0x100000>;
+ interrupts = <0 38 0>;
+ clocks = <&car 109>, <&car 111>;
+ clock-names = "core", "iface";
+ wp-inverted;
+ non-removable;
+ status = "disabled";
+ bus-width = <8>;
+ };
+
+ sd1: sdhci@16100000 {
+ cell-index = <1>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x16100000 0x100000>;
+ interrupts = <0 38 0>;
+ clocks = <&car 109>, <&car 111>;
+ clock-names = "core", "iface";
+ non-removable;
+ status = "disabled";
+ bus-width = <8>;
+ };
+
+ usb0: usb@17060000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-usb";
+ reg = <0x17060000 0x200>;
+ interrupts = <0 10 0>;
+ clocks = <&car 113>;
+ sirf,usbphy = <&usbphy0>;
+ phy_type = "utmi";
+ dr_mode = "otg";
+ maximum-speed = "high-speed";
+ status = "okay";
+ };
+
+ usb1: usb@17070000 {
+ cell-index = <1>;
+ compatible = "sirf,atlas7-usb";
+ reg = <0x17070000 0x200>;
+ interrupts = <0 11 0>;
+ clocks = <&car 114>;
+ sirf,usbphy = <&usbphy1>;
+ phy_type = "utmi";
+ dr_mode = "host";
+ maximum-speed = "high-speed";
+ status = "okay";
+ };
+
+ usbphy0: usbphy@0 {
+ compatible = "sirf,atlas7-usbphy";
+ reg = <0x17060200 0x100>;
+ clocks = <&car 115>;
+ status = "okay";
+ };
+
+ usbphy1: usbphy@1 {
+ compatible = "sirf,atlas7-usbphy";
+ reg = <0x17070200 0x100>;
+ clocks = <&car 116>;
+ status = "okay";
+ };
+
+ i2c0: i2c@17020000 {
+ cell-index = <0>;
+ compatible = "sirf,prima2-i2c";
+ reg = <0x17020000 0x1000>;
+ interrupts = <0 24 0>;
+ clocks = <&car 105>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ };
+
+ vdifm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13290000 0x13290000 0x3000>,
+ <0x13300000 0x13300000 0x1000>,
+ <0x14200000 0x14200000 0x600000>;
+
+ vdifm@13290000 {
+ compatible = "sirf,nocfw-vdifm";
+ reg = <0x13290000 0x3000>;
+ };
+
+ gpio_1: gpio_vdifm@13300000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,atlas7-gpio";
+ reg = <0x13300000 0x1000>;
+ interrupts = <0 43 0>, <0 44 0>, <0 45 0>;
+ clocks = <&car 84>;
+ clock-names = "gpio1_io";
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ sd2: sdhci@14200000 {
+ cell-index = <2>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14200000 0x100000>;
+ interrupts = <0 23 0>;
+ clocks = <&car 70>, <&car 75>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ sd-uhs-sdr50;
+ vqmmc-supply = <&vqmmc>;
+ vqmmc: vqmmc@2 {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <1950000>;
+ regulator-name = "vqmmc-ldo";
+ regulator-type = "voltage";
+ regulator-boot-on;
+ regulator-allow-bypass;
+ };
+ };
+
+ sd3: sdhci@14300000 {
+ cell-index = <3>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14300000 0x100000>;
+ interrupts = <0 23 0>;
+ clocks = <&car 76>, <&car 81>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ };
+
+ sd5: sdhci@14500000 {
+ cell-index = <5>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14500000 0x100000>;
+ interrupts = <0 39 0>;
+ clocks = <&car 71>, <&car 76>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ loop-dma;
+ };
+
+ sd6: sdhci@14600000 {
+ cell-index = <6>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14600000 0x100000>;
+ interrupts = <0 98 0>;
+ clocks = <&car 72>, <&car 77>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ };
+
+ sd7: sdhci@14700000 {
+ cell-index = <7>;
+ compatible = "sirf,atlas7-sdhc";
+ reg = <0x14700000 0x100000>;
+ interrupts = <0 98 0>;
+ clocks = <&car 72>, <&car 77>;
+ clock-names = "core", "iface";
+ status = "disabled";
+ bus-width = <4>;
+ };
+ };
+
+ audiom {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10d50000 0x10d50000 0x0000ffff>,
+ <0x10d60000 0x10d60000 0x0000ffff>,
+ <0x10d80000 0x10d80000 0x0000ffff>,
+ <0x10d90000 0x10d90000 0x0000ffff>,
+ <0x10ED0000 0x10ED0000 0x3000>,
+ <0x10dc8000 0x10dc8000 0x1000>,
+ <0x10dc0000 0x10dc0000 0x1000>,
+ <0x10db0000 0x10db0000 0x4000>,
+ <0x10d40000 0x10d40000 0x1000>,
+ <0x10d30000 0x10d30000 0x1000>;
+
+ timer@10dc0000 {
+ compatible = "sirf,atlas7-tick";
+ reg = <0x10dc0000 0x1000>;
+ interrupts = <0 0 0>,
+ <0 1 0>,
+ <0 2 0>,
+ <0 49 0>,
+ <0 50 0>,
+ <0 51 0>;
+ clocks = <&car 47>;
+ };
+
+ timerb@10dc8000 {
+ compatible = "sirf,atlas7-tick";
+ reg = <0x10dc8000 0x1000>;
+ interrupts = <0 74 0>,
+ <0 75 0>,
+ <0 76 0>,
+ <0 77 0>,
+ <0 78 0>,
+ <0 79 0>;
+ clocks = <&car 47>;
+ };
+
+ vip0@10db0000 {
+ compatible = "sirf,atlas7-vip0";
+ reg = <0x10db0000 0x2000>;
+ interrupts = <0 85 0>;
+ sirf,vip_cma_size = <0xC00000>;
+ };
+
+ cvd@10db2000 {
+ compatible = "sirf,cvd";
+ reg = <0x10db2000 0x2000>;
+ clocks = <&car 46>;
+ };
+
+ dmac2: dma-controller@10d50000 {
+ cell-index = <2>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x10d50000 0xffff>;
+ interrupts = <0 55 0>;
+ clocks = <&car 60>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+
+ dmac3: dma-controller@10d60000 {
+ cell-index = <3>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x10d60000 0xffff>;
+ interrupts = <0 56 0>;
+ clocks = <&car 61>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+
+ adc: adc@10d80000 {
+ compatible = "sirf,atlas7-adc";
+ reg = <0x10d80000 0xffff>;
+ interrupts = <0 34 0>;
+ clocks = <&car 49>;
+ #io-channel-cells = <1>;
+ };
+
+ pulsec@10d90000 {
+ compatible = "sirf,prima2-pulsec";
+ reg = <0x10d90000 0xffff>;
+ interrupts = <0 42 0>;
+ clocks = <&car 54>;
+ };
+
+ audiom@10ED0000 {
+ compatible = "sirf,nocfw-audiom";
+ reg = <0x10ED0000 0x3000>;
+ interrupts = <0 102 0>;
+ };
+
+ usp1: usp@10d30000 {
+ cell-index = <1>;
+ reg = <0x10d30000 0x1000>;
+ fifosize = <512>;
+ clocks = <&car 58>;
+ dmas = <&dmac2 6>, <&dmac2 7>;
+ dma-names = "rx", "tx";
+ };
+
+ usp2: usp@10d40000 {
+ cell-index = <2>;
+ reg = <0x10d40000 0x1000>;
+ interrupts = <0 22 0>;
+ clocks = <&car 59>;
+ dmas = <&dmac2 12>, <&dmac2 13>;
+ dma-names = "rx", "tx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
+
+ ddrm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x10820000 0x10820000 0x3000>,
+ <0x10800000 0x10800000 0x2000>;
+ ddrm@10820000 {
+ compatible = "sirf,nocfw-ddrm";
+ reg = <0x10820000 0x3000>;
+ interrupts = <0 105 0>;
+ };
+
+ memory-controller@0x10800000 {
+ compatible = "sirf,atlas7-memc";
+ reg = <0x10800000 0x2000>;
+ };
+
+ };
+
+ btm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x11002000 0x11002000 0x0000ffff>,
+ <0x11010000 0x11010000 0x3000>,
+ <0x11000000 0x11000000 0x1000>,
+ <0x11001000 0x11001000 0x1000>;
+
+ dmac4: dma-controller@11002000 {
+ cell-index = <4>;
+ compatible = "sirf,atlas7-dmac";
+ reg = <0x11002000 0x1000>;
+ interrupts = <0 99 0>;
+ clocks = <&car 130>;
+ dma-channels = <16>;
+ #dma-cells = <1>;
+ };
+ uart6: uart@11000000 {
+ cell-index = <6>;
+ compatible = "sirf,atlas7-bt-uart",
+ "sirf,atlas7-uart";
+ reg = <0x11000000 0x1000>;
+ interrupts = <0 100 0>;
+ clocks = <&car 131>, <&car 133>, <&car 134>;
+ clock-names = "uart", "general", "noc";
+ fifosize = <128>;
+ dmas = <&dmac4 12>, <&dmac4 13>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ usp3: usp@11001000 {
+ compatible = "sirf,atlas7-bt-usp",
+ "sirf,prima2-usp-pcm";
+ cell-index = <3>;
+ reg = <0x11001000 0x1000>;
+ fifosize = <512>;
+ clocks = <&car 132>, <&car 129>, <&car 133>,
+ <&car 134>, <&car 135>;
+ clock-names = "usp3_io", "a7ca_btss", "a7ca_io",
+ "noc_btm_io", "thbtm_io";
+ dmas = <&dmac4 0>, <&dmac4 1>;
+ dma-names = "rx", "tx";
+ };
+
+ btm@11010000 {
+ compatible = "sirf,nocfw-btm";
+ reg = <0x11010000 0x3000>;
+ };
+ };
+
+ rtcm {
+ compatible = "arteris, flexnoc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x18810000 0x18810000 0x3000>,
+ <0x18840000 0x18840000 0x1000>,
+ <0x18890000 0x18890000 0x1000>,
+ <0x188B0000 0x188B0000 0x10000>,
+ <0x188D0000 0x188D0000 0x1000>;
+ rtcm@18810000 {
+ compatible = "sirf,nocfw-rtcm";
+ reg = <0x18810000 0x3000>;
+ interrupts = <0 109 0>;
+ };
+
+ gpio_2: gpio_rtcm@18890000 {
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ compatible = "sirf,atlas7-gpio";
+ reg = <0x18890000 0x1000>;
+ interrupts = <0 47 0>;
+ gpio-controller;
+ interrupt-controller;
+ };
+
+ rtc-iobg@18840000 {
+ compatible = "sirf,prima2-rtciobg",
+ "sirf-prima2-rtciobg-bus",
+ "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x18840000 0x1000>;
+
+ sysrtc@2000 {
+ compatible = "sirf,prima2-sysrtc";
+ reg = <0x2000 0x100>;
+ interrupts = <0 52 0>;
+ };
+ pwrc@3000 {
+ compatible = "sirf,atlas7-pwrc";
+ reg = <0x3000 0x100>;
+ };
+ };
+
+ qspi: flash@188B0000 {
+ cell-index = <0>;
+ compatible = "sirf,atlas7-qspi-nor";
+ reg = <0x188B0000 0x10000>;
+ interrupts = <0 15 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ retain@0x188D0000 {
+ compatible = "sirf,atlas7-retain";
+ reg = <0x188D0000 0x1000>;
+ };
+
+ };
+ disp-iobg {
+ /* lcdc0 */
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x13100000 0x13100000 0x20000>,
+ <0x10e10000 0x10e10000 0x10000>;
+
+ lcd@13100000 {
+ compatible = "sirf,atlas7-lcdc";
+ reg = <0x13100000 0x10000>;
+ interrupts = <0 30 0>;
+ clocks = <&car 79>;
+ };
+ vpp@13110000 {
+ compatible = "sirf,atlas7-vpp";
+ reg = <0x13110000 0x10000>;
+ interrupts = <0 31 0>;
+ clocks = <&car 78>;
+ resets = <&car 29>;
+ };
+ lvds@10e10000 {
+ compatible = "sirf,atlas7-lvdsc";
+ reg = <0x10e10000 0x10000>;
+ interrupts = <0 64 0>;
+ clocks = <&car 54>;
+ resets = <&car 29>;
+ };
+
+ };
+
+ graphics-iobg {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x12000000 0x12000000 0x1000000>;
+
+ graphics@12000000 {
+ compatible = "powervr,sgx531";
+ reg = <0x12000000 0x1000000>;
+ interrupts = <0 6 0>;
+ clocks = <&car 126>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
new file mode 100644
index 000000000000..c20cf537f5a5
--- /dev/null
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * AXP202/209 Integrated Power Management Chip
+ * http://www.x-powers.com/product/AXP20X.php
+ * http://dl.linux-sunxi.org/AXP/AXP209%20Datasheet%20v1.0_cn.pdf
+ */
+
+&axp209 {
+ compatible = "x-powers,axp209";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ regulators {
+ /* Default work frequency for buck regulators */
+ x-powers,dcdc-freq = <1500>;
+
+ reg_dcdc2: dcdc2 {
+ regulator-name = "dcdc2";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-name = "dcdc3";
+ };
+
+ reg_ldo1: ldo1 {
+ /* LDO1 is a fixed output regulator */
+ regulator-always-on;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-name = "ldo1";
+ };
+
+ reg_ldo2: ldo2 {
+ regulator-name = "ldo2";
+ };
+
+ reg_ldo3: ldo3 {
+ regulator-name = "ldo3";
+ };
+
+ reg_ldo4: ldo4 {
+ regulator-name = "ldo4";
+ };
+
+ reg_ldo5: ldo5 {
+ regulator-name = "ldo5";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
index 5fc0fae03092..b359c1e6178e 100644
--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
@@ -23,11 +23,77 @@
reg = <0x00000000 0x08000000>;
};
+ spi {
+ compatible = "spi-gpio";
+ num-chipselects = <1>;
+ gpio-sck = <&chipcommon 7 0>;
+ gpio-mosi = <&chipcommon 4 0>;
+ cs-gpios = <&chipcommon 6 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hc595: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ reg = <0>;
+ registers-number = <1>;
+ spi-max-frequency = <100000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power0 {
+ label = "bcm53xx:red:power";
+ gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ power1 {
+ label = "bcm53xx:white:power";
+ gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ router0 {
+ label = "bcm53xx:blue:router";
+ gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ router1 {
+ label = "bcm53xx:amber:router";
+ gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan {
+ label = "bcm53xx:blue:wan";
+ gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ wireless0 {
+ label = "bcm53xx:blue:wireless";
+ gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wireless1 {
+ label = "bcm53xx:amber:wireless";
+ gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
- poll-interval = <200>;
restart {
label = "Reset";
diff --git a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
new file mode 100644
index 000000000000..946c728c4eb7
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
@@ -0,0 +1,60 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Luxul XWC-1000
+ *
+ * Copyright 2014 Luxul Inc.
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+
+/ {
+ compatible = "luxul,xwc-1000", "brcm,bcm4708";
+ model = "Luxul XWC-1000 (BCM4708)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ axi@18000000 {
+ nand@28000 {
+ reg = <0x00028000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "ubi";
+ reg = <0x00000000 0x08000000>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ status {
+ label = "bcm53xx:green:status";
+ gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "timer";
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
index 4ed7de1058b7..f18c9d9b2f2c 100644
--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
@@ -71,7 +71,6 @@
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
- poll-interval = <200>;
wps {
label = "WPS";
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
index 12fc2a01e6ab..39910428246a 100644
--- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
@@ -61,7 +61,6 @@
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
- poll-interval = <200>;
wps {
label = "WPS";
diff --git a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
index fb76378bd511..0ee85ea10bb2 100644
--- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
@@ -61,7 +61,6 @@
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
- poll-interval = <200>;
restart {
label = "Reset";
diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
index bbb414fbad65..db9131e03268 100644
--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
@@ -23,11 +23,77 @@
reg = <0x00000000 0x08000000>;
};
+ spi {
+ compatible = "spi-gpio";
+ num-chipselects = <1>;
+ gpio-sck = <&chipcommon 7 0>;
+ gpio-mosi = <&chipcommon 4 0>;
+ cs-gpios = <&chipcommon 6 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hc595: gpio_spi@0 {
+ compatible = "fairchild,74hc595";
+ reg = <0>;
+ registers-number = <1>;
+ spi-max-frequency = <100000>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power0 {
+ label = "bcm53xx:green:power";
+ gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ power1 {
+ label = "bcm53xx:red:power";
+ gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ router0 {
+ label = "bcm53xx:green:router";
+ gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ router1 {
+ label = "bcm53xx:amber:router";
+ gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wan {
+ label = "bcm53xx:green:wan";
+ gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ wireless0 {
+ label = "bcm53xx:green:wireless";
+ gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+
+ wireless1 {
+ label = "bcm53xx:amber:wireless";
+ gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-off";
+ };
+ };
+
gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
- poll-interval = <200>;
aoss {
label = "AOSS";
diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
new file mode 100644
index 000000000000..7d6868acb1c6
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
@@ -0,0 +1,37 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Buffalo WZR-900DHP
+ *
+ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm47081.dtsi"
+
+/ {
+ compatible = "buffalo,wzr-900dhp", "brcm,bcm47081", "brcm,bcm4708";
+ model = "Buffalo WZR-900DHP (BCM47081)";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x00000000 0x08000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ restart {
+ label = "Reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index 015a06c67c91..63d00a63cfa6 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -104,7 +104,7 @@
local-timer@ad0600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xad0600 0x20>;
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
clocks = <&chip CLKID_TWD>;
};
diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 230df3b1770e..81b670ac494a 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -45,6 +45,11 @@
ranges = <0 0xf7000000 0x1000000>;
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
sdhci0: sdhci@ab0000 {
compatible = "mrvl,pxav3-mmc";
reg = <0xab0000 0x200>;
@@ -71,7 +76,7 @@
local-timer@ad0600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xad0600 0x20>;
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
clocks = <&chip CLKID_TWD>;
};
diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index e2f61f27944e..be5397288d24 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -63,6 +63,14 @@
ranges = <0 0xf7000000 0x1000000>;
interrupt-parent = <&gic>;
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
sdhci0: sdhci@ab0000 {
compatible = "mrvl,pxav3-mmc";
reg = <0xab0000 0x200>;
@@ -105,7 +113,7 @@
compatible = "arm,cortex-a9-twd-timer";
reg = <0xad0600 0x20>;
clocks = <&chip CLKID_TWD>;
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
gic: interrupt-controller@ad1000 {
diff --git a/arch/arm/boot/dts/cx92755.dtsi b/arch/arm/boot/dts/cx92755.dtsi
new file mode 100644
index 000000000000..490c08075e67
--- /dev/null
+++ b/arch/arm/boot/dts/cx92755.dtsi
@@ -0,0 +1,113 @@
+/*
+ * Device Tree Include file for the Conexant Digicolor CX92755 SoC
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "cnxt,cx92755";
+
+ interrupt-parent = <&intc>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0x0>;
+ };
+ };
+
+ main_clk: main_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <200000000>;
+ };
+
+ intc: interrupt-controller@f0000040 {
+ compatible = "cnxt,cx92755-ic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xf0000040 0x40>;
+ syscon = <&uc_regs>;
+ };
+
+ timer@f0000fc0 {
+ compatible = "cnxt,cx92755-timer";
+ reg = <0xf0000fc0 0x40>;
+ interrupts = <19>, <31>, <34>, <35>, <52>, <53>, <54>, <55>;
+ clocks = <&main_clk>;
+ };
+
+ uc_regs: syscon@f00003a0 {
+ compatible = "cnxt,cx92755-uc", "syscon";
+ reg = <0xf00003a0 0x10>;
+ };
+
+ uart0: uart@f0000740 {
+ compatible = "cnxt,cx92755-usart";
+ reg = <0xf0000740 0x20>;
+ clocks = <&main_clk>;
+ interrupts = <44>;
+ status = "disabled";
+ };
+
+ uart1: uart@f0000760 {
+ compatible = "cnxt,cx92755-usart";
+ reg = <0xf0000760 0x20>;
+ clocks = <&main_clk>;
+ interrupts = <45>;
+ status = "disabled";
+ };
+
+ uart2: uart@f0000780 {
+ compatible = "cnxt,cx92755-usart";
+ reg = <0xf0000780 0x20>;
+ clocks = <&main_clk>;
+ interrupts = <46>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/cx92755_equinox.dts b/arch/arm/boot/dts/cx92755_equinox.dts
new file mode 100644
index 000000000000..f33bf5635d47
--- /dev/null
+++ b/arch/arm/boot/dts/cx92755_equinox.dts
@@ -0,0 +1,74 @@
+/*
+ * Device Tree file for the Conexant Equinox CX92755 EVK
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "cx92755.dtsi"
+
+/ {
+ model = "Conexant Equinox CX92755 EVK";
+ compatible = "cnxt,equinox", "cnxt,cx92755";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ memory@0 {
+ reg = <0 0x8000000>;
+ device_type = "memory";
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ stdout-path = &uart0;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts
new file mode 100644
index 000000000000..857d0289ad4d
--- /dev/null
+++ b/arch/arm/boot/dts/dm8168-evm.dts
@@ -0,0 +1,129 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "dm816x.dtsi"
+
+/ {
+ model = "DM8168 EVM";
+ compatible = "ti,dm8168-evm", "ti,dm8168";
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000 /* 1 GB */
+ 0xc0000000 0x40000000>; /* 1 GB */
+ };
+
+ /* FDC6331L controlled by SD_POW pin */
+ vmmcsd_fixed: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&dm816x_pinmux {
+ mcspi1_pins: pinmux_mcspi1_pins {
+ pinctrl-single,pins = <
+ DM816X_IOPAD(0x0a94, PIN_INPUT | MUX_MODE0) /* SPI_SCLK */
+ DM816X_IOPAD(0x0a98, PIN_OUTPUT | MUX_MODE0) /* SPI_SCS0 */
+ DM816X_IOPAD(0x0aa8, PIN_INPUT | MUX_MODE0) /* SPI_D0 */
+ DM816X_IOPAD(0x0aac, PIN_INPUT | MUX_MODE0) /* SPI_D1 */
+ >;
+ };
+};
+
+&i2c1 {
+ extgpio0: pcf8575@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&i2c2 {
+ extgpio1: pcf8575@20 {
+ compatible = "nxp,pcf8575";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ linux,mtd-name= "micron,mt29f2g16aadwp";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,nand-ecc-opt = "bch8";
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wait-on-read = "true";
+ gpmc,wait-on-write = "true";
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+ partition@0 {
+ label = "X-Loader";
+ reg = <0 0x80000>;
+ };
+ partition@0x80000 {
+ label = "U-Boot";
+ reg = <0x80000 0x1c0000>;
+ };
+ partition@0x1c0000 {
+ label = "Environment";
+ reg = <0x240000 0x40000>;
+ };
+ partition@0x280000 {
+ label = "Kernel";
+ reg = <0x280000 0x500000>;
+ };
+ partition@0x780000 {
+ label = "Filesystem";
+ reg = <0x780000 0xf880000>;
+ };
+ };
+};
+
+&mcspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi1_pins>;
+
+ m25p80@0 {
+ compatible = "w25x32";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+};
+
+&mmc1 {
+ vmmc-supply = <&vmmcsd_fixed>;
+};
diff --git a/arch/arm/boot/dts/dm816x-clocks.dtsi b/arch/arm/boot/dts/dm816x-clocks.dtsi
new file mode 100644
index 000000000000..50d9d338fbe9
--- /dev/null
+++ b/arch/arm/boot/dts/dm816x-clocks.dtsi
@@ -0,0 +1,250 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+&scrm {
+ main_fapll: main_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x400 0x40>;
+ clocks = <&sys_clkin_ck &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>, <4>, <5>,
+ <6>, <7>;
+ clock-output-names = "main_pll_clk1",
+ "main_pll_clk2",
+ "main_pll_clk3",
+ "main_pll_clk4",
+ "main_pll_clk5",
+ "main_pll_clk6",
+ "main_pll_clk7";
+ };
+
+ ddr_fapll: ddr_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x440 0x30>;
+ clocks = <&sys_clkin_ck &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>, <4>;
+ clock-output-names = "ddr_pll_clk1",
+ "ddr_pll_clk2",
+ "ddr_pll_clk3",
+ "ddr_pll_clk4";
+ };
+
+ video_fapll: video_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x470 0x30>;
+ clocks = <&sys_clkin_ck &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>;
+ clock-output-names = "video_pll_clk1",
+ "video_pll_clk2",
+ "video_pll_clk3";
+ };
+
+ audio_fapll: audio_fapll {
+ #clock-cells = <1>;
+ compatible = "ti,dm816-fapll-clock";
+ reg = <0x4a0 0x30>;
+ clocks = <&main_fapll 7>, < &sys_clkin_ck>;
+ clock-indices = <1>, <2>, <3>, <4>, <5>;
+ clock-output-names = "audio_pll_clk1",
+ "audio_pll_clk2",
+ "audio_pll_clk3",
+ "audio_pll_clk4",
+ "audio_pll_clk5";
+ };
+};
+
+&scrm_clocks {
+ secure_32k_ck: secure_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ sys_32k_ck: sys_32k_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ tclkin_ck: tclkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ sys_clkin_ck: sys_clkin_ck {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ };
+};
+
+/* 0x48180000 */
+&prcm_clocks {
+ clkout_pre_ck: clkout_pre_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&main_fapll 5 &ddr_fapll 1 &video_fapll 1
+ &audio_fapll 1>;
+ reg = <0x100>;
+ };
+
+ clkout_div_ck: clkout_div_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&clkout_pre_ck>;
+ ti,bit-shift = <3>;
+ ti,max-div = <8>;
+ reg = <0x100>;
+ };
+
+ clkout_ck: clkout_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&clkout_div_ck>;
+ ti,bit-shift = <7>;
+ reg = <0x100>;
+ };
+
+ /* CM_DPLL clocks p1795 */
+ sysclk1_ck: sysclk1_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 1>;
+ ti,max-div = <7>;
+ reg = <0x0300>;
+ };
+
+ sysclk2_ck: sysclk2_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 2>;
+ ti,max-div = <7>;
+ reg = <0x0304>;
+ };
+
+ sysclk3_ck: sysclk3_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 3>;
+ ti,max-div = <7>;
+ reg = <0x0308>;
+ };
+
+ sysclk4_ck: sysclk4_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 4>;
+ ti,max-div = <1>;
+ reg = <0x030c>;
+ };
+
+ sysclk5_ck: sysclk5_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&sysclk4_ck>;
+ ti,max-div = <1>;
+ reg = <0x0310>;
+ };
+
+ sysclk6_ck: sysclk6_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 4>;
+ ti,dividers = <2>, <4>;
+ reg = <0x0314>;
+ };
+
+ sysclk10_ck: sysclk10_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&ddr_fapll 2>;
+ ti,max-div = <7>;
+ reg = <0x0324>;
+ };
+
+ sysclk24_ck: sysclk24_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&main_fapll 5>;
+ ti,max-div = <7>;
+ reg = <0x03b4>;
+ };
+
+ mpu_ck: mpu_ck {
+ #clock-cells = <0>;
+ compatible = "ti,gate-clock";
+ clocks = <&sysclk2_ck>;
+ ti,bit-shift = <1>;
+ reg = <0x15dc>;
+ };
+
+ audio_pll_a_ck: audio_pll_a_ck {
+ #clock-cells = <0>;
+ compatible = "ti,divider-clock";
+ clocks = <&audio_fapll 1>;
+ ti,max-div = <7>;
+ reg = <0x035c>;
+ };
+
+ sysclk18_ck: sysclk18_ck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&sys_32k_ck>, <&audio_pll_a_ck>;
+ reg = <0x0378>;
+ };
+
+ timer1_fck: timer1_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x0390>;
+ };
+
+ timer2_fck: timer2_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x0394>;
+ };
+
+ timer3_fck: timer3_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x0398>;
+ };
+
+ timer4_fck: timer4_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x039c>;
+ };
+
+ timer5_fck: timer5_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x03a0>;
+ };
+
+ timer6_fck: timer6_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x03a4>;
+ };
+
+ timer7_fck: timer7_fck {
+ #clock-cells = <0>;
+ compatible = "ti,mux-clock";
+ clocks = <&tclkin_ck>, <&sysclk18_ck>, <&sys_clkin_ck>;
+ reg = <0x03a8>;
+ };
+};
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi
new file mode 100644
index 000000000000..d98d0f7de380
--- /dev/null
+++ b/arch/arm/boot/dts/dm816x.dtsi
@@ -0,0 +1,392 @@
+/*
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "ti,dm816";
+ interrupt-parent = <&intc>;
+
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c2;
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ ethernet0 = &eth0;
+ ethernet1 = &eth1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "arm,cortex-a8";
+ device_type = "cpu";
+ reg = <0>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,cortex-a8-pmu";
+ interrupts = <3>;
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is used for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap3-mpu";
+ ti,hwmods = "mpu";
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the dm816x interconnect.
+ * The real dm816x interconnect network is quite complex. Since
+ * it will not bring real advantage to represent that in DT
+ * for the moment, just use a fake OCP bus entry to represent
+ * the whole bus hierarchy.
+ */
+ ocp {
+ compatible = "ti,omap3-l3-smx", "simple-bus";
+ reg = <0x44000000 0x10000>;
+ interrupts = <9 10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main";
+
+ prcm: prcm@48180000 {
+ compatible = "ti,dm816-prcm";
+ reg = <0x48180000 0x4000>;
+
+ prcm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ prcm_clockdomains: clockdomains {
+ };
+ };
+
+ scrm: scrm@48140000 {
+ compatible = "ti,dm816-scrm", "simple-bus";
+ reg = <0x48140000 0x21000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x48140000 0x21000>;
+
+ dm816x_pinmux: pinmux@800 {
+ compatible = "pinctrl-single";
+ reg = <0x800 0x50a>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-single,register-width = <16>;
+ pinctrl-single,function-mask = <0xf>;
+ };
+
+ /* Device Configuration Registers */
+ scm_conf: syscon@600 {
+ compatible = "syscon";
+ reg = <0x600 0x110>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ scrm_clocks: clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ scrm_clockdomains: clockdomains {
+ };
+ };
+
+ edma: edma@49000000 {
+ compatible = "ti,edma3";
+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2", "tptc3";
+ reg = <0x49000000 0x10000>,
+ <0x44e10f90 0x40>;
+ interrupts = <12 13 14>;
+ #dma-cells = <1>;
+ };
+
+ elm: elm@48080000 {
+ compatible = "ti,816-elm";
+ ti,hwmods = "elm";
+ reg = <0x48080000 0x2000>;
+ interrupts = <4>;
+ };
+
+ gpio1: gpio@48032000 {
+ compatible = "ti,omap3-gpio";
+ ti,hwmods = "gpio1";
+ reg = <0x48032000 0x1000>;
+ interrupts = <97>;
+ };
+
+ gpio2: gpio@4804c000 {
+ compatible = "ti,omap3-gpio";
+ ti,hwmods = "gpio2";
+ reg = <0x4804c000 0x1000>;
+ interrupts = <99>;
+ };
+
+ gpmc: gpmc@50000000 {
+ compatible = "ti,am3352-gpmc";
+ ti,hwmods = "gpmc";
+ reg = <0x50000000 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ interrupts = <100>;
+ gpmc,num-cs = <6>;
+ gpmc,num-waitpins = <2>;
+ };
+
+ i2c1: i2c@48028000 {
+ compatible = "ti,omap4-i2c";
+ ti,hwmods = "i2c1";
+ reg = <0x48028000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <70>;
+ dmas = <&edma 58 &edma 59>;
+ dma-names = "tx", "rx";
+ };
+
+ i2c2: i2c@4802a000 {
+ compatible = "ti,omap4-i2c";
+ ti,hwmods = "i2c2";
+ reg = <0x4802a000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <71>;
+ dmas = <&edma 60 &edma 61>;
+ dma-names = "tx", "rx";
+ };
+
+ intc: interrupt-controller@48200000 {
+ compatible = "ti,dm816-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x48200000 0x1000>;
+ };
+
+ mailbox: mailbox@480c8000 {
+ compatible = "ti,omap4-mailbox";
+ reg = <0x480c8000 0x2000>;
+ interrupts = <77>;
+ ti,hwmods = "mailbox";
+ ti,mbox-num-users = <4>;
+ ti,mbox-num-fifos = <12>;
+ mbox_dsp: mbox_dsp {
+ ti,mbox-tx = <3 0 0>;
+ ti,mbox-rx = <0 0 0>;
+ };
+ };
+
+ mdio: mdio@4a100800 {
+ compatible = "ti,davinci_mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4a100800 0x100>;
+ ti,hwmods = "davinci_mdio";
+ bus_freq = <1000000>;
+ phy0: ethernet-phy@0 {
+ reg = <1>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <2>;
+ };
+ };
+
+ eth0: ethernet@4a100000 {
+ compatible = "ti,dm816-emac";
+ ti,hwmods = "emac0";
+ reg = <0x4a100000 0x800
+ 0x4a100900 0x3700>;
+ clocks = <&sysclk24_ck>;
+ syscon = <&scm_conf>;
+ ti,davinci-ctrl-reg-offset = <0>;
+ ti,davinci-ctrl-mod-reg-offset = <0x900>;
+ ti,davinci-ctrl-ram-offset = <0x2000>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ interrupts = <40 41 42 43>;
+ phy-handle = <&phy0>;
+ };
+
+ eth1: ethernet@4a120000 {
+ compatible = "ti,dm816-emac";
+ ti,hwmods = "emac1";
+ reg = <0x4a120000 0x4000>;
+ clocks = <&sysclk24_ck>;
+ syscon = <&scm_conf>;
+ ti,davinci-ctrl-reg-offset = <0>;
+ ti,davinci-ctrl-mod-reg-offset = <0x900>;
+ ti,davinci-ctrl-ram-offset = <0x2000>;
+ ti,davinci-ctrl-ram-size = <0x2000>;
+ interrupts = <44 45 46 47>;
+ phy-handle = <&phy1>;
+ };
+
+ mcspi1: spi@48030000 {
+ compatible = "ti,omap4-mcspi";
+ reg = <0x48030000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <65>;
+ ti,spi-num-cs = <4>;
+ ti,hwmods = "mcspi1";
+ dmas = <&edma 16 &edma 17
+ &edma 18 &edma 19>;
+ dma-names = "tx0", "rx0", "tx1", "rx1";
+ };
+
+ mmc1: mmc@48060000 {
+ compatible = "ti,omap4-hsmmc";
+ reg = <0x48060000 0x11000>;
+ ti,hwmods = "mmc1";
+ interrupts = <64>;
+ dmas = <&edma 24 &edma 25>;
+ dma-names = "tx", "rx";
+ };
+
+ timer1: timer@4802e000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x4802e000 0x2000>;
+ interrupts = <67>;
+ ti,hwmods = "timer1";
+ ti,timer-alwon;
+ };
+
+ timer2: timer@48040000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48040000 0x2000>;
+ interrupts = <68>;
+ ti,hwmods = "timer2";
+ };
+
+ timer3: timer@48042000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48042000 0x2000>;
+ interrupts = <69>;
+ ti,hwmods = "timer3";
+ };
+
+ timer4: timer@48044000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48044000 0x2000>;
+ interrupts = <92>;
+ ti,hwmods = "timer4";
+ };
+
+ timer5: timer@48046000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48046000 0x2000>;
+ interrupts = <93>;
+ ti,hwmods = "timer5";
+ };
+
+ timer6: timer@48048000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x48048000 0x2000>;
+ interrupts = <94>;
+ ti,hwmods = "timer6";
+ };
+
+ timer7: timer@4804a000 {
+ compatible = "ti,dm816-timer";
+ reg = <0x4804a000 0x2000>;
+ interrupts = <95>;
+ ti,hwmods = "timer7";
+ };
+
+ uart1: uart@48020000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart1";
+ reg = <0x48020000 0x2000>;
+ clock-frequency = <48000000>;
+ interrupts = <72>;
+ dmas = <&edma 26 &edma 27>;
+ dma-names = "tx", "rx";
+ };
+
+ uart2: uart@48022000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart2";
+ reg = <0x48022000 0x2000>;
+ clock-frequency = <48000000>;
+ interrupts = <73>;
+ dmas = <&edma 28 &edma 29>;
+ dma-names = "tx", "rx";
+ };
+
+ uart3: uart@48024000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart3";
+ reg = <0x48024000 0x2000>;
+ clock-frequency = <48000000>;
+ interrupts = <74>;
+ dmas = <&edma 30 &edma 31>;
+ dma-names = "tx", "rx";
+ };
+
+ /* NOTE: USB needs a transceiver driver for phys to work */
+ usb: usb_otg_hs@47401000 {
+ compatible = "ti,am33xx-usb";
+ reg = <0x47401000 0x400000>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,hwmods = "usb_otg_hs";
+
+ usb0: usb@47401000 {
+ compatible = "ti,musb-am33xx";
+ reg = <0x47401400 0x400
+ 0x47401000 0x200>;
+ reg-names = "mc", "control";
+ interrupts = <18>;
+ interrupt-names = "mc";
+ dr_mode = "otg";
+ mentor,multipoint = <1>;
+ mentor,num-eps = <16>;
+ mentor,ram-bits = <12>;
+ mentor,power = <500>;
+ };
+
+ usb1: usb@47401800 {
+ compatible = "ti,musb-am33xx";
+ status = "disabled";
+ reg = <0x47401c00 0x400
+ 0x47401800 0x200>;
+ reg-names = "mc", "control";
+ interrupts = <19>;
+ interrupt-names = "mc";
+ dr_mode = "otg";
+ mentor,multipoint = <1>;
+ mentor,num-eps = <16>;
+ mentor,ram-bits = <12>;
+ mentor,power = <500>;
+ };
+ };
+
+ wd_timer2: wd_timer@480c2000 {
+ compatible = "ti,omap3-wdt";
+ ti,hwmods = "wd_timer";
+ reg = <0x480c2000 0x1000>;
+ interrupts = <0>;
+ };
+ };
+};
+
+#include "dm816x-clocks.dtsi"
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index ad4118f7e1a6..746cddb1b8f5 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -26,6 +26,16 @@
regulator-max-microvolt = <3300000>;
};
+ extcon_usb1: extcon_usb1 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
+ };
+
vtt_fixed: fixedregulator-vtt {
compatible = "regulator-fixed";
regulator-name = "vtt_fixed";
@@ -391,6 +401,19 @@
};
};
};
+
+ pcf_gpio_21: gpio@21 {
+ compatible = "ti,pcf8575";
+ reg = <0x21>;
+ lines-initial-states = <0x1408>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
};
&i2c2 {
@@ -520,6 +543,14 @@
};
};
+&omap_dwc3_1 {
+ extcon = <&extcon_usb1>;
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
+
&usb1 {
dr_mode = "peripheral";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 63f8b007bdc5..5827fedafd43 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1111,7 +1111,6 @@
"wkupclk", "refclk",
"div-clk", "phy-div";
#phy-cells = <0>;
- id = <1>;
ti,hwmods = "pcie1-phy";
};
@@ -1132,7 +1131,6 @@
"div-clk", "phy-div";
#phy-cells = <0>;
ti,hwmods = "pcie2-phy";
- id = <2>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index 89085d066c65..4d8711713610 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -8,6 +8,7 @@
/dts-v1/;
#include "dra72x.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "TI DRA722";
@@ -24,6 +25,16 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
+
+ extcon_usb1: extcon_usb1 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ extcon_usb2: extcon_usb2 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
+ };
};
&dra7_pmx_core {
@@ -121,6 +132,18 @@
0x418 (MUX_MODE15) /* wakeup0.off */
>;
};
+
+ qspi1_pins: pinmux_qspi1_pins {
+ pinctrl-single,pins = <
+ 0x74 (PIN_OUTPUT | MUX_MODE1) /* gpmc_a13.qspi1_rtclk */
+ 0x78 (PIN_INPUT | MUX_MODE1) /* gpmc_a14.qspi1_d3 */
+ 0x7c (PIN_INPUT | MUX_MODE1) /* gpmc_a15.qspi1_d2 */
+ 0x80 (PIN_INPUT | MUX_MODE1) /* gpmc_a16.qspi1_d1 */
+ 0x84 (PIN_INPUT | MUX_MODE1) /* gpmc_a17.qspi1_d0 */
+ 0x88 (PIN_OUTPUT | MUX_MODE1) /* qpmc_a18.qspi1_sclk */
+ 0xb8 (PIN_OUTPUT | MUX_MODE1) /* gpmc_cs2.qspi1_cs0 */
+ >;
+ };
};
&i2c1 {
@@ -243,6 +266,18 @@
ti,palmas-long-press-seconds = <6>;
};
};
+
+ pcf_gpio_21: gpio@21 {
+ compatible = "ti,pcf8575";
+ reg = <0x21>;
+ lines-initial-states = <0x1408>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
&uart1 {
@@ -345,6 +380,14 @@
phy-supply = <&ldo4_reg>;
};
+&omap_dwc3_1 {
+ extcon = <&extcon_usb1>;
+};
+
+&omap_dwc3_2 {
+ extcon = <&extcon_usb2>;
+};
+
&usb1 {
dr_mode = "peripheral";
pinctrl-names = "default";
@@ -461,3 +504,68 @@
pinctrl-0 = <&dcan1_pins_default>;
pinctrl-1 = <&dcan1_pins_sleep>;
};
+
+&qspi {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi1_pins>;
+
+ spi-max-frequency = <48000000>;
+ m25p80@0 {
+ compatible = "s25fl256s1";
+ spi-max-frequency = <48000000>;
+ reg = <0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-cpol;
+ spi-cpha;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* MTD partition table.
+ * The ROM checks the first four physical blocks
+ * for a valid file to boot and the flash here is
+ * 64KiB block size.
+ */
+ partition@0 {
+ label = "QSPI.SPL";
+ reg = <0x00000000 0x000010000>;
+ };
+ partition@1 {
+ label = "QSPI.SPL.backup1";
+ reg = <0x00010000 0x00010000>;
+ };
+ partition@2 {
+ label = "QSPI.SPL.backup2";
+ reg = <0x00020000 0x00010000>;
+ };
+ partition@3 {
+ label = "QSPI.SPL.backup3";
+ reg = <0x00030000 0x00010000>;
+ };
+ partition@4 {
+ label = "QSPI.u-boot";
+ reg = <0x00040000 0x00100000>;
+ };
+ partition@5 {
+ label = "QSPI.u-boot-spl-os";
+ reg = <0x00140000 0x00080000>;
+ };
+ partition@6 {
+ label = "QSPI.u-boot-env";
+ reg = <0x001c0000 0x00010000>;
+ };
+ partition@7 {
+ label = "QSPI.u-boot-env.backup1";
+ reg = <0x001d0000 0x0010000>;
+ };
+ partition@8 {
+ label = "QSPI.kernel";
+ reg = <0x001e0000 0x0800000>;
+ };
+ partition@9 {
+ label = "QSPI.file-system";
+ reg = <0x009e0000 0x01620000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/ethernut5.dts b/arch/arm/boot/dts/ethernut5.dts
index 8f941c2db7c6..243044343ee8 100644
--- a/arch/arm/boot/dts/ethernut5.dts
+++ b/arch/arm/boot/dts/ethernut5.dts
@@ -6,7 +6,7 @@
* Licensed under GPLv2.
*/
/dts-v1/;
-#include "at91sam9260.dtsi"
+#include "at91sam9xe.dtsi"
/ {
model = "Ethernut 5";
diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 24822aa98057..1d483c1c8b48 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -15,6 +15,7 @@
/dts-v1/;
#include "exynos3250.dtsi"
#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Samsung Monk board";
@@ -37,9 +38,7 @@
compatible = "gpio-keys";
power_key {
- interrupt-parent = <&gpx2>;
- interrupts = <7 0>;
- gpios = <&gpx2 7 1>;
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label = "power key";
debounce-interval = <10>;
@@ -109,6 +108,13 @@
};
};
};
+
+ haptics {
+ compatible = "regulator-haptic";
+ haptic-supply = <&motor_reg>;
+ min-microvolt = <1100000>;
+ max-microvolt = <2700000>;
+ };
};
&adc {
@@ -134,6 +140,17 @@
};
};
+&exynos_usbphy {
+ status = "okay";
+};
+
+&hsotg {
+ vusb_d-supply = <&ldo15_reg>;
+ vusb_a-supply = <&ldo12_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
&i2c_0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -420,6 +437,46 @@
status = "okay";
};
+&ppmu_dmc0 {
+ status = "okay";
+
+ events {
+ ppmu_dmc0_3: ppmu-event3-dmc0 {
+ event-name = "ppmu-event3-dmc0";
+ };
+ };
+};
+
+&ppmu_dmc1 {
+ status = "okay";
+
+ events {
+ ppmu_dmc1_3: ppmu-event3-dmc1 {
+ event-name = "ppmu-event3-dmc1";
+ };
+ };
+};
+
+&ppmu_leftbus {
+ status = "okay";
+
+ events {
+ ppmu_leftbus_3: ppmu-event3-leftbus {
+ event-name = "ppmu-event3-leftbus";
+ };
+ };
+};
+
+&ppmu_rightbus {
+ status = "okay";
+
+ events {
+ ppmu_rightbus_3: ppmu-event3-rightbus {
+ event-name = "ppmu-event3-rightbus";
+ };
+ };
+};
+
&xusbxti {
clock-frequency = <24000000>;
};
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 80aa8b4c4a3d..0b9906880c0c 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -15,6 +15,7 @@
/dts-v1/;
#include "exynos3250.dtsi"
#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Samsung Rinato board";
@@ -37,9 +38,7 @@
compatible = "gpio-keys";
power_key {
- interrupt-parent = <&gpx2>;
- interrupts = <7 0>;
- gpios = <&gpx2 7 1>;
+ gpios = <&gpx2 7 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label = "power key";
debounce-interval = <10>;
@@ -100,6 +99,13 @@
};
};
};
+
+ haptics {
+ compatible = "regulator-haptic";
+ haptic-supply = <&motor_reg>;
+ min-microvolt = <1100000>;
+ max-microvolt = <2700000>;
+ };
};
&adc {
@@ -125,6 +131,87 @@
};
};
+&exynos_usbphy {
+ status = "okay";
+};
+
+&hsotg {
+ vusb_d-supply = <&ldo15_reg>;
+ vusb_a-supply = <&ldo12_reg>;
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&dsi_0 {
+ vddcore-supply = <&ldo6_reg>;
+ vddio-supply = <&ldo6_reg>;
+ samsung,pll-clock-frequency = <24000000>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ dsi_out: endpoint {
+ remote-endpoint = <&dsi_in>;
+ samsung,burst-clock-frequency = <250000000>;
+ samsung,esc-clock-frequency = <20000000>;
+ };
+ };
+ };
+
+ panel@0 {
+ compatible = "samsung,s6e63j0x03";
+ reg = <0>;
+ vdd3-supply = <&ldo16_reg>;
+ vci-supply = <&ldo20_reg>;
+ reset-gpios = <&gpe0 1 0>;
+ te-gpios = <&gpx0 6 0>;
+ power-on-delay= <30>;
+ power-off-delay= <120>;
+ reset-delay = <5>;
+ init-delay = <100>;
+ flip-horizontal;
+ flip-vertical;
+ panel-width-mm = <29>;
+ panel-height-mm = <29>;
+
+ display-timings {
+ timing-0 {
+ clock-frequency = <0>;
+ hactive = <320>;
+ vactive = <320>;
+ hfront-porch = <1>;
+ hback-porch = <1>;
+ hsync-len = <1>;
+ vfront-porch = <150>;
+ vback-porch = <1>;
+ vsync-len = <2>;
+ };
+ };
+
+ port {
+ dsi_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+&fimd {
+ status = "okay";
+
+ i80-if-timings {
+ cs-setup = <0>;
+ wr-setup = <0>;
+ wr-act = <1>;
+ wr-hold = <0>;
+ };
+};
+
&i2c_0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -523,6 +610,46 @@
status = "okay";
};
+&ppmu_dmc0 {
+ status = "okay";
+
+ events {
+ ppmu_dmc0_3: ppmu-event3-dmc0 {
+ event-name = "ppmu-event3-dmc0";
+ };
+ };
+};
+
+&ppmu_dmc1 {
+ status = "okay";
+
+ events {
+ ppmu_dmc1_3: ppmu-event3-dmc1 {
+ event-name = "ppmu-event3-dmc1";
+ };
+ };
+};
+
+&ppmu_leftbus {
+ status = "okay";
+
+ events {
+ ppmu_leftbus_3: ppmu-event3-leftbus {
+ event-name = "ppmu-event3-leftbus";
+ };
+ };
+};
+
+&ppmu_rightbus {
+ status = "okay";
+
+ events {
+ ppmu_rightbus_3: ppmu-event3-rightbus {
+ event-name = "ppmu-event3-rightbus";
+ };
+ };
+};
+
&xusbxti {
clock-frequency = <24000000>;
};
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index 22465494b796..277b48b0b6f9 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -141,26 +141,31 @@
pd_cam: cam-power-domain@10023C00 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C00 0x20>;
+ #power-domain-cells = <0>;
};
pd_mfc: mfc-power-domain@10023C40 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C40 0x20>;
+ #power-domain-cells = <0>;
};
pd_g3d: g3d-power-domain@10023C60 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C60 0x20>;
+ #power-domain-cells = <0>;
};
pd_lcd0: lcd0-power-domain@10023C80 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C80 0x20>;
+ #power-domain-cells = <0>;
};
pd_isp: isp-power-domain@10023CA0 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023CA0 0x20>;
+ #power-domain-cells = <0>;
};
cmu: clock-controller@10030000 {
@@ -235,7 +240,7 @@
interrupts = <0 84 0>, <0 85 0>, <0 86 0>;
clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
clock-names = "sclk_fimd", "fimd";
- samsung,power-domain = <&pd_lcd0>;
+ power-domains = <&pd_lcd0>;
samsung,sysreg = <&sys_reg>;
status = "disabled";
};
@@ -245,7 +250,7 @@
reg = <0x11C80000 0x10000>;
interrupts = <0 83 0>;
samsung,phy-type = <0>;
- samsung,power-domain = <&pd_lcd0>;
+ power-domains = <&pd_lcd0>;
phys = <&mipi_phy 1>;
phy-names = "dsim";
clocks = <&cmu CLK_DSIM0>, <&cmu CLK_SCLK_MIPI0>;
@@ -255,6 +260,17 @@
status = "disabled";
};
+ hsotg: hsotg@12480000 {
+ compatible = "snps,dwc2";
+ reg = <0x12480000 0x20000>;
+ interrupts = <0 141 0>;
+ clocks = <&cmu CLK_USBOTG>;
+ clock-names = "otg";
+ phys = <&exynos_usbphy 0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
mshc_0: mshc@12510000 {
compatible = "samsung,exynos5250-dw-mshc";
reg = <0x12510000 0x1000>;
@@ -279,6 +295,16 @@
status = "disabled";
};
+ exynos_usbphy: exynos-usbphy@125B0000 {
+ compatible = "samsung,exynos3250-usb2-phy";
+ reg = <0x125B0000 0x100>;
+ samsung,pmureg-phandle = <&pmu_system_controller>;
+ clocks = <&cmu CLK_USBOTG>, <&cmu CLK_SCLK_UPLL>;
+ clock-names = "phy", "ref";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
amba {
compatible = "arm,amba-bus";
#address-cells = <1>;
@@ -327,7 +353,7 @@
interrupts = <0 102 0>;
clock-names = "mfc", "sclk_mfc";
clocks = <&cmu CLK_MFC>, <&cmu CLK_SCLK_MFC>;
- samsung,power-domain = <&pd_mfc>;
+ power-domains = <&pd_mfc>;
status = "disabled";
};
@@ -515,6 +541,80 @@
compatible = "arm,cortex-a7-pmu";
interrupts = <0 18 0>, <0 19 0>;
};
+
+ ppmu_dmc0: ppmu_dmc0@106a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106a0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_dmc1: ppmu_dmc1@106b0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106b0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_cpu: ppmu_cpu@106c0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106c0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_rightbus: ppmu_rightbus@112a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x112a0000 0x2000>;
+ clocks = <&cmu CLK_PPMURIGHT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_leftbus: ppmu_leftbus0@116a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x116a0000 0x2000>;
+ clocks = <&cmu CLK_PPMULEFT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_camif: ppmu_camif@11ac0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11ac0000 0x2000>;
+ clocks = <&cmu CLK_PPMUCAMIF>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_lcd0: ppmu_lcd0@11e40000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11e40000 0x2000>;
+ clocks = <&cmu CLK_PPMULCD0>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_fsys: ppmu_fsys@12630000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12630000 0x2000>;
+ clocks = <&cmu CLK_PPMUFILE>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_g3d: ppmu_g3d@13220000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13220000 0x2000>;
+ clocks = <&cmu CLK_PPMUG3D>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_mfc: ppmu_mfc@13660000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13660000 0x2000>;
+ clocks = <&cmu CLK_PPMUMFC_L>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index cb6001085f1a..76173cacd450 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -79,41 +79,49 @@
compatible = "samsung,s5pv210-mipi-video-phy";
reg = <0x10020710 8>;
#phy-cells = <1>;
+ syscon = <&pmu_system_controller>;
};
pd_mfc: mfc-power-domain@10023C40 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C40 0x20>;
+ #power-domain-cells = <0>;
};
pd_g3d: g3d-power-domain@10023C60 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C60 0x20>;
+ #power-domain-cells = <0>;
};
pd_lcd0: lcd0-power-domain@10023C80 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C80 0x20>;
+ #power-domain-cells = <0>;
};
pd_tv: tv-power-domain@10023C20 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C20 0x20>;
+ #power-domain-cells = <0>;
};
pd_cam: cam-power-domain@10023C00 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023C00 0x20>;
+ #power-domain-cells = <0>;
};
pd_gps: gps-power-domain@10023CE0 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023CE0 0x20>;
+ #power-domain-cells = <0>;
};
pd_gps_alive: gps-alive-power-domain@10023D00 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023D00 0x20>;
+ #power-domain-cells = <0>;
};
gic: interrupt-controller@10490000 {
@@ -150,7 +158,7 @@
compatible = "samsung,exynos4210-mipi-dsi";
reg = <0x11C80000 0x10000>;
interrupts = <0 79 0>;
- samsung,power-domain = <&pd_lcd0>;
+ power-domains = <&pd_lcd0>;
phys = <&mipi_phy 1>;
phy-names = "dsim";
clocks = <&clock CLK_DSIM0>, <&clock CLK_SCLK_MIPI0>;
@@ -175,7 +183,7 @@
interrupts = <0 84 0>;
clocks = <&clock CLK_FIMC0>, <&clock CLK_SCLK_FIMC0>;
clock-names = "fimc", "sclk_fimc";
- samsung,power-domain = <&pd_cam>;
+ power-domains = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
status = "disabled";
};
@@ -186,7 +194,7 @@
interrupts = <0 85 0>;
clocks = <&clock CLK_FIMC1>, <&clock CLK_SCLK_FIMC1>;
clock-names = "fimc", "sclk_fimc";
- samsung,power-domain = <&pd_cam>;
+ power-domains = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
status = "disabled";
};
@@ -197,7 +205,7 @@
interrupts = <0 86 0>;
clocks = <&clock CLK_FIMC2>, <&clock CLK_SCLK_FIMC2>;
clock-names = "fimc", "sclk_fimc";
- samsung,power-domain = <&pd_cam>;
+ power-domains = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
status = "disabled";
};
@@ -208,7 +216,7 @@
interrupts = <0 87 0>;
clocks = <&clock CLK_FIMC3>, <&clock CLK_SCLK_FIMC3>;
clock-names = "fimc", "sclk_fimc";
- samsung,power-domain = <&pd_cam>;
+ power-domains = <&pd_cam>;
samsung,sysreg = <&sys_reg>;
status = "disabled";
};
@@ -220,7 +228,7 @@
clocks = <&clock CLK_CSIS0>, <&clock CLK_SCLK_CSIS0>;
clock-names = "csis", "sclk_csis";
bus-width = <4>;
- samsung,power-domain = <&pd_cam>;
+ power-domains = <&pd_cam>;
phys = <&mipi_phy 0>;
phy-names = "csis";
status = "disabled";
@@ -235,7 +243,7 @@
clocks = <&clock CLK_CSIS1>, <&clock CLK_SCLK_CSIS1>;
clock-names = "csis", "sclk_csis";
bus-width = <2>;
- samsung,power-domain = <&pd_cam>;
+ power-domains = <&pd_cam>;
phys = <&mipi_phy 2>;
phy-names = "csis";
status = "disabled";
@@ -400,7 +408,7 @@
compatible = "samsung,mfc-v5";
reg = <0x13400000 0x10000>;
interrupts = <0 94 0>;
- samsung,power-domain = <&pd_mfc>;
+ power-domains = <&pd_mfc>;
clocks = <&clock CLK_MFC>, <&clock CLK_SCLK_MFC>;
clock-names = "mfc", "sclk_mfc";
status = "disabled";
@@ -650,8 +658,116 @@
interrupts = <11 0>, <11 1>, <11 2>;
clocks = <&clock CLK_SCLK_FIMD0>, <&clock CLK_FIMD0>;
clock-names = "sclk_fimd", "fimd";
- samsung,power-domain = <&pd_lcd0>;
+ power-domains = <&pd_lcd0>;
samsung,sysreg = <&sys_reg>;
status = "disabled";
};
+
+ ppmu_dmc0: ppmu_dmc0@106a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106a0000 0x2000>;
+ clocks = <&clock CLK_PPMUDMC0>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_dmc1: ppmu_dmc1@106b0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106b0000 0x2000>;
+ clocks = <&clock CLK_PPMUDMC1>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_cpu: ppmu_cpu@106c0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106c0000 0x2000>;
+ clocks = <&clock CLK_PPMUCPU>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_acp: ppmu_acp@10ae0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x106e0000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_rightbus: ppmu_rightbus@112a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x112a0000 0x2000>;
+ clocks = <&clock CLK_PPMURIGHT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_leftbus: ppmu_leftbus0@116a0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x116a0000 0x2000>;
+ clocks = <&clock CLK_PPMULEFT>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_camif: ppmu_camif@11ac0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11ac0000 0x2000>;
+ clocks = <&clock CLK_PPMUCAMIF>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_lcd0: ppmu_lcd0@11e40000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x11e40000 0x2000>;
+ clocks = <&clock CLK_PPMULCD0>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_fsys: ppmu_g3d@12630000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12630000 0x2000>;
+ status = "disabled";
+ };
+
+ ppmu_image: ppmu_image@12aa0000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12aa0000 0x2000>;
+ clocks = <&clock CLK_PPMUIMAGE>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_tv: ppmu_tv@12e40000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12e40000 0x2000>;
+ clocks = <&clock CLK_PPMUTV>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_g3d: ppmu_g3d@13220000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13220000 0x2000>;
+ clocks = <&clock CLK_PPMUG3D>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_mfc_left: ppmu_mfc_left@13660000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13660000 0x2000>;
+ clocks = <&clock CLK_PPMUMFC_L>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
+
+ ppmu_mfc_right: ppmu_mfc_right@13670000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x13670000 0x2000>;
+ clocks = <&clock CLK_PPMUMFC_R>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index a406df3d6df8..3d6652a4b6cb 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -92,6 +92,7 @@
hsotg@12480000 {
vusb_d-supply = <&vusb_reg>;
vusb_a-supply = <&vusbdac_reg>;
+ dr_mode = "peripheral";
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 6effb13f98a6..b57e6b82ea20 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -72,6 +72,7 @@
hsotg@12480000 {
vusb_d-supply = <&ldo3_reg>;
vusb_a-supply = <&ldo8_reg>;
+ dr_mode = "peripheral";
status = "okay";
};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 8e45ea44317e..67c832c9dcf1 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -79,6 +79,7 @@
pd_lcd1: lcd1-power-domain@10023CA0 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023CA0 0x20>;
+ #power-domain-cells = <0>;
};
l2c: l2-cache-controller@10502000 {
@@ -201,4 +202,12 @@
samsung,lcd-wb;
};
};
+
+ ppmu_lcd1: ppmu_lcd1@12240000 {
+ compatible = "samsung,exynos-ppmu";
+ reg = <0x12240000 0x2000>;
+ clocks = <&clock CLK_PPMULCD1>;
+ clock-names = "ppmu";
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 2c43d1859308..de80b5bba204 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -402,6 +402,7 @@
};
hsotg@12480000 {
+ dr_mode = "peripheral";
status = "okay";
vusb_d-supply = <&ldo15_reg>;
vusb_a-supply = <&ldo12_reg>;
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 5fbb01335a0f..21f748083586 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -15,6 +15,7 @@
/dts-v1/;
#include "exynos4412.dtsi"
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
/ {
model = "Samsung Trats 2 based on Exynos4412";
@@ -24,6 +25,7 @@
i2c9 = &i2c_ak8975;
i2c10 = &i2c_cm36651;
i2c11 = &i2c_max77693;
+ i2c12 = &i2c_max77693_fuel;
};
memory {
@@ -57,15 +59,6 @@
#address-cells = <1>;
#size-cells = <0>;
- vemmc_reg: regulator-0 {
- compatible = "regulator-fixed";
- regulator-name = "VMEM_VDD_2.8V";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- gpio = <&gpk0 2 0>;
- enable-active-high;
- };
-
cam_io_reg: voltage-regulator-1 {
compatible = "regulator-fixed";
regulator-name = "CAM_SENSOR_A";
@@ -93,16 +86,6 @@
enable-active-high;
};
- cam_isp_core_reg: voltage-regulator-4 {
- compatible = "regulator-fixed";
- regulator-name = "CAM_ISP_CORE_1.2V_EN";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- gpio = <&gpm0 3 0>;
- enable-active-high;
- regulator-always-on;
- };
-
ps_als_reg: voltage-regulator-5 {
compatible = "regulator-fixed";
regulator-name = "LED_A_3.0V";
@@ -204,6 +187,25 @@
};
};
+ i2c@138A0000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <100000>;
+ pinctrl-0 = <&i2c4_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ wm1811: wm1811@1a {
+ compatible = "wlf,wm1811";
+ reg = <0x1a>;
+ clocks = <&pmu_system_controller 0>;
+ clock-names = "MCLK1";
+ DCVDD-supply = <&ldo3_reg>;
+ DBVDD1-supply = <&ldo3_reg>;
+ wlf,ldo1ena = <&gpj0 4 0>;
+ };
+ };
+
i2c@138D0000 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-slave-addr = <0x10>;
@@ -226,7 +228,6 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
- regulator-mem-on;
};
ldo2_reg: ldo2 {
@@ -235,7 +236,9 @@
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
- regulator-mem-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
ldo3_reg: ldo3 {
@@ -244,7 +247,6 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
- regulator-mem-on;
};
ldo4_reg: ldo4 {
@@ -253,7 +255,6 @@
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
- regulator-mem-on;
};
ldo5_reg: ldo5 {
@@ -262,7 +263,6 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
- regulator-mem-on;
};
ldo6_reg: ldo6 {
@@ -271,7 +271,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
- regulator-mem-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
ldo7_reg: ldo7 {
@@ -280,7 +282,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
- regulator-mem-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
ldo8_reg: ldo8 {
@@ -288,7 +292,9 @@
regulator-name = "VMIPI_1.0V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo9_reg: ldo9 {
@@ -296,7 +302,6 @@
regulator-name = "CAM_ISP_MIPI_1.2V";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
- regulator-mem-idle;
};
ldo10_reg: ldo10 {
@@ -304,7 +309,9 @@
regulator-name = "VMIPI_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo11_reg: ldo11 {
@@ -313,7 +320,9 @@
regulator-min-microvolt = <1950000>;
regulator-max-microvolt = <1950000>;
regulator-always-on;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo12_reg: ldo12 {
@@ -321,7 +330,9 @@
regulator-name = "VUOTG_3.0V";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo13_reg: ldo13 {
@@ -329,7 +340,6 @@
regulator-name = "NFC_AVDD_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-mem-idle;
};
ldo14_reg: ldo14 {
@@ -338,7 +348,9 @@
regulator-min-microvolt = <1950000>;
regulator-max-microvolt = <1950000>;
regulator-always-on;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo15_reg: ldo15 {
@@ -346,7 +358,9 @@
regulator-name = "VHSIC_1.0V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
ldo16_reg: ldo16 {
@@ -354,7 +368,9 @@
regulator-name = "VHSIC_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
ldo17_reg: ldo17 {
@@ -362,7 +378,6 @@
regulator-name = "CAM_SENSOR_CORE_1.2V";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
- regulator-mem-idle;
};
ldo18_reg: ldo18 {
@@ -370,7 +385,6 @@
regulator-name = "CAM_ISP_SEN_IO_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-mem-idle;
};
ldo19_reg: ldo19 {
@@ -378,7 +392,6 @@
regulator-name = "VT_CAM_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-mem-idle;
};
ldo20_reg: ldo20 {
@@ -386,7 +399,6 @@
regulator-name = "VDDQ_PRE_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-mem-idle;
};
ldo21_reg: ldo21 {
@@ -394,7 +406,7 @@
regulator-name = "VTF_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- regulator-mem-idle;
+ maxim,ena-gpios = <&gpy2 0 GPIO_ACTIVE_HIGH>;
};
ldo22_reg: ldo22 {
@@ -402,6 +414,7 @@
regulator-name = "VMEM_VDD_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
+ maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
};
ldo23_reg: ldo23 {
@@ -409,7 +422,6 @@
regulator-name = "TSP_AVDD_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- regulator-mem-idle;
};
ldo24_reg: ldo24 {
@@ -417,7 +429,6 @@
regulator-name = "TSP_VDD_1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
- regulator-mem-idle;
};
ldo25_reg: ldo25 {
@@ -425,7 +436,6 @@
regulator-name = "LCD_VCC_3.3V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- regulator-mem-idle;
};
ldo26_reg: ldo26 {
@@ -433,7 +443,6 @@
regulator-name = "MOTOR_VCC_3.0V";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
- regulator-mem-idle;
};
buck1_reg: buck1 {
@@ -443,7 +452,9 @@
regulator-max-microvolt = <1100000>;
regulator-always-on;
regulator-boot-on;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck2_reg: buck2 {
@@ -453,7 +464,9 @@
regulator-max-microvolt = <1500000>;
regulator-always-on;
regulator-boot-on;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
buck3_reg: buck3 {
@@ -463,7 +476,9 @@
regulator-max-microvolt = <1150000>;
regulator-always-on;
regulator-boot-on;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck4_reg: buck4 {
@@ -472,7 +487,9 @@
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1150000>;
regulator-boot-on;
- regulator-mem-off;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck5_reg: buck5 {
@@ -504,6 +521,7 @@
regulator-name = "VMEM_VDDF_3.0V";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
+ maxim,ena-gpios = <&gpk0 2 GPIO_ACTIVE_HIGH>;
};
buck9_reg: buck9 {
@@ -511,7 +529,7 @@
regulator-name = "CAM_ISP_CORE_1.2V";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1200000>;
- regulator-mem-off;
+ maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
};
};
};
@@ -550,6 +568,32 @@
haptic-supply = <&ldo26_reg>;
pwms = <&pwm 0 38022 0>;
};
+
+ charger {
+ compatible = "maxim,max77693-charger";
+
+ maxim,constant-microvolt = <4350000>;
+ maxim,min-system-microvolt = <3600000>;
+ maxim,thermal-regulation-celsius = <100>;
+ maxim,battery-overcurrent-microamp = <3500000>;
+ maxim,charge-input-threshold-microvolt = <4300000>;
+ };
+ };
+ };
+
+ i2c_max77693_fuel: i2c-gpio-3 {
+ compatible = "i2c-gpio";
+ gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>, <&gpf1 4 GPIO_ACTIVE_HIGH>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ max77693-fuel-gauge@36 {
+ compatible = "maxim,max17047";
+ interrupt-parent = <&gpx2>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+ reg = <0x36>;
};
};
@@ -558,7 +602,7 @@
broken-cd;
non-removable;
card-detect-delay = <200>;
- vmmc-supply = <&vemmc_reg>;
+ vmmc-supply = <&ldo22_reg>;
clock-frequency = <400000000>;
samsung,dw-mshc-ciu-div = <0>;
samsung,dw-mshc-sdr-timing = <2 3>;
@@ -722,8 +766,8 @@
status = "okay";
assigned-clocks = <&clock CLK_MOUT_CAM0>,
<&clock CLK_MOUT_CAM1>;
- assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>,
- <&clock CLK_MOUT_MPLL_USER_T>;
+ assigned-clock-parents = <&clock CLK_XUSBXTI>,
+ <&clock CLK_XUSBXTI>;
fimc_0: fimc@11800000 {
status = "okay";
@@ -839,6 +883,24 @@
};
};
+ i2s0: i2s@03830000 {
+ pinctrl-0 = <&i2s0_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+ };
+
+ sound {
+ compatible = "samsung,trats2-audio";
+ samsung,i2s-controller = <&i2s0>;
+ samsung,model = "Trats2";
+ samsung,audio-codec = <&wm1811>;
+ samsung,audio-routing =
+ "SPK", "SPKOUTLN",
+ "SPK", "SPKOUTLP",
+ "SPK", "SPKOUTRN",
+ "SPK", "SPKOUTRP";
+ };
+
exynos-usbphy@125B0000 {
status = "okay";
};
@@ -846,6 +908,7 @@
hsotg@12480000 {
vusb_d-supply = <&ldo15_reg>;
vusb_a-supply = <&ldo12_reg>;
+ dr_mode = "peripheral";
status = "okay";
};
@@ -866,6 +929,51 @@
};
};
+&pmu_system_controller {
+ assigned-clocks = <&pmu_system_controller 0>;
+ assigned-clock-parents = <&clock CLK_XUSBXTI>;
+};
+
+&ppmu_dmc0 {
+ status = "okay";
+
+ events {
+ ppmu_dmc0_3: ppmu-event3-dmc0 {
+ event-name = "ppmu-event3-dmc0";
+ };
+ };
+};
+
+&ppmu_dmc1 {
+ status = "okay";
+
+ events {
+ ppmu_dmc1_3: ppmu-event3-dmc1 {
+ event-name = "ppmu-event3-dmc1";
+ };
+ };
+};
+
+&ppmu_leftbus {
+ status = "okay";
+
+ events {
+ ppmu_leftbus_3: ppmu-event3-leftbus {
+ event-name = "ppmu-event3-leftbus";
+ };
+ };
+};
+
+&ppmu_rightbus {
+ status = "okay";
+
+ events {
+ ppmu_rightbus_3: ppmu-event3-rightbus {
+ event-name = "ppmu-event3-rightbus";
+ };
+ };
+};
+
&pinctrl_0 {
pinctrl-names = "default";
pinctrl-0 = <&sleep0>;
diff --git a/arch/arm/boot/dts/exynos4415.dtsi b/arch/arm/boot/dts/exynos4415.dtsi
index c1c9b37340d9..5caea996e090 100644
--- a/arch/arm/boot/dts/exynos4415.dtsi
+++ b/arch/arm/boot/dts/exynos4415.dtsi
@@ -131,36 +131,43 @@
pd_cam: cam-power-domain@10024000 {
compatible = "samsung,exynos4210-pd";
reg = <0x10024000 0x20>;
+ #power-domain-cells = <0>;
};
pd_tv: tv-power-domain@10024020 {
compatible = "samsung,exynos4210-pd";
reg = <0x10024020 0x20>;
+ #power-domain-cells = <0>;
};
pd_mfc: mfc-power-domain@10024040 {
compatible = "samsung,exynos4210-pd";
reg = <0x10024040 0x20>;
+ #power-domain-cells = <0>;
};
pd_g3d: g3d-power-domain@10024060 {
compatible = "samsung,exynos4210-pd";
reg = <0x10024060 0x20>;
+ #power-domain-cells = <0>;
};
pd_lcd0: lcd0-power-domain@10024080 {
compatible = "samsung,exynos4210-pd";
reg = <0x10024080 0x20>;
+ #power-domain-cells = <0>;
};
pd_isp0: isp0-power-domain@100240A0 {
compatible = "samsung,exynos4210-pd";
reg = <0x100240A0 0x20>;
+ #power-domain-cells = <0>;
};
pd_isp1: isp1-power-domain@100240E0 {
compatible = "samsung,exynos4210-pd";
reg = <0x100240E0 0x20>;
+ #power-domain-cells = <0>;
};
cmu: clock-controller@10030000 {
@@ -234,6 +241,33 @@
interrupts = <0 240 0>;
};
+ fimd: fimd@11C00000 {
+ compatible = "samsung,exynos4415-fimd";
+ reg = <0x11C00000 0x30000>;
+ interrupt-names = "fifo", "vsync", "lcd_sys";
+ interrupts = <0 84 0>, <0 85 0>, <0 86 0>;
+ clocks = <&cmu CLK_SCLK_FIMD0>, <&cmu CLK_FIMD0>;
+ clock-names = "sclk_fimd", "fimd";
+ samsung,power-domain = <&pd_lcd0>;
+ samsung,sysreg = <&sysreg_system_controller>;
+ status = "disabled";
+ };
+
+ dsi_0: dsi@11C80000 {
+ compatible = "samsung,exynos4415-mipi-dsi";
+ reg = <0x11C80000 0x10000>;
+ interrupts = <0 83 0>;
+ samsung,phy-type = <0>;
+ samsung,power-domain = <&pd_lcd0>;
+ phys = <&mipi_phy 1>;
+ phy-names = "dsim";
+ clocks = <&cmu CLK_DSIM0>, <&cmu CLK_SCLK_MIPI0>;
+ clock-names = "bus_clk", "pll_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
hsotg: hsotg@12480000 {
compatible = "samsung,s3c6400-hsotg";
reg = <0x12480000 0x20000>;
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 8bc97c415c9a..f5e0ae780d6c 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -52,6 +52,7 @@
pd_isp: isp-power-domain@10023CA0 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023CA0 0x20>;
+ #power-domain-cells = <0>;
};
l2c: l2-cache-controller@10502000 {
@@ -209,7 +210,7 @@
compatible = "samsung,exynos4212-fimc-lite";
reg = <0x12390000 0x1000>;
interrupts = <0 105 0>;
- samsung,power-domain = <&pd_isp>;
+ power-domains = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE0>;
clock-names = "flite";
status = "disabled";
@@ -219,7 +220,7 @@
compatible = "samsung,exynos4212-fimc-lite";
reg = <0x123A0000 0x1000>;
interrupts = <0 106 0>;
- samsung,power-domain = <&pd_isp>;
+ power-domains = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE1>;
clock-names = "flite";
status = "disabled";
@@ -229,7 +230,7 @@
compatible = "samsung,exynos4212-fimc-is", "simple-bus";
reg = <0x12000000 0x260000>;
interrupts = <0 90 0>, <0 95 0>;
- samsung,power-domain = <&pd_isp>;
+ power-domains = <&pd_isp>;
clocks = <&clock CLK_FIMC_LITE0>,
<&clock CLK_FIMC_LITE1>, <&clock CLK_PPMUISPX>,
<&clock CLK_PPMUISPMX>,
@@ -239,7 +240,7 @@
<&clock CLK_DIV_ISP0>,<&clock CLK_DIV_ISP1>,
<&clock CLK_DIV_MCUISP0>,
<&clock CLK_DIV_MCUISP1>,
- <&clock CLK_SCLK_UART_ISP>,
+ <&clock CLK_UART_ISP_SCLK>,
<&clock CLK_ACLK200>, <&clock CLK_DIV_ACLK200>,
<&clock CLK_ACLK400_MCUISP>,
<&clock CLK_DIV_ACLK400_MCUISP>;
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index effaf2af41bc..b9aeec430527 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -33,6 +33,8 @@
gpio-keys {
compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_key_irq &lid_irq>;
power {
label = "Power";
@@ -540,6 +542,13 @@
};
&pinctrl_0 {
+ power_key_irq: power-key-irq {
+ samsung,pins = "gpx1-3";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
ec_irq: ec-irq {
samsung,pins = "gpx1-6";
samsung,pin-function = <0>;
@@ -575,6 +584,13 @@
samsung,pin-drv = <0>;
};
+ lid_irq: lid-irq {
+ samsung,pins = "gpx3-5";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
hdmi_hpd_irq: hdmi-hpd-irq {
samsung,pins = "gpx3-7";
samsung,pin-function = <0>;
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index d75c89d7666a..9bb1b0b738f5 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -93,11 +93,13 @@
pd_gsc: gsc-power-domain@10044000 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044000 0x20>;
+ #power-domain-cells = <0>;
};
pd_mfc: mfc-power-domain@10044040 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044040 0x20>;
+ #power-domain-cells = <0>;
};
clock: clock-controller@10010000 {
@@ -222,7 +224,7 @@
compatible = "samsung,mfc-v6";
reg = <0x11000000 0x10000>;
interrupts = <0 96 0>;
- samsung,power-domain = <&pd_mfc>;
+ power-domains = <&pd_mfc>;
clocks = <&clock CLK_MFC>;
clock-names = "mfc";
};
@@ -682,7 +684,7 @@
compatible = "samsung,exynos5-gsc";
reg = <0x13e00000 0x1000>;
interrupts = <0 85 0>;
- samsung,power-domain = <&pd_gsc>;
+ power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL0>;
clock-names = "gscl";
};
@@ -691,7 +693,7 @@
compatible = "samsung,exynos5-gsc";
reg = <0x13e10000 0x1000>;
interrupts = <0 86 0>;
- samsung,power-domain = <&pd_gsc>;
+ power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL1>;
clock-names = "gscl";
};
@@ -700,7 +702,7 @@
compatible = "samsung,exynos5-gsc";
reg = <0x13e20000 0x1000>;
interrupts = <0 87 0>;
- samsung,power-domain = <&pd_gsc>;
+ power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL2>;
clock-names = "gscl";
};
@@ -709,7 +711,7 @@
compatible = "samsung,exynos5-gsc";
reg = <0x13e30000 0x1000>;
interrupts = <0 88 0>;
- samsung,power-domain = <&pd_gsc>;
+ power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL3>;
clock-names = "gscl";
};
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 9a050e19a4dc..c47bb70665c1 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -13,6 +13,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/clock/maxim,max77802.h>
+#include <dt-bindings/regulator/maxim,max77802.h>
#include "exynos5420.dtsi"
/ {
@@ -53,7 +54,7 @@
compatible = "gpio-keys";
pinctrl-names = "default";
- pinctrl-0 = <&power_key_irq>;
+ pinctrl-0 = <&power_key_irq &lid_irq>;
power {
label = "Power";
@@ -61,6 +62,15 @@
linux,code = <KEY_POWER>;
gpio-key,wakeup;
};
+
+ lid-switch {
+ label = "Lid";
+ gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
};
memory {
@@ -192,6 +202,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck2_reg: BUCK2 {
@@ -201,6 +214,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck3_reg: BUCK3 {
@@ -210,6 +226,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck4_reg: BUCK4 {
@@ -219,6 +238,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck5_reg: BUCK5 {
@@ -227,6 +249,9 @@
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck6_reg: BUCK6 {
@@ -236,6 +261,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck7_reg: BUCK7 {
@@ -244,6 +272,9 @@
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
buck8_reg: BUCK8 {
@@ -252,6 +283,9 @@
regulator-max-microvolt = <2850000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck9_reg: BUCK9 {
@@ -260,6 +294,9 @@
regulator-max-microvolt = <2000000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
buck10_reg: BUCK10 {
@@ -268,6 +305,9 @@
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
ldo1_reg: LDO1 {
@@ -275,6 +315,10 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo2_reg: LDO2 {
@@ -288,6 +332,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
vqmmc_sdcard: ldo4_reg: LDO4 {
@@ -295,6 +343,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo5_reg: LDO5 {
@@ -302,6 +353,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo6_reg: LDO6 {
@@ -309,6 +363,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo7_reg: LDO7 {
@@ -322,6 +379,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo9_reg: LDO9 {
@@ -329,6 +389,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo10_reg: LDO10 {
@@ -336,6 +400,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo11_reg: LDO11 {
@@ -343,6 +410,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo12_reg: LDO12 {
@@ -350,6 +421,9 @@
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo13_reg: LDO13 {
@@ -357,6 +431,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo14_reg: LDO14 {
@@ -364,6 +442,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo15_reg: LDO15 {
@@ -371,6 +452,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo17_reg: LDO17 {
@@ -378,6 +462,9 @@
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo18_reg: LDO18 {
@@ -451,6 +538,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo32_reg: LDO32 {
@@ -658,6 +748,13 @@
samsung,pin-drv = <0>;
};
+ lid_irq: lid-irq {
+ samsung,pins = "gpx3-4";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
hdmi_hpd_irq: hdmi-hpd-irq {
samsung,pins = "gpx3-7";
samsung,pin-function = <0>;
@@ -815,6 +912,7 @@
};
tps65090_fet5: fet5 {
regulator-name = "camout";
+ regulator-always-on;
};
tps65090_fet6: fet6 {
regulator-name = "lcd_vdd";
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 6d38f8bfd0e6..9dc2e9773b30 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -178,7 +178,7 @@
interrupts = <0 96 0>;
clocks = <&clock CLK_MFC>;
clock-names = "mfc";
- samsung,power-domain = <&mfc_pd>;
+ power-domains = <&mfc_pd>;
};
mmc_0: mmc@12200000 {
@@ -250,11 +250,13 @@
gsc_pd: power-domain@10044000 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044000 0x20>;
+ #power-domain-cells = <0>;
};
isp_pd: power-domain@10044020 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044020 0x20>;
+ #power-domain-cells = <0>;
};
mfc_pd: power-domain@10044060 {
@@ -263,11 +265,27 @@
clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>,
<&clock CLK_MOUT_USER_ACLK333>;
clock-names = "oscclk", "pclk0", "clk0";
+ #power-domain-cells = <0>;
};
msc_pd: power-domain@10044120 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044120 0x20>;
+ #power-domain-cells = <0>;
+ };
+
+ disp_pd: power-domain@100440C0 {
+ compatible = "samsung,exynos4210-pd";
+ reg = <0x100440C0 0x20>;
+ #power-domain-cells = <0>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK200>,
+ <&clock CLK_MOUT_USER_ACLK200_DISP1>,
+ <&clock CLK_MOUT_SW_ACLK300>,
+ <&clock CLK_MOUT_USER_ACLK300_DISP1>,
+ <&clock CLK_MOUT_SW_ACLK400>,
+ <&clock CLK_MOUT_USER_ACLK400_DISP1>;
+ clock-names = "oscclk", "pclk0", "clk0",
+ "pclk1", "clk1", "pclk2", "clk2";
};
pinctrl_0: pinctrl@13400000 {
@@ -537,6 +555,7 @@
fimd: fimd@14400000 {
clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
clock-names = "sclk_fimd", "fimd";
+ power-domains = <&disp_pd>;
};
adc: adc@12D10000 {
@@ -710,6 +729,7 @@
phy = <&hdmiphy>;
samsung,syscon-phandle = <&pmu_system_controller>;
status = "disabled";
+ power-domains = <&disp_pd>;
};
hdmiphy: hdmiphy@145D0000 {
@@ -722,6 +742,7 @@
interrupts = <0 94 0>;
clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>;
clock-names = "mixer", "sclk_hdmi";
+ power-domains = <&disp_pd>;
};
gsc_0: video-scaler@13e00000 {
@@ -730,7 +751,7 @@
interrupts = <0 85 0>;
clocks = <&clock CLK_GSCL0>;
clock-names = "gscl";
- samsung,power-domain = <&gsc_pd>;
+ power-domains = <&gsc_pd>;
};
gsc_1: video-scaler@13e10000 {
@@ -739,7 +760,7 @@
interrupts = <0 86 0>;
clocks = <&clock CLK_GSCL1>;
clock-names = "gscl";
- samsung,power-domain = <&gsc_pd>;
+ power-domains = <&gsc_pd>;
};
pmu_system_controller: system-controller@10040000 {
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
new file mode 100644
index 000000000000..a519c863248d
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -0,0 +1,371 @@
+/*
+ * Hardkernel Odroid XU3 board device tree source
+ *
+ * Copyright (c) 2014 Collabora Ltd.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos5800.dtsi"
+
+/ {
+ model = "Hardkernel Odroid XU3";
+ compatible = "hardkernel,odroid-xu3", "samsung,exynos5800", "samsung,exynos5";
+
+ memory {
+ reg = <0x40000000 0x7EA00000>;
+ };
+
+ chosen {
+ linux,stdout-path = &serial_2;
+ };
+
+ fimd@14400000 {
+ status = "okay";
+ };
+
+ firmware@02073000 {
+ compatible = "samsung,secure-firmware";
+ reg = <0x02073000 0x1000>;
+ };
+
+ fixed-rate-clocks {
+ oscclk {
+ compatible = "samsung,exynos5420-oscclk";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ hsi2c_4: i2c@12CA0000 {
+ status = "okay";
+
+ s2mps11_pmic@66 {
+ compatible = "samsung,s2mps11-pmic";
+ reg = <0x66>;
+ s2mps11,buck2-ramp-delay = <12>;
+ s2mps11,buck34-ramp-delay = <12>;
+ s2mps11,buck16-ramp-delay = <12>;
+ s2mps11,buck6-ramp-enable = <1>;
+ s2mps11,buck2-ramp-enable = <1>;
+ s2mps11,buck3-ramp-enable = <1>;
+ s2mps11,buck4-ramp-enable = <1>;
+
+ s2mps11_osc: clocks {
+ #clock-cells = <1>;
+ clock-output-names = "s2mps11_ap",
+ "s2mps11_cp", "s2mps11_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "vdd_ldo1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "vdd_ldo3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "vdd_ldo5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "vdd_ldo6";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "vdd_ldo7";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "vdd_ldo8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "vdd_ldo9";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "vdd_ldo10";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "vdd_ldo11";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "vdd_ldo12";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "vdd_ldo13";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "vdd_ldo15";
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-always-on;
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "vdd_ldo16";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ regulator-always-on;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "tsp_avdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "tsp_io";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "vdd_ldo26";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "vdd_mif";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "vdd_int";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "vdd_g3d";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "vdd_mem";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "vdd_kfc";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "vdd_1.0v_ldo";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "vdd_1.8v_ldo";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "vdd_2.8v_ldo";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3750000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_vmem";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ i2c_2: i2c@12C80000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <66000>;
+ status = "okay";
+
+ hdmiddc@50 {
+ compatible = "samsung,exynos4210-hdmiddc";
+ reg = <0x50>;
+ };
+ };
+
+ rtc@101E0000 {
+ status = "okay";
+ };
+};
+
+&hdmi {
+ status = "okay";
+ hpd-gpio = <&gpx3 7 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_hpd_irq>;
+
+ vdd_osc-supply = <&ldo7_reg>;
+ vdd_pll-supply = <&ldo6_reg>;
+ vdd-supply = <&ldo6_reg>;
+};
+
+&mfc {
+ samsung,mfc-r = <0x43000000 0x800000>;
+ samsung,mfc-l = <0x51000000 0x800000>;
+};
+
+&mmc_0 {
+ status = "okay";
+ broken-cd;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+};
+
+&mmc_2 {
+ status = "okay";
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+};
+
+&pinctrl_0 {
+ hdmi_hpd_irq: hdmi-hpd-irq {
+ samsung,pins = "gpx3-7";
+ samsung,pin-function = <0>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&usbdrd_dwc3_0 {
+ dr_mode = "host";
+};
+
+&usbdrd_dwc3_1 {
+ dr_mode = "otg";
+};
+
+&i2c_0 {
+ status = "okay";
+
+ /* A15 cluster: VDD_ARM */
+ ina231@40 {
+ compatible = "ti,ina231";
+ reg = <0x40>;
+ shunt-resistor = <10000>;
+ };
+
+ /* memory: VDD_MEM */
+ ina231@41 {
+ compatible = "ti,ina231";
+ reg = <0x41>;
+ shunt-resistor = <10000>;
+ };
+
+ /* GPU: VDD_G3D */
+ ina231@44 {
+ compatible = "ti,ina231";
+ reg = <0x44>;
+ shunt-resistor = <10000>;
+ };
+
+ /* A7 cluster: VDD_KFC */
+ ina231@45 {
+ compatible = "ti,ina231";
+ reg = <0x45>;
+ shunt-resistor = <10000>;
+ };
+};
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index e8fdda827fc9..06737c60d333 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -13,6 +13,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/clock/maxim,max77802.h>
+#include <dt-bindings/regulator/maxim,max77802.h>
#include "exynos5800.dtsi"
/ {
@@ -52,7 +53,7 @@
compatible = "gpio-keys";
pinctrl-names = "default";
- pinctrl-0 = <&power_key_irq>;
+ pinctrl-0 = <&power_key_irq &lid_irq>;
power {
label = "Power";
@@ -60,6 +61,16 @@
linux,code = <KEY_POWER>;
gpio-key,wakeup;
};
+
+ lid-switch {
+ label = "Lid";
+ gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;
+ linux,input-type = <5>; /* EV_SW */
+ linux,code = <0>; /* SW_LID */
+ debounce-interval = <1>;
+ gpio-key,wakeup;
+ };
+
};
memory {
@@ -191,6 +202,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck2_reg: BUCK2 {
@@ -200,6 +214,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck3_reg: BUCK3 {
@@ -209,6 +226,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck4_reg: BUCK4 {
@@ -218,6 +238,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck5_reg: BUCK5 {
@@ -226,6 +249,9 @@
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck6_reg: BUCK6 {
@@ -235,6 +261,9 @@
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <12500>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck7_reg: BUCK7 {
@@ -243,6 +272,9 @@
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
buck8_reg: BUCK8 {
@@ -251,6 +283,9 @@
regulator-max-microvolt = <2850000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
buck9_reg: BUCK9 {
@@ -259,6 +294,9 @@
regulator-max-microvolt = <2000000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
buck10_reg: BUCK10 {
@@ -267,6 +305,9 @@
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
ldo1_reg: LDO1 {
@@ -274,6 +315,10 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo2_reg: LDO2 {
@@ -287,6 +332,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
vqmmc_sdcard: ldo4_reg: LDO4 {
@@ -294,6 +343,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo5_reg: LDO5 {
@@ -301,6 +353,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo6_reg: LDO6 {
@@ -308,6 +363,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo7_reg: LDO7 {
@@ -321,6 +379,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo9_reg: LDO9 {
@@ -328,6 +389,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo10_reg: LDO10 {
@@ -335,6 +400,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo11_reg: LDO11 {
@@ -342,6 +410,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo12_reg: LDO12 {
@@ -349,6 +421,9 @@
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo13_reg: LDO13 {
@@ -356,6 +431,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-mode = <MAX77802_OPMODE_LP>;
+ };
};
ldo14_reg: LDO14 {
@@ -363,6 +442,9 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo15_reg: LDO15 {
@@ -370,6 +452,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo17_reg: LDO17 {
@@ -377,6 +462,9 @@
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo18_reg: LDO18 {
@@ -450,6 +538,9 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
ldo32_reg: LDO32 {
@@ -646,6 +737,13 @@
samsung,pin-drv = <0>;
};
+ lid_irq: lid-irq {
+ samsung,pins = "gpx3-4";
+ samsung,pin-function = <0xf>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
hdmi_hpd_irq: hdmi-hpd-irq {
samsung,pins = "gpx3-7";
samsung,pin-function = <0>;
@@ -803,6 +901,7 @@
};
tps65090_fet5: fet5 {
regulator-name = "camout";
+ regulator-always-on;
};
tps65090_fet6: fet6 {
regulator-name = "lcd_vdd";
diff --git a/arch/arm/boot/dts/hip01-ca9x2.dts b/arch/arm/boot/dts/hip01-ca9x2.dts
new file mode 100644
index 000000000000..eca5e42770fe
--- /dev/null
+++ b/arch/arm/boot/dts/hip01-ca9x2.dts
@@ -0,0 +1,51 @@
+/*
+ * Hisilicon Ltd. HiP01 SoC
+ *
+ * Copyright (C) 2014 Hisilicon Ltd.
+ * Copyright (C) 2014 Huawei Ltd.
+ *
+ * Author: Wang Long <long.wanglong@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+/* First 8KB reserved for secondary core boot */
+/memreserve/ 0x80000000 0x00002000;
+
+#include "hip01.dtsi"
+
+/ {
+ model = "Hisilicon HIP01 Development Board";
+ compatible = "hisilicon,hip01-ca9x2", "hisilicon,hip01";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "hisilicon,hip01-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/hip01.dtsi b/arch/arm/boot/dts/hip01.dtsi
new file mode 100644
index 000000000000..33130f8461c3
--- /dev/null
+++ b/arch/arm/boot/dts/hip01.dtsi
@@ -0,0 +1,110 @@
+/*
+ * Hisilicon Ltd. HiP01 SoC
+ *
+ * Copyright (c) 2014 Hisilicon Ltd.
+ * Copyright (c) 2014 Huawei Ltd.
+ *
+ * Author: Wang Long <long.wanglong@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gic: interrupt-controller@1e001000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x1a001000 0x1000>, <0x1a000100 0x1000>;
+ };
+
+ hisi_refclk144mhz: refclk144mkhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <144000000>;
+ clock-output-names = "hisi:refclk144khz";
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges = <0 0x10000000 0x20000000>;
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ ranges;
+
+ uart0: uart@10001000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10001000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 32 4>;
+ status = "disabled";
+ };
+
+ uart1: uart@10002000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10002000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 33 4>;
+ status = "disabled";
+ };
+
+ uart2: uart@10003000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10003000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 34 4>;
+ status = "disabled";
+ };
+
+ uart3: uart@10006000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10006000 0x1000>;
+ clocks = <&hisi_refclk144mhz>;
+ clock-names = "apb_pclk";
+ reg-shift = <2>;
+ interrupts = <0 4 4>;
+ status = "disabled";
+ };
+ };
+
+ system-controller@10000000 {
+ compatible = "hisilicon,hip01-sysctrl", "hisilicon,sysctrl";
+ reg = <0x10000000 0x1000>;
+ reboot-offset = <0x4>;
+ };
+
+ global_timer@0a000200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x0a000200 0x100>;
+ interrupts = <1 11 0xf04>;
+ clocks = <&hisi_refclk144mhz>;
+ };
+
+ local_timer@0a000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x0a000600 0x100>;
+ interrupts = <1 13 0xf04>;
+ clocks = <&hisi_refclk144mhz>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-apf27dev.dts b/arch/arm/boot/dts/imx27-apf27dev.dts
index da306c5dd678..bba3f41b89ef 100644
--- a/arch/arm/boot/dts/imx27-apf27dev.dts
+++ b/arch/arm/boot/dts/imx27-apf27dev.dts
@@ -59,6 +59,21 @@
linux,default-trigger = "heartbeat";
};
};
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_max5821: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "max5821-reg";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+ };
};
&cspi1 {
@@ -107,6 +122,12 @@
compatible = "dallas,ds1374";
reg = <0x68>;
};
+
+ max5821@38 {
+ compatible = "maxim,max5821";
+ reg = <0x38>;
+ vref-supply = <&reg_max5821>;
+ };
};
&i2c2 {
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index 107d713e1cbe..4b063b68db44 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -464,7 +464,7 @@
};
coda: coda@10023000 {
- compatible = "fsl,imx27-vpu";
+ compatible = "fsl,imx27-vpu", "cnm,codadx6";
reg = <0x10023000 0x0200>;
interrupts = <53>;
clocks = <&clks IMX27_CLK_VPU_BAUD_GATE>,
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index 0e13b4b10a92..279249b8c3f3 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -182,7 +182,6 @@
};
lradc@80050000 {
- fsl,lradc-touchscreen-wires = <4>;
status = "okay";
fsl,lradc-touchscreen-wires = <4>;
fsl,ave-ctrl = <4>;
diff --git a/arch/arm/boot/dts/imx51-apf51dev.dts b/arch/arm/boot/dts/imx51-apf51dev.dts
index c5a9a24c280a..93d3ea12328c 100644
--- a/arch/arm/boot/dts/imx51-apf51dev.dts
+++ b/arch/arm/boot/dts/imx51-apf51dev.dts
@@ -16,6 +16,14 @@
model = "Armadeus Systems APF51Dev docking/development board";
compatible = "armadeus,imx51-apf51dev", "armadeus,imx51-apf51", "fsl,imx51";
+ backlight@bl1{
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ compatible = "gpio-backlight";
+ gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
+ default-on;
+ };
+
display@di1 {
compatible = "fsl,imx-parallel-display";
interface-pix-fmt = "bgr666";
@@ -114,6 +122,12 @@
pinctrl-0 = <&pinctrl_hog>;
imx51-apf51dev {
+ pinctrl_backlight: bl1grp {
+ fsl,pins = <
+ MX51_PAD_DI1_D1_CS__GPIO3_4 0x1F5
+ >;
+ };
+
pinctrl_hog: hoggrp {
fsl,pins = <
MX51_PAD_EIM_EB2__GPIO2_22 0x0C5
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index a30bddfdbdb6..ff4fa7ecacd8 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -756,7 +756,7 @@
};
vpu: vpu@63ff4000 {
- compatible = "fsl,imx53-vpu";
+ compatible = "fsl,imx53-vpu", "cnm,coda7541";
reg = <0x63ff4000 0x1000>;
interrupts = <9>;
clocks = <&clks IMX5_CLK_VPU_REFERENCE_GATE>,
@@ -765,6 +765,15 @@
resets = <&src 1>;
iram = <&ocram>;
};
+
+ sahara: crypto@63ff8000 {
+ compatible = "fsl,imx53-sahara";
+ reg = <0x63ff8000 0x4000>;
+ interrupts = <19 20>;
+ clocks = <&clks IMX5_CLK_SAHARA_IPG_GATE>,
+ <&clks IMX5_CLK_SAHARA_IPG_GATE>;
+ clock-names = "ipg", "ahb";
+ };
};
ocram: sram@f8000000 {
diff --git a/arch/arm/boot/dts/imx6dl-udoo.dts b/arch/arm/boot/dts/imx6dl-udoo.dts
new file mode 100644
index 000000000000..e3713f00e819
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-udoo.dts
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-udoo.dtsi"
+
+/ {
+ model = "Udoo i.MX6 Dual-lite Board";
+ compatible = "udoo,imx6dl-udoo", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index 1ac2fe732867..f94bf72832af 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -28,7 +28,7 @@
next-level-cache = <&L2>;
operating-points = <
/* kHz uV */
- 996000 1275000
+ 996000 1250000
792000 1175000
396000 1075000
>;
diff --git a/arch/arm/boot/dts/imx6q-udoo.dts b/arch/arm/boot/dts/imx6q-udoo.dts
index e3bff2ac00db..c3e64ff3d544 100644
--- a/arch/arm/boot/dts/imx6q-udoo.dts
+++ b/arch/arm/boot/dts/imx6q-udoo.dts
@@ -8,137 +8,15 @@
* published by the Free Software Foundation.
*
*/
-
/dts-v1/;
#include "imx6q.dtsi"
+#include "imx6qdl-udoo.dtsi"
/ {
model = "Udoo i.MX6 Quad Board";
compatible = "udoo,imx6q-udoo", "fsl,imx6q";
-
- chosen {
- stdout-path = &uart2;
- };
-
- memory {
- reg = <0x10000000 0x40000000>;
- };
-
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
-
- reg_usb_h1_vbus: regulator@0 {
- compatible = "regulator-fixed";
- reg = <0>;
- regulator-name = "usb_h1_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */
- gpio = <&gpio7 12 0>;
- };
- };
-};
-
-&fec {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_enet>;
- phy-mode = "rgmii";
- status = "okay";
-};
-
-&hdmi {
- ddc-i2c-bus = <&i2c2>;
- status = "okay";
-};
-
-&i2c2 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- status = "okay";
-};
-
-&iomuxc {
- imx6q-udoo {
- pinctrl_enet: enetgrp {
- fsl,pins = <
- MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
- MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
- MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
- MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
- MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
- MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
- MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
- MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
- MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
- MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
- MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
- MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
- MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
- MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
- MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
- MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
- >;
- };
-
- pinctrl_i2c2: i2c2grp {
- fsl,pins = <
- MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
- MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
- >;
- };
-
- pinctrl_uart2: uart2grp {
- fsl,pins = <
- MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
- MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
- >;
- };
-
- pinctrl_usbh: usbhgrp {
- fsl,pins = <
- MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000
- MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x130b0
- >;
- };
-
- pinctrl_usdhc3: usdhc3grp {
- fsl,pins = <
- MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
- MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
- MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
- MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
- MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
- MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
- >;
- };
- };
};
&sata {
status = "okay";
};
-
-&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
- status = "okay";
-};
-
-&usbh1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbh>;
- vbus-supply = <&reg_usb_h1_vbus>;
- clocks = <&clks 201>;
- status = "okay";
-};
-
-&usdhc3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc3>;
- non-removable;
- status = "okay";
-};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 85f72e6b5bad..93ec79bb6b35 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -31,7 +31,7 @@
1200000 1275000
996000 1250000
852000 1250000
- 792000 1150000
+ 792000 1175000
396000 975000
>;
fsl,soc-operating-points = <
@@ -95,6 +95,8 @@
clocks = <&clks IMX6Q_CLK_ECSPI5>,
<&clks IMX6Q_CLK_ECSPI5>;
clock-names = "ipg", "per";
+ dmas = <&sdma 11 7 1>, <&sdma 12 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index 0a36129152e0..0b28a9d5241e 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -173,6 +173,11 @@
status = "okay";
};
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
@@ -188,6 +193,20 @@
};
};
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+};
+
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
@@ -265,6 +284,20 @@
>;
};
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
+ >;
+ };
+
pinctrl_pwm1: pwm1grp {
fsl,pins = <
MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
new file mode 100644
index 000000000000..1211da894ee9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg_usb_h1_vbus: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "usb_h1_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */
+ gpio = <&gpio7 12 0>;
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii";
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c2>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6q-udoo {
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_usbh: usbhgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000
+ MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x130b0
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh>;
+ vbus-supply = <&reg_usb_h1_vbus>;
+ clocks = <&clks 201>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 2109d0763c1b..d6c69ec44314 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -339,9 +339,8 @@
<0 3 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "bit", "jpeg";
clocks = <&clks IMX6QDL_CLK_VPU_AXI>,
- <&clks IMX6QDL_CLK_MMDC_CH0_AXI>,
- <&clks IMX6QDL_CLK_OCRAM>;
- clock-names = "per", "ahb", "ocram";
+ <&clks IMX6QDL_CLK_MMDC_CH0_AXI>;
+ clock-names = "per", "ahb";
resets = <&src 1>;
iram = <&ocram>;
};
diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts
new file mode 100644
index 000000000000..e3c0b63c2205
--- /dev/null
+++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "imx6sx.dtsi"
+
+/ {
+ model = "Freescale i.MX6 SoloX Sabre Auto Board";
+ compatible = "fsl,imx6sx-sabreauto", "fsl,imx6sx";
+
+ memory {
+ reg = <0x80000000 0x80000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vcc_sd3: regulator@0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_vcc_sd3>;
+ regulator-name = "VCC_SD3";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <8>;
+ cd-gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>;
+ wp-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ vmmc-supply = <&vcc_sd3>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ cd-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
+ no-1-8-v;
+ keep-power-in-suspend;
+ enable-sdio-wakup;
+ status = "okay";
+};
+
+&iomuxc {
+ imx6x-sabreauto {
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1
+ MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17059
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10059
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17059
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17059
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17059
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17059
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x17059
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x17059
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x17059
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x17059
+ MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x17059 /* CD */
+ MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x17059 /* WP */
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3grp-100mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170b9
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100b9
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170b9
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170b9
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170b9
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170b9
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170b9
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170b9
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170b9
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170b9
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3grp-200mhz {
+ fsl,pins = <
+ MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170f9
+ MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100f9
+ MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170f9
+ MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170f9
+ MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170f9
+ MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170f9
+ MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170f9
+ MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170f9
+ MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170f9
+ MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170f9
+ >;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <
+ MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x17059
+ MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x10059
+ MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x17059
+ MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x17059
+ MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x17059
+ MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x17059
+ MX6SX_PAD_SD4_DATA7__GPIO6_IO_21 0x17059 /* CD */
+ MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x17059 /* WP */
+ >;
+ };
+
+ pinctrl_vcc_sd3: vccsd3grp {
+ fsl,pins = <
+ MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
+ >;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
index c108bb451337..32f07d6b4042 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb.dts
@@ -355,6 +355,28 @@
status = "okay";
};
+&qspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi2>;
+ status = "okay";
+
+ flash0: s25fl128s@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl128s";
+ spi-max-frequency = <66000000>;
+ };
+
+ flash1: s25fl128s@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spansion,s25fl128s";
+ spi-max-frequency = <66000000>;
+ };
+};
+
&ssi2 {
status = "okay";
};
@@ -539,6 +561,23 @@
>;
};
+ pinctrl_qspi2: qspi2grp {
+ fsl,pins = <
+ MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0 0x70f1
+ MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1 0x70f1
+ MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2 0x70f1
+ MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3 0x70f1
+ MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK 0x70f1
+ MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B 0x70f1
+ MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0 0x70f1
+ MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1 0x70f1
+ MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2 0x70f1
+ MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3 0x70f1
+ MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK 0x70f1
+ MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B 0x70f1
+ >;
+ };
+
pinctrl_vcc_sd3: vccsd3grp {
fsl,pins = <
MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059
diff --git a/arch/arm/boot/dts/kirkwood-6192.dtsi b/arch/arm/boot/dts/kirkwood-6192.dtsi
index dd81508b919b..9e6e9e2691d5 100644
--- a/arch/arm/boot/dts/kirkwood-6192.dtsi
+++ b/arch/arm/boot/dts/kirkwood-6192.dtsi
@@ -66,6 +66,8 @@
interrupts = <21>;
clocks = <&gate_clk 14>, <&gate_clk 15>;
clock-names = "0", "1";
+ phys = <&sata_phy0>, <&sata_phy1>;
+ phy-names = "port0", "port1";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
new file mode 100644
index 000000000000..fa02a9aff05e
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
@@ -0,0 +1,173 @@
+/*
+ * Device Tree file for Seagate Blackarmor NAS220
+ *
+ * Copyright (C) 2014 Evgeni Dobrev <evgeni@studio-punkt.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "kirkwood.dtsi"
+#include "kirkwood-6192.dtsi"
+
+/ {
+ model = "Seagate Blackarmor NAS220";
+ compatible = "seagate,blackarmor-nas220","marvell,kirkwood-88f6192",
+ "marvell,kirkwood";
+
+ memory { /* 128 MB */
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio_poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ button@1{
+ label = "Reset";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+
+ button@2{
+ label = "Power";
+ linux,code = <KEY_SLEEP>;
+ gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ blue-power {
+ label = "nas220:blue:power";
+ gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_power_sata0 &pmx_power_sata1>;
+ pinctrl-names = "default";
+
+ sata0_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "SATA0 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 24 GPIO_ACTIVE_LOW>;
+ };
+
+ sata1_power: regulator@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "SATA1 Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 28 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+/*
+ * Serial port routed to connector CN5
+ *
+ * pin 1 - TX (CPU's TX)
+ * pin 4 - RX (CPU's RX)
+ * pin 6 - GND
+ */
+&uart0 {
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl-0 = <&pmx_button_reset &pmx_button_power>;
+ pinctrl-names = "default";
+
+ pmx_act_sata0: pmx-act-sata0 {
+ marvell,pins = "mpp15";
+ marvell,function = "sata0";
+ };
+
+ pmx_act_sata1: pmx-act-sata1 {
+ marvell,pins = "mpp16";
+ marvell,function = "sata1";
+ };
+
+ pmx_power_sata0: pmx-power-sata0 {
+ marvell,pins = "mpp24";
+ marvell,function = "gpio";
+ };
+
+ pmx_power_sata1: pmx-power-sata1 {
+ marvell,pins = "mpp28";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_reset: pmx-button-reset {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_button_power: pmx-button-power {
+ marvell,pins = "mpp26";
+ marvell,function = "gpio";
+ };
+};
+
+&sata {
+ status = "okay";
+ nr-ports = <2>;
+};
+
+&i2c0 {
+ status = "okay";
+
+ adt7476: thermal@2e {
+ compatible = "adi,adt7476";
+ reg = <0x2e>;
+ };
+};
+
+&nand {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@8 {
+ reg = <8>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
index 05291f3990d0..8474bffec0ca 100644
--- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
@@ -169,6 +169,10 @@
gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
};
};
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+ };
};
&nand {
@@ -192,8 +196,8 @@
};
partition@400000 {
- label = "uInitrd";
- reg = <0x540000 0x1000000>;
+ label = "rootfs";
+ reg = <0x400000 0x1C00000>;
};
};
diff --git a/arch/arm/boot/dts/kirkwood-pogo_e02.dts b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
new file mode 100644
index 000000000000..a190080c9c4f
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
@@ -0,0 +1,134 @@
+/*
+ * kirkwood-pogo_e02.dts - Device tree file for Pogoplug E02
+ *
+ * Copyright (C) 2015 Christoph Junghans <ottxor@gentoo.org>
+ *
+ * based on information of dts files from
+ * Arch Linux ARM by Oleg Rakhmanov <moonman.ca@gmail.com>
+ * OpenWrt by Felix Kaechele <heffer@fedoraproject.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+
+/ {
+ model = "Cloud Engines Pogoplug E02";
+ compatible = "cloudengines,pogoe02", "marvell,kirkwood-88f6281",
+ "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ stdout-path = &uart0;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ health {
+ label = "pogo_e02:green:health";
+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ default-state = "keep";
+ };
+ fault {
+ label = "pogo_e02:orange:fault";
+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_enable>;
+ pinctrl-names = "default";
+
+ usb_power: regulator@1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "USB Power";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&pinctrl {
+ pinctrl-0 = < &pmx_usb_power_enable &pmx_led_orange
+ &pmx_led_green >;
+ pinctrl-names = "default";
+
+ pmx_usb_power_enable: pmx-usb-power-enable {
+ marvell,pins = "mpp29";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_green: pmx-led-green {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+
+ pmx_led_orange: pmx-led-orange {
+ marvell,pins = "mpp49";
+ marvell,function = "gpio";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&nand {
+ chip-delay = <40>;
+ status = "okay";
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0000000 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "uImage";
+ reg = <0x0100000 0x400000>;
+ };
+
+ partition@500000 {
+ label = "pogoplug";
+ reg = <0x0500000 0x2000000>;
+ };
+
+ partition@2500000 {
+ label = "root";
+ reg = <0x02500000 0x5b00000>;
+ };
+};
+
+&mdio {
+ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&eth0 {
+ status = "okay";
+ ethernet0-port@0 {
+ phy-handle = <&ethphy0>;
+ };
+};
diff --git a/arch/arm/boot/dts/marco-evb.dts b/arch/arm/boot/dts/marco-evb.dts
deleted file mode 100644
index 5130aeacfca5..000000000000
--- a/arch/arm/boot/dts/marco-evb.dts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * DTS file for CSR SiRFmarco Evaluation Board
- *
- * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-/dts-v1/;
-
-/include/ "marco.dtsi"
-
-/ {
- model = "CSR SiRFmarco Evaluation Board";
- compatible = "sirf,marco-cb", "sirf,marco";
-
- memory {
- reg = <0x40000000 0x60000000>;
- };
-
- axi {
- peri-iobg {
- uart1: uart@cc060000 {
- status = "okay";
- };
- uart2: uart@cc070000 {
- status = "okay";
- };
- i2c0: i2c@cc0e0000 {
- status = "okay";
- fpga-cpld@4d {
- compatible = "sirf,fpga-cpld";
- reg = <0x4d>;
- };
- };
- spi1: spi@cc170000 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins_a>;
- spi@0 {
- compatible = "spidev";
- reg = <0>;
- spi-max-frequency = <1000000>;
- };
- };
- pci-iobg {
- sd0: sdhci@cd000000 {
- bus-width = <8>;
- status = "okay";
- };
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/marco.dtsi b/arch/arm/boot/dts/marco.dtsi
deleted file mode 100644
index fb354225740a..000000000000
--- a/arch/arm/boot/dts/marco.dtsi
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * DTS file for CSR SiRFmarco SoC
- *
- * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-/include/ "skeleton.dtsi"
-/ {
- compatible = "sirf,marco";
- #address-cells = <1>;
- #size-cells = <1>;
- interrupt-parent = <&gic>;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <0>;
- };
- cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <1>;
- };
- };
-
- axi {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x40000000 0x40000000 0xa0000000>;
-
- l2-cache-controller@c0030000 {
- compatible = "arm,pl310-cache";
- reg = <0xc0030000 0x1000>;
- interrupts = <0 59 0>;
- arm,tag-latency = <1 1 1>;
- arm,data-latency = <1 1 1>;
- arm,filter-ranges = <0x40000000 0x80000000>;
- };
-
- gic: interrupt-controller@c0011000 {
- compatible = "arm,cortex-a9-gic";
- interrupt-controller;
- #interrupt-cells = <3>;
- reg = <0xc0011000 0x1000>,
- <0xc0010100 0x0100>;
- };
-
- rstc-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xc2000000 0xc2000000 0x1000000>;
-
- rstc: reset-controller@c2000000 {
- compatible = "sirf,marco-rstc";
- reg = <0xc2000000 0x10000>;
- #reset-cells = <1>;
- };
- };
-
- sys-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xc3000000 0xc3000000 0x1000000>;
-
- clock-controller@c3000000 {
- compatible = "sirf,marco-clkc";
- reg = <0xc3000000 0x1000>;
- interrupts = <0 3 0>;
- };
-
- rsc-controller@c3010000 {
- compatible = "sirf,marco-rsc";
- reg = <0xc3010000 0x1000>;
- };
- };
-
- mem-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xc4000000 0xc4000000 0x1000000>;
-
- memory-controller@c4000000 {
- compatible = "sirf,marco-memc";
- reg = <0xc4000000 0x10000>;
- interrupts = <0 27 0>;
- };
- };
-
- disp-iobg0 {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xc5000000 0xc5000000 0x1000000>;
-
- display0@c5000000 {
- compatible = "sirf,marco-lcd";
- reg = <0xc5000000 0x10000>;
- interrupts = <0 30 0>;
- };
-
- vpp0@c5010000 {
- compatible = "sirf,marco-vpp";
- reg = <0xc5010000 0x10000>;
- interrupts = <0 31 0>;
- };
- };
-
- disp-iobg1 {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xc6000000 0xc6000000 0x1000000>;
-
- display1@c6000000 {
- compatible = "sirf,marco-lcd";
- reg = <0xc6000000 0x10000>;
- interrupts = <0 62 0>;
- };
-
- vpp1@c6010000 {
- compatible = "sirf,marco-vpp";
- reg = <0xc6010000 0x10000>;
- interrupts = <0 63 0>;
- };
- };
-
- graphics-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xc8000000 0xc8000000 0x1000000>;
-
- graphics@c8000000 {
- compatible = "powervr,sgx540";
- reg = <0xc8000000 0x1000000>;
- interrupts = <0 6 0>;
- };
- };
-
- multimedia-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xc9000000 0xc9000000 0x1000000>;
-
- multimedia@a0000000 {
- compatible = "sirf,marco-video-codec";
- reg = <0xc9000000 0x1000000>;
- interrupts = <0 5 0>;
- };
- };
-
- dsp-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xca000000 0xca000000 0x2000000>;
-
- dspif@ca000000 {
- compatible = "sirf,marco-dspif";
- reg = <0xca000000 0x10000>;
- interrupts = <0 9 0>;
- };
-
- gps@ca010000 {
- compatible = "sirf,marco-gps";
- reg = <0xca010000 0x10000>;
- interrupts = <0 7 0>;
- };
-
- dsp@cb000000 {
- compatible = "sirf,marco-dsp";
- reg = <0xcb000000 0x1000000>;
- interrupts = <0 8 0>;
- };
- };
-
- peri-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xcc000000 0xcc000000 0x2000000>;
-
- timer@cc020000 {
- compatible = "sirf,marco-tick";
- reg = <0xcc020000 0x1000>;
- interrupts = <0 0 0>,
- <0 1 0>,
- <0 2 0>,
- <0 49 0>,
- <0 50 0>,
- <0 51 0>;
- };
-
- nand@cc030000 {
- compatible = "sirf,marco-nand";
- reg = <0xcc030000 0x10000>;
- interrupts = <0 41 0>;
- };
-
- audio@cc040000 {
- compatible = "sirf,marco-audio";
- reg = <0xcc040000 0x10000>;
- interrupts = <0 35 0>;
- };
-
- uart0: uart@cc050000 {
- cell-index = <0>;
- compatible = "sirf,marco-uart";
- reg = <0xcc050000 0x1000>;
- interrupts = <0 17 0>;
- fifosize = <128>;
- status = "disabled";
- };
-
- uart1: uart@cc060000 {
- cell-index = <1>;
- compatible = "sirf,marco-uart";
- reg = <0xcc060000 0x1000>;
- interrupts = <0 18 0>;
- fifosize = <32>;
- status = "disabled";
- };
-
- uart2: uart@cc070000 {
- cell-index = <2>;
- compatible = "sirf,marco-uart";
- reg = <0xcc070000 0x1000>;
- interrupts = <0 19 0>;
- fifosize = <128>;
- status = "disabled";
- };
-
- uart3: uart@cc190000 {
- cell-index = <3>;
- compatible = "sirf,marco-uart";
- reg = <0xcc190000 0x1000>;
- interrupts = <0 66 0>;
- fifosize = <128>;
- status = "disabled";
- };
-
- uart4: uart@cc1a0000 {
- cell-index = <4>;
- compatible = "sirf,marco-uart";
- reg = <0xcc1a0000 0x1000>;
- interrupts = <0 69 0>;
- fifosize = <128>;
- status = "disabled";
- };
-
- usp0: usp@cc080000 {
- cell-index = <0>;
- compatible = "sirf,marco-usp";
- reg = <0xcc080000 0x10000>;
- interrupts = <0 20 0>;
- status = "disabled";
- };
-
- usp1: usp@cc090000 {
- cell-index = <1>;
- compatible = "sirf,marco-usp";
- reg = <0xcc090000 0x10000>;
- interrupts = <0 21 0>;
- status = "disabled";
- };
-
- usp2: usp@cc0a0000 {
- cell-index = <2>;
- compatible = "sirf,marco-usp";
- reg = <0xcc0a0000 0x10000>;
- interrupts = <0 22 0>;
- status = "disabled";
- };
-
- dmac0: dma-controller@cc0b0000 {
- cell-index = <0>;
- compatible = "sirf,marco-dmac";
- reg = <0xcc0b0000 0x10000>;
- interrupts = <0 12 0>;
- };
-
- dmac1: dma-controller@cc160000 {
- cell-index = <1>;
- compatible = "sirf,marco-dmac";
- reg = <0xcc160000 0x10000>;
- interrupts = <0 13 0>;
- };
-
- vip@cc0c0000 {
- compatible = "sirf,marco-vip";
- reg = <0xcc0c0000 0x10000>;
- };
-
- spi0: spi@cc0d0000 {
- cell-index = <0>;
- compatible = "sirf,marco-spi";
- reg = <0xcc0d0000 0x10000>;
- interrupts = <0 15 0>;
- sirf,spi-num-chipselects = <1>;
- cs-gpios = <&gpio 0 0>;
- sirf,spi-dma-rx-channel = <25>;
- sirf,spi-dma-tx-channel = <20>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi1: spi@cc170000 {
- cell-index = <1>;
- compatible = "sirf,marco-spi";
- reg = <0xcc170000 0x10000>;
- interrupts = <0 16 0>;
- sirf,spi-num-chipselects = <1>;
- cs-gpios = <&gpio 0 0>;
- sirf,spi-dma-rx-channel = <12>;
- sirf,spi-dma-tx-channel = <13>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c0: i2c@cc0e0000 {
- cell-index = <0>;
- compatible = "sirf,marco-i2c";
- reg = <0xcc0e0000 0x10000>;
- interrupts = <0 24 0>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c1: i2c@cc0f0000 {
- cell-index = <1>;
- compatible = "sirf,marco-i2c";
- reg = <0xcc0f0000 0x10000>;
- interrupts = <0 25 0>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- tsc@cc110000 {
- compatible = "sirf,marco-tsc";
- reg = <0xcc110000 0x10000>;
- interrupts = <0 33 0>;
- };
-
- gpio: pinctrl@cc120000 {
- #gpio-cells = <2>;
- #interrupt-cells = <2>;
- compatible = "sirf,marco-pinctrl";
- reg = <0xcc120000 0x10000>;
- interrupts = <0 43 0>,
- <0 44 0>,
- <0 45 0>,
- <0 46 0>,
- <0 47 0>;
- gpio-controller;
- interrupt-controller;
-
- lcd_16pins_a: lcd0_0 {
- lcd {
- sirf,pins = "lcd_16bitsgrp";
- sirf,function = "lcd_16bits";
- };
- };
- lcd_18pins_a: lcd0_1 {
- lcd {
- sirf,pins = "lcd_18bitsgrp";
- sirf,function = "lcd_18bits";
- };
- };
- lcd_24pins_a: lcd0_2 {
- lcd {
- sirf,pins = "lcd_24bitsgrp";
- sirf,function = "lcd_24bits";
- };
- };
- lcdrom_pins_a: lcdrom0_0 {
- lcd {
- sirf,pins = "lcdromgrp";
- sirf,function = "lcdrom";
- };
- };
- uart0_pins_a: uart0_0 {
- uart {
- sirf,pins = "uart0grp";
- sirf,function = "uart0";
- };
- };
- uart1_pins_a: uart1_0 {
- uart {
- sirf,pins = "uart1grp";
- sirf,function = "uart1";
- };
- };
- uart2_pins_a: uart2_0 {
- uart {
- sirf,pins = "uart2grp";
- sirf,function = "uart2";
- };
- };
- uart2_noflow_pins_a: uart2_1 {
- uart {
- sirf,pins = "uart2_nostreamctrlgrp";
- sirf,function = "uart2_nostreamctrl";
- };
- };
- spi0_pins_a: spi0_0 {
- spi {
- sirf,pins = "spi0grp";
- sirf,function = "spi0";
- };
- };
- spi1_pins_a: spi1_0 {
- spi {
- sirf,pins = "spi1grp";
- sirf,function = "spi1";
- };
- };
- i2c0_pins_a: i2c0_0 {
- i2c {
- sirf,pins = "i2c0grp";
- sirf,function = "i2c0";
- };
- };
- i2c1_pins_a: i2c1_0 {
- i2c {
- sirf,pins = "i2c1grp";
- sirf,function = "i2c1";
- };
- };
- pwm0_pins_a: pwm0_0 {
- pwm {
- sirf,pins = "pwm0grp";
- sirf,function = "pwm0";
- };
- };
- pwm1_pins_a: pwm1_0 {
- pwm {
- sirf,pins = "pwm1grp";
- sirf,function = "pwm1";
- };
- };
- pwm2_pins_a: pwm2_0 {
- pwm {
- sirf,pins = "pwm2grp";
- sirf,function = "pwm2";
- };
- };
- pwm3_pins_a: pwm3_0 {
- pwm {
- sirf,pins = "pwm3grp";
- sirf,function = "pwm3";
- };
- };
- gps_pins_a: gps_0 {
- gps {
- sirf,pins = "gpsgrp";
- sirf,function = "gps";
- };
- };
- vip_pins_a: vip_0 {
- vip {
- sirf,pins = "vipgrp";
- sirf,function = "vip";
- };
- };
- sdmmc0_pins_a: sdmmc0_0 {
- sdmmc0 {
- sirf,pins = "sdmmc0grp";
- sirf,function = "sdmmc0";
- };
- };
- sdmmc1_pins_a: sdmmc1_0 {
- sdmmc1 {
- sirf,pins = "sdmmc1grp";
- sirf,function = "sdmmc1";
- };
- };
- sdmmc2_pins_a: sdmmc2_0 {
- sdmmc2 {
- sirf,pins = "sdmmc2grp";
- sirf,function = "sdmmc2";
- };
- };
- sdmmc3_pins_a: sdmmc3_0 {
- sdmmc3 {
- sirf,pins = "sdmmc3grp";
- sirf,function = "sdmmc3";
- };
- };
- sdmmc4_pins_a: sdmmc4_0 {
- sdmmc4 {
- sirf,pins = "sdmmc4grp";
- sirf,function = "sdmmc4";
- };
- };
- sdmmc5_pins_a: sdmmc5_0 {
- sdmmc5 {
- sirf,pins = "sdmmc5grp";
- sirf,function = "sdmmc5";
- };
- };
- i2s_pins_a: i2s_0 {
- i2s {
- sirf,pins = "i2sgrp";
- sirf,function = "i2s";
- };
- };
- ac97_pins_a: ac97_0 {
- ac97 {
- sirf,pins = "ac97grp";
- sirf,function = "ac97";
- };
- };
- nand_pins_a: nand_0 {
- nand {
- sirf,pins = "nandgrp";
- sirf,function = "nand";
- };
- };
- usp0_pins_a: usp0_0 {
- usp0 {
- sirf,pins = "usp0grp";
- sirf,function = "usp0";
- };
- };
- usp1_pins_a: usp1_0 {
- usp1 {
- sirf,pins = "usp1grp";
- sirf,function = "usp1";
- };
- };
- usp2_pins_a: usp2_0 {
- usp2 {
- sirf,pins = "usp2grp";
- sirf,function = "usp2";
- };
- };
- usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus_0 {
- usb0_utmi_drvbus {
- sirf,pins = "usb0_utmi_drvbusgrp";
- sirf,function = "usb0_utmi_drvbus";
- };
- };
- usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus_0 {
- usb1_utmi_drvbus {
- sirf,pins = "usb1_utmi_drvbusgrp";
- sirf,function = "usb1_utmi_drvbus";
- };
- };
- warm_rst_pins_a: warm_rst_0 {
- warm_rst {
- sirf,pins = "warm_rstgrp";
- sirf,function = "warm_rst";
- };
- };
- pulse_count_pins_a: pulse_count_0 {
- pulse_count {
- sirf,pins = "pulse_countgrp";
- sirf,function = "pulse_count";
- };
- };
- cko0_rst_pins_a: cko0_rst_0 {
- cko0_rst {
- sirf,pins = "cko0_rstgrp";
- sirf,function = "cko0_rst";
- };
- };
- cko1_rst_pins_a: cko1_rst_0 {
- cko1_rst {
- sirf,pins = "cko1_rstgrp";
- sirf,function = "cko1_rst";
- };
- };
- };
-
- pwm@cc130000 {
- compatible = "sirf,marco-pwm";
- reg = <0xcc130000 0x10000>;
- };
-
- efusesys@cc140000 {
- compatible = "sirf,marco-efuse";
- reg = <0xcc140000 0x10000>;
- };
-
- pulsec@cc150000 {
- compatible = "sirf,marco-pulsec";
- reg = <0xcc150000 0x10000>;
- interrupts = <0 48 0>;
- };
-
- pci-iobg {
- compatible = "sirf,marco-pciiobg", "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xcd000000 0xcd000000 0x1000000>;
-
- sd0: sdhci@cd000000 {
- cell-index = <0>;
- compatible = "sirf,marco-sdhc";
- reg = <0xcd000000 0x100000>;
- interrupts = <0 38 0>;
- status = "disabled";
- };
-
- sd1: sdhci@cd100000 {
- cell-index = <1>;
- compatible = "sirf,marco-sdhc";
- reg = <0xcd100000 0x100000>;
- interrupts = <0 38 0>;
- status = "disabled";
- };
-
- sd2: sdhci@cd200000 {
- cell-index = <2>;
- compatible = "sirf,marco-sdhc";
- reg = <0xcd200000 0x100000>;
- interrupts = <0 23 0>;
- status = "disabled";
- };
-
- sd3: sdhci@cd300000 {
- cell-index = <3>;
- compatible = "sirf,marco-sdhc";
- reg = <0xcd300000 0x100000>;
- interrupts = <0 23 0>;
- status = "disabled";
- };
-
- sd4: sdhci@cd400000 {
- cell-index = <4>;
- compatible = "sirf,marco-sdhc";
- reg = <0xcd400000 0x100000>;
- interrupts = <0 39 0>;
- status = "disabled";
- };
-
- sd5: sdhci@cd500000 {
- cell-index = <5>;
- compatible = "sirf,marco-sdhc";
- reg = <0xcd500000 0x100000>;
- interrupts = <0 39 0>;
- status = "disabled";
- };
-
- pci-copy@cd900000 {
- compatible = "sirf,marco-pcicp";
- reg = <0xcd900000 0x100000>;
- interrupts = <0 40 0>;
- };
-
- rom-interface@cda00000 {
- compatible = "sirf,marco-romif";
- reg = <0xcda00000 0x100000>;
- };
- };
- };
-
- rtc-iobg {
- compatible = "sirf,marco-rtciobg", "sirf-marco-rtciobg-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0xc1000000 0x10000>;
-
- gpsrtc@1000 {
- compatible = "sirf,marco-gpsrtc";
- reg = <0x1000 0x1000>;
- interrupts = <0 55 0>,
- <0 56 0>,
- <0 57 0>;
- };
-
- sysrtc@2000 {
- compatible = "sirf,marco-sysrtc";
- reg = <0x2000 0x1000>;
- interrupts = <0 52 0>,
- <0 53 0>,
- <0 54 0>;
- };
-
- pwrc@3000 {
- compatible = "sirf,marco-pwrc";
- reg = <0x3000 0x1000>;
- interrupts = <0 32 0>;
- };
- };
-
- uus-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xce000000 0xce000000 0x1000000>;
-
- usb0: usb@ce000000 {
- compatible = "chipidea,ci13611a-marco";
- reg = <0xce000000 0x10000>;
- interrupts = <0 10 0>;
- };
-
- usb1: usb@ce010000 {
- compatible = "chipidea,ci13611a-marco";
- reg = <0xce010000 0x10000>;
- interrupts = <0 11 0>;
- };
-
- security@ce020000 {
- compatible = "sirf,marco-security";
- reg = <0xce020000 0x10000>;
- interrupts = <0 42 0>;
- };
- };
-
- can-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xd0000000 0xd0000000 0x1000000>;
-
- can0: can@d0000000 {
- compatible = "sirf,marco-can";
- reg = <0xd0000000 0x10000>;
- };
-
- can1: can@d0010000 {
- compatible = "sirf,marco-can";
- reg = <0xd0010000 0x10000>;
- };
- };
-
- lvds-iobg {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0xd1000000 0xd1000000 0x1000000>;
-
- lvds@d1000000 {
- compatible = "sirf,marco-lvds";
- reg = <0xd1000000 0x10000>;
- interrupts = <0 64 0>;
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/mt6589-aquaris5.dts b/arch/arm/boot/dts/mt6589-aquaris5.dts
index 0da047013120..594a6f3bebda 100644
--- a/arch/arm/boot/dts/mt6589-aquaris5.dts
+++ b/arch/arm/boot/dts/mt6589-aquaris5.dts
@@ -21,10 +21,20 @@
compatible = "mundoreader,bq-aquaris5", "mediatek,mt6589";
chosen {
- bootargs = "earlyprintk";
+ bootargs = "console=ttyS0,921600n8 earlyprintk";
+ stdout-path = &uart0;
};
memory {
reg = <0x80000000 0x40000000>;
};
+
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
};
diff --git a/arch/arm/boot/dts/mt6589.dtsi b/arch/arm/boot/dts/mt6589.dtsi
index e3c7600ddb38..106b61b10030 100644
--- a/arch/arm/boot/dts/mt6589.dtsi
+++ b/arch/arm/boot/dts/mt6589.dtsi
@@ -19,7 +19,7 @@
/ {
compatible = "mediatek,mt6589";
- interrupt-parent = <&gic>;
+ interrupt-parent = <&sysirq>;
cpus {
#address-cells = <1>;
@@ -65,6 +65,12 @@
clock-frequency = <32000>;
#clock-cells = <0>;
};
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
};
soc {
@@ -76,19 +82,61 @@
timer: timer@10008000 {
compatible = "mediatek,mt6577-timer";
reg = <0x10008000 0x80>;
- interrupts = <GIC_SPI 113 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>;
clocks = <&system_clk>, <&rtc_clk>;
clock-names = "system-clk", "rtc-clk";
};
+ sysirq: interrupt-controller@10200100 {
+ compatible = "mediatek,mt6589-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10200100 0x1c>;
+ };
+
gic: interrupt-controller@10211000 {
compatible = "arm,cortex-a7-gic";
interrupt-controller;
#interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
reg = <0x10211000 0x1000>,
<0x10212000 0x1000>,
<0x10214000 0x2000>,
<0x10216000 0x2000>;
};
+
+ uart0: serial@11006000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11006000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11007000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11007000 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11008000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11008000 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11009000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11009000 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/mt6592.dtsi b/arch/arm/boot/dts/mt6592.dtsi
index 31e5a0979d78..c69201ffff72 100644
--- a/arch/arm/boot/dts/mt6592.dtsi
+++ b/arch/arm/boot/dts/mt6592.dtsi
@@ -18,7 +18,7 @@
/ {
compatible = "mediatek,mt6592";
- interrupt-parent = <&gic>;
+ interrupt-parent = <&sysirq>;
cpus {
#address-cells = <1>;
@@ -78,21 +78,66 @@
#clock-cells = <0>;
};
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+
timer: timer@10008000 {
compatible = "mediatek,mt6577-timer";
reg = <0x10008000 0x80>;
- interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW>;
clocks = <&system_clk>, <&rtc_clk>;
clock-names = "system-clk", "rtc-clk";
};
+ sysirq: interrupt-controller@10200220 {
+ compatible = "mediatek,mt6592-sysirq", "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10200220 0x1c>;
+ };
+
gic: interrupt-controller@10211000 {
compatible = "arm,cortex-a7-gic";
interrupt-controller;
#interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
reg = <0x10211000 0x1000>,
<0x10212000 0x1000>;
};
-};
+ uart0: serial@11002000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11002000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11003000 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+ uart2: serial@11004000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11004000 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11005000 {
+ compatible = "mediatek,mt6577-uart";
+ reg = <0x11005000 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/mt8127-moose.dts b/arch/arm/boot/dts/mt8127-moose.dts
index 13cba0e77e08..073e295a1cb4 100644
--- a/arch/arm/boot/dts/mt8127-moose.dts
+++ b/arch/arm/boot/dts/mt8127-moose.dts
@@ -23,3 +23,7 @@
reg = <0 0x80000000 0 0x40000000>;
};
};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi
index b24c0a2f3c44..aaa786233d93 100644
--- a/arch/arm/boot/dts/mt8127.dtsi
+++ b/arch/arm/boot/dts/mt8127.dtsi
@@ -18,7 +18,7 @@
/ {
compatible = "mediatek,mt8127";
- interrupt-parent = <&gic>;
+ interrupt-parent = <&sysirq>;
cpus {
#address-cells = <1>;
@@ -64,6 +64,12 @@
clock-frequency = <32000>;
#clock-cells = <0>;
};
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
};
soc {
@@ -76,19 +82,61 @@
compatible = "mediatek,mt8127-timer",
"mediatek,mt6577-timer";
reg = <0 0x10008000 0 0x80>;
- interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
clocks = <&system_clk>, <&rtc_clk>;
clock-names = "system-clk", "rtc-clk";
};
+ sysirq: interrupt-controller@10200100 {
+ compatible = "mediatek,mt8127-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0 0x10200100 0 0x1c>;
+ };
+
gic: interrupt-controller@10211000 {
compatible = "arm,cortex-a7-gic";
interrupt-controller;
#interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
reg = <0 0x10211000 0 0x1000>,
<0 0x10212000 0 0x1000>,
<0 0x10214000 0 0x2000>,
<0 0x10216000 0 0x2000>;
};
+
+ uart0: serial@11006000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11002000 0 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11007000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11003000 0 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11008000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11004000 0 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11009000 {
+ compatible = "mediatek,mt8127-uart","mediatek,mt6577-uart";
+ reg = <0 0x11005000 0 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/mt8135-evbp1.dts b/arch/arm/boot/dts/mt8135-evbp1.dts
index a5adf9742308..36677382bdd8 100644
--- a/arch/arm/boot/dts/mt8135-evbp1.dts
+++ b/arch/arm/boot/dts/mt8135-evbp1.dts
@@ -23,3 +23,7 @@
reg = <0 0x80000000 0 0x40000000>;
};
};
+
+&uart3 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
index 7d56a986358e..a161e99ffcc4 100644
--- a/arch/arm/boot/dts/mt8135.dtsi
+++ b/arch/arm/boot/dts/mt8135.dtsi
@@ -18,7 +18,7 @@
/ {
compatible = "mediatek,mt8135";
- interrupt-parent = <&gic>;
+ interrupt-parent = <&sysirq>;
cpu-map {
cluster0 {
@@ -86,6 +86,13 @@
clock-frequency = <32000>;
#clock-cells = <0>;
};
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+
};
soc {
@@ -98,19 +105,62 @@
compatible = "mediatek,mt8135-timer",
"mediatek,mt6577-timer";
reg = <0 0x10008000 0 0x80>;
- interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_LOW>;
clocks = <&system_clk>, <&rtc_clk>;
clock-names = "system-clk", "rtc-clk";
};
+ sysirq: interrupt-controller@10200030 {
+ compatible = "mediatek,mt8135-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0 0x10200030 0 0x1c>;
+ };
+
gic: interrupt-controller@10211000 {
compatible = "arm,cortex-a15-gic";
interrupt-controller;
#interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
reg = <0 0x10211000 0 0x1000>,
<0 0x10212000 0 0x1000>,
<0 0x10214000 0 0x2000>,
<0 0x10216000 0 0x2000>;
};
+
+ uart0: serial@11006000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11006000 0 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11007000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11007000 0 0x400>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11008000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11008000 0 0x400>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11009000 {
+ compatible = "mediatek,mt8135-uart","mediatek,mt6577-uart";
+ reg = <0 0x11009000 0 0x400>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
};
};
diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
index 6ea6d460db30..4d091ca43e25 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi
@@ -259,3 +259,61 @@
pinctrl-names = "default";
pinctrl-0 = <&mcbsp2_pins>;
};
+
+&gpmc {
+ ranges = <0 0 0x00000000 0x01000000>;
+
+ nand@0,0 {
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ nand-bus-width = <8>;
+ gpmc,device-width = <1>;
+ ti,nand-ecc-opt = "sw";
+
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <120>;
+ gpmc,cs-wr-off-ns = <120>;
+
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <120>;
+ gpmc,adv-wr-off-ns = <120>;
+
+ gpmc,we-on-ns = <6>;
+ gpmc,we-off-ns = <90>;
+
+ gpmc,oe-on-ns = <6>;
+ gpmc,oe-off-ns = <90>;
+
+ gpmc,page-burst-access-ns = <6>;
+ gpmc,access-ns = <72>;
+ gpmc,cycle2cycle-delay-ns = <60>;
+
+ gpmc,rd-cycle-ns = <120>;
+ gpmc,wr-cycle-ns = <120>;
+ gpmc,wr-access-ns = <186>;
+ gpmc,wr-data-mux-bus-ns = <90>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0 0x80000>;
+ };
+ partition@0x80000 {
+ label = "uboot";
+ reg = <0x80000 0x1e0000>;
+ };
+ partition@0x260000 {
+ label = "uboot environment";
+ reg = <0x260000 0x40000>;
+ };
+ partition@0x2a0000 {
+ label = "linux";
+ reg = <0x2a0000 0x400000>;
+ };
+ partition@0x6a0000 {
+ label = "rootfs";
+ reg = <0x6a0000 0x1f880000>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
index 9a4a3ab9af78..d9e92b654f85 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
@@ -50,7 +50,8 @@
#include "omap-gpmc-smsc911x.dtsi"
&gpmc {
- ranges = <5 0 0x2c000000 0x01000000>;
+ ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
smsc1: ethernet@gpmc {
compatible = "smsc,lan9221", "smsc,lan9115";
diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi
index 655d6e920a86..fb3a69604ed5 100644
--- a/arch/arm/boot/dts/omap3-gta04.dtsi
+++ b/arch/arm/boot/dts/omap3-gta04.dtsi
@@ -83,6 +83,41 @@
compatible = "usb-nop-xceiv";
reset-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
};
+
+ tv0: connector@1 {
+ compatible = "svideo-connector";
+ label = "tv";
+
+ port {
+ tv_connector_in: endpoint {
+ remote-endpoint = <&opa_out>;
+ };
+ };
+ };
+
+ tv_amp: opa362 {
+ compatible = "ti,opa362";
+ enable-gpios = <&gpio1 23 0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ opa_in: endpoint@0 {
+ remote-endpoint = <&venc_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ opa_out: endpoint@0 {
+ remote-endpoint = <&tv_connector_in>;
+ };
+ };
+ };
+ };
};
&omap3_pmx_core {
@@ -202,11 +237,18 @@
reg = <0x48>;
interrupts = <7>; /* SYS_NIRQ cascaded to intc */
interrupt-parent = <&intc>;
- };
- twl_audio: audio {
- compatible = "ti,twl4030-audio";
- codec {
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ ti,enable-vibra = <1>;
+ codec {
+ ti,ramp_delay_value = <3>;
+ };
+ };
+
+ twl_power: power {
+ compatible = "ti,twl4030-power";
+ ti,use_poweroff;
};
};
};
@@ -222,15 +264,23 @@
compatible = "bosch,bmp085";
reg = <0x77>;
interrupt-parent = <&gpio4>;
- interrupts = <17 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <17 IRQ_TYPE_EDGE_RISING>; /* GPIO_113 */
};
/* accelerometer */
bma180@41 {
compatible = "bosch,bma180";
reg = <0x41>;
- interrupt-parent = <&gpio3>;
- interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_115 */
+ };
+
+ /* gyroscope */
+ itg3200@68 {
+ compatible = "invensense,itg3200";
+ reg = <0x68>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <24 0>; /* GPIO_56 */
};
/* leds */
@@ -281,7 +331,7 @@
compatible = "ti,tsc2007";
reg = <0x48>;
interrupt-parent = <&gpio6>;
- interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>; /* GPIO_160 */
gpios = <&gpio6 0 GPIO_ACTIVE_LOW>;
ti,x-plate-ohms = <600>;
};
@@ -320,12 +370,17 @@
vmmc-supply = <&vaux4>;
bus-width = <4>;
ti,non-removable;
+ cap-power-off-card;
};
&mmc3 {
status = "disabled";
};
+&twl_keypad {
+ status = "disabled";
+};
+
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins>;
@@ -342,8 +397,8 @@
};
&charger {
- bb_uvolt = <3200000>;
- bb_uamp = <150>;
+ ti,bb-uvolt = <3200000>;
+ ti,bb-uamp = <150>;
};
/* spare */
@@ -377,16 +432,12 @@
regulator-max-microvolt = <3150000>;
};
-/* Needed to power the DPI pins */
-&vpll2 {
- regulator-always-on;
-};
-
&dss {
pinctrl-names = "default";
pinctrl-0 = < &dss_dpi_pins >;
status = "okay";
+ vdds_dsi-supply = <&vpll2>;
port {
dpi_out: endpoint {
@@ -396,6 +447,20 @@
};
};
+&venc {
+ status = "okay";
+
+ vdda-supply = <&vdac>;
+
+ port {
+ venc_out: endpoint {
+ remote-endpoint = <&opa_in>;
+ ti,channels = <2>;
+ ti,invert-polarity;
+ };
+ };
+};
+
&gpmc {
ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
@@ -449,3 +514,7 @@
};
};
};
+
+&mcbsp2 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index b550c41b46f1..60403273f83e 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -307,7 +307,7 @@
regulator-name = "V28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
- regulator-always-on; /* due battery cover sensor */
+ regulator-always-on; /* due to battery cover sensor */
};
&vaux2 {
@@ -365,7 +365,6 @@
regulator-name = "VIO";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
-
};
&vintana1 {
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 1e49dfe7e212..c41db94ee9c2 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -60,6 +60,11 @@
&twl {
compatible = "ti,twl5031";
+
+ twl_power: power {
+ compatible = "ti,twl4030-power";
+ ti,use_poweroff;
+ };
};
&twl_gpio {
diff --git a/arch/arm/boot/dts/omap3-sbc-t3517.dts b/arch/arm/boot/dts/omap3-sbc-t3517.dts
index 17986536c61f..c2d5c28a1a70 100644
--- a/arch/arm/boot/dts/omap3-sbc-t3517.dts
+++ b/arch/arm/boot/dts/omap3-sbc-t3517.dts
@@ -69,3 +69,7 @@
};
};
+&gpmc {
+ ranges = <4 0 0x2d000000 0x01000000>, /* SB-T35 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
+};
diff --git a/arch/arm/boot/dts/omap3-sbc-t3530.dts b/arch/arm/boot/dts/omap3-sbc-t3530.dts
index c994f0f7e38a..834bc786cd12 100644
--- a/arch/arm/boot/dts/omap3-sbc-t3530.dts
+++ b/arch/arm/boot/dts/omap3-sbc-t3530.dts
@@ -26,14 +26,10 @@
};
};
-/*
- * The following ranges correspond to SMSC9x eth chips on CM-T3530 CoM and
- * SB-T35 baseboard respectively.
- * This setting includes both chips in SBC-T3530 board device tree.
- */
&gpmc {
- ranges = <5 0 0x2c000000 0x01000000>,
- <4 0 0x2d000000 0x01000000>;
+ ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
+ <4 0 0x2d000000 0x01000000>, /* SB-T35 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
};
&mmc1 {
diff --git a/arch/arm/boot/dts/omap3-sbc-t3730.dts b/arch/arm/boot/dts/omap3-sbc-t3730.dts
index 5bdddf29341d..73c7bf4a4a08 100644
--- a/arch/arm/boot/dts/omap3-sbc-t3730.dts
+++ b/arch/arm/boot/dts/omap3-sbc-t3730.dts
@@ -27,8 +27,9 @@
};
&gpmc {
- ranges = <5 0 0x2c000000 0x01000000>,
- <4 0 0x2d000000 0x01000000>;
+ ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
+ <4 0 0x2d000000 0x01000000>, /* SB-T35 SMSC9x Eth */
+ <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
};
&dss {
diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
index b396c8311b27..e641001ca2a7 100644
--- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -1,4 +1,5 @@
#include "qcom-apq8064-v2.0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "Qualcomm APQ8064/IFC6410";
@@ -12,6 +13,14 @@
function = "gsbi1";
};
};
+
+ card_detect: card_detect {
+ mux {
+ pins = "gpio26";
+ function = "gpio";
+ bias-disable;
+ };
+ };
};
gsbi@12440000 {
@@ -49,6 +58,9 @@
/* External micro SD card */
sdcc3: sdcc@12180000 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&card_detect>;
+ cd-gpios = <&tlmm_pinmux 26 GPIO_ACTIVE_LOW>;
};
/* WLAN */
sdcc4: sdcc@121c0000 {
diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 63b2146f563b..cb225dafe97c 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -74,7 +74,7 @@
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
- interrupts = <0 32 0x4>;
+ interrupts = <0 16 0x4>;
};
intc: interrupt-controller@2000000 {
diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts
index 1518c5bcca33..a9da7a89fc4b 100644
--- a/arch/arm/boot/dts/r7s72100-genmai.dts
+++ b/arch/arm/boot/dts/r7s72100-genmai.dts
@@ -45,7 +45,7 @@
};
&mtu2 {
- status = "ok";
+ status = "okay";
};
&i2c2 {
diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts
index 84e05f713c54..b3d8f844b57a 100644
--- a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts
+++ b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts
@@ -67,7 +67,7 @@
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0 0 0 0x80000000>;
+ ranges = <0 0 0 0x20000000>;
};
};
diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
index ce085fa444a1..0d50bef01234 100644
--- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts
+++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
@@ -10,14 +10,20 @@
/dts-v1/;
#include "r8a73a4.dtsi"
-#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
/ {
model = "APE6EVM";
compatible = "renesas,ape6evm", "renesas,r8a73a4";
+ aliases {
+ serial0 = &scifa0;
+ };
+
chosen {
bootargs = "console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw";
+ stdout-path = &scifa0;
};
memory@40000000 {
@@ -30,7 +36,35 @@
reg = <2 0x00000000 0 0x40000000>;
};
- ape6evm_fixed_3v3: fixedregulator@0 {
+ vcc_mmc0: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "MMC0 Vcc";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ vcc_sdhi0: regulator@1 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "SDHI0 Vcc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&pfc 76 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ /* Common 1.8V and 3.3V rails, used by several devices on APE6EVM */
+ ape6evm_fixed_1v8: regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ape6evm_fixed_3v3: regulator@3 {
compatible = "regulator-fixed";
regulator-name = "3V3";
regulator-min-microvolt = <3300000>;
@@ -39,11 +73,13 @@
};
lbsc {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
+ ranges = <0 0 0 0x20000000>;
ethernet@8000000 {
- compatible = "smsc,lan9118", "smsc,lan9115";
+ compatible = "smsc,lan9220", "smsc,lan9115";
reg = <0x08000000 0x1000>;
interrupt-parent = <&irqc1>;
interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
@@ -52,7 +88,75 @@
smsc,irq-active-high;
smsc,irq-push-pull;
vdd33a-supply = <&ape6evm_fixed_3v3>;
- vddvario-supply = <&ape6evm_fixed_3v3>;
+ vddvario-supply = <&ape6evm_fixed_1v8>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ led1 {
+ gpios = <&pfc 28 GPIO_ACTIVE_LOW>;
+ label = "GNSS_EN";
+ };
+ led2 {
+ gpios = <&pfc 126 GPIO_ACTIVE_LOW>;
+ label = "NFC_NRST";
+ };
+ led3 {
+ gpios = <&pfc 132 GPIO_ACTIVE_LOW>;
+ label = "GNSS_NRST";
+ };
+ led4 {
+ gpios = <&pfc 232 GPIO_ACTIVE_LOW>;
+ label = "BT_WAKEUP";
+ };
+ led5 {
+ gpios = <&pfc 250 GPIO_ACTIVE_LOW>;
+ label = "STROBE";
+ };
+ led6 {
+ gpios = <&pfc 288 GPIO_ACTIVE_LOW>;
+ label = "BBRESETOUT";
+ };
+ };
+
+ keyboard {
+ compatible = "gpio-keys";
+
+ zero-key {
+ gpios = <&pfc 324 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_0>;
+ label = "S16";
+ };
+
+ menu-key {
+ gpios = <&pfc 325 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ label = "S17";
+ };
+
+ home-key {
+ gpios = <&pfc 326 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ label = "S18";
+ };
+
+ back-key {
+ gpios = <&pfc 327 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ label = "S19";
+ };
+
+ volup-key {
+ gpios = <&pfc 328 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ label = "S20";
+ };
+
+ voldown-key {
+ gpios = <&pfc 329 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ label = "S21";
};
};
};
@@ -79,3 +183,64 @@
>;
voltage-tolerance = <1>; /* 1% */
};
+
+&cmt1 {
+ status = "okay";
+};
+
+&pfc {
+ scifa0_pins: serial0 {
+ renesas,groups = "scifa0_data";
+ renesas,function = "scifa0";
+ };
+
+ mmc0_pins: mmc {
+ renesas,groups = "mmc0_data8", "mmc0_ctrl";
+ renesas,function = "mmc0";
+ };
+
+ sdhi0_pins: sd0 {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd";
+ renesas,function = "sdhi0";
+ };
+
+ sdhi1_pins: sd1 {
+ renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
+ renesas,function = "sdhi1";
+ };
+};
+
+&mmcif0 {
+ vmmc-supply = <&vcc_mmc0>;
+ bus-width = <8>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ status = "okay";
+};
+
+&scifa0 {
+ pinctrl-0 = <&scifa0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&sdhi0 {
+ vmmc-supply = <&vcc_sdhi0>;
+ bus-width = <4>;
+ toshiba,mmc-wrprotect-disable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhi0_pins>;
+ status = "okay";
+};
+
+&sdhi1 {
+ vmmc-supply = <&ape6evm_fixed_3v3>;
+ bus-width = <4>;
+ broken-cd;
+ toshiba,mmc-wrprotect-disable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhi1_pins>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
index 5ac57babc3b9..38136d9f6d95 100644
--- a/arch/arm/boot/dts/r8a73a4.dtsi
+++ b/arch/arm/boot/dts/r8a73a4.dtsi
@@ -38,6 +38,16 @@
<1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
+ dbsc1: memory-controller@e6790000 {
+ compatible = "renesas,dbsc-r8a73a4";
+ reg = <0 0xe6790000 0 0x10000>;
+ };
+
+ dbsc2: memory-controller@e67a0000 {
+ compatible = "renesas,dbsc-r8a73a4";
+ reg = <0 0xe67a0000 0 0x10000>;
+ };
+
dmac: dma-multiplexer {
compatible = "renesas,shdma-mux";
#dma-cells = <1>;
diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
index d4af4d86c6b0..9bd0cb439f44 100644
--- a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
+++ b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
@@ -172,7 +172,7 @@
pinctrl-names = "default";
phy-handle = <&phy0>;
- status = "ok";
+ status = "okay";
phy0: ethernet-phy@0 {
reg = <0>;
@@ -193,7 +193,7 @@
};
&cmt1 {
- status = "ok";
+ status = "okay";
};
&i2c0 {
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index a8a674bafa67..8a092605d641 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -25,6 +25,7 @@
device_type = "cpu";
reg = <0x0>;
clock-frequency = <800000000>;
+ power-domains = <&pd_a3sm>;
};
};
@@ -36,17 +37,29 @@
<0xc2000000 0x1000>;
};
+ dbsc3: memory-controller@fe400000 {
+ compatible = "renesas,dbsc3-r8a7740";
+ reg = <0xfe400000 0x400>;
+ power-domains = <&pd_a4s>;
+ };
+
pmu {
compatible = "arm,cortex-a9-pmu";
interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
};
+ ptm {
+ compatible = "arm,coresight-etm3x";
+ power-domains = <&pd_d4>;
+ };
+
cmt1: timer@e6138000 {
compatible = "renesas,cmt-48-r8a7740", "renesas,cmt-48";
reg = <0xe6138000 0x170>;
interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7740_CLK_CMT1>;
clock-names = "fck";
+ power-domains = <&pd_c5>;
renesas,channels-mask = <0x3f>;
@@ -72,6 +85,7 @@
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
};
/* irqpin1: IRQ8 - IRQ15 */
@@ -93,6 +107,7 @@
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
};
/* irqpin2: IRQ16 - IRQ23 */
@@ -114,6 +129,7 @@
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
};
/* irqpin3: IRQ24 - IRQ31 */
@@ -135,6 +151,7 @@
0 149 IRQ_TYPE_LEVEL_HIGH
0 149 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
+ power-domains = <&pd_a4s>;
};
ether: ethernet@e9a00000 {
@@ -143,6 +160,7 @@
<0xe9a01800 0x800>;
interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7740_CLK_GETHER>;
+ power-domains = <&pd_a4s>;
phy-mode = "mii";
#address-cells = <1>;
#size-cells = <0>;
@@ -159,6 +177,7 @@
0 203 IRQ_TYPE_LEVEL_HIGH
0 204 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7740_CLK_IIC0>;
+ power-domains = <&pd_a4r>;
status = "disabled";
};
@@ -172,6 +191,7 @@
0 72 IRQ_TYPE_LEVEL_HIGH
0 73 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7740_CLK_IIC1>;
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -181,6 +201,7 @@
interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA0>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -190,6 +211,7 @@
interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA1>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -199,6 +221,7 @@
interrupts = <0 102 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA2>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -208,6 +231,7 @@
interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA3>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -217,6 +241,7 @@
interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA4>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -226,6 +251,7 @@
interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA5>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -235,6 +261,7 @@
interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA6>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -244,6 +271,7 @@
interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFA7>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -253,6 +281,7 @@
interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7740_CLK_SCIFB>;
clock-names = "sci_ick";
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -271,12 +300,14 @@
<&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
<&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
<&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
+ power-domains = <&pd_c5>;
};
tpu: pwm@e6600000 {
compatible = "renesas,tpu-r8a7740", "renesas,tpu";
reg = <0xe6600000 0x100>;
clocks = <&mstp3_clks R8A7740_CLK_TPU0>;
+ power-domains = <&pd_a3sp>;
status = "disabled";
#pwm-cells = <3>;
};
@@ -287,6 +318,7 @@
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH
0 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7740_CLK_MMC>;
+ power-domains = <&pd_a3sp>;
status = "disabled";
};
@@ -297,6 +329,7 @@
0 118 IRQ_TYPE_LEVEL_HIGH
0 119 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7740_CLK_SDHI0>;
+ power-domains = <&pd_a3sp>;
cap-sd-highspeed;
cap-sdio-irq;
status = "disabled";
@@ -309,6 +342,7 @@
0 122 IRQ_TYPE_LEVEL_HIGH
0 123 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7740_CLK_SDHI1>;
+ power-domains = <&pd_a3sp>;
cap-sd-highspeed;
cap-sdio-irq;
status = "disabled";
@@ -321,6 +355,7 @@
0 126 IRQ_TYPE_LEVEL_HIGH
0 127 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp4_clks R8A7740_CLK_SDHI2>;
+ power-domains = <&pd_a3sp>;
cap-sd-highspeed;
cap-sdio-irq;
status = "disabled";
@@ -332,6 +367,7 @@
reg = <0xfe1f0000 0x400>;
interrupts = <0 9 0x4>;
clocks = <&mstp3_clks R8A7740_CLK_FSI>;
+ power-domains = <&pd_a4mp>;
status = "disabled";
};
@@ -343,6 +379,7 @@
<0 200 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7740_CLK_TMU0>;
clock-names = "fck";
+ power-domains = <&pd_a4r>;
#renesas,channels = <3>;
@@ -357,6 +394,7 @@
<0 172 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp1_clks R8A7740_CLK_TMU1>;
clock-names = "fck";
+ power-domains = <&pd_a4r>;
#renesas,channels = <3>;
@@ -453,7 +491,7 @@
reg = <0xe6150080 4>;
clocks = <&sub_clk>, <&sub_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7740_CLK_SUBCK R8A7740_CLK_SUBCK2
>;
clock-output-names =
@@ -468,7 +506,7 @@
<&cpg_clocks R8A7740_CLK_HPP>, <&sub_clk>,
<&cpg_clocks R8A7740_CLK_B>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7740_CLK_CEU21 R8A7740_CLK_CEU20 R8A7740_CLK_TMU0
R8A7740_CLK_LCDC1 R8A7740_CLK_IIC0 R8A7740_CLK_TMU1
R8A7740_CLK_LCDC0
@@ -489,7 +527,7 @@
<&sub_clk>, <&sub_clk>, <&sub_clk>,
<&sub_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7740_CLK_SCIFA6 R8A7740_CLK_INTCA
R8A7740_CLK_SCIFA7
R8A7740_CLK_DMAC1 R8A7740_CLK_DMAC2
@@ -518,7 +556,7 @@
<&cpg_clocks R8A7740_CLK_HP>,
<&cpg_clocks R8A7740_CLK_HP>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7740_CLK_CMT1 R8A7740_CLK_FSI R8A7740_CLK_IIC1
R8A7740_CLK_USBF R8A7740_CLK_SDHI0 R8A7740_CLK_SDHI1
R8A7740_CLK_MMC R8A7740_CLK_GETHER R8A7740_CLK_TPU0
@@ -535,7 +573,7 @@
<&cpg_clocks R8A7740_CLK_HP>,
<&cpg_clocks R8A7740_CLK_HP>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7740_CLK_USBH R8A7740_CLK_SDHI2
R8A7740_CLK_USBFUNC R8A7740_CLK_USBPHY
>;
@@ -543,4 +581,71 @@
"usbhost", "sdhi2", "usbfunc", "usphy";
};
};
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,sysc-r8a7740", "renesas,sysc-rmobile";
+ reg = <0xe6180000 0x8000>, <0xe6188000 0x8000>;
+
+ pm-domains {
+ pd_c5: c5 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a4lc: a4lc@1 {
+ reg = <1>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4mp: a4mp@2 {
+ reg = <2>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_d4: d4@3 {
+ reg = <3>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a4r: a4r@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3rv: a3rv@6 {
+ reg = <6>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4s: a4s@10 {
+ reg = <10>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #power-domain-cells = <0>;
+
+ pd_a3sp: a3sp@11 {
+ reg = <11>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3sm: a3sm@12 {
+ reg = <12>;
+ #power-domain-cells = <0>;
+ };
+
+ pd_a3sg: a3sg@13 {
+ reg = <13>;
+ #power-domain-cells = <0>;
+ };
+ };
+
+ pd_a4su: a4su@20 {
+ reg = <20>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+ };
};
diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
index ede9a29e4bc6..5c2219b9f3eb 100644
--- a/arch/arm/boot/dts/r8a7779.dtsi
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -12,6 +12,7 @@
/include/ "skeleton.dtsi"
#include <dt-bindings/clock/r8a7779-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
@@ -62,6 +63,14 @@
<0xf0000100 0x100>;
};
+ timer@f0000600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xf0000600 0x20>;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&cpg_clocks R8A7779_CLK_ZS>;
+ };
+
gpio0: gpio@ffc40000 {
compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
reg = <0xffc40000 0x2c>;
@@ -200,7 +209,7 @@
compatible = "renesas,scif-r8a7779", "renesas,scif";
reg = <0xffe40000 0x100>;
interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg_clocks R8A7779_CLK_P>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF0>;
clock-names = "sci_ick";
status = "disabled";
};
@@ -209,7 +218,7 @@
compatible = "renesas,scif-r8a7779", "renesas,scif";
reg = <0xffe41000 0x100>;
interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg_clocks R8A7779_CLK_P>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF1>;
clock-names = "sci_ick";
status = "disabled";
};
@@ -218,7 +227,7 @@
compatible = "renesas,scif-r8a7779", "renesas,scif";
reg = <0xffe42000 0x100>;
interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg_clocks R8A7779_CLK_P>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF2>;
clock-names = "sci_ick";
status = "disabled";
};
@@ -227,7 +236,7 @@
compatible = "renesas,scif-r8a7779", "renesas,scif";
reg = <0xffe43000 0x100>;
interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg_clocks R8A7779_CLK_P>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF3>;
clock-names = "sci_ick";
status = "disabled";
};
@@ -236,7 +245,7 @@
compatible = "renesas,scif-r8a7779", "renesas,scif";
reg = <0xffe44000 0x100>;
interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg_clocks R8A7779_CLK_P>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF4>;
clock-names = "sci_ick";
status = "disabled";
};
@@ -245,7 +254,7 @@
compatible = "renesas,scif-r8a7779", "renesas,scif";
reg = <0xffe45000 0x100>;
interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg_clocks R8A7779_CLK_P>;
+ clocks = <&mstp0_clks R8A7779_CLK_SCIF5>;
clock-names = "sci_ick";
status = "disabled";
};
@@ -464,18 +473,18 @@
<&cpg_clocks R8A7779_CLK_P>,
<&cpg_clocks R8A7779_CLK_S>,
<&cpg_clocks R8A7779_CLK_S>,
- <&cpg_clocks R8A7779_CLK_S1>,
- <&cpg_clocks R8A7779_CLK_S1>,
- <&cpg_clocks R8A7779_CLK_S1>,
- <&cpg_clocks R8A7779_CLK_S1>,
- <&cpg_clocks R8A7779_CLK_S1>,
- <&cpg_clocks R8A7779_CLK_S1>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
+ <&cpg_clocks R8A7779_CLK_P>,
<&cpg_clocks R8A7779_CLK_P>,
<&cpg_clocks R8A7779_CLK_P>,
<&cpg_clocks R8A7779_CLK_P>,
<&cpg_clocks R8A7779_CLK_P>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7779_CLK_HSPI R8A7779_CLK_TMU2
R8A7779_CLK_TMU1 R8A7779_CLK_TMU0
R8A7779_CLK_HSCIF1 R8A7779_CLK_HSCIF0
@@ -506,7 +515,7 @@
<&cpg_clocks R8A7779_CLK_P>,
<&cpg_clocks R8A7779_CLK_S>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7779_CLK_USB01 R8A7779_CLK_USB2
R8A7779_CLK_DU R8A7779_CLK_VIN2
R8A7779_CLK_VIN1 R8A7779_CLK_VIN0
@@ -527,7 +536,7 @@
clocks = <&s4_clk>, <&s4_clk>, <&s4_clk>, <&s4_clk>,
<&s4_clk>, <&s4_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7779_CLK_SDHI3 R8A7779_CLK_SDHI2
R8A7779_CLK_SDHI1 R8A7779_CLK_SDHI0
R8A7779_CLK_MMC1 R8A7779_CLK_MMC0
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 636d53bb87a2..0c3b6783b72a 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -47,12 +47,12 @@
compatible = "renesas,lager", "renesas,r8a7790";
aliases {
- serial6 = &scifa0;
- serial7 = &scifa1;
+ serial0 = &scifa0;
+ serial1 = &scifa1;
};
chosen {
- bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
stdout-path = &scifa0;
};
@@ -355,7 +355,7 @@
phy-handle = <&phy1>;
renesas,ether-link-active-low;
- status = "ok";
+ status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
@@ -366,7 +366,7 @@
};
&cmt0 {
- status = "ok";
+ status = "okay";
};
&mmcif1 {
@@ -397,6 +397,8 @@
spi-max-frequency = <30000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
+ spi-cpha;
+ spi-cpol;
m25p,fast-read;
partition@0 {
@@ -470,17 +472,17 @@
};
&iic0 {
- status = "ok";
+ status = "okay";
};
&iic1 {
- status = "ok";
+ status = "okay";
pinctrl-0 = <&iic1_pins>;
pinctrl-names = "default";
};
&iic2 {
- status = "ok";
+ status = "okay";
pinctrl-0 = <&iic2_pins>;
pinctrl-names = "default";
@@ -562,7 +564,7 @@
pinctrl-0 = <&vin1_pins>;
pinctrl-names = "default";
- status = "ok";
+ status = "okay";
port {
#address-cells = <1>;
@@ -579,6 +581,7 @@
pinctrl-0 = <&sound_pins &sound_clk_pins>;
pinctrl-names = "default";
+ /* Single DAI */
#sound-dai-cells = <0>;
status = "okay";
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index af7e255f629e..4b38fc920114 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -1054,7 +1054,7 @@
reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
clocks = <&mp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <R8A7790_CLK_MSIOF0>;
+ clock-indices = <R8A7790_CLK_MSIOF0>;
clock-output-names = "msiof0";
};
mstp1_clks: mstp1_clks@e6150134 {
@@ -1065,7 +1065,7 @@
<&zs_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
<&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7790_CLK_VCP1 R8A7790_CLK_VCP0 R8A7790_CLK_VPC1
R8A7790_CLK_VPC0 R8A7790_CLK_JPU R8A7790_CLK_SSP1
R8A7790_CLK_TMU1 R8A7790_CLK_3DG R8A7790_CLK_2DDMAC
@@ -1087,7 +1087,7 @@
<&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&zs_clk>,
<&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0
R8A7790_CLK_MSIOF2 R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1
R8A7790_CLK_MSIOF1 R8A7790_CLK_MSIOF3 R8A7790_CLK_SCIFB2
@@ -1106,7 +1106,7 @@
<&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>,
<&hp_clk>, <&hp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7790_CLK_IIC2 R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0 R8A7790_CLK_MMCIF0
R8A7790_CLK_IIC0 R8A7790_CLK_PCIEC R8A7790_CLK_IIC1 R8A7790_CLK_SSUSB R8A7790_CLK_CMT1
@@ -1123,8 +1123,10 @@
reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
clocks = <&hp_clk>, <&hp_clk>, <&extal_clk>, <&p_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <R8A7790_CLK_AUDIO_DMAC0 R8A7790_CLK_AUDIO_DMAC1
- R8A7790_CLK_THERMAL R8A7790_CLK_PWM>;
+ clock-indices = <
+ R8A7790_CLK_AUDIO_DMAC0 R8A7790_CLK_AUDIO_DMAC1
+ R8A7790_CLK_THERMAL R8A7790_CLK_PWM
+ >;
clock-output-names = "audmac0", "audmac1", "thermal", "pwm";
};
mstp7_clks: mstp7_clks@e615014c {
@@ -1134,7 +1136,7 @@
<&p_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>,
<&zx_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7790_CLK_EHCI R8A7790_CLK_HSUSB R8A7790_CLK_HSCIF1
R8A7790_CLK_HSCIF0 R8A7790_CLK_SCIF1 R8A7790_CLK_SCIF0
R8A7790_CLK_DU2 R8A7790_CLK_DU1 R8A7790_CLK_DU0
@@ -1147,16 +1149,17 @@
mstp8_clks: mstp8_clks@e6150990 {
compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
- clocks = <&zg_clk>, <&zg_clk>, <&zg_clk>, <&zg_clk>, <&p_clk>,
- <&zs_clk>, <&zs_clk>;
+ clocks = <&hp_clk>, <&zg_clk>, <&zg_clk>, <&zg_clk>,
+ <&zg_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
- R8A7790_CLK_VIN3 R8A7790_CLK_VIN2 R8A7790_CLK_VIN1
- R8A7790_CLK_VIN0 R8A7790_CLK_ETHER R8A7790_CLK_SATA1
- R8A7790_CLK_SATA0
+ clock-indices = <
+ R8A7790_CLK_MLB R8A7790_CLK_VIN3 R8A7790_CLK_VIN2
+ R8A7790_CLK_VIN1 R8A7790_CLK_VIN0 R8A7790_CLK_ETHER
+ R8A7790_CLK_SATA1 R8A7790_CLK_SATA0
>;
clock-output-names =
- "vin3", "vin2", "vin1", "vin0", "ether", "sata1", "sata0";
+ "mlb", "vin3", "vin2", "vin1", "vin0", "ether",
+ "sata1", "sata0";
};
mstp9_clks: mstp9_clks@e6150994 {
compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
@@ -1166,7 +1169,7 @@
<&p_clk>, <&p_clk>, <&cpg_clocks R8A7790_CLK_QSPI>, <&cp_clk>,
<&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7790_CLK_GPIO5 R8A7790_CLK_GPIO4 R8A7790_CLK_GPIO3
R8A7790_CLK_GPIO2 R8A7790_CLK_GPIO1 R8A7790_CLK_GPIO0
R8A7790_CLK_RCAN1 R8A7790_CLK_RCAN0 R8A7790_CLK_QSPI_MOD R8A7790_CLK_IICDVFS
@@ -1397,8 +1400,13 @@
};
rcar_sound: rcar_sound@ec500000 {
- #sound-dai-cells = <1>;
- compatible = "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2", "renesas,rcar_sound";
+ /*
+ * #sound-dai-cells is required
+ *
+ * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+ * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+ */
+ compatible = "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2";
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
@@ -1432,16 +1440,16 @@
};
rcar_sound,src {
- src0: src@0 { };
- src1: src@1 { };
- src2: src@2 { };
- src3: src@3 { };
- src4: src@4 { };
- src5: src@5 { };
- src6: src@6 { };
- src7: src@7 { };
- src8: src@8 { };
- src9: src@9 { };
+ src0: src@0 { interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; };
+ src1: src@1 { interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; };
+ src2: src@2 { interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; };
+ src3: src@3 { interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; };
+ src4: src@4 { interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; };
+ src5: src@5 { interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; };
+ src6: src@6 { interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; };
+ src7: src@7 { interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; };
+ src8: src@8 { interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; };
+ src9: src@9 { interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; };
};
rcar_sound,ssi {
diff --git a/arch/arm/boot/dts/r8a7791-henninger.dts b/arch/arm/boot/dts/r8a7791-henninger.dts
index 740e38678032..d2ebf11f9881 100644
--- a/arch/arm/boot/dts/r8a7791-henninger.dts
+++ b/arch/arm/boot/dts/r8a7791-henninger.dts
@@ -156,7 +156,7 @@
phy-handle = <&phy1>;
renesas,ether-link-active-low;
- status = "ok";
+ status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
@@ -293,7 +293,7 @@
/* composite video input */
&vin0 {
- status = "ok";
+ status = "okay";
pinctrl-0 = <&vin0_pins>;
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 990af167c551..a3c27807f6c5 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -48,8 +48,8 @@
compatible = "renesas,koelsch", "renesas,r8a7791";
aliases {
- serial6 = &scif0;
- serial7 = &scif1;
+ serial0 = &scif0;
+ serial1 = &scif1;
};
chosen {
@@ -366,7 +366,7 @@
phy-handle = <&phy1>;
renesas,ether-link-active-low;
- status = "ok";
+ status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
@@ -377,7 +377,7 @@
};
&cmt0 {
- status = "ok";
+ status = "okay";
};
&sata0 {
@@ -444,6 +444,8 @@
spi-max-frequency = <30000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
+ spi-cpha;
+ spi-cpol;
m25p,fast-read;
partition@0 {
@@ -452,13 +454,13 @@
read-only;
};
partition@80000 {
- label = "bootenv";
- reg = <0x00080000 0x00080000>;
+ label = "user";
+ reg = <0x00080000 0x00580000>;
read-only;
};
- partition@100000 {
- label = "data";
- reg = <0x00100000 0x03f00000>;
+ partition@600000 {
+ label = "flash";
+ reg = <0x00600000 0x03a00000>;
};
};
};
@@ -563,7 +565,7 @@
/* composite video input */
&vin1 {
- status = "ok";
+ status = "okay";
pinctrl-0 = <&vin1_pins>;
pinctrl-names = "default";
@@ -582,6 +584,7 @@
pinctrl-0 = <&sound_pins &sound_clk_pins>;
pinctrl-names = "default";
+ /* Single DAI */
#sound-dai-cells = <0>;
status = "okay";
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 77c0beeb8d7c..e35812a0d8d4 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -78,7 +78,7 @@
<0 0xf1002000 0 0x1000>,
<0 0xf1004000 0 0x2000>,
<0 0xf1006000 0 0x2000>;
- interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
};
gpio0: gpio@e6050000 {
@@ -186,10 +186,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
};
cmt0: timer@ffca0000 {
@@ -1062,7 +1062,7 @@
reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
clocks = <&mp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <R8A7791_CLK_MSIOF0>;
+ clock-indices = <R8A7791_CLK_MSIOF0>;
clock-output-names = "msiof0";
};
mstp1_clks: mstp1_clks@e6150134 {
@@ -1073,7 +1073,7 @@
<&p_clk>, <&rclk_clk>, <&cp_clk>, <&zs_clk>, <&zs_clk>,
<&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7791_CLK_VCP0 R8A7791_CLK_VPC0 R8A7791_CLK_JPU
R8A7791_CLK_SSP1 R8A7791_CLK_TMU1 R8A7791_CLK_3DG
R8A7791_CLK_2DDMAC R8A7791_CLK_FDP1_1 R8A7791_CLK_FDP1_0
@@ -1093,7 +1093,7 @@
<&mp_clk>, <&mp_clk>, <&mp_clk>,
<&zs_clk>, <&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7791_CLK_SCIFA2 R8A7791_CLK_SCIFA1 R8A7791_CLK_SCIFA0
R8A7791_CLK_MSIOF2 R8A7791_CLK_SCIFB0 R8A7791_CLK_SCIFB1
R8A7791_CLK_MSIOF1 R8A7791_CLK_SCIFB2
@@ -1111,7 +1111,7 @@
<&mmc0_clk>, <&hp_clk>, <&mp_clk>, <&hp_clk>, <&mp_clk>, <&rclk_clk>,
<&hp_clk>, <&hp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7791_CLK_TPU0 R8A7791_CLK_SDHI2 R8A7791_CLK_SDHI1 R8A7791_CLK_SDHI0
R8A7791_CLK_MMCIF0 R8A7791_CLK_IIC0 R8A7791_CLK_PCIEC R8A7791_CLK_IIC1
R8A7791_CLK_SSUSB R8A7791_CLK_CMT1
@@ -1127,8 +1127,10 @@
reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
clocks = <&hp_clk>, <&hp_clk>, <&extal_clk>, <&p_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <R8A7791_CLK_AUDIO_DMAC0 R8A7791_CLK_AUDIO_DMAC1
- R8A7791_CLK_THERMAL R8A7791_CLK_PWM>;
+ clock-indices = <
+ R8A7791_CLK_AUDIO_DMAC0 R8A7791_CLK_AUDIO_DMAC1
+ R8A7791_CLK_THERMAL R8A7791_CLK_PWM
+ >;
clock-output-names = "audmac0", "audmac1", "thermal", "pwm";
};
mstp7_clks: mstp7_clks@e615014c {
@@ -1138,7 +1140,7 @@
<&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
<&zx_clk>, <&zx_clk>, <&zx_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7791_CLK_EHCI R8A7791_CLK_HSUSB R8A7791_CLK_HSCIF2 R8A7791_CLK_SCIF5
R8A7791_CLK_SCIF4 R8A7791_CLK_HSCIF1 R8A7791_CLK_HSCIF0
R8A7791_CLK_SCIF3 R8A7791_CLK_SCIF2 R8A7791_CLK_SCIF1
@@ -1152,15 +1154,17 @@
mstp8_clks: mstp8_clks@e6150990 {
compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
- clocks = <&zg_clk>, <&zg_clk>, <&zg_clk>, <&p_clk>, <&zs_clk>,
- <&zs_clk>;
+ clocks = <&zg_clk>, <&hp_clk>, <&zg_clk>, <&zg_clk>,
+ <&zg_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
+ R8A7791_CLK_IPMMU_SGX R8A7791_CLK_MLB
R8A7791_CLK_VIN2 R8A7791_CLK_VIN1 R8A7791_CLK_VIN0
R8A7791_CLK_ETHER R8A7791_CLK_SATA1 R8A7791_CLK_SATA0
>;
clock-output-names =
- "vin2", "vin1", "vin0", "ether", "sata1", "sata0";
+ "ipmmu_sgx", "mlb", "vin2", "vin1", "vin0", "ether",
+ "sata1", "sata0";
};
mstp9_clks: mstp9_clks@e6150994 {
compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
@@ -1171,7 +1175,7 @@
<&cp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>,
<&hp_clk>, <&hp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7791_CLK_GPIO7 R8A7791_CLK_GPIO6 R8A7791_CLK_GPIO5 R8A7791_CLK_GPIO4
R8A7791_CLK_GPIO3 R8A7791_CLK_GPIO2 R8A7791_CLK_GPIO1 R8A7791_CLK_GPIO0
R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_QSPI_MOD R8A7791_CLK_I2C5
@@ -1221,7 +1225,7 @@
reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7791_CLK_SCIFA3 R8A7791_CLK_SCIFA4 R8A7791_CLK_SCIFA5
>;
clock-output-names = "scifa3", "scifa4", "scifa5";
@@ -1381,8 +1385,13 @@
};
rcar_sound: rcar_sound@ec500000 {
- #sound-dai-cells = <1>;
- compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2", "renesas,rcar_sound";
+ /*
+ * #sound-dai-cells is required
+ *
+ * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>;
+ * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>;
+ */
+ compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
reg = <0 0xec500000 0 0x1000>, /* SCU */
<0 0xec5a0000 0 0x100>, /* ADG */
<0 0xec540000 0 0x1000>, /* SSIU */
@@ -1416,16 +1425,16 @@
};
rcar_sound,src {
- src0: src@0 { };
- src1: src@1 { };
- src2: src@2 { };
- src3: src@3 { };
- src4: src@4 { };
- src5: src@5 { };
- src6: src@6 { };
- src7: src@7 { };
- src8: src@8 { };
- src9: src@9 { };
+ src0: src@0 { interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; };
+ src1: src@1 { interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; };
+ src2: src@2 { interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; };
+ src3: src@3 { interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; };
+ src4: src@4 { interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; };
+ src5: src@5 { interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; };
+ src6: src@6 { interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; };
+ src7: src@7 { interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; };
+ src8: src@8 { interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; };
+ src9: src@9 { interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; };
};
rcar_sound,ssi {
diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
index f2cf7576bf3f..0d848e605071 100644
--- a/arch/arm/boot/dts/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -40,9 +40,9 @@
};
&cmt0 {
- status = "ok";
+ status = "okay";
};
&scif2 {
- status = "ok";
+ status = "okay";
};
diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 19c9de3f2a5a..8f78da5ef10b 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -47,7 +47,7 @@
<0 0xf1002000 0 0x1000>,
<0 0xf1004000 0 0x2000>,
<0 0xf1006000 0 0x2000>;
- interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
};
cmt0: timer@ffca0000 {
@@ -84,10 +84,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
- <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
};
irqc0: interrupt-controller@e61c0000 {
@@ -293,6 +293,28 @@
clock-output-names = "main", "pll0", "pll1", "pll3",
"lb", "qspi", "sdh", "sd0", "z";
};
+ /* Variable factor clocks */
+ sd1_clk: sd2_clk@e6150078 {
+ compatible = "renesas,r8a7794-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150078 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd1";
+ };
+ sd2_clk: sd3_clk@e615007c {
+ compatible = "renesas,r8a7794-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe615007c 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sd2";
+ };
+ mmc0_clk: mmc0_clk@e6150240 {
+ compatible = "renesas,r8a7794-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0 0xe6150240 0 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mmc0";
+ };
/* Fixed factor clocks */
pll1_div2_clk: pll1_div2_clk {
@@ -455,7 +477,7 @@
reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>;
clocks = <&mp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <R8A7794_CLK_MSIOF0>;
+ clock-indices = <R8A7794_CLK_MSIOF0>;
clock-output-names = "msiof0";
};
mstp1_clks: mstp1_clks@e6150134 {
@@ -465,7 +487,7 @@
<&zs_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, <&cp_clk>,
<&zs_clk>, <&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7794_CLK_VCP0 R8A7794_CLK_VPC0 R8A7794_CLK_TMU1
R8A7794_CLK_3DG R8A7794_CLK_2DDMAC R8A7794_CLK_FDP1_0
R8A7794_CLK_TMU3 R8A7794_CLK_TMU2 R8A7794_CLK_CMT0
@@ -479,41 +501,51 @@
compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
- <&mp_clk>, <&mp_clk>, <&mp_clk>;
+ <&mp_clk>, <&mp_clk>, <&mp_clk>,
+ <&zs_clk>, <&zs_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7794_CLK_SCIFA2 R8A7794_CLK_SCIFA1 R8A7794_CLK_SCIFA0
R8A7794_CLK_MSIOF2 R8A7794_CLK_SCIFB0 R8A7794_CLK_SCIFB1
R8A7794_CLK_MSIOF1 R8A7794_CLK_SCIFB2
+ R8A7794_CLK_SYS_DMAC1 R8A7794_CLK_SYS_DMAC0
>;
clock-output-names =
"scifa2", "scifa1", "scifa0", "msiof2", "scifb0",
- "scifb1", "msiof1", "scifb2";
+ "scifb1", "msiof1", "scifb2",
+ "sys-dmac1", "sys-dmac0";
};
mstp3_clks: mstp3_clks@e615013c {
compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
- clocks = <&rclk_clk>;
+ clocks = <&sd2_clk>, <&sd1_clk>, <&cpg_clocks R8A7794_CLK_SD0>,
+ <&mmc0_clk>, <&rclk_clk>, <&hp_clk>, <&hp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
- R8A7794_CLK_CMT1
+ clock-indices = <
+ R8A7794_CLK_SDHI2 R8A7794_CLK_SDHI1 R8A7794_CLK_SDHI0
+ R8A7794_CLK_MMCIF0 R8A7794_CLK_CMT1
+ R8A7794_CLK_USBDMAC0 R8A7794_CLK_USBDMAC1
>;
clock-output-names =
- "cmt1";
+ "sdhi2", "sdhi1", "sdhi0",
+ "mmcif0", "cmt1", "usbdmac0", "usbdmac1";
};
mstp7_clks: mstp7_clks@e615014c {
compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
- clocks = <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
+ clocks = <&mp_clk>, <&mp_clk>,
+ <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>,
<&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
+ R8A7794_CLK_EHCI R8A7794_CLK_HSUSB
R8A7794_CLK_HSCIF2 R8A7794_CLK_SCIF5
R8A7794_CLK_SCIF4 R8A7794_CLK_HSCIF1 R8A7794_CLK_HSCIF0
R8A7794_CLK_SCIF3 R8A7794_CLK_SCIF2 R8A7794_CLK_SCIF1
R8A7794_CLK_SCIF0
>;
clock-output-names =
+ "ehci", "hsusb",
"hscif2", "scif5", "scif4", "hscif1", "hscif0",
"scif3", "scif2", "scif1", "scif0";
};
@@ -522,18 +554,32 @@
reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
clocks = <&zg_clk>, <&zg_clk>, <&p_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7794_CLK_VIN1 R8A7794_CLK_VIN0 R8A7794_CLK_ETHER
>;
clock-output-names =
"vin1", "vin0", "ether";
};
+ mstp9_clks: mstp9_clks@e6150994 {
+ compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+ clocks = <&cpg_clocks R8A7794_CLK_QSPI>, <&hp_clk>, <&hp_clk>,
+ <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ R8A7794_CLK_QSPI_MOD R8A7794_CLK_I2C5 R8A7794_CLK_I2C4
+ R8A7794_CLK_I2C3 R8A7794_CLK_I2C2 R8A7794_CLK_I2C1
+ R8A7794_CLK_I2C0
+ >;
+ clock-output-names =
+ "qspi_mod", "i2c5", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0";
+ };
mstp11_clks: mstp11_clks@e615099c {
compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
#clock-cells = <1>;
- renesas,clock-indices = <
+ clock-indices = <
R8A7794_CLK_SCIFA3 R8A7794_CLK_SCIFA4 R8A7794_CLK_SCIFA5
>;
clock-output-names = "scifa3", "scifa4", "scifa5";
diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts
new file mode 100644
index 000000000000..3ac151102c2f
--- /dev/null
+++ b/arch/arm/boot/dts/rk3066a-rayeager.dts
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3066a.dtsi"
+
+/ {
+ model = "Rayeager PX2";
+ compatible = "chipspark,rayeager-px2", "rockchip,rk3066a";
+
+ memory {
+ reg = <0x60000000 0x40000000>;
+ };
+
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio6 1 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ gpio-key,wakeup = <1>;
+ gpios = <&gpio6 2 GPIO_ACTIVE_LOW>;
+ label = "GPIO Power";
+ linux,code = <116>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+ };
+ };
+
+ vsys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* input for 5V_STDBY is VSYS or DC5V, selectable by jumper J4 */
+ vcc_stdby: 5v-stdby-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "5v_stdby";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_emmc: emmc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "emmc_vccq";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ vin-supply = <&vsys>;
+ };
+
+ vcc_sata: sata-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sata_pwr>;
+ regulator-name = "usb_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_stdby>;
+ };
+
+ vcc_sd: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio3 7 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwr>;
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_host: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_drv>;
+ regulator-name = "host-pwr";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_stdby>;
+ };
+
+ vcc_otg: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_drv>;
+ regulator-name = "vcc_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_stdby>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_arm>;
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_xfer>, <&emac_mdio>, <&rmii_rst>;
+ phy = <&phy0>;
+ phy-supply = <&vcc_rmii>;
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&emmc {
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_rst>;
+ vmmc-supply = <&vcc_emmc>;
+ vqmmc-supply = <&vcc_emmc>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ ak8963: ak8963@0d {
+ compatible = "asahi-kasei,ak8975";
+ reg = <0x0d>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <17 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&comp_int>;
+ };
+
+ mma8452: mma8452@1d {
+ compatible = "fsl,mma8452";
+ reg = <0x1d>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <16 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsensor_int>;
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ tps: tps@2d {
+ reg = <0x2d>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <4 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int>, <&pwr_hold>;
+
+ vcc1-supply = <&vsys>;
+ vcc2-supply = <&vsys>;
+ vcc3-supply = <&vsys>;
+ vcc4-supply = <&vsys>;
+ vcc5-supply = <&vcc_io>;
+ vcc6-supply = <&vcc_io>;
+ vcc7-supply = <&vsys>;
+ vccio-supply = <&vsys>;
+
+ regulators {
+ vcc_rtc: regulator@0 {
+ regulator-name = "vcc_rtc";
+ regulator-always-on;
+ };
+
+ vcc_io: regulator@1 {
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_arm: regulator@2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_ddr: regulator@3 {
+ regulator-name = "vcc_ddr";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc18: regulator@5 {
+ regulator-name = "vcc18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vdd_11: regulator@6 {
+ regulator-name = "vdd_11";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vcc_25: regulator@7 {
+ regulator-name = "vcc_25";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vccio_wl: regulator@8 {
+ regulator-name = "vccio_wl";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc25_hdmi: regulator@9 {
+ regulator-name = "vcc25_hdmi";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ vcca_33: regulator@10 {
+ regulator-name = "vcca_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_rmii: regulator@11 {
+ regulator-name = "vcc_rmii";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc28_cif: regulator@12 {
+ regulator-name = "vcc28_cif";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+ };
+ };
+};
+
+#include "tps65910.dtsi"
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&mmc0 {
+ bus-width = <4>;
+ disable-wp;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ status = "okay";
+};
+
+&mmc1 {
+ broken-cd;
+ bus-width = <4>;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>;
+ vmmc-supply = <&vccio_wl>;
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ ak8963 {
+ comp_int: comp-int {
+ rockchip,pins = <4 17 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ emac {
+ rmii_rst: rmii-rst {
+ rockchip,pins = <1 30 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <6 1 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <6 2 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ mma8452 {
+ gsensor_int: gsensor-int {
+ rockchip,pins = <4 16 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ mmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <3 7 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ usb_host {
+ host_drv: host-drv {
+ rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+
+ hub_rst: hub-rst {
+ rockchip,pins = <1 31 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+
+ sata_pwr: sata-pwr {
+ rockchip,pins = <4 22 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+
+ sata_reset: sata-reset {
+ rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ usb_otg {
+ otg_drv: otg-drv {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ tps {
+ pmic_int: pmic-int {
+ rockchip,pins = <6 4 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+
+ pwr_hold: pwr-hold {
+ rockchip,pins = <6 8 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_25>;
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>, <&uart3_cts>, <&uart3_rts>;
+ status = "okay";
+};
+
+&usb_host {
+ pinctrl-names = "default";
+ pinctrl-0 = <&hub_rst>, <&sata_reset>;
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts
index a76dd44adb53..d7b8bbc0c25f 100644
--- a/arch/arm/boot/dts/rk3288-evb-act8846.dts
+++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts
@@ -17,7 +17,34 @@
compatible = "rockchip,rk3288-evb-act8846", "rockchip,rk3288";
};
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
&i2c0 {
+ clock-frequency = <400000>;
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x40>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_gpu: syr828@41 {
+ compatible = "silergy,syr828";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x41>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
hym8563@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
diff --git a/arch/arm/boot/dts/rk3288-evb-rk808.dts b/arch/arm/boot/dts/rk3288-evb-rk808.dts
index e1d3eeb8f094..a1c294bf7fed 100644
--- a/arch/arm/boot/dts/rk3288-evb-rk808.dts
+++ b/arch/arm/boot/dts/rk3288-evb-rk808.dts
@@ -30,7 +30,6 @@
&i2c0 {
clock-frequency = <400000>;
- status = "okay";
rk808: pmic@1b {
compatible = "rockchip,rk808";
@@ -38,7 +37,7 @@
interrupt-parent = <&gpio0>;
interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
- pinctrl-0 = <&pmic_int>;
+ pinctrl-0 = <&pmic_int &global_pwroff>;
rockchip,system-power-controller;
wakeup-source;
#clock-cells = <1>;
@@ -57,6 +56,9 @@
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1350000>;
regulator-name = "vdd_arm";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
vdd_gpu: DCDC_REG2 {
@@ -65,12 +67,19 @@
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1250000>;
regulator-name = "vdd_gpu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
};
vcc_ddr: DCDC_REG3 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vcc_ddr";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
vcc_io: DCDC_REG4 {
@@ -79,6 +88,10 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc_io";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
};
vccio_pmu: LDO_REG1 {
@@ -87,6 +100,10 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vccio_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
};
vcc_tp: LDO_REG2 {
@@ -95,6 +112,9 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc_tp";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
};
vdd_10: LDO_REG3 {
@@ -103,6 +123,10 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-name = "vdd_10";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
};
vcc18_lcd: LDO_REG4 {
@@ -111,6 +135,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc18_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
};
vccio_sd: LDO_REG5 {
@@ -119,6 +147,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vccio_sd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
};
vdd10_lcd: LDO_REG6 {
@@ -127,6 +159,10 @@
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-name = "vdd10_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
};
vcc_18: LDO_REG7 {
@@ -135,6 +171,10 @@
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc_18";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
};
vcca_codec: LDO_REG8 {
@@ -143,18 +183,28 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcca_codec";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
};
vcc_wl: SWITCH_REG1 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vcc_wl";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
vcc_lcd: SWITCH_REG2 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vcc_lcd";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi
index 1c08eb0ecdb9..5e895a514a0b 100644
--- a/arch/arm/boot/dts/rk3288-evb.dtsi
+++ b/arch/arm/boot/dts/rk3288-evb.dtsi
@@ -117,6 +117,11 @@
status = "okay";
};
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
&sdmmc {
bus-width = <4>;
cap-mmc-highspeed;
@@ -133,6 +138,10 @@
status = "okay";
};
+&i2c5 {
+ status = "okay";
+};
+
&wdt {
status = "okay";
};
@@ -236,3 +245,19 @@
&usb_host1 {
status = "okay";
};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
+
+&vopl {
+ status = "okay";
+};
+
+&vopl_mmu {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-firefly-beta.dts b/arch/arm/boot/dts/rk3288-firefly-beta.dts
new file mode 100644
index 000000000000..75d77e38e0d6
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-firefly-beta.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-firefly.dtsi"
+
+/ {
+ model = "Firefly-RK3288 Beta";
+ compatible = "firefly,firefly-rk3288-beta", "rockchip,rk3288";
+};
+
+&ir {
+ gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+};
+
+&pinctrl {
+ act8846 {
+ pmic_vsel: pmic-vsel {
+ rockchip,pins = <7 1 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+ };
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <7 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pwm0 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-firefly.dts b/arch/arm/boot/dts/rk3288-firefly.dts
new file mode 100644
index 000000000000..c07fe92dc69f
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-firefly.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-firefly.dtsi"
+
+/ {
+ model = "Firefly-RK3288";
+ compatible = "firefly,firefly-rk3288", "rockchip,rk3288";
+};
+
+&ir {
+ gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+};
+
+&pinctrl {
+ act8846 {
+ pmic_vsel: pmic-vsel {
+ rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+ };
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pwm1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
new file mode 100644
index 000000000000..e6f873abbe0d
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "rk3288.dtsi"
+
+/ {
+ memory {
+ reg = <0 0x80000000>;
+ };
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ };
+
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
+ keys: gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ gpio-key,wakeup = <1>;
+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+ label = "GPIO Power";
+ linux,code = <116>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwr_key>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ work {
+ gpios = <&gpio8 1 GPIO_ACTIVE_LOW>;
+ label = "firefly:blue:user";
+ linux,default-trigger = "rc-feedback";
+ pinctrl-names = "default";
+ pinctrl-0 = <&work_led>;
+ };
+
+ power {
+ gpios = <&gpio8 2 GPIO_ACTIVE_LOW>;
+ label = "firefly:green:power";
+ linux,default-trigger = "default-on";
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_led>;
+ };
+ };
+
+ vcc_sys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_sd: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio7 11 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwr>;
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_flash: flash-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_flash";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_5v: usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc_host_5v: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "vcc_host_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_5v>;
+ };
+
+ vcc_otg_5v: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ regulator-name = "vcc_otg_5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ vin-supply = <&vcc_5v>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_cpu>;
+};
+
+&emmc {
+ broken-cd;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>;
+ vmmc-supply = <&vcc_io>;
+ vqmmc-supply = <&vcc_flash>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ vdd_cpu: syr827@40 {
+ compatible = "silergy,syr827";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x40>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vdd_gpu: syr828@41 {
+ compatible = "silergy,syr828";
+ fcs,suspend-voltage-selector = <1>;
+ reg = <0x41>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ vin-supply = <&vcc_sys>;
+ };
+
+ hym8563: hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ interrupt-parent = <&gpio7>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int>;
+ };
+
+ act8846: act8846@5a {
+ compatible = "active-semi,act8846";
+ reg = <0x5a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_vsel>, <&pwr_hold>;
+ system-power-controller;
+
+ regulators {
+ vcc_ddr: REG1 {
+ regulator-name = "vcc_ddr";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vcc_io: REG2 {
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_log: REG3 {
+ regulator-name = "vdd_log";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vcc_20: REG4 {
+ regulator-name = "vcc_20";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-always-on;
+ };
+
+ vccio_sd: REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd10_lcd: REG6 {
+ regulator-name = "vdd10_lcd";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcca_18: REG7 {
+ regulator-name = "vcca_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcca_33: REG8 {
+ regulator-name = "vcca_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_lan: REG9 {
+ regulator-name = "vcc_lan";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vdd_10: REG10 {
+ regulator-name = "vdd_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vcc_18: REG11 {
+ regulator-name = "vcc_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc18_lcd: REG12 {
+ regulator-name = "vcc18_lcd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&i2c2 {
+ status = "okay";
+};
+
+&i2c4 {
+ status = "okay";
+};
+
+&i2c5 {
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_output_high: pcfg-output-high {
+ output-high;
+ };
+
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ act8846 {
+ pwr_hold: pwr-hold {
+ rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ gmac {
+ phy_int: phy-int {
+ rockchip,pins = <0 9 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ phy_pmeb: phy-pmeb {
+ rockchip,pins = <0 8 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ phy_rst: phy-rst {
+ rockchip,pins = <4 8 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ hym8563 {
+ rtc_int: rtc-int {
+ rockchip,pins = <7 4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ keys {
+ pwr_key: pwr-key {
+ rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ leds {
+ power_led: power-led {
+ rockchip,pins = <8 2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ work_led: work-led {
+ rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb_host {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usbhub_rst: usbhub-rst {
+ rockchip,pins = <8 3 RK_FUNC_GPIO &pcfg_output_high>;
+ };
+ };
+
+ usb_otg {
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_18>;
+ status = "okay";
+};
+
+&sdio0 {
+ broken-cd;
+ bus-width = <4>;
+ disable-wp;
+ non-removable;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>;
+ vmmc-supply = <&vcc_18>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ disable-wp;
+ num-slots = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
+ vmmc-supply = <&vcc_sd>;
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk>, <&spi0_cs0>, <&spi0_tx>, <&spi0_rx>, <&spi0_cs1>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>;
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usb_host1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usbhub_rst>;
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
+
+&vopl {
+ status = "okay";
+};
+
+&vopl_mmu {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 910dcad2088a..d771f687a13b 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -149,8 +149,22 @@
clock-frequency = <24000000>;
};
+ timer: timer@ff810000 {
+ compatible = "rockchip,rk3288-timer";
+ reg = <0xff810000 0x20>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&xin24m>, <&cru PCLK_TIMER>;
+ clock-names = "timer", "pclk";
+ };
+
+ display-subsystem {
+ compatible = "rockchip,display-subsystem";
+ ports = <&vopl_out>, <&vopb_out>;
+ };
+
sdmmc: dwmmc@ff0c0000 {
compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
clock-names = "biu", "ciu";
fifo-depth = <0x100>;
@@ -161,6 +175,7 @@
sdio0: dwmmc@ff0d0000 {
compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>;
clock-names = "biu", "ciu";
fifo-depth = <0x100>;
@@ -171,6 +186,7 @@
sdio1: dwmmc@ff0e0000 {
compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>;
clock-names = "biu", "ciu";
fifo-depth = <0x100>;
@@ -181,6 +197,7 @@
emmc: dwmmc@ff0f0000 {
compatible = "rockchip,rk3288-dw-mshc";
+ clock-freq-min-max = <400000 150000000>;
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
clock-names = "biu", "ciu";
fifo-depth = <0x100>;
@@ -518,6 +535,11 @@
};
};
+ sram@ff720000 {
+ compatible = "rockchip,rk3288-pmu-sram", "mmio-sram";
+ reg = <0xff720000 0x1000>;
+ };
+
pmu: power-management@ff730000 {
compatible = "rockchip,rk3288-pmu", "syscon";
reg = <0xff730000 0x100>;
@@ -554,6 +576,7 @@
wdt: watchdog@ff800000 {
compatible = "rockchip,rk3288-wdt", "snps,dw-wdt";
reg = <0xff800000 0x100>;
+ clocks = <&cru PCLK_WDT>;
interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -573,6 +596,28 @@
status = "disabled";
};
+ vopb: vop@ff930000 {
+ compatible = "rockchip,rk3288-vop";
+ reg = <0xff930000 0x19c>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
+ clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+ resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>;
+ reset-names = "axi", "ahb", "dclk";
+ iommus = <&vopb_mmu>;
+ status = "disabled";
+
+ vopb_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vopb_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vopb>;
+ };
+ };
+ };
+
vopb_mmu: iommu@ff930300 {
compatible = "rockchip,iommu";
reg = <0xff930300 0x100>;
@@ -582,6 +627,28 @@
status = "disabled";
};
+ vopl: vop@ff940000 {
+ compatible = "rockchip,rk3288-vop";
+ reg = <0xff940000 0x19c>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>;
+ clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+ resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>;
+ reset-names = "axi", "ahb", "dclk";
+ iommus = <&vopl_mmu>;
+ status = "disabled";
+
+ vopl_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vopl_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vopl>;
+ };
+ };
+ };
+
vopl_mmu: iommu@ff940300 {
compatible = "rockchip,iommu";
reg = <0xff940300 0x100>;
@@ -591,6 +658,32 @@
status = "disabled";
};
+ hdmi: hdmi@ff980000 {
+ compatible = "rockchip,rk3288-dw-hdmi";
+ reg = <0xff980000 0x20000>;
+ reg-io-width = <4>;
+ rockchip,grf = <&grf>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>;
+ clock-names = "iahb", "isfr";
+ status = "disabled";
+
+ ports {
+ hdmi_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ hdmi_in_vopb: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vopb_out_hdmi>;
+ };
+ hdmi_in_vopl: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&vopl_out_hdmi>;
+ };
+ };
+ };
+ };
+
gic: interrupt-controller@ffc01000 {
compatible = "arm,gic-400";
interrupt-controller;
@@ -746,6 +839,24 @@
drive-strength = <12>;
};
+ sleep {
+ global_pwroff: global-pwroff {
+ rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ ddrio_pwroff: ddrio-pwroff {
+ rockchip,pins = <0 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ ddr0_retention: ddr0-retention {
+ rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_up>;
+ };
+
+ ddr1_retention: ddr1-retention {
+ rockchip,pins = <0 3 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
i2c0 {
i2c0_xfer: i2c0-xfer {
rockchip,pins = <0 15 RK_FUNC_1 &pcfg_pull_none>,
diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts
index aa31b84a707a..f00cea7aca2f 100644
--- a/arch/arm/boot/dts/s5pv210-aquila.dts
+++ b/arch/arm/boot/dts/s5pv210-aquila.dts
@@ -355,6 +355,7 @@
&hsotg {
vusb_a-supply = <&ldo3_reg>;
vusb_d-supply = <&ldo8_reg>;
+ dr_mode = "peripheral";
status = "okay";
};
diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts
index 6387c77a6f7b..a3d4643b202e 100644
--- a/arch/arm/boot/dts/s5pv210-goni.dts
+++ b/arch/arm/boot/dts/s5pv210-goni.dts
@@ -333,6 +333,7 @@
&hsotg {
vusb_a-supply = <&ldo3_reg>;
vusb_d-supply = <&ldo8_reg>;
+ dr_mode = "peripheral";
status = "okay";
};
diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts
index cb8521899ec8..da7d210df670 100644
--- a/arch/arm/boot/dts/s5pv210-smdkv210.dts
+++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts
@@ -181,6 +181,7 @@
};
&hsotg {
+ dr_mode = "peripheral";
status = "okay";
};
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 5f4144d1e3a1..261311bdf65b 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -78,6 +78,11 @@
};
};
+ sram: sram@00300000 {
+ compatible = "mmio-sram";
+ reg = <0x00300000 0x20000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -214,7 +219,20 @@
compatible = "atmel,at91sam9g45-isi";
reg = <0xf0034000 0x4000>;
interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_isi_data_0_7>;
+ clocks = <&isi_clk>;
+ clock-names = "isi_clk";
status = "disabled";
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ sfr: sfr@f0038000 {
+ compatible = "atmel,sama5d3-sfr", "syscon";
+ reg = <0xf0038000 0x60>;
};
mmc1: mmc@f8000000 {
@@ -545,7 +563,7 @@
};
isi {
- pinctrl_isi: isi-0 {
+ pinctrl_isi_data_0_7: isi-0-data-0-7 {
atmel,pins =
<AT91_PIOA 16 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA16 periph C ISI_D0, conflicts with LCDDAT16 */
AT91_PIOA 17 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA17 periph C ISI_D1, conflicts with LCDDAT17 */
@@ -557,13 +575,19 @@
AT91_PIOA 23 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA23 periph C ISI_D7, conflicts with LCDDAT23, PWML1 */
AT91_PIOC 30 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC30 periph C ISI_PCK, conflicts with UTXD0 */
AT91_PIOA 31 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA31 periph C ISI_HSYNC, conflicts with TWCK0, UTXD1 */
- AT91_PIOA 30 AT91_PERIPH_C AT91_PINCTRL_NONE /* PA30 periph C ISI_VSYNC, conflicts with TWD0, URXD1 */
- AT91_PIOC 29 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC29 periph C ISI_PD8, conflicts with URXD0, PWMFI2 */
+ AT91_PIOA 30 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PA30 periph C ISI_VSYNC, conflicts with TWD0, URXD1 */
+ };
+
+ pinctrl_isi_data_8_9: isi-0-data-8-9 {
+ atmel,pins =
+ <AT91_PIOC 29 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC29 periph C ISI_PD8, conflicts with URXD0, PWMFI2 */
AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC28 periph C ISI_PD9, conflicts with SPI1_NPCS3, PWMFI0 */
};
- pinctrl_isi_pck_as_mck: isi_pck_as_mck-0 {
+
+ pinctrl_isi_data_10_11: isi-0-data-10-11 {
atmel,pins =
- <AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD31 periph B ISI_MCK */
+ <AT91_PIOC 27 AT91_PERIPH_C AT91_PINCTRL_NONE /* PC27 periph C ISI_PD10, conflicts with SPI1_NPCS2, TWCK1 */
+ AT91_PIOC 26 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* PC26 periph C ISI_PD11, conflicts with SPI1_NPCS1, TWD1 */
};
};
diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi
index cfcd200b0c17..7d6babdab039 100644
--- a/arch/arm/boot/dts/sama5d3xcm.dtsi
+++ b/arch/arm/boot/dts/sama5d3xcm.dtsi
@@ -122,6 +122,7 @@
d2 {
label = "d2";
gpios = <&pioE 25 GPIO_ACTIVE_LOW>; /* PE25, conflicts with A25, RXD2 */
+ linux,default-trigger = "heartbeat";
};
};
};
diff --git a/arch/arm/boot/dts/sama5d3xmb.dtsi b/arch/arm/boot/dts/sama5d3xmb.dtsi
index 77e03655aca3..83bee7a3a617 100644
--- a/arch/arm/boot/dts/sama5d3xmb.dtsi
+++ b/arch/arm/boot/dts/sama5d3xmb.dtsi
@@ -45,13 +45,36 @@
*/
i2c0: i2c@f0014000 {
wm8904: wm8904@1a {
- compatible = "wm8904";
+ compatible = "wlf,wm8904";
reg = <0x1a>;
clocks = <&pck0>;
clock-names = "mclk";
};
};
+ i2c1: i2c@f0018000 {
+ ov2640: camera@0x30 {
+ compatible = "ovti,ov2640";
+ reg = <0x30>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pck1_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>;
+ resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>;
+ pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>;
+ /* use pck1 for the master clock of ov2640 */
+ clocks = <&pck1>;
+ clock-names = "xvclk";
+ assigned-clocks = <&pck1>;
+ assigned-clock-rates = <25000000>;
+
+ port {
+ ov2640_0: endpoint {
+ remote-endpoint = <&isi_0>;
+ bus-width = <8>;
+ };
+ };
+ };
+ };
+
usart1: serial@f0020000 {
dmas = <0>, <0>; /* Do not use DMA for usart1 */
pinctrl-names = "default";
@@ -60,8 +83,12 @@
};
isi: isi@f0034000 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_isi &pinctrl_isi_pck_as_mck &pinctrl_isi_power &pinctrl_isi_reset>;
+ port {
+ isi_0: endpoint {
+ remote-endpoint = <&ov2640_0>;
+ bus-width = <8>;
+ };
+ };
};
mmc1: mmc@f8000000 {
@@ -117,12 +144,17 @@
<AT91_PIOD 30 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD30 periph B */
};
- pinctrl_isi_reset: isi_reset-0 {
+ pinctrl_pck1_as_isi_mck: pck1_as_isi_mck-0 {
+ atmel,pins =
+ <AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PD31 periph B ISI_MCK */
+ };
+
+ pinctrl_sensor_reset: sensor_reset-0 {
atmel,pins =
<AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE24 gpio */
};
- pinctrl_isi_power: isi_power-0 {
+ pinctrl_sensor_power: sensor_power-0 {
atmel,pins =
<AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE29 gpio */
};
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index b94995d1889f..d986b41b9654 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -62,6 +62,7 @@
gpio0 = &pioA;
gpio1 = &pioB;
gpio2 = &pioC;
+ gpio3 = &pioD;
gpio4 = &pioE;
tcb0 = &tcb0;
tcb1 = &tcb1;
@@ -103,6 +104,11 @@
};
};
+ ns_sram: sram@00210000 {
+ compatible = "mmio-sram";
+ reg = <0x00210000 0x10000>;
+ };
+
ahb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -267,7 +273,7 @@
};
nand0: nand@80000000 {
- compatible = "atmel,at91rm9200-nand";
+ compatible = "atmel,sama5d4-nand", "atmel,at91rm9200-nand";
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -870,6 +876,11 @@
status = "disabled";
};
+ sfr: sfr@f8028000 {
+ compatible = "atmel,sama5d4-sfr", "syscon";
+ reg = <0xf8028000 0x60>;
+ };
+
mmc1: mmc@fc000000 {
compatible = "atmel,hsmci";
reg = <0xfc000000 0x600>;
@@ -1111,6 +1122,18 @@
clocks = <&pioC_clk>;
};
+ pioD: gpio@fc068000 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfc068000 0x100>;
+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pioD_clk>;
+ status = "disabled";
+ };
+
pioE: gpio@fc06d000 {
compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
reg = <0xfc06d000 0x100>;
diff --git a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
index 939be1299ca6..6d32c87632d4 100644
--- a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
+++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
@@ -179,7 +179,11 @@
};
&cmt1 {
- status = "ok";
+ status = "okay";
+};
+
+&extal2_clk {
+ clock-frequency = <48000000>;
};
&i2c0 {
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index d8def5a529da..2dfd5b44255d 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -10,6 +10,7 @@
/include/ "skeleton.dtsi"
+#include <dt-bindings/clock/sh73a0-clock.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
@@ -42,6 +43,22 @@
<0xf0000100 0x100>;
};
+ sbsc2: memory-controller@fb400000 {
+ compatible = "renesas,sbsc-sh73a0";
+ reg = <0xfb400000 0x400>;
+ interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>,
+ <0 38 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sec", "temp";
+ };
+
+ sbsc1: memory-controller@fe400000 {
+ compatible = "renesas,sbsc-sh73a0";
+ reg = <0xfe400000 0x400>;
+ interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>,
+ <0 36 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "sec", "temp";
+ };
+
pmu {
compatible = "arm,cortex-a9-pmu";
interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>,
@@ -55,6 +72,8 @@
renesas,channels-mask = <0x3f>;
+ clocks = <&mstp3_clks SH73A0_CLK_CMT1>;
+ clock-names = "fck";
status = "disabled";
};
@@ -144,6 +163,7 @@
0 168 IRQ_TYPE_LEVEL_HIGH
0 169 IRQ_TYPE_LEVEL_HIGH
0 170 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp1_clks SH73A0_CLK_IIC0>;
status = "disabled";
};
@@ -156,6 +176,7 @@
0 52 IRQ_TYPE_LEVEL_HIGH
0 53 IRQ_TYPE_LEVEL_HIGH
0 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_IIC1>;
status = "disabled";
};
@@ -168,6 +189,7 @@
0 172 IRQ_TYPE_LEVEL_HIGH
0 173 IRQ_TYPE_LEVEL_HIGH
0 174 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp0_clks SH73A0_CLK_IIC2>;
status = "disabled";
};
@@ -180,6 +202,7 @@
0 184 IRQ_TYPE_LEVEL_HIGH
0 185 IRQ_TYPE_LEVEL_HIGH
0 186 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks SH73A0_CLK_IIC3>;
status = "disabled";
};
@@ -192,6 +215,7 @@
0 188 IRQ_TYPE_LEVEL_HIGH
0 189 IRQ_TYPE_LEVEL_HIGH
0 190 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp4_clks SH73A0_CLK_IIC4>;
status = "disabled";
};
@@ -200,6 +224,7 @@
reg = <0xe6bd0000 0x100>;
interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH
0 141 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>;
reg-io-width = <4>;
status = "disabled";
};
@@ -210,6 +235,7 @@
interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH
0 84 IRQ_TYPE_LEVEL_HIGH
0 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SDHI0>;
cap-sd-highspeed;
status = "disabled";
};
@@ -220,6 +246,7 @@
reg = <0xee120000 0x100>;
interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH
0 89 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SDHI1>;
toshiba,mmc-wrprotect-disable;
cap-sd-highspeed;
status = "disabled";
@@ -230,6 +257,7 @@
reg = <0xee140000 0x100>;
interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH
0 105 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SDHI2>;
toshiba,mmc-wrprotect-disable;
cap-sd-highspeed;
status = "disabled";
@@ -239,6 +267,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6c40000 0x100>;
interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -246,6 +276,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6c50000 0x100>;
interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -253,6 +285,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6c60000 0x100>;
interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -260,6 +294,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6c70000 0x100>;
interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -267,6 +303,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6c80000 0x100>;
interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -274,6 +312,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6cb0000 0x100>;
interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -281,6 +321,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6cc0000 0x100>;
interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -288,6 +330,8 @@
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6cd0000 0x100>;
interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -295,6 +339,8 @@
compatible = "renesas,scifb-sh73a0", "renesas,scifb";
reg = <0xe6c30000 0x100>;
interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&mstp2_clks SH73A0_CLK_SCIFB>;
+ clock-names = "sci_ick";
status = "disabled";
};
@@ -317,9 +363,337 @@
sh_fsi2: sound@ec230000 {
#sound-dai-cells = <1>;
- compatible = "renesas,sh_fsi2";
+ compatible = "renesas,fsi2-sh73a0", "renesas,sh_fsi2";
reg = <0xec230000 0x400>;
interrupts = <0 146 0x4>;
status = "disabled";
};
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* External root clocks */
+ extalr_clk: extalr_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "extalr";
+ };
+ extal1_clk: extal1_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "extal1";
+ };
+ extal2_clk: extal2_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "extal2";
+ };
+ extcki_clk: extcki_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "extcki";
+ };
+ fsiack_clk: fsiack_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fsiack";
+ };
+ fsibck_clk: fsibck_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "fsibck";
+ };
+
+ /* Special CPG clocks */
+ cpg_clocks: cpg_clocks@e6150000 {
+ compatible = "renesas,sh73a0-cpg-clocks";
+ reg = <0xe6150000 0x10000>;
+ clocks = <&extal1_clk>, <&extal2_clk>;
+ #clock-cells = <1>;
+ clock-output-names = "main", "pll0", "pll1", "pll2",
+ "pll3", "dsi0phy", "dsi1phy",
+ "zg", "m3", "b", "m1", "m2",
+ "z", "zx", "hp";
+ };
+
+ /* Variable factor clocks (DIV6) */
+ vclk1_clk: vclk1_clk@e6150008 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150008 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk1";
+ };
+ vclk2_clk: vclk2_clk@e615000c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615000c 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk2";
+ };
+ vclk3_clk: vclk3_clk@e615001c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615001c 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "vclk3";
+ };
+ zb_clk: zb_clk@e6150010 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150010 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "zb";
+ };
+ flctl_clk: flctl_clk@e6150014 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150014 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "flctlck";
+ };
+ sdhi0_clk: sdhi0_clk@e6150074 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150074 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi0ck";
+ };
+ sdhi1_clk: sdhi1_clk@e6150078 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150078 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi1ck";
+ };
+ sdhi2_clk: sdhi2_clk@e615007c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615007c 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sdhi2ck";
+ };
+ fsia_clk: fsia_clk@e6150018 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150018 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "fsia";
+ };
+ fsib_clk: fsib_clk@e6150090 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150090 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "fsib";
+ };
+ sub_clk: sub_clk@e6150080 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150080 4>;
+ clocks = <&extal2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "sub";
+ };
+ spua_clk: spua_clk@e6150084 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150084 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "spua";
+ };
+ spuv_clk: spuv_clk@e6150094 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150094 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "spuv";
+ };
+ msu_clk: msu_clk@e6150088 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150088 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "msu";
+ };
+ hsi_clk: hsi_clk@e615008c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615008c 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "hsi";
+ };
+ mfg1_clk: mfg1_clk@e6150098 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150098 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mfg1";
+ };
+ mfg2_clk: mfg2_clk@e615009c {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe615009c 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "mfg2";
+ };
+ dsit_clk: dsit_clk@e6150060 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150060 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "dsit";
+ };
+ dsi0p_clk: dsi0p_clk@e6150064 {
+ compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock";
+ reg = <0xe6150064 4>;
+ clocks = <&pll1_div2_clk>;
+ #clock-cells = <0>;
+ clock-output-names = "dsi0pck";
+ };
+
+ /* Fixed factor clocks */
+ main_div2_clk: main_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_MAIN>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "main_div2";
+ };
+ pll1_div2_clk: pll1_div2_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div2";
+ };
+ pll1_div7_clk: pll1_div7_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <7>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div7";
+ };
+ pll1_div13_clk: pll1_div13_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_PLL1>;
+ #clock-cells = <0>;
+ clock-div = <13>;
+ clock-mult = <1>;
+ clock-output-names = "pll1_div13";
+ };
+ twd_clk: twd_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&cpg_clocks SH73A0_CLK_Z>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "twd";
+ };
+
+ /* Gate clocks */
+ mstp0_clks: mstp0_clks@e6150130 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150130 4>, <0xe6150030 4>;
+ clocks = <&cpg_clocks SH73A0_CLK_HP>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_IIC2
+ >;
+ clock-output-names =
+ "iic2";
+ };
+ mstp1_clks: mstp1_clks@e6150134 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150134 4>, <0xe6150038 4>;
+ clocks = <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_B>,
+ <&sub_clk>, <&cpg_clocks SH73A0_CLK_B>,
+ <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_ZG>,
+ <&cpg_clocks SH73A0_CLK_B>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_CEU1 SH73A0_CLK_CSI2_RX1
+ SH73A0_CLK_CEU0 SH73A0_CLK_CSI2_RX0
+ SH73A0_CLK_TMU0 SH73A0_CLK_DSITX0
+ SH73A0_CLK_IIC0 SH73A0_CLK_SGX
+ SH73A0_CLK_LCDC0
+ >;
+ clock-output-names =
+ "ceu1", "csi2_rx1", "ceu0", "csi2_rx0",
+ "tmu0", "dsitx0", "iic0", "sgx", "lcdc0";
+ };
+ mstp2_clks: mstp2_clks@e6150138 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150138 4>, <0xe6150040 4>;
+ clocks = <&sub_clk>, <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>,
+ <&sub_clk>, <&sub_clk>, <&sub_clk>, <&sub_clk>,
+ <&sub_clk>, <&sub_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_SCIFA7 SH73A0_CLK_SY_DMAC
+ SH73A0_CLK_MP_DMAC SH73A0_CLK_SCIFA5
+ SH73A0_CLK_SCIFB SH73A0_CLK_SCIFA0
+ SH73A0_CLK_SCIFA1 SH73A0_CLK_SCIFA2
+ SH73A0_CLK_SCIFA3 SH73A0_CLK_SCIFA4
+ >;
+ clock-output-names =
+ "scifa7", "sy_dmac", "mp_dmac", "scifa5",
+ "scifb", "scifa0", "scifa1", "scifa2",
+ "scifa3", "scifa4";
+ };
+ mstp3_clks: mstp3_clks@e615013c {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe615013c 4>, <0xe6150048 4>;
+ clocks = <&sub_clk>, <&extalr_clk>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>,
+ <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&flctl_clk>,
+ <&sdhi0_clk>, <&sdhi1_clk>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&sdhi2_clk>,
+ <&main_div2_clk>, <&main_div2_clk>,
+ <&main_div2_clk>, <&main_div2_clk>,
+ <&main_div2_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_SCIFA6 SH73A0_CLK_CMT1
+ SH73A0_CLK_FSI SH73A0_CLK_IRDA
+ SH73A0_CLK_IIC1 SH73A0_CLK_USB SH73A0_CLK_FLCTL
+ SH73A0_CLK_SDHI0 SH73A0_CLK_SDHI1
+ SH73A0_CLK_MMCIF0 SH73A0_CLK_SDHI2
+ SH73A0_CLK_TPU0 SH73A0_CLK_TPU1
+ SH73A0_CLK_TPU2 SH73A0_CLK_TPU3
+ SH73A0_CLK_TPU4
+ >;
+ clock-output-names =
+ "scifa6", "cmt1", "fsi", "irda", "iic1",
+ "usb", "flctl", "sdhi0", "sdhi1", "mmcif0", "sdhi2",
+ "tpu0", "tpu1", "tpu2", "tpu3", "tpu4";
+ };
+ mstp4_clks: mstp4_clks@e6150140 {
+ compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks";
+ reg = <0xe6150140 4>, <0xe615004c 4>;
+ clocks = <&cpg_clocks SH73A0_CLK_HP>,
+ <&cpg_clocks SH73A0_CLK_HP>, <&extalr_clk>;
+ #clock-cells = <1>;
+ clock-indices = <
+ SH73A0_CLK_IIC3 SH73A0_CLK_IIC4
+ SH73A0_CLK_KEYSC
+ >;
+ clock-output-names =
+ "iic3", "iic4", "keysc";
+ };
+ };
};
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
index a6eb5436d26d..40accc87e3a2 100644
--- a/arch/arm/boot/dts/spear13xx.dtsi
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -117,7 +117,7 @@
chan_priority = <1>;
block_size = <0xfff>;
dma-masters = <2>;
- data_width = <3 3 0 0>;
+ data_width = <3 3>;
};
dma@eb000000 {
@@ -133,7 +133,7 @@
chan_allocation_order = <1>;
chan_priority = <1>;
block_size = <0xfff>;
- data_width = <3 3 0 0>;
+ data_width = <3 3>;
};
fsmc: flash@b0000000 {
diff --git a/arch/arm/boot/dts/stih407-b2120.dts b/arch/arm/boot/dts/stih407-b2120.dts
index 261d5e2c48d2..af487145cd89 100644
--- a/arch/arm/boot/dts/stih407-b2120.dts
+++ b/arch/arm/boot/dts/stih407-b2120.dts
@@ -7,9 +7,8 @@
* published by the Free Software Foundation.
*/
/dts-v1/;
-#include "stih407-clock.dtsi"
-#include "stih407-family.dtsi"
#include "stihxxx-b2120.dtsi"
+#include "stih407.dtsi"
/ {
model = "STiH407 B2120";
compatible = "st,stih407-b2120", "st,stih407";
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index d4a8f843cdc8..c06a54681912 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -283,5 +283,58 @@
<&picophyreset STIH407_PICOPHY0_RESET>;
reset-names = "global", "port";
};
+
+ miphy28lp_phy: miphy28lp@9b22000 {
+ compatible = "st,miphy28lp-phy";
+ st,syscfg = <&syscfg_core>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ phy_port0: port@9b22000 {
+ reg = <0x9b22000 0xff>,
+ <0x9b09000 0xff>,
+ <0x9b04000 0xff>;
+ reg-names = "sata-up",
+ "pcie-up",
+ "pipew";
+
+ st,syscfg = <0x114 0x818 0xe0 0xec>;
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY0_SOFTRESET>;
+ };
+
+ phy_port1: port@9b2a000 {
+ reg = <0x9b2a000 0xff>,
+ <0x9b19000 0xff>,
+ <0x9b14000 0xff>;
+ reg-names = "sata-up",
+ "pcie-up",
+ "pipew";
+
+ st,syscfg = <0x118 0x81c 0xe4 0xf0>;
+
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY1_SOFTRESET>;
+ };
+
+ phy_port2: port@8f95000 {
+ reg = <0x8f95000 0xff>,
+ <0x8f90000 0xff>;
+ reg-names = "pipew",
+ "usb3-up";
+
+ st,syscfg = <0x11c 0x820>;
+
+ #phy-cells = <1>;
+
+ reset-names = "miphy-sw-rst";
+ resets = <&softreset STIH407_MIPHY2_SOFTRESET>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/stih407.dtsi b/arch/arm/boot/dts/stih407.dtsi
new file mode 100644
index 000000000000..3efa3b2ebe90
--- /dev/null
+++ b/arch/arm/boot/dts/stih407.dtsi
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 STMicroelectronics Limited.
+ * Author: Gabriel Fernandez <gabriel.fernandez@linaro.org>
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih407-clock.dtsi"
+#include "stih407-family.dtsi"
+/ {
+ soc {
+ /* Display */
+ vtg_main: sti-vtg-main@8d02800 {
+ compatible = "st,vtg";
+ reg = <0x8d02800 0x200>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_NONE>;
+ };
+
+ vtg_aux: sti-vtg-aux@8d00200 {
+ compatible = "st,vtg";
+ reg = <0x8d00200 0x100>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_NONE>;
+ };
+
+ sti-display-subsystem {
+ compatible = "st,sti-display-subsystem";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ assigned-clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>;
+
+ assigned-clock-parents = <0>,
+ <0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+
+ assigned-clock-rates = <297000000>, <297000000>;
+
+ ranges;
+
+ sti-compositor@9d11000 {
+ compatible = "st,stih407-compositor";
+ reg = <0x9d11000 0x1000>;
+
+ clock-names = "compo_main",
+ "compo_aux",
+ "pix_main",
+ "pix_aux",
+ "pix_gdp1",
+ "pix_gdp2",
+ "pix_gdp3",
+ "pix_gdp4",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ reset-names = "compo-main", "compo-aux";
+ resets = <&softreset STIH407_COMPO_SOFTRESET>,
+ <&softreset STIH407_COMPO_SOFTRESET>;
+ st,vtg = <&vtg_main>, <&vtg_aux>;
+ };
+
+ sti-tvout@8d08000 {
+ compatible = "st,stih407-tvout";
+ reg = <0x8d08000 0x1000>;
+ reg-names = "tvout-reg";
+ reset-names = "tvout";
+ resets = <&softreset STIH407_HDTVOUT_SOFTRESET>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ assigned-clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>;
+
+ assigned-clock-parents = <&clk_s_d2_quadfs 0>,
+ <&clk_tmdsout_hdmi>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d0_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+ ranges;
+
+ sti-hdmi@8d04000 {
+ compatible = "st,stih407-hdmi";
+ reg = <0x8d04000 0x1000>;
+ reg-names = "hdmi-reg";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_NONE>;
+ interrupt-names = "irq";
+ clock-names = "pix",
+ "tmds",
+ "phy",
+ "audio",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ hdmi,hpd-gpio = <&pio5 3>;
+ reset-names = "hdmi";
+ resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
+ ddc = <&hdmiddc>;
+
+ };
+
+ sti-hda@8d02000 {
+ compatible = "st,stih407-hda";
+ reg = <0x8d02000 0x400>, <0x92b0120 0x4>;
+ reg-names = "hda-reg", "video-dacs-ctrl";
+ clock-names = "pix",
+ "hddac",
+ "main_parent",
+ "aux_parent";
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index 37995f4739d2..208b5e89036a 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -80,5 +80,143 @@
phys = <&usb2_picophy2>;
phy-names = "usb";
};
+
+ /* Display */
+ vtg_main: sti-vtg-main@8d02800 {
+ compatible = "st,vtg";
+ reg = <0x8d02800 0x200>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_NONE>;
+ };
+
+ vtg_aux: sti-vtg-aux@8d00200 {
+ compatible = "st,vtg";
+ reg = <0x8d00200 0x100>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_NONE>;
+ };
+
+ sti-display-subsystem {
+ compatible = "st,sti-display-subsystem";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ assigned-clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>;
+
+ assigned-clock-parents = <0>,
+ <0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+
+ assigned-clock-rates = <297000000>, <297000000>;
+
+ ranges;
+
+ sti-compositor@9d11000 {
+ compatible = "st,stih407-compositor";
+ reg = <0x9d11000 0x1000>;
+
+ clock-names = "compo_main",
+ "compo_aux",
+ "pix_main",
+ "pix_aux",
+ "pix_gdp1",
+ "pix_gdp2",
+ "pix_gdp3",
+ "pix_gdp4",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_c0_flexgen CLK_COMPO_DVP>,
+ <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_AUX_DISP>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP1>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP2>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP3>,
+ <&clk_s_d2_flexgen CLK_PIX_GDP4>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ reset-names = "compo-main", "compo-aux";
+ resets = <&softreset STIH407_COMPO_SOFTRESET>,
+ <&softreset STIH407_COMPO_SOFTRESET>;
+ st,vtg = <&vtg_main>, <&vtg_aux>;
+ };
+
+ sti-tvout@8d08000 {
+ compatible = "st,stih407-tvout";
+ reg = <0x8d08000 0x1000>;
+ reg-names = "tvout-reg";
+ reset-names = "tvout";
+ resets = <&softreset STIH407_HDTVOUT_SOFTRESET>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ assigned-clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>;
+
+ assigned-clock-parents = <&clk_s_d2_quadfs 0>,
+ <&clk_tmdsout_hdmi>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d0_quadfs 0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 0>;
+ ranges;
+
+ sti-hdmi@8d04000 {
+ compatible = "st,stih407-hdmi";
+ reg = <0x8d04000 0x1000>;
+ reg-names = "hdmi-reg";
+ interrupts = <GIC_SPI 106 IRQ_TYPE_NONE>;
+ interrupt-names = "irq";
+ clock-names = "pix",
+ "tmds",
+ "phy",
+ "audio",
+ "main_parent",
+ "aux_parent";
+
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDMI>,
+ <&clk_s_d2_flexgen CLK_TMDS_HDMI>,
+ <&clk_s_d2_flexgen CLK_REF_HDMIPHY>,
+ <&clk_s_d0_flexgen CLK_PCM_0>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+
+ hdmi,hpd-gpio = <&pio5 3>;
+ reset-names = "hdmi";
+ resets = <&softreset STIH407_HDMI_TX_PHY_SOFTRESET>;
+ ddc = <&hdmiddc>;
+
+ };
+
+ sti-hda@8d02000 {
+ compatible = "st,stih407-hda";
+ reg = <0x8d02000 0x400>, <0x92b0120 0x4>;
+ reg-names = "hda-reg", "video-dacs-ctrl";
+ clock-names = "pix",
+ "hddac",
+ "main_parent",
+ "aux_parent";
+ clocks = <&clk_s_d2_flexgen CLK_PIX_HDDAC>,
+ <&clk_s_d2_flexgen CLK_HDDAC>,
+ <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>;
+ };
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
new file mode 100644
index 000000000000..926235c08e4d
--- /dev/null
+++ b/arch/arm/boot/dts/stih418-b2199.dts
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 STMicroelectronics (R&D) Limited.
+ * Author: Maxime Coquelin <maxime.coquelin@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih418.dtsi"
+/ {
+ model = "STiH418 B2199";
+ compatible = "st,stih418-b2199", "st,stih418";
+
+ chosen {
+ bootargs = "console=ttyAS0,115200 clk_ignore_unused";
+ linux,stdout-path = &sbc_serial0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x40000000 0xc0000000>;
+ };
+
+ aliases {
+ ttyAS0 = &sbc_serial0;
+ };
+
+ soc {
+ sbc_serial0: serial@9530000 {
+ status = "okay";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ red {
+ #gpio-cells = <2>;
+ label = "Front Panel LED";
+ gpios = <&pio4 1 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ green {
+ #gpio-cells = <2>;
+ gpios = <&pio1 3 0>;
+ default-state = "off";
+ };
+ };
+
+ i2c@9842000 {
+ status = "okay";
+ };
+
+ i2c@9843000 {
+ status = "okay";
+ };
+
+ i2c@9844000 {
+ status = "okay";
+ };
+
+ i2c@9845000 {
+ status = "okay";
+ };
+
+ i2c@9540000 {
+ status = "okay";
+ };
+
+ /* SSC11 to HDMI */
+ i2c@9541000 {
+ status = "okay";
+ /* HDMI V1.3a supports Standard mode only */
+ clock-frequency = <100000>;
+ st,i2c-min-scl-pulse-width-us = <0>;
+ st,i2c-min-sda-pulse-width-us = <5>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
new file mode 100644
index 000000000000..0ab23daa2829
--- /dev/null
+++ b/arch/arm/boot/dts/stih418-clock.dtsi
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2015 STMicroelectronics R&D Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <dt-bindings/clock/stih418-clks.h>
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ compatible = "st,stih418-clk", "simple-bus";
+
+ /*
+ * Fixed 30MHz oscillator inputs to SoC
+ */
+ clk_sysin: clk-sysin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <30000000>;
+ clock-output-names = "CLK_SYSIN";
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ arm_periph_clk: clk-m-a9-periphs {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_m_a9>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * A9 PLL.
+ */
+ clockgen-a9@92b0000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x92b0000 0xffff>;
+
+ clockgen_a9_pll: clockgen-a9-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a9", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clockgen-a9-pll-odf";
+ };
+ };
+
+ /*
+ * ARM CPU related clocks.
+ */
+ clk_m_a9: clk-m-a9@92b0000 {
+ #clock-cells = <0>;
+ compatible = "st,stih407-clkgen-a9-mux", "st,clkgen-mux";
+ reg = <0x92b0000 0x10000>;
+
+ clocks = <&clockgen_a9_pll 0>,
+ <&clockgen_a9_pll 0>,
+ <&clk_s_c0_flexgen 13>,
+ <&clk_m_a9_ext2f_div2>;
+ };
+
+ /*
+ * ARM Peripheral clock for timers
+ */
+ clk_m_a9_ext2f_div2: clk-m-a9-ext2f-div2s {
+ #clock-cells = <0>;
+ compatible = "fixed-factor-clock";
+
+ clocks = <&clk_s_c0_flexgen 13>;
+
+ clock-output-names = "clk-m-a9-ext2f-div2";
+
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+
+ /*
+ * Bootloader initialized system infrastructure clock for
+ * serial devices.
+ */
+ clk_ext2f_a9: clockgen-c0@13 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <200000000>;
+ clock-output-names = "clk-s-icn-reg-0";
+ };
+
+ clockgen-a@090ff000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x90ff000 0x1000>;
+
+ clk_s_a0_pll: clk-s-a0-pll {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-a0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-a0-pll-ofd-0";
+ };
+
+ clk_s_a0_flexgen: clk-s-a0-flexgen {
+ compatible = "st,flexgen";
+
+ #clock-cells = <1>;
+
+ clocks = <&clk_s_a0_pll 0>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-ic-lmi0",
+ "clk-ic-lmi1";
+ };
+ };
+
+ clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-C", "st,quadfs";
+ reg = <0x9103000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-fs0-ch0",
+ "clk-s-c0-fs0-ch1",
+ "clk-s-c0-fs0-ch2",
+ "clk-s-c0-fs0-ch3";
+ };
+
+ clk_s_c0: clockgen-c@09103000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9103000 0x1000>;
+
+ clk_s_c0_pll0: clk-s-c0-pll0 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_0", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll0-odf-0";
+ };
+
+ clk_s_c0_pll1: clk-s-c0-pll1 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-plls-c32-c0_1", "st,clkgen-plls-c32";
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-c0-pll1-odf-0";
+ };
+
+ clk_s_c0_flexgen: clk-s-c0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_c0_pll0 0>,
+ <&clk_s_c0_pll1 0>,
+ <&clk_s_c0_quadfs 0>,
+ <&clk_s_c0_quadfs 1>,
+ <&clk_s_c0_quadfs 2>,
+ <&clk_s_c0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-icn-gpu",
+ "clk-fdma",
+ "clk-nand",
+ "clk-hva",
+ "clk-proc-stfe",
+ "clk-tp",
+ "clk-rx-icn-dmu",
+ "clk-rx-icn-hva",
+ "clk-icn-cpu",
+ "clk-tx-icn-dmu",
+ "clk-mmc-0",
+ "clk-mmc-1",
+ "clk-jpegdec",
+ "clk-icn-reg",
+ "clk-proc-bdisp-0",
+ "clk-proc-bdisp-1",
+ "clk-pp-dmu",
+ "clk-vid-dmu",
+ "clk-dss-lpc",
+ "clk-st231-aud-0",
+ "clk-st231-gp-1",
+ "clk-st231-dmu",
+ "clk-icn-lmi",
+ "clk-tx-icn-1",
+ "clk-icn-sbc",
+ "clk-stfe-frc2",
+ "clk-eth-phyref",
+ "clk-eth-ref-phyclk",
+ "clk-flash-promip",
+ "clk-main-disp",
+ "clk-aux-disp",
+ "clk-compo-dvp",
+ "clk-tx-icn-hades",
+ "clk-rx-icn-hades",
+ "clk-icn-reg-16",
+ "clk-pp-hevc",
+ "clk-clust-hevc",
+ "clk-hwpe-hevc",
+ "clk-fc-hevc",
+ "clk-proc-mixer",
+ "clk-proc-sc",
+ "clk-avsp-hevc";
+ };
+ };
+
+ clk_s_d0_quadfs: clk-s-d0-quadfs@9104000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9104000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d0-fs0-ch0",
+ "clk-s-d0-fs0-ch1",
+ "clk-s-d0-fs0-ch2",
+ "clk-s-d0-fs0-ch3";
+ };
+
+ clockgen-d0@09104000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9104000 0x1000>;
+
+ clk_s_d0_flexgen: clk-s-d0-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d0_quadfs 0>,
+ <&clk_s_d0_quadfs 1>,
+ <&clk_s_d0_quadfs 2>,
+ <&clk_s_d0_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-pcm-0",
+ "clk-pcm-1",
+ "clk-pcm-2",
+ "clk-spdiff",
+ "clk-pcmr10-master",
+ "clk-usb2-phy";
+ };
+ };
+
+ clk_s_d2_quadfs: clk-s-d2-quadfs@9106000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9106000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d2-fs0-ch0",
+ "clk-s-d2-fs0-ch1",
+ "clk-s-d2-fs0-ch2",
+ "clk-s-d2-fs0-ch3";
+ };
+
+ clk_tmdsout_hdmi: clk-tmdsout-hdmi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ clockgen-d2@x9106000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9106000 0x1000>;
+
+ clk_s_d2_flexgen: clk-s-d2-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d2_quadfs 0>,
+ <&clk_s_d2_quadfs 1>,
+ <&clk_s_d2_quadfs 2>,
+ <&clk_s_d2_quadfs 3>,
+ <&clk_sysin>,
+ <&clk_sysin>,
+ <&clk_tmdsout_hdmi>;
+
+ clock-output-names = "clk-pix-main-disp",
+ "",
+ "",
+ "",
+ "",
+ "clk-tmds-hdmi-div2",
+ "clk-pix-aux-disp",
+ "clk-denc",
+ "clk-pix-hddac",
+ "clk-hddac",
+ "clk-sddac",
+ "clk-pix-dvo",
+ "clk-dvo",
+ "clk-pix-hdmi",
+ "clk-tmds-hdmi",
+ "clk-ref-hdmiphy",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "", "", "", "",
+ "", "clk-vp9";
+ };
+ };
+
+ clk_s_d3_quadfs: clk-s-d3-quadfs@9107000 {
+ #clock-cells = <1>;
+ compatible = "st,stih407-quadfs660-D", "st,quadfs";
+ reg = <0x9107000 0x1000>;
+
+ clocks = <&clk_sysin>;
+
+ clock-output-names = "clk-s-d3-fs0-ch0",
+ "clk-s-d3-fs0-ch1",
+ "clk-s-d3-fs0-ch2",
+ "clk-s-d3-fs0-ch3";
+ };
+
+ clockgen-d3@9107000 {
+ compatible = "st,clkgen-c32";
+ reg = <0x9107000 0x1000>;
+
+ clk_s_d3_flexgen: clk-s-d3-flexgen {
+ #clock-cells = <1>;
+ compatible = "st,flexgen";
+
+ clocks = <&clk_s_d3_quadfs 0>,
+ <&clk_s_d3_quadfs 1>,
+ <&clk_s_d3_quadfs 2>,
+ <&clk_s_d3_quadfs 3>,
+ <&clk_sysin>;
+
+ clock-output-names = "clk-stfe-frc1",
+ "clk-tsout-0",
+ "clk-tsout-1",
+ "clk-mchi",
+ "clk-vsens-compo",
+ "clk-frc1-remote",
+ "clk-lpc-0",
+ "clk-lpc-1";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
new file mode 100644
index 000000000000..354d90f521b6
--- /dev/null
+++ b/arch/arm/boot/dts/stih418.dtsi
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics Limited.
+ * Author: Peter Griffin <peter.griffin@linaro.org>
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih418-clock.dtsi"
+#include "stih407-family.dtsi"
+#include "stih410-pinctrl.dtsi"
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ };
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ };
+ };
+
+ soc {
+ usb2_picophy1: phy2 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xf8 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+ };
+
+ usb2_picophy2: phy3 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xfc 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY1_RESET>;
+ reset-names = "global", "port";
+ };
+
+ ohci0: usb@9a03c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a03c00 0x100>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ehci0: usb@9a03e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a03e00 0x100>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ohci1: usb@9a83c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a83c00 0x100>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
+
+ ehci1: usb@9a83e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a83e00 0x100>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index 0074bd49797c..c1d859092be7 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -48,12 +48,23 @@
};
/* SSC11 to HDMI */
- i2c@9541000 {
+ hdmiddc: i2c@9541000 {
status = "okay";
/* HDMI V1.3a supports Standard mode only */
clock-frequency = <100000>;
st,i2c-min-scl-pulse-width-us = <0>;
st,i2c-min-sda-pulse-width-us = <5>;
};
+
+ miphy28lp_phy: miphy28lp@9b22000 {
+
+ phy_port0: port@9b22000 {
+ st,osc-rdy;
+ };
+
+ phy_port1: port@9b2a000 {
+ st,osc-force-ext;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index 3bcfd81837f0..b67e5be618cf 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -48,8 +48,11 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Mele A1000";
@@ -77,7 +80,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -112,15 +115,15 @@
emac_power_pin_a1000: emac_power_pin@0 {
allwinner,pins = "PH15";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_a1000: led_pins@0 {
allwinner,pins = "PH10", "PH20";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -159,12 +162,12 @@
red {
label = "a1000:red:usr";
- gpios = <&pio 7 10 0>;
+ gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>;
};
blue {
label = "a1000:blue:usr";
- gpios = <&pio 7 20 0>;
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
};
};
@@ -176,7 +179,7 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
- gpio = <&pio 7 15 0>;
+ gpio = <&pio 7 15 GPIO_ACTIVE_HIGH>;
};
reg_usb1_vbus: usb1-vbus {
diff --git a/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
index f3f2974658e4..490b77c9bb36 100644
--- a/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
+++ b/arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
@@ -46,8 +46,10 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "BA10 tvbox";
@@ -74,7 +76,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -140,7 +142,7 @@
};
reg_usb2_vbus: usb2-vbus {
- gpio = <&pio 7 12 0>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
new file mode 100644
index 000000000000..58214f249598
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Chuwi V7 CW0825";
+ compatible = "chuwi,v7-cw0825", "allwinner,sun4i-a10";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 6a310da53f18..4260c2b47607 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -47,8 +47,11 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Cubietech Cubieboard";
@@ -75,7 +78,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -111,8 +114,8 @@
led_pins_cubieboard: led_pins@0 {
allwinner,pins = "PH20", "PH21";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -134,12 +137,8 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupts = <0>;
-
- interrupt-controller;
- #interrupt-cells = <1>;
};
};
@@ -148,6 +147,12 @@
pinctrl-0 = <&i2c1_pins_a>;
status = "okay";
};
+
+ spi0: spi@01c05000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+ };
};
leds {
@@ -157,12 +162,12 @@
blue {
label = "cubieboard:blue:usr";
- gpios = <&pio 7 21 0>; /* LED1 */
+ gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; /* LED1 */
};
green {
label = "cubieboard:green:usr";
- gpios = <&pio 7 20 0>; /* LED2 */
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>; /* LED2 */
linux,default-trigger = "heartbeat";
};
};
@@ -179,3 +184,34 @@
status = "okay";
};
};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
index efc116287e0f..d3f73ea25567 100644
--- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts
+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts
@@ -48,8 +48,11 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Miniand Hackberry";
@@ -77,7 +80,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -111,15 +114,15 @@
hackberry_hogs: hogs@0 {
allwinner,pins = "PH19";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb2_vbus_pin_hackberry: usb2_vbus_pin@0 {
allwinner,pins = "PH12";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -157,7 +160,7 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
- gpio = <&pio 7 19 0>;
+ gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>;
};
reg_usb1_vbus: usb1-vbus {
@@ -166,7 +169,7 @@
reg_usb2_vbus: usb2-vbus {
pinctrl-0 = <&usb2_vbus_pin_hackberry>;
- gpio = <&pio 7 12 0>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts
new file mode 100644
index 000000000000..c88382aacc36
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Hyundai A7HD";
+ compatible = "hyundai,a7hd", "allwinner,sun4i-a10";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb2_vbus_pin_a {
+ allwinner,pins = "PH6";
+};
+
+&usbphy {
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index 3e25ee4d3248..482914333bba 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -48,8 +48,10 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "INet-97F Rev 02";
@@ -65,7 +67,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun4i-a10-marsboard.dts b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
new file mode 100644
index 000000000000..9ee86a700c2b
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-marsboard.dts
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2015 Aleksei Mamlin
+ * Aleksei Mamlin <mamlinav@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "HAOYU Electronics Marsboard A10";
+ compatible = "haoyu,a10-marsboard", "allwinner,sun4i-a10";
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_marsboard>;
+
+ red1 {
+ label = "marsboard:red1:usr";
+ gpios = <&pio 1 5 GPIO_ACTIVE_HIGH>;
+ };
+
+ red2 {
+ label = "marsboard:red2:usr";
+ gpios = <&pio 1 6 GPIO_ACTIVE_HIGH>;
+ };
+
+ red3 {
+ label = "marsboard:red3:usr";
+ gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ red4 {
+ label = "marsboard:red4:usr";
+ gpios = <&pio 1 8 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&ahci {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_pins_a>;
+ phy = <&phy1>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ led_pins_marsboard: led_pins@0 {
+ allwinner,pins = "PB5", "PB6", "PB7", "PB8";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
index 8b3f97470249..eb5fd6904a69 100644
--- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts
@@ -48,8 +48,11 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "PineRiver Mini X-Plus";
@@ -61,7 +64,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -91,7 +94,7 @@
pinctrl@01c20800 {
ir0_pins_a: ir0@0 {
/* The ir receiver is not always populated */
- allwinner,pull = <1>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
};
diff --git a/arch/arm/boot/dts/sun4i-a10-mk802.dts b/arch/arm/boot/dts/sun4i-a10-mk802.dts
new file mode 100644
index 000000000000..e9a6886f0d51
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-mk802.dts
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "MK802";
+ compatible = "allwinner,mk802", "allwinner,sun4i-a10";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ usb2_vbus_pin_mk802: usb2_vbus_pin@0 {
+ allwinner,pins = "PH12";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ pinctrl-0 = <&usb2_vbus_pin_mk802>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>; /* PH12 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-mk802ii.dts b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts
new file mode 100644
index 000000000000..802eda494d1c
--- /dev/null
+++ b/arch/arm/boot/dts/sun4i-a10-mk802ii.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "MK802ii";
+ compatible = "allwinner,mk802ii", "allwinner,sun4i-a10";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&reg_usb1_vbus {
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
index 88cf1a531155..ab7891c43231 100644
--- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
@@ -46,8 +46,11 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Olimex A10-OLinuXino-LIME";
@@ -74,7 +77,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -110,15 +113,15 @@
ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
allwinner,pins = "PC3";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_olinuxinolime: led_pins@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -151,14 +154,14 @@
green {
label = "a10-olinuxino-lime:green:usr";
- gpios = <&pio 7 2 0>;
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
reg_ahci_5v: ahci-5v {
pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>;
- gpio = <&pio 2 3 0>;
+ gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
index ce5994597407..9d1e5482cf82 100644
--- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts
+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts
@@ -47,8 +47,12 @@
*/
/dts-v1/;
-/include/ "sun4i-a10.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun4i-a10.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "LinkSprite pcDuino";
@@ -62,6 +66,22 @@
status = "okay";
};
+ pinctrl@01c20800 {
+ led_pins_pcduino: led_pins@0 {
+ allwinner,pins = "PH15", "PH16";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ key_pins_pcduino: key_pins@0 {
+ allwinner,pins = "PH17", "PH18", "PH19";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
mdio@01c0b080 {
status = "okay";
@@ -75,7 +95,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -124,6 +144,48 @@
};
};
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_pcduino>;
+
+ tx {
+ label = "pcduino:green:tx";
+ gpios = <&pio 7 15 GPIO_ACTIVE_LOW>;
+ };
+
+ rx {
+ label = "pcduino:green:rx";
+ gpios = <&pio 7 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_pins_pcduino>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ button@0 {
+ label = "Key Back";
+ linux,code = <KEY_BACK>;
+ gpios = <&pio 7 17 GPIO_ACTIVE_LOW>;
+ };
+
+ button@1 {
+ label = "Key Home";
+ linux,code = <KEY_HOME>;
+ gpios = <&pio 7 18 GPIO_ACTIVE_LOW>;
+ };
+
+ button@2 {
+ label = "Key Menu";
+ linux,code = <KEY_MENU>;
+ gpios = <&pio 7 19 GPIO_ACTIVE_LOW>;
+ };
+ };
+
reg_usb1_vbus: usb1-vbus {
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index d5c4669224b1..8ca3c1a2063d 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -10,7 +10,12 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+
+#include <dt-bindings/thermal/thermal.h>
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
interrupt-parent = <&intc>;
@@ -39,15 +44,78 @@
<&ahb_gates 44>, <&ahb_gates 46>;
status = "disabled";
};
+
+ framebuffer@2 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_fe0-de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
+ <&ahb_gates 46>;
+ status = "disabled";
+ };
+
+ framebuffer@3 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_fe0-de_be0-lcd0-tve0";
+ clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
+ <&ahb_gates 44>, <&ahb_gates 46>;
+ status = "disabled";
+ };
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a8";
reg = <0x0>;
+ clocks = <&cpu>;
+ clock-latency = <244144>; /* 8 32k periods */
+ operating-points = <
+ /* kHz uV */
+ 1056000 1500000
+ 1008000 1400000
+ 912000 1350000
+ 864000 1300000
+ 624000 1250000
+ >;
+ #cooling-cells = <2>;
+ cooling-min-level = <0>;
+ cooling-max-level = <4>;
+ };
+ };
+
+ thermal-zones {
+ cpu_thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&rtp>;
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ /* milliCelsius */
+ temperature = <850000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit: cpu_crit {
+ /* milliCelsius */
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
};
@@ -359,7 +427,8 @@
interrupts = <10>;
clocks = <&ahb_gates 20>, <&spi0_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 27>, <&dma 1 26>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -372,7 +441,8 @@
interrupts = <11>;
clocks = <&ahb_gates 21>, <&spi1_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 9>, <&dma 1 8>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -387,7 +457,7 @@
status = "disabled";
};
- mdio@01c0b080 {
+ mdio: mdio@01c0b080 {
compatible = "allwinner,sun4i-a10-mdio";
reg = <0x01c0b080 0x14>;
status = "disabled";
@@ -469,7 +539,8 @@
interrupts = <12>;
clocks = <&ahb_gates 22>, <&spi2_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 29>, <&dma 1 28>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -510,7 +581,8 @@
interrupts = <50>;
clocks = <&ahb_gates 23>, <&spi3_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 31>, <&dma 1 30>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 31>,
+ <&dma SUN4I_DMA_DEDICATED 30>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -538,57 +610,57 @@
pwm0_pins_a: pwm0@0 {
allwinner,pins = "PB2";
allwinner,function = "pwm";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
pwm1_pins_a: pwm1@0 {
allwinner,pins = "PI3";
allwinner,function = "pwm";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart0_pins_a: uart0@0 {
allwinner,pins = "PB22", "PB23";
allwinner,function = "uart0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart0_pins_b: uart0@1 {
allwinner,pins = "PF2", "PF4";
allwinner,function = "uart0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart1_pins_a: uart1@0 {
allwinner,pins = "PA10", "PA11";
allwinner,function = "uart1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PB0", "PB1";
allwinner,function = "i2c0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c1_pins_a: i2c1@0 {
allwinner,pins = "PB18", "PB19";
allwinner,function = "i2c1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c2_pins_a: i2c2@0 {
allwinner,pins = "PB20", "PB21";
allwinner,function = "i2c2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
emac_pins_a: emac0@0 {
@@ -598,36 +670,78 @@
"PA11", "PA12", "PA13", "PA14",
"PA15", "PA16";
allwinner,function = "emac";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
allwinner,function = "mmc0";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
allwinner,pins = "PH1";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
ir0_pins_a: ir0@0 {
allwinner,pins = "PB3","PB4";
allwinner,function = "ir0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
ir1_pins_a: ir1@0 {
allwinner,pins = "PB22","PB23";
allwinner,function = "ir1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi0_pins_a: spi0@0 {
+ allwinner,pins = "PI10", "PI11", "PI12", "PI13";
+ allwinner,function = "spi0";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi1_pins_a: spi1@0 {
+ allwinner,pins = "PI16", "PI17", "PI18", "PI19";
+ allwinner,function = "spi1";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi2_pins_a: spi2@0 {
+ allwinner,pins = "PB14", "PB15", "PB16", "PB17";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ spi2_pins_b: spi2@1 {
+ allwinner,pins = "PC19", "PC20", "PC21", "PC22";
+ allwinner,function = "spi2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps20_pins_a: ps20@0 {
+ allwinner,pins = "PI20", "PI21";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps21_pins_a: ps21@0 {
+ allwinner,pins = "PH12", "PH13";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -675,6 +789,13 @@
status = "disabled";
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-a10-sid";
reg = <0x01c23800 0x10>;
@@ -684,6 +805,7 @@
compatible = "allwinner,sun4i-a10-ts";
reg = <0x01c25000 0x100>;
interrupts = <29>;
+ #thermal-sensor-cells = <0>;
};
uart0: serial@01c28000 {
@@ -795,5 +917,21 @@
#address-cells = <1>;
#size-cells = <0>;
};
+
+ ps20: ps2@01c2a000 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a000 0x400>;
+ interrupts = <62>;
+ clocks = <&apb1_gates 6>;
+ status = "disabled";
+ };
+
+ ps21: ps2@01c2a400 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a400 0x400>;
+ interrupts = <63>;
+ clocks = <&apb1_gates 7>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/sun5i-a10s-mk802.dts b/arch/arm/boot/dts/sun5i-a10s-mk802.dts
new file mode 100644
index 000000000000..b21af87d9eae
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s-mk802.dts
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a10s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "MK802-A10s";
+ compatible = "allwinner,a10s-mk802", "allwinner,sun5i-a10s";
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_mk802>;
+
+ red {
+ label = "mk802:red:usr";
+ gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */
+ };
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_mk802>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+ cd-inverted;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ led_pins_mk802: led_pins@0 {
+ allwinner,pins = "PB2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_mk802: mmc0_cd_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb1_vbus_pin_mk802: usb1_vbus_pin@0 {
+ allwinner,pins = "PB10";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ pinctrl-0 = <&usb1_vbus_pin_mk802>;
+ gpio = <&pio 1 10 GPIO_ACTIVE_HIGH>; /* PB10 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index bfa742817690..2bbc93b935ca 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -48,8 +48,12 @@
*/
/dts-v1/;
-/include/ "sun5i-a10s.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun5i-a10s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Olimex A10s-Olinuxino Micro";
@@ -82,7 +86,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino_micro>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 6 1 0>; /* PG1 */
+ cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
cd-inverted;
status = "okay";
};
@@ -92,7 +96,7 @@
pinctrl-0 = <&mmc1_pins_a>, <&mmc1_cd_pin_olinuxino_micro>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 6 13 0>; /* PG13 */
+ cd-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
cd-inverted;
status = "okay";
};
@@ -114,29 +118,69 @@
mmc0_cd_pin_olinuxino_micro: mmc0_cd_pin@0 {
allwinner,pins = "PG1";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
mmc1_cd_pin_olinuxino_micro: mmc1_cd_pin@0 {
allwinner,pins = "PG13";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PE3";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb1_vbus_pin_olinuxino_m: usb1_vbus_pin@0 {
allwinner,pins = "PB10";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@191 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <191274>;
+ };
+
+ button@392 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <392644>;
+ };
+
+ button@601 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <601151>;
+ };
+
+ button@795 {
+ label = "Enter";
+ linux,code = <KEY_ENTER>;
+ channel = <0>;
+ voltage = <795090>;
+ };
+
+ button@987 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <987387>;
};
};
@@ -191,14 +235,14 @@
green {
label = "a10s-olinuxino-micro:green:usr";
- gpios = <&pio 4 3 0>;
+ gpios = <&pio 4 3 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
reg_usb1_vbus: usb1-vbus {
pinctrl-0 = <&usb1_vbus_pin_olinuxino_m>;
- gpio = <&pio 1 10 0>;
+ gpio = <&pio 1 10 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts b/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
index 1fa2916eafc2..7deddfc9df8b 100644
--- a/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts
@@ -46,8 +46,11 @@
*/
/dts-v1/;
-/include/ "sun5i-a10s.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun5i-a10s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "R7 A10s hdmi tv-stick";
@@ -59,7 +62,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_r7>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 6 1 0>; /* PG1 */
+ cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
cd-inverted;
status = "okay";
};
@@ -90,22 +93,22 @@
mmc0_cd_pin_r7: mmc0_cd_pin@0 {
allwinner,pins = "PG1";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
led_pins_r7: led_pins@0 {
allwinner,pins = "PB2";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb1_vbus_pin_r7: usb1_vbus_pin@0 {
allwinner,pins = "PG13";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -123,14 +126,14 @@
green {
label = "r7-tv-dongle:green:usr";
- gpios = <&pio 1 2 0>;
+ gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
reg_usb1_vbus: usb1-vbus {
pinctrl-0 = <&usb1_vbus_pin_r7>;
- gpio = <&pio 6 13 0>;
+ gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 2e7d8263799d..905f84d141f0 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -11,7 +11,10 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
interrupt-parent = <&intc>;
@@ -32,6 +35,14 @@
<&ahb_gates 44>;
status = "disabled";
};
+
+ framebuffer@1 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+ status = "disabled";
+ };
};
cpus {
@@ -316,7 +327,8 @@
interrupts = <10>;
clocks = <&ahb_gates 20>, <&spi0_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 27>, <&dma 1 26>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -329,7 +341,8 @@
interrupts = <11>;
clocks = <&ahb_gates 21>, <&spi1_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 9>, <&dma 1 8>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -344,7 +357,7 @@
status = "disabled";
};
- mdio@01c0b080 {
+ mdio: mdio@01c0b080 {
compatible = "allwinner,sun4i-a10-mdio";
reg = <0x01c0b080 0x14>;
status = "disabled";
@@ -417,7 +430,8 @@
interrupts = <12>;
clocks = <&ahb_gates 22>, <&spi2_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 29>, <&dma 1 28>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -445,22 +459,22 @@
uart0_pins_a: uart0@0 {
allwinner,pins = "PB19", "PB20";
allwinner,function = "uart0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart2_pins_a: uart2@0 {
allwinner,pins = "PC18", "PC19";
allwinner,function = "uart2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart3_pins_a: uart3@0 {
allwinner,pins = "PG9", "PG10";
allwinner,function = "uart3";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
emac_pins_a: emac0@0 {
@@ -470,43 +484,43 @@
"PA11", "PA12", "PA13", "PA14",
"PA15", "PA16";
allwinner,function = "emac";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PB0", "PB1";
allwinner,function = "i2c0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c1_pins_a: i2c1@0 {
allwinner,pins = "PB15", "PB16";
allwinner,function = "i2c1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c2_pins_a: i2c2@0 {
allwinner,pins = "PB17", "PB18";
allwinner,function = "i2c2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
allwinner,function = "mmc0";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc1_pins_a: mmc1@0 {
allwinner,pins = "PG3","PG4","PG5","PG6","PG7","PG8";
allwinner,function = "mmc1";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -522,6 +536,13 @@
reg = <0x01c20c90 0x10>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-a10-sid";
reg = <0x01c23800 0x10>;
@@ -531,6 +552,7 @@
compatible = "allwinner,sun4i-a10-ts";
reg = <0x01c25000 0x100>;
interrupts = <29>;
+ #thermal-sensor-cells = <0>;
};
uart0: serial@01c28000 {
diff --git a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
index c7be3abd9fcc..03aa04555630 100644
--- a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
+++ b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
@@ -46,8 +46,11 @@
*/
/dts-v1/;
-/include/ "sun5i-a13.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "HSG H702";
@@ -63,17 +66,13 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_h702>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 6 0 0>; /* PG0 */
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
cd-inverted;
status = "okay";
};
usbphy: phy@01c13400 {
- /*
- * There doesn't seem to be a GPIO for controlling
- * usb1 vbus, despite the fex file saying otherwise.
- */
- usb1_vbus-supply = <&reg_vcc5v0>;
+ usb1_vbus-supply = <&reg_ldo3>;
status = "okay";
};
@@ -89,8 +88,8 @@
mmc0_cd_pin_h702: mmc0_cd_pin@0 {
allwinner,pins = "PG0";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
};
@@ -106,11 +105,8 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupts = <0>;
- interrupt-controller;
- #interrupt-cells = <1>;
};
};
@@ -132,3 +128,40 @@
};
};
};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
+
+&reg_ldo3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
index 3decefb3c37a..03deb84268ce 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
@@ -47,8 +47,11 @@
*/
/dts-v1/;
-/include/ "sun5i-a13.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Olimex A13-Olinuxino Micro";
@@ -64,7 +67,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxinom>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 6 0 0>; /* PG0 */
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
cd-inverted;
status = "okay";
};
@@ -86,22 +89,22 @@
mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
allwinner,pins = "PG0";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
led_pins_olinuxinom: led_pins@0 {
allwinner,pins = "PG9";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb1_vbus_pin_olinuxinom: usb1_vbus_pin@0 {
allwinner,pins = "PG11";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -137,14 +140,14 @@
power {
label = "a13-olinuxino-micro:green:power";
- gpios = <&pio 6 9 0>;
+ gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
reg_usb1_vbus: usb1-vbus {
pinctrl-0 = <&usb1_vbus_pin_olinuxinom>;
- gpio = <&pio 6 11 0>;
+ gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index b421f7fa197b..6b24876ed462 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -48,8 +48,12 @@
*/
/dts-v1/;
-/include/ "sun5i-a13.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Olimex A13-Olinuxino";
@@ -65,7 +69,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 6 0 0>; /* PG0 */
+ cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
cd-inverted;
status = "okay";
};
@@ -87,22 +91,62 @@
mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 {
allwinner,pins = "PG0";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PG9";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb1_vbus_pin_olinuxino: usb1_vbus_pin@0 {
allwinner,pins = "PG11";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@191 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <191274>;
+ };
+
+ button@392 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <392644>;
+ };
+
+ button@601 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <601151>;
+ };
+
+ button@795 {
+ label = "Enter";
+ linux,code = <KEY_ENTER>;
+ channel = <0>;
+ voltage = <795090>;
+ };
+
+ button@987 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <987387>;
};
};
@@ -116,6 +160,15 @@
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_a>;
status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupts = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
};
i2c1: i2c@01c2b000 {
@@ -137,14 +190,14 @@
pinctrl-0 = <&led_pins_olinuxino>;
power {
- gpios = <&pio 6 9 0>;
+ gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
reg_usb1_vbus: usb1-vbus {
pinctrl-0 = <&usb1_vbus_pin_olinuxino>;
- gpio = <&pio 6 11 0>;
+ gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index c556688f8b8b..4910393d1b09 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -11,18 +11,85 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+
+#include <dt-bindings/thermal/thermal.h>
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
interrupt-parent = <&intc>;
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+ status = "disabled";
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+
+ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a8";
reg = <0x0>;
+ clocks = <&cpu>;
+ clock-latency = <244144>; /* 8 32k periods */
+ operating-points = <
+ /* kHz uV */
+ 1104000 1500000
+ 1008000 1400000
+ 912000 1350000
+ 864000 1300000
+ 624000 1200000
+ 576000 1200000
+ 432000 1200000
+ >;
+ #cooling-cells = <2>;
+ cooling-min-level = <0>;
+ cooling-max-level = <6>;
+ };
+ };
+
+ thermal-zones {
+ cpu_thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&rtp>;
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ /* milliCelsius */
+ temperature = <850000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit: cpu_crit {
+ /* milliCelsius */
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
};
@@ -299,7 +366,8 @@
interrupts = <10>;
clocks = <&ahb_gates 20>, <&spi0_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 27>, <&dma 1 26>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -312,7 +380,8 @@
interrupts = <11>;
clocks = <&ahb_gates 21>, <&spi1_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 9>, <&dma 1 8>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -375,7 +444,8 @@
interrupts = <12>;
clocks = <&ahb_gates 22>, <&spi2_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 29>, <&dma 1 28>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -403,43 +473,43 @@
uart1_pins_a: uart1@0 {
allwinner,pins = "PE10", "PE11";
allwinner,function = "uart1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart1_pins_b: uart1@1 {
allwinner,pins = "PG3", "PG4";
allwinner,function = "uart1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PB0", "PB1";
allwinner,function = "i2c0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c1_pins_a: i2c1@0 {
allwinner,pins = "PB15", "PB16";
allwinner,function = "i2c1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c2_pins_a: i2c2@0 {
allwinner,pins = "PB17", "PB18";
allwinner,function = "i2c2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
allwinner,function = "mmc0";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -455,6 +525,13 @@
reg = <0x01c20c90 0x10>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-a10-sid";
reg = <0x01c23800 0x10>;
@@ -464,6 +541,7 @@
compatible = "allwinner,sun4i-a10-ts";
reg = <0x01c25000 0x100>;
interrupts = <29>;
+ #thermal-sensor-cells = <0>;
};
uart1: serial@01c28400 {
diff --git a/arch/arm/boot/dts/sun6i-a31-app4-evb1.dts b/arch/arm/boot/dts/sun6i-a31-app4-evb1.dts
index c74a63a39531..be9f5ee6b59e 100644
--- a/arch/arm/boot/dts/sun6i-a31-app4-evb1.dts
+++ b/arch/arm/boot/dts/sun6i-a31-app4-evb1.dts
@@ -48,8 +48,11 @@
*/
/dts-v1/;
-/include/ "sun6i-a31.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Allwinner A31 APP4 EVB1 Evaluation Board";
@@ -64,8 +67,8 @@
usb1_vbus_pin_a: usb1_vbus_pin@0 {
allwinner,pins = "PH27";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -87,7 +90,7 @@
reg_usb1_vbus: usb1-vbus {
pinctrl-0 = <&usb1_vbus_pin_a>;
- gpio = <&pio 7 27 0>;
+ gpio = <&pio 7 27 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun6i-a31-colombus.dts b/arch/arm/boot/dts/sun6i-a31-colombus.dts
index c36b4dc89c13..84630e56acd7 100644
--- a/arch/arm/boot/dts/sun6i-a31-colombus.dts
+++ b/arch/arm/boot/dts/sun6i-a31-colombus.dts
@@ -48,8 +48,11 @@
*/
/dts-v1/;
-/include/ "sun6i-a31.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "WITS A31 Colombus Evaluation Board";
@@ -65,7 +68,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_colombus>;
vmmc-supply = <&reg_vcc3v0>;
bus-width = <4>;
- cd-gpios = <&pio 0 8 0>; /* PA8 */
+ cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
cd-inverted;
status = "okay";
};
@@ -81,21 +84,21 @@
pio: pinctrl@01c20800 {
mmc0_pins_a: mmc0@0 {
- allwinner,pull = <1>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
mmc0_cd_pin_colombus: mmc0_cd_pin@0 {
allwinner,pins = "PA8";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
usb2_vbus_pin_colombus: usb2_vbus_pin@0 {
allwinner,pins = "PH24";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -127,7 +130,7 @@
reg_usb2_vbus: usb2-vbus {
pinctrl-names = "default";
pinctrl-0 = <&usb2_vbus_pin_colombus>;
- gpio = <&pio 7 24 0>;
+ gpio = <&pio 7 24 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index 6e924d9d2912..8b61b1b342e0 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -48,8 +48,11 @@
*/
/dts-v1/;
-/include/ "sun6i-a31.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Merrii A31 Hummingbird";
@@ -58,98 +61,96 @@
chosen {
bootargs = "earlyprintk console=ttyS0,115200";
};
+};
+
+&ehci0 {
+ status = "okay";
+};
- soc@01c00000 {
- mmc0: mmc@01c0f000 {
- pinctrl-names = "default";
- pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
- vmmc-supply = <&reg_vcc3v0>;
- bus-width = <4>;
- cd-gpios = <&pio 0 8 0>; /* PA8 */
- cd-inverted;
- status = "okay";
- };
-
- usbphy: phy@01c19400 {
- usb1_vbus-supply = <&reg_usb1_vbus>;
- status = "okay";
- };
-
- ehci0: usb@01c1a000 {
- status = "okay";
- };
-
- ohci0: usb@01c1a400 {
- status = "okay";
- };
-
- pio: pinctrl@01c20800 {
- mmc0_pins_a: mmc0@0 {
- /* external pull-ups missing for some pins */
- allwinner,pull = <1>;
- };
-
- mmc0_cd_pin_hummingbird: mmc0_cd_pin@0 {
- allwinner,pins = "PA8";
- allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
- };
-
- usb1_vbus_pin_a: usb1_vbus_pin@0 {
- allwinner,pins = "PH24";
- allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
- };
- };
-
- uart0: serial@01c28000 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins_a>;
- status = "okay";
- };
-
- i2c0: i2c@01c2ac00 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins_a>;
- /* pull-ups and devices require AXP221 DLDO3 */
- status = "failed";
- };
-
- i2c1: i2c@01c2b000 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_pins_a>;
- status = "okay";
- };
-
- i2c2: i2c@01c2b400 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c2_pins_a>;
- status = "okay";
-
- pcf8563: rtc@51 {
- compatible = "nxp,pcf8563";
- reg = <0x51>;
- };
- };
-
- gmac: ethernet@01c30000 {
- pinctrl-names = "default";
- pinctrl-0 = <&gmac_pins_rgmii_a>;
- phy = <&phy1>;
- phy-mode = "rgmii";
- status = "okay";
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- };
- };
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 30000>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
};
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ /* pull-ups and devices require AXP221 DLDO3 */
+ status = "failed";
+};
- reg_usb1_vbus: usb1-vbus {
- pinctrl-0 = <&usb1_vbus_pin_a>;
- gpio = <&pio 7 24 0>; /* PH24 */
- status = "okay";
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
};
};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc0_pins_a {
+ /* external pull-ups missing for some pins */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&pio {
+ mmc0_cd_pin_hummingbird: mmc0_cd_pin@0 {
+ allwinner,pins = "PA8";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&reg_usb1_vbus {
+ gpio = <&pio 7 24 GPIO_ACTIVE_HIGH>; /* PH24 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb1_vbus_pin_a {
+ /* different pin from sunxi-common-regulators */
+ allwinner,pins = "PH24";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun6i-a31-m9.dts b/arch/arm/boot/dts/sun6i-a31-m9.dts
index 3ab544f3af4a..139a21e6b695 100644
--- a/arch/arm/boot/dts/sun6i-a31-m9.dts
+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts
@@ -46,8 +46,11 @@
*/
/dts-v1/;
-/include/ "sun6i-a31.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun6i-a31.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Mele M9 / A1000G Quad top set box";
@@ -63,7 +66,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_m9>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 22 0>; /* PH22 */
+ cd-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
cd-inverted;
status = "okay";
};
@@ -85,22 +88,22 @@
led_pins_m9: led_pins@0 {
allwinner,pins = "PH13";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_cd_pin_m9: mmc0_cd_pin@0 {
allwinner,pins = "PH22";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
usb1_vbus_pin_m9: usb1_vbus_pin@0 {
allwinner,pins = "PC27";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -121,6 +124,12 @@
reg = <1>;
};
};
+
+ ir@01f02000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+ };
};
leds {
@@ -130,14 +139,14 @@
blue {
label = "m9:blue:usr";
- gpios = <&pio 7 13 0>;
+ gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>;
};
};
reg_usb1_vbus: usb1-vbus {
pinctrl-names = "default";
pinctrl-0 = <&usb1_vbus_pin_m9>;
- gpio = <&pio 2 27 0>;
+ gpio = <&pio 2 27 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 1e7e7bcf8307..47e557656993 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -47,7 +47,11 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
interrupt-parent = <&gic>;
@@ -67,6 +71,24 @@
clocks = <&pll6 0>;
status = "disabled";
};
+
+ framebuffer@1 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll6 0>;
+ status = "disabled";
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <24000000>;
+ arm,cpu-registers-not-fw-configured;
};
cpus {
@@ -105,10 +127,10 @@
pmu {
compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
- interrupts = <0 120 4>,
- <0 121 4>,
- <0 122 4>,
- <0 123 4>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
};
clocks {
@@ -355,7 +377,7 @@
dma: dma-controller@01c02000 {
compatible = "allwinner,sun6i-a31-dma";
reg = <0x01c02000 0x1000>;
- interrupts = <0 50 4>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 6>;
resets = <&ahb1_rst 6>;
#dma-cells = <1>;
@@ -372,7 +394,7 @@
clock-names = "ahb", "mmc";
resets = <&ahb1_rst 8>;
reset-names = "ahb";
- interrupts = <0 60 4>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -383,7 +405,7 @@
clock-names = "ahb", "mmc";
resets = <&ahb1_rst 9>;
reset-names = "ahb";
- interrupts = <0 61 4>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -394,7 +416,7 @@
clock-names = "ahb", "mmc";
resets = <&ahb1_rst 10>;
reset-names = "ahb";
- interrupts = <0 62 4>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -405,7 +427,7 @@
clock-names = "ahb", "mmc";
resets = <&ahb1_rst 11>;
reset-names = "ahb";
- interrupts = <0 63 4>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -436,7 +458,7 @@
ehci0: usb@01c1a000 {
compatible = "allwinner,sun6i-a31-ehci", "generic-ehci";
reg = <0x01c1a000 0x100>;
- interrupts = <0 72 4>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 26>;
resets = <&ahb1_rst 26>;
phys = <&usbphy 1>;
@@ -447,7 +469,7 @@
ohci0: usb@01c1a400 {
compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
reg = <0x01c1a400 0x100>;
- interrupts = <0 73 4>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 29>, <&usb_clk 16>;
resets = <&ahb1_rst 29>;
phys = <&usbphy 1>;
@@ -458,7 +480,7 @@
ehci1: usb@01c1b000 {
compatible = "allwinner,sun6i-a31-ehci", "generic-ehci";
reg = <0x01c1b000 0x100>;
- interrupts = <0 74 4>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 27>;
resets = <&ahb1_rst 27>;
phys = <&usbphy 2>;
@@ -469,7 +491,7 @@
ohci1: usb@01c1b400 {
compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
reg = <0x01c1b400 0x100>;
- interrupts = <0 75 4>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 30>, <&usb_clk 17>;
resets = <&ahb1_rst 30>;
phys = <&usbphy 2>;
@@ -480,7 +502,7 @@
ohci2: usb@01c1c400 {
compatible = "allwinner,sun6i-a31-ohci", "generic-ohci";
reg = <0x01c1c400 0x100>;
- interrupts = <0 77 4>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 31>, <&usb_clk 18>;
resets = <&ahb1_rst 31>;
status = "disabled";
@@ -489,10 +511,10 @@
pio: pinctrl@01c20800 {
compatible = "allwinner,sun6i-a31-pinctrl";
reg = <0x01c20800 0x400>;
- interrupts = <0 11 4>,
- <0 15 4>,
- <0 16 4>,
- <0 17 4>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 5>;
gpio-controller;
interrupt-controller;
@@ -503,36 +525,36 @@
uart0_pins_a: uart0@0 {
allwinner,pins = "PH20", "PH21";
allwinner,function = "uart0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PH14", "PH15";
allwinner,function = "i2c0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c1_pins_a: i2c1@0 {
allwinner,pins = "PH16", "PH17";
allwinner,function = "i2c1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c2_pins_a: i2c2@0 {
allwinner,pins = "PH18", "PH19";
allwinner,function = "i2c2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
allwinner,function = "mmc0";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
gmac_pins_mii_a: gmac_mii@0 {
@@ -542,8 +564,8 @@
"PA20", "PA21", "PA22", "PA23",
"PA24", "PA26", "PA27";
allwinner,function = "gmac";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
gmac_pins_gmii_a: gmac_gmii@0 {
@@ -559,8 +581,8 @@
* data lines in GMII mode run at 125MHz and
* might need a higher signal drive strength
*/
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
gmac_pins_rgmii_a: gmac_rgmii@0 {
@@ -573,8 +595,8 @@
* data lines in RGMII mode use DDR mode
* and need a higher signal drive strength
*/
- allwinner,drive = <3>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -599,11 +621,11 @@
timer@01c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0xa0>;
- interrupts = <0 18 4>,
- <0 19 4>,
- <0 20 4>,
- <0 21 4>,
- <0 22 4>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc24M>;
};
@@ -612,10 +634,17 @@
reg = <0x01c20ca0 0x20>;
};
+ rtp: rtp@01c25000 {
+ compatible = "allwinner,sun6i-a31-ts";
+ reg = <0x01c25000 0x100>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+ };
+
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
- interrupts = <0 0 4>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 16>;
@@ -628,7 +657,7 @@
uart1: serial@01c28400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28400 0x400>;
- interrupts = <0 1 4>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 17>;
@@ -641,7 +670,7 @@
uart2: serial@01c28800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28800 0x400>;
- interrupts = <0 2 4>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 18>;
@@ -654,7 +683,7 @@
uart3: serial@01c28c00 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28c00 0x400>;
- interrupts = <0 3 4>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 19>;
@@ -667,7 +696,7 @@
uart4: serial@01c29000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29000 0x400>;
- interrupts = <0 4 4>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 20>;
@@ -680,7 +709,7 @@
uart5: serial@01c29400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29400 0x400>;
- interrupts = <0 5 4>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 21>;
@@ -693,7 +722,7 @@
i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2ac00 0x400>;
- interrupts = <0 6 4>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb2_gates 0>;
resets = <&apb2_rst 0>;
status = "disabled";
@@ -704,7 +733,7 @@
i2c1: i2c@01c2b000 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2b000 0x400>;
- interrupts = <0 7 4>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb2_gates 1>;
resets = <&apb2_rst 1>;
status = "disabled";
@@ -715,7 +744,7 @@
i2c2: i2c@01c2b400 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2b400 0x400>;
- interrupts = <0 8 4>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb2_gates 2>;
resets = <&apb2_rst 2>;
status = "disabled";
@@ -726,7 +755,7 @@
i2c3: i2c@01c2b800 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2b800 0x400>;
- interrupts = <0 9 4>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb2_gates 3>;
resets = <&apb2_rst 3>;
status = "disabled";
@@ -737,7 +766,7 @@
gmac: ethernet@01c30000 {
compatible = "allwinner,sun7i-a20-gmac";
reg = <0x01c30000 0x1054>;
- interrupts = <0 82 4>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
clocks = <&ahb1_gates 17>, <&gmac_tx_clk>;
clock-names = "stmmaceth", "allwinner_gmac_tx";
@@ -754,10 +783,10 @@
timer@01c60000 {
compatible = "allwinner,sun6i-a31-hstimer", "allwinner,sun7i-a20-hstimer";
reg = <0x01c60000 0x1000>;
- interrupts = <0 51 4>,
- <0 52 4>,
- <0 53 4>,
- <0 54 4>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 19>;
resets = <&ahb1_rst 19>;
};
@@ -765,7 +794,7 @@
spi0: spi@01c68000 {
compatible = "allwinner,sun6i-a31-spi";
reg = <0x01c68000 0x1000>;
- interrupts = <0 65 4>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 20>, <&spi0_clk>;
clock-names = "ahb", "mod";
dmas = <&dma 23>, <&dma 23>;
@@ -777,7 +806,7 @@
spi1: spi@01c69000 {
compatible = "allwinner,sun6i-a31-spi";
reg = <0x01c69000 0x1000>;
- interrupts = <0 66 4>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 21>, <&spi1_clk>;
clock-names = "ahb", "mod";
dmas = <&dma 24>, <&dma 24>;
@@ -789,7 +818,7 @@
spi2: spi@01c6a000 {
compatible = "allwinner,sun6i-a31-spi";
reg = <0x01c6a000 0x1000>;
- interrupts = <0 67 4>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 22>, <&spi2_clk>;
clock-names = "ahb", "mod";
dmas = <&dma 25>, <&dma 25>;
@@ -801,7 +830,7 @@
spi3: spi@01c6b000 {
compatible = "allwinner,sun6i-a31-spi";
reg = <0x01c6b000 0x1000>;
- interrupts = <0 68 4>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 23>, <&spi3_clk>;
clock-names = "ahb", "mod";
dmas = <&dma 26>, <&dma 26>;
@@ -818,13 +847,14 @@
<0x01c86000 0x2000>;
interrupt-controller;
#interrupt-cells = <3>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
rtc: rtc@01f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>;
- interrupts = <0 40 4>, <0 41 4>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
nmi_intc: interrupt-controller@01f00c0c {
@@ -832,7 +862,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x01f00c0c 0x38>;
- interrupts = <0 32 4>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
};
prcm@01f01400 {
@@ -872,6 +902,13 @@
"apb0_i2c";
};
+ ir_clk: ir_clk {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-mod0-clk";
+ clocks = <&osc32k>, <&osc24M>;
+ clock-output-names = "ir";
+ };
+
apb0_rst: apb0_rst {
compatible = "allwinner,sun6i-a31-clock-reset";
#reset-cells = <1>;
@@ -883,11 +920,21 @@
reg = <0x01f01c00 0x300>;
};
+ ir: ir@01f02000 {
+ compatible = "allwinner,sun5i-a13-ir";
+ clocks = <&apb0_gates 1>, <&ir_clk>;
+ clock-names = "apb", "ir";
+ resets = <&apb0_rst 1>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x01f02000 0x40>;
+ status = "disabled";
+ };
+
r_pio: pinctrl@01f02c00 {
compatible = "allwinner,sun6i-a31-r-pinctrl";
reg = <0x01f02c00 0x400>;
- interrupts = <0 45 4>,
- <0 46 4>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 0>;
resets = <&apb0_rst 0>;
gpio-controller;
@@ -895,6 +942,13 @@
#interrupt-cells = <2>;
#size-cells = <0>;
#gpio-cells = <3>;
+
+ ir_pins_a: ir@0 {
+ allwinner,pins = "PL4";
+ allwinner,function = "s_ir";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/sun6i-a31s-cs908.dts b/arch/arm/boot/dts/sun6i-a31s-cs908.dts
new file mode 100644
index 000000000000..bc3734f67cf0
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-cs908.dts
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31s.dtsi"
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+ model = "CSQ CS908 top set box";
+ compatible = "csq,cs908", "allwinner,sun6i-a31s";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ usb1_vbus_pin_csq908: usb1_vbus_pin@0 {
+ allwinner,pins = "PC27";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_mii_a>;
+ phy = <&phy1>;
+ phy-mode = "mii";
+ status = "okay";
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&ir {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_pins_a>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun6i-a31s.dtsi b/arch/arm/boot/dts/sun6i-a31s.dtsi
new file mode 100644
index 000000000000..eaf5ec8fd459
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The A31s is the same die as the A31 in a different package, this is
+ * reflected by it having different pinctrl compatible everything else is
+ * identical.
+ */
+
+#include "sun6i-a31.dtsi"
+
+&pio {
+ compatible = "allwinner,sun6i-a31s-pinctrl";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
index bd7b15add697..5dd139e7792e 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -48,8 +48,12 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "LeMaker Banana Pi";
@@ -73,7 +77,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapi>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 10 0>; /* PH10 */
+ cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
cd-inverted;
status = "okay";
};
@@ -108,22 +112,22 @@
mmc0_cd_pin_bananapi: mmc0_cd_pin@0 {
allwinner,pins = "PH10";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
gmac_power_pin_bananapi: gmac_power_pin@0 {
allwinner,pins = "PH23";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_bananapi: led_pins@0 {
allwinner,pins = "PH24";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -160,7 +164,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
@@ -194,7 +198,7 @@
green {
label = "bananapi:green:usr";
- gpios = <&pio 7 24 0>;
+ gpios = <&pio 7 24 GPIO_ACTIVE_HIGH>;
};
};
@@ -215,6 +219,6 @@
regulator-max-microvolt = <3300000>;
startup-delay-us = <100000>;
enable-active-high;
- gpio = <&pio 7 23 0>;
+ gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapro.dts b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
new file mode 100644
index 000000000000..fb89fe7ed21b
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ model = "LeMaker Banana Pro";
+ compatible = "lemaker,bananapro", "allwinner,sun7i-a20";
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_bananapro>;
+
+ blue {
+ label = "bananapro:blue:usr";
+ gpios = <&pio 6 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ green {
+ label = "bananapro:green:usr";
+ gpios = <&pio 7 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_gmac_3v3: gmac-3v3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_power_pin_bananapro>;
+ regulator-name = "gmac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ enable-active-high;
+ gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_vmmc3: vmmc3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vmmc3_pin_bananapro>;
+ regulator-name = "vmmc3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 22 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&ahci {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins_rgmii_a>;
+ phy = <&phy1>;
+ phy-mode = "rgmii";
+ phy-supply = <&reg_gmac_3v3>;
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ axp209: pmic@34 {
+ compatible = "x-powers,axp209";
+ reg = <0x34>;
+ interrupt-parent = <&nmi_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+};
+
+&ir0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir0_pins_a>;
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bananapro>;
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc3_pins_a>;
+ vmmc-supply = <&reg_vmmc3>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ gmac_power_pin_bananapro: gmac_power_pin@0 {
+ allwinner,pins = "PH23";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ led_pins_bananapro: led_pins@0 {
+ allwinner,pins = "PH24", "PG2";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_bananapro: mmc0_cd_pin@0 {
+ allwinner,pins = "PH10";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+
+ usb1_vbus_pin_bananapro: usb1_vbus_pin@0 {
+ allwinner,pins = "PH0";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ usb2_vbus_pin_bananapro: usb2_vbus_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ vmmc3_pin_bananapro: vmmc3_pin@0 {
+ allwinner,pins = "PH22";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+&reg_usb1_vbus {
+ pinctrl-0 = <&usb1_vbus_pin_bananapro>;
+ gpio = <&pio 7 0 GPIO_ACTIVE_HIGH>; /* PH0 */
+ status = "okay";
+};
+
+&reg_usb2_vbus {
+ pinctrl-0 = <&usb2_vbus_pin_bananapro>;
+ gpio = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins_a>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins_a>;
+ status = "okay";
+};
+
+&uart7 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart7_pins_a>;
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_usb1_vbus>;
+ usb2_vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 53680983461a..c4ab6edb6f15 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -3,17 +3,57 @@
*
* Maxime Ripard <maxime.ripard@free-electrons.com>
*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Cubietech Cubieboard2";
@@ -25,7 +65,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -61,8 +101,8 @@
led_pins_cubieboard2: led_pins@0 {
allwinner,pins = "PH20", "PH21";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -84,13 +124,9 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
-
- interrupt-controller;
- #interrupt-cells = <1>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
};
};
@@ -120,12 +156,12 @@
blue {
label = "cubieboard2:blue:usr";
- gpios = <&pio 7 21 0>;
+ gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>;
};
green {
label = "cubieboard2:green:usr";
- gpios = <&pio 7 20 0>;
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
};
};
@@ -141,3 +177,34 @@
status = "okay";
};
};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index a281d259b9b8..8f74a649576d 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -3,17 +3,57 @@
*
* Oliver Schinagl <oliver@schinagl.nl>
*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
*
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Cubietech Cubietruck";
@@ -25,7 +65,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -70,35 +110,35 @@
pinctrl@01c20800 {
mmc3_pins_a: mmc3@0 {
/* AP6210 requires pull-up */
- allwinner,pull = <1>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
vmmc3_pin_cubietruck: vmmc3_pin@0 {
allwinner,pins = "PH9";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
ahci_pwr_pin_cubietruck: ahci_pwr_pin@1 {
allwinner,pins = "PH12";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_cubietruck: led_pins@0 {
allwinner,pins = "PH7", "PH11", "PH20", "PH21";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb0_vbus_pin_a: usb0_vbus_pin@0 {
allwinner,pins = "PH17";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -126,13 +166,9 @@
status = "okay";
axp209: pmic@34 {
- compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
-
- interrupt-controller;
- #interrupt-cells = <1>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
};
};
@@ -168,34 +204,34 @@
blue {
label = "cubietruck:blue:usr";
- gpios = <&pio 7 21 0>;
+ gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>;
};
orange {
label = "cubietruck:orange:usr";
- gpios = <&pio 7 20 0>;
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
};
white {
label = "cubietruck:white:usr";
- gpios = <&pio 7 11 0>;
+ gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>;
};
green {
label = "cubietruck:green:usr";
- gpios = <&pio 7 7 0>;
+ gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>;
};
};
reg_ahci_5v: ahci-5v {
pinctrl-0 = <&ahci_pwr_pin_cubietruck>;
- gpio = <&pio 7 12 0>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
status = "okay";
};
reg_usb0_vbus: usb0-vbus {
pinctrl-0 = <&usb0_vbus_pin_a>;
- gpio = <&pio 7 17 0>;
+ gpio = <&pio 7 17 GPIO_ACTIVE_HIGH>;
status = "okay";
};
@@ -215,6 +251,37 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
- gpio = <&pio 7 9 0>;
+ gpio = <&pio 7 9 GPIO_ACTIVE_HIGH>;
};
};
+
+#include "axp209.dtsi"
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+ regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "avcc";
+};
diff --git a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
index 0bcefcbbb756..86a944ce19f8 100644
--- a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
+++ b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
@@ -12,8 +12,12 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Merrii A20 Hummingbird";
@@ -33,7 +37,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v0>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -78,29 +82,29 @@
ahci_pwr_pin_a20_hummingbird: ahci_pwr_pin@0 {
allwinner,pins = "PH15";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb1_vbus_pin_a20_hummingbird: usb1_vbus_pin@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc3_vdd_pin_a20_hummingbird: mmc3_vdd_pin@0 {
allwinner,pins = "PH9";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
gmac_vdd_pin_a20_hummingbird: gmac_vdd_pin@0 {
allwinner,pins = "PH16";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -155,7 +159,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
};
@@ -192,7 +196,7 @@
phy-mode = "rgmii";
phy-supply = <&reg_gmac_vdd>;
/* phy reset config */
- snps,reset-gpio = <&pio 0 17 0>; /* PA17 */
+ snps,reset-gpio = <&pio 0 17 GPIO_ACTIVE_HIGH>; /* PA17 */
snps,reset-active-low;
/* wait 1s after reset, otherwise fail to read phy id */
snps,reset-delays-us = <0 10000 1000000>;
@@ -206,13 +210,13 @@
reg_ahci_5v: ahci-5v {
pinctrl-0 = <&ahci_pwr_pin_a20_hummingbird>;
- gpio = <&pio 7 15 0>; /* PH15 */
+ gpio = <&pio 7 15 GPIO_ACTIVE_HIGH>; /* PH15 */
status = "okay";
};
reg_usb1_vbus: usb1-vbus {
pinctrl-0 = <&usb1_vbus_pin_a20_hummingbird>;
- gpio = <&pio 7 2 0>; /* PH2 */
+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */
status = "okay";
};
@@ -228,7 +232,7 @@
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
enable-active-high;
- gpio = <&pio 7 9 0>; /* PH9 */
+ gpio = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
};
reg_gmac_vdd: gmac_vdd {
@@ -239,6 +243,6 @@
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
enable-active-high;
- gpio = <&pio 7 16 0>; /* PH16 */
+ gpio = <&pio 7 16 GPIO_ACTIVE_HIGH>; /* PH16 */
};
};
diff --git a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
index f38bb1a6656c..06148b4d000f 100644
--- a/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
+++ b/arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
@@ -46,8 +46,12 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "I12 / Q5 / QT840A A20 tvbox";
@@ -59,7 +63,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -98,35 +102,35 @@
pinctrl@01c20800 {
mmc3_pins_a: mmc3@0 {
/* AP6210 / AP6330 requires pull-up */
- allwinner,pull = <1>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
vmmc3_pin_i12_tvbox: vmmc3_pin@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
vmmc3_io_pin_i12_tvbox: vmmc3_io_pin@0 {
allwinner,pins = "PH12";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
gmac_power_pin_i12_tvbox: gmac_power_pin@0 {
allwinner,pins = "PH21";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_i12_tvbox: led_pins@0 {
allwinner,pins = "PH9", "PH20";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -151,7 +155,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
@@ -179,12 +183,12 @@
red {
label = "i12_tvbox:red:usr";
- gpios = <&pio 7 9 1>;
+ gpios = <&pio 7 9 GPIO_ACTIVE_LOW>;
};
blue {
label = "i12_tvbox:blue:usr";
- gpios = <&pio 7 20 0>;
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
};
};
@@ -204,7 +208,7 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
- gpio = <&pio 7 2 0>;
+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>;
};
reg_vmmc3_io: vmmc3-io {
@@ -217,7 +221,7 @@
/* This controls VCC-PI, must be always on! */
regulator-always-on;
enable-active-high;
- gpio = <&pio 7 12 0>;
+ gpio = <&pio 7 12 GPIO_ACTIVE_HIGH>;
};
reg_gmac_3v3: gmac-3v3 {
@@ -229,6 +233,6 @@
regulator-max-microvolt = <3300000>;
startup-delay-us = <50000>;
enable-active-high;
- gpio = <&pio 7 21 0>;
+ gpio = <&pio 7 21 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm/boot/dts/sun7i-a20-m3.dts b/arch/arm/boot/dts/sun7i-a20-m3.dts
index b8e568c55271..5add9f243ec3 100644
--- a/arch/arm/boot/dts/sun7i-a20-m3.dts
+++ b/arch/arm/boot/dts/sun7i-a20-m3.dts
@@ -48,8 +48,12 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Mele M3";
@@ -61,7 +65,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -101,8 +105,8 @@
led_pins_m3: led_pins@0 {
allwinner,pins = "PH20";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -127,7 +131,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
@@ -154,7 +158,7 @@
blue {
label = "m3:blue:usr";
- gpios = <&pio 7 20 0>;
+ gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
index 3f3ff9693992..12ded69d61eb 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
@@ -49,8 +49,12 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Olimex A20-OLinuXino-LIME";
@@ -62,7 +66,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -98,15 +102,15 @@
ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
allwinner,pins = "PC3";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_olinuxinolime: led_pins@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -125,7 +129,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
@@ -152,14 +156,14 @@
green {
label = "a20-olinuxino-lime:green:usr";
- gpios = <&pio 7 2 0>;
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
reg_ahci_5v: ahci-5v {
pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>;
- gpio = <&pio 2 3 0>;
+ gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
index ed364d5e755e..260dbd3bf29d 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
@@ -46,8 +46,12 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Olimex A20-OLinuXino-LIME2";
@@ -59,7 +63,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -95,15 +99,15 @@
ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 {
allwinner,pins = "PC3";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_olinuxinolime: led_pins@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -122,7 +126,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
@@ -199,14 +203,14 @@
green {
label = "a20-olinuxino-lime2:green:usr";
- gpios = <&pio 7 2 0>;
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
reg_ahci_5v: ahci-5v {
pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>;
- gpio = <&pio 2 3 0>;
+ gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index 66cc77707198..714e15ac5416 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -12,8 +12,13 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Olimex A20-Olinuxino Micro";
@@ -39,7 +44,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -49,7 +54,7 @@
pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_olinuxinom>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 11 0>; /* PH11 */
+ cd-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
cd-inverted;
status = "okay";
};
@@ -91,15 +96,69 @@
mmc3_cd_pin_olinuxinom: mmc3_cd_pin@0 {
allwinner,pins = "PH11";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
- allwinner,drive = <1>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@191 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <191274>;
+ };
+
+ button@392 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <392644>;
+ };
+
+ button@601 {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ channel = <0>;
+ voltage = <601151>;
+ };
+
+ button@795 {
+ label = "Search";
+ linux,code = <KEY_SEARCH>;
+ channel = <0>;
+ voltage = <795090>;
+ };
+
+ button@987 {
+ label = "Home";
+ linux,code = <KEY_HOMEPAGE>;
+ channel = <0>;
+ voltage = <987387>;
+ };
+
+ button@1184 {
+ label = "Esc";
+ linux,code = <KEY_ESC>;
+ channel = <0>;
+ voltage = <1184678>;
+ };
+
+ button@1398 {
+ label = "Enter";
+ linux,code = <KEY_ENTER>;
+ channel = <0>;
+ voltage = <1398804>;
};
};
@@ -130,7 +189,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
@@ -169,7 +228,7 @@
green {
label = "a20-olinuxino-micro:green:usr";
- gpios = <&pio 7 2 0>;
+ gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
index 8dca49b2477b..0a2c2aeb4687 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
@@ -47,10 +47,13 @@
*/
/dts-v1/;
-/include/ "sun7i-a20.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "LinkSprite pcDuino3";
@@ -62,7 +65,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
- cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
cd-inverted;
status = "okay";
};
@@ -102,15 +105,15 @@
led_pins_pcduino3: led_pins@0 {
allwinner,pins = "PH15", "PH16";
allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
key_pins_pcduino3: key_pins@0 {
allwinner,pins = "PH17", "PH18", "PH19";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -135,7 +138,7 @@
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
- interrupts = <0 8>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
@@ -203,7 +206,7 @@
};
reg_ahci_5v: ahci-5v {
- gpio = <&pio 7 2 0>;
+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 89749ce34a84..786d491542ac 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -47,7 +47,13 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
interrupt-parent = <&gic>;
@@ -68,16 +74,49 @@
<&ahb_gates 44>;
status = "disabled";
};
+
+ framebuffer@1 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
+ status = "disabled";
+ };
+
+ framebuffer@2 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0-tve0";
+ clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
+ <&ahb_gates 44>;
+ status = "disabled";
+ };
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ cpu0: cpu@0 {
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0>;
+ clocks = <&cpu>;
+ clock-latency = <244144>; /* 8 32k periods */
+ operating-points = <
+ /* kHz uV */
+ 1008000 1450000
+ 960000 1400000
+ 912000 1400000
+ 864000 1300000
+ 720000 1200000
+ 528000 1100000
+ 312000 1000000
+ 144000 900000
+ >;
+ #cooling-cells = <2>;
+ cooling-min-level = <0>;
+ cooling-max-level = <7>;
};
cpu@1 {
@@ -87,22 +126,54 @@
};
};
+ thermal-zones {
+ cpu_thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&rtp>;
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ cpu_alert0: cpu_alert0 {
+ /* milliCelsius */
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_crit: cpu_crit {
+ /* milliCelsius */
+ temperature = <100000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
memory {
reg = <0x40000000 0x80000000>;
};
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 13 0xf08>,
- <1 14 0xf08>,
- <1 11 0xf08>,
- <1 10 0xf08>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
pmu {
compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu";
- interrupts = <0 120 4>,
- <0 121 4>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
};
clocks {
@@ -454,13 +525,13 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x01c00030 0x0c>;
- interrupts = <0 0 4>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
};
dma: dma-controller@01c02000 {
compatible = "allwinner,sun4i-a10-dma";
reg = <0x01c02000 0x1000>;
- interrupts = <0 27 4>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 6>;
#dma-cells = <2>;
};
@@ -468,10 +539,11 @@
spi0: spi@01c05000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c05000 0x1000>;
- interrupts = <0 10 4>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 20>, <&spi0_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 27>, <&dma 1 26>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+ <&dma SUN4I_DMA_DEDICATED 26>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -481,10 +553,11 @@
spi1: spi@01c06000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c06000 0x1000>;
- interrupts = <0 11 4>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 21>, <&spi1_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 9>, <&dma 1 8>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+ <&dma SUN4I_DMA_DEDICATED 8>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -494,12 +567,12 @@
emac: ethernet@01c0b000 {
compatible = "allwinner,sun4i-a10-emac";
reg = <0x01c0b000 0x1000>;
- interrupts = <0 55 4>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 17>;
status = "disabled";
};
- mdio@01c0b080 {
+ mdio: mdio@01c0b080 {
compatible = "allwinner,sun4i-a10-mdio";
reg = <0x01c0b080 0x14>;
status = "disabled";
@@ -512,7 +585,7 @@
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mmc";
- interrupts = <0 32 4>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -521,7 +594,7 @@
reg = <0x01c10000 0x1000>;
clocks = <&ahb_gates 9>, <&mmc1_clk>;
clock-names = "ahb", "mmc";
- interrupts = <0 33 4>;
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -530,7 +603,7 @@
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>, <&mmc2_clk>;
clock-names = "ahb", "mmc";
- interrupts = <0 34 4>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -539,7 +612,7 @@
reg = <0x01c12000 0x1000>;
clocks = <&ahb_gates 11>, <&mmc3_clk>;
clock-names = "ahb", "mmc";
- interrupts = <0 35 4>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -558,7 +631,7 @@
ehci0: usb@01c14000 {
compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
reg = <0x01c14000 0x100>;
- interrupts = <0 39 4>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 1>;
phys = <&usbphy 1>;
phy-names = "usb";
@@ -568,7 +641,7 @@
ohci0: usb@01c14400 {
compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
reg = <0x01c14400 0x100>;
- interrupts = <0 64 4>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&usb_clk 6>, <&ahb_gates 2>;
phys = <&usbphy 1>;
phy-names = "usb";
@@ -578,10 +651,11 @@
spi2: spi@01c17000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c17000 0x1000>;
- interrupts = <0 12 4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 22>, <&spi2_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 29>, <&dma 1 28>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+ <&dma SUN4I_DMA_DEDICATED 28>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -591,7 +665,7 @@
ahci: sata@01c18000 {
compatible = "allwinner,sun4i-a10-ahci";
reg = <0x01c18000 0x1000>;
- interrupts = <0 56 4>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&pll6 0>, <&ahb_gates 25>;
status = "disabled";
};
@@ -599,7 +673,7 @@
ehci1: usb@01c1c000 {
compatible = "allwinner,sun7i-a20-ehci", "generic-ehci";
reg = <0x01c1c000 0x100>;
- interrupts = <0 40 4>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 3>;
phys = <&usbphy 2>;
phy-names = "usb";
@@ -609,7 +683,7 @@
ohci1: usb@01c1c400 {
compatible = "allwinner,sun7i-a20-ohci", "generic-ohci";
reg = <0x01c1c400 0x100>;
- interrupts = <0 65 4>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&usb_clk 7>, <&ahb_gates 4>;
phys = <&usbphy 2>;
phy-names = "usb";
@@ -619,10 +693,11 @@
spi3: spi@01c1f000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c1f000 0x1000>;
- interrupts = <0 50 4>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 23>, <&spi3_clk>;
clock-names = "ahb", "mod";
- dmas = <&dma 1 31>, <&dma 1 30>;
+ dmas = <&dma SUN4I_DMA_DEDICATED 31>,
+ <&dma SUN4I_DMA_DEDICATED 30>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
@@ -632,7 +707,7 @@
pio: pinctrl@01c20800 {
compatible = "allwinner,sun7i-a20-pinctrl";
reg = <0x01c20800 0x400>;
- interrupts = <0 28 4>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 5>;
gpio-controller;
interrupt-controller;
@@ -643,99 +718,99 @@
pwm0_pins_a: pwm0@0 {
allwinner,pins = "PB2";
allwinner,function = "pwm";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
pwm1_pins_a: pwm1@0 {
allwinner,pins = "PI3";
allwinner,function = "pwm";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart0_pins_a: uart0@0 {
allwinner,pins = "PB22", "PB23";
allwinner,function = "uart0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart2_pins_a: uart2@0 {
allwinner,pins = "PI16", "PI17", "PI18", "PI19";
allwinner,function = "uart2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart3_pins_a: uart3@0 {
allwinner,pins = "PG6", "PG7", "PG8", "PG9";
allwinner,function = "uart3";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart3_pins_b: uart3@1 {
allwinner,pins = "PH0", "PH1";
allwinner,function = "uart3";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart4_pins_a: uart4@0 {
allwinner,pins = "PG10", "PG11";
allwinner,function = "uart4";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart5_pins_a: uart5@0 {
allwinner,pins = "PI10", "PI11";
allwinner,function = "uart5";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart6_pins_a: uart6@0 {
allwinner,pins = "PI12", "PI13";
allwinner,function = "uart6";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart7_pins_a: uart7@0 {
allwinner,pins = "PI20", "PI21";
allwinner,function = "uart7";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PB0", "PB1";
allwinner,function = "i2c0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c1_pins_a: i2c1@0 {
allwinner,pins = "PB18", "PB19";
allwinner,function = "i2c1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c2_pins_a: i2c2@0 {
allwinner,pins = "PB20", "PB21";
allwinner,function = "i2c2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c3_pins_a: i2c3@0 {
allwinner,pins = "PI0", "PI1";
allwinner,function = "i2c3";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
emac_pins_a: emac0@0 {
@@ -745,22 +820,22 @@
"PA11", "PA12", "PA13", "PA14",
"PA15", "PA16";
allwinner,function = "emac";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
clk_out_a_pins_a: clk_out_a@0 {
allwinner,pins = "PI12";
allwinner,function = "clk_out_a";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
clk_out_b_pins_a: clk_out_b@0 {
allwinner,pins = "PI13";
allwinner,function = "clk_out_b";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
gmac_pins_mii_a: gmac_mii@0 {
@@ -770,8 +845,8 @@
"PA11", "PA12", "PA13", "PA14",
"PA15", "PA16";
allwinner,function = "gmac";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
gmac_pins_rgmii_a: gmac_rgmii@0 {
@@ -785,90 +860,104 @@
* data lines in RGMII mode use DDR mode
* and need a higher signal drive strength
*/
- allwinner,drive = <3>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
spi0_pins_a: spi0@0 {
allwinner,pins = "PI10", "PI11", "PI12", "PI13", "PI14";
allwinner,function = "spi0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
spi1_pins_a: spi1@0 {
allwinner,pins = "PI16", "PI17", "PI18", "PI19";
allwinner,function = "spi1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
spi2_pins_a: spi2@0 {
allwinner,pins = "PC19", "PC20", "PC21", "PC22";
allwinner,function = "spi2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
spi2_pins_b: spi2@1 {
allwinner,pins = "PB14", "PB15", "PB16", "PB17";
allwinner,function = "spi2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
allwinner,function = "mmc0";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_cd_pin_reference_design: mmc0_cd_pin@0 {
allwinner,pins = "PH1";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
mmc2_pins_a: mmc2@0 {
allwinner,pins = "PC6","PC7","PC8","PC9","PC10","PC11";
allwinner,function = "mmc2";
- allwinner,drive = <2>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
mmc3_pins_a: mmc3@0 {
allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
allwinner,function = "mmc3";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
ir0_pins_a: ir0@0 {
allwinner,pins = "PB3","PB4";
allwinner,function = "ir0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
ir1_pins_a: ir1@0 {
allwinner,pins = "PB22","PB23";
allwinner,function = "ir1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps20_pins_a: ps20@0 {
+ allwinner,pins = "PI20", "PI21";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ ps21_pins_a: ps21@0 {
+ allwinner,pins = "PH12", "PH13";
+ allwinner,function = "ps2";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
timer@01c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0x90>;
- interrupts = <0 22 4>,
- <0 23 4>,
- <0 24 4>,
- <0 25 4>,
- <0 67 4>,
- <0 68 4>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc24M>;
};
@@ -880,7 +969,7 @@
rtc: rtc@01c20d00 {
compatible = "allwinner,sun7i-a20-rtc";
reg = <0x01c20d00 0x20>;
- interrupts = <0 24 4>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
};
pwm: pwm@01c20e00 {
@@ -895,7 +984,7 @@
compatible = "allwinner,sun4i-a10-ir";
clocks = <&apb0_gates 6>, <&ir0_clk>;
clock-names = "apb", "ir";
- interrupts = <0 5 4>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01c21800 0x40>;
status = "disabled";
};
@@ -904,11 +993,18 @@
compatible = "allwinner,sun4i-a10-ir";
clocks = <&apb0_gates 7>, <&ir1_clk>;
clock-names = "apb", "ir";
- interrupts = <0 6 4>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01c21c00 0x40>;
status = "disabled";
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>;
@@ -917,13 +1013,14 @@
rtp: rtp@01c25000 {
compatible = "allwinner,sun4i-a10-ts";
reg = <0x01c25000 0x100>;
- interrupts = <0 29 4>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
};
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
- interrupts = <0 1 4>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 16>;
@@ -933,7 +1030,7 @@
uart1: serial@01c28400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28400 0x400>;
- interrupts = <0 2 4>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 17>;
@@ -943,7 +1040,7 @@
uart2: serial@01c28800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28800 0x400>;
- interrupts = <0 3 4>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 18>;
@@ -953,7 +1050,7 @@
uart3: serial@01c28c00 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28c00 0x400>;
- interrupts = <0 4 4>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 19>;
@@ -963,7 +1060,7 @@
uart4: serial@01c29000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29000 0x400>;
- interrupts = <0 17 4>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 20>;
@@ -973,7 +1070,7 @@
uart5: serial@01c29400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29400 0x400>;
- interrupts = <0 18 4>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 21>;
@@ -983,7 +1080,7 @@
uart6: serial@01c29800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29800 0x400>;
- interrupts = <0 19 4>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 22>;
@@ -993,7 +1090,7 @@
uart7: serial@01c29c00 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29c00 0x400>;
- interrupts = <0 20 4>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 23>;
@@ -1003,7 +1100,7 @@
i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
reg = <0x01c2ac00 0x400>;
- interrupts = <0 7 4>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 0>;
status = "disabled";
#address-cells = <1>;
@@ -1013,7 +1110,7 @@
i2c1: i2c@01c2b000 {
compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
reg = <0x01c2b000 0x400>;
- interrupts = <0 8 4>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 1>;
status = "disabled";
#address-cells = <1>;
@@ -1023,7 +1120,7 @@
i2c2: i2c@01c2b400 {
compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
reg = <0x01c2b400 0x400>;
- interrupts = <0 9 4>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 2>;
status = "disabled";
#address-cells = <1>;
@@ -1033,7 +1130,7 @@
i2c3: i2c@01c2b800 {
compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
reg = <0x01c2b800 0x400>;
- interrupts = <0 88 4>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 3>;
status = "disabled";
#address-cells = <1>;
@@ -1043,7 +1140,7 @@
i2c4: i2c@01c2c000 {
compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c";
reg = <0x01c2c000 0x400>;
- interrupts = <0 89 4>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 15>;
status = "disabled";
#address-cells = <1>;
@@ -1053,7 +1150,7 @@
gmac: ethernet@01c50000 {
compatible = "allwinner,sun7i-a20-gmac";
reg = <0x01c50000 0x10000>;
- interrupts = <0 85 4>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
clocks = <&ahb_gates 49>, <&gmac_tx_clk>;
clock-names = "stmmaceth", "allwinner_gmac_tx";
@@ -1068,10 +1165,10 @@
hstimer@01c60000 {
compatible = "allwinner,sun7i-a20-hstimer";
reg = <0x01c60000 0x1000>;
- interrupts = <0 81 4>,
- <0 82 4>,
- <0 83 4>,
- <0 84 4>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb_gates 28>;
};
@@ -1083,7 +1180,23 @@
<0x01c86000 0x2000>;
interrupt-controller;
#interrupt-cells = <3>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ ps20: ps2@01c2a000 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a000 0x400>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 6>;
+ status = "disabled";
+ };
+
+ ps21: ps2@01c2a400 {
+ compatible = "allwinner,sun4i-a10-ps2";
+ reg = <0x01c2a400 0x400>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&apb1_gates 7>;
+ status = "disabled";
};
};
};
diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
new file mode 100644
index 000000000000..dd31c53e2ab6
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The Ippo Q8H v1.2 is almost identical to the v5, still it needs a separate
+ * dtb file since some gpio-s surrounding the wlan/bluetooth are different,
+ * and it uses different camera sensors.
+ */
+
+#include "sun8i-a23-ippo-q8h-v5.dts"
+
+/ {
+ model = "Ippo Q8H Dual Core Tablet (v1.2)";
+ compatible = "ippo,q8h-v1.2", "allwinner,sun8i-a23";
+};
diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
index 32ad80804dbb..623573e46080 100644
--- a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
+++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
@@ -48,8 +48,12 @@
*/
/dts-v1/;
-/include/ "sun8i-a23.dtsi"
-/include/ "sunxi-common-regulators.dtsi"
+#include "sun8i-a23.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Ippo Q8H Dual Core Tablet (v5)";
@@ -69,7 +73,7 @@
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8h>;
vmmc-supply = <&reg_vcc3v0>;
bus-width = <4>;
- cd-gpios = <&pio 1 4 0>; /* PB4 */
+ cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
cd-inverted;
status = "okay";
};
@@ -78,8 +82,27 @@
mmc0_cd_pin_q8h: mmc0_cd_pin@0 {
allwinner,pins = "PB4";
allwinner,function = "gpio_in";
- allwinner,drive = <0>;
- allwinner,pull = <1>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+ };
+
+ lradc: lradc@01c22800 {
+ vref-supply = <&reg_vcc3v0>;
+ status = "okay";
+
+ button@200 {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ channel = <0>;
+ voltage = <200000>;
+ };
+
+ button@400 {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ channel = <0>;
+ voltage = <400000>;
};
};
diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi
index 86584fcf5e32..dd34527293e4 100644
--- a/arch/arm/boot/dts/sun8i-a23.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23.dtsi
@@ -47,11 +47,29 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
interrupt-parent = <&gic>;
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@0 {
+ compatible = "allwinner,simple-framebuffer",
+ "simple-framebuffer";
+ allwinner,pipeline = "de_be0-lcd0";
+ clocks = <&pll6 0>;
+ status = "disabled";
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -233,7 +251,7 @@
dma: dma-controller@01c02000 {
compatible = "allwinner,sun8i-a23-dma";
reg = <0x01c02000 0x1000>;
- interrupts = <0 50 4>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ahb1_gates 6>;
resets = <&ahb1_rst 6>;
#dma-cells = <1>;
@@ -246,7 +264,7 @@
clock-names = "ahb", "mmc";
resets = <&ahb1_rst 8>;
reset-names = "ahb";
- interrupts = <0 60 4>;
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -257,7 +275,7 @@
clock-names = "ahb", "mmc";
resets = <&ahb1_rst 9>;
reset-names = "ahb";
- interrupts = <0 61 4>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
@@ -268,16 +286,16 @@
clock-names = "ahb", "mmc";
resets = <&ahb1_rst 10>;
reset-names = "ahb";
- interrupts = <0 62 4>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
pio: pinctrl@01c20800 {
compatible = "allwinner,sun8i-a23-pinctrl";
reg = <0x01c20800 0x400>;
- interrupts = <0 11 4>,
- <0 15 4>,
- <0 17 4>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 5>;
gpio-controller;
interrupt-controller;
@@ -288,43 +306,43 @@
uart0_pins_a: uart0@0 {
allwinner,pins = "PF2", "PF4";
allwinner,function = "uart0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
allwinner,function = "mmc0";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc1_pins_a: mmc1@0 {
allwinner,pins = "PG0","PG1","PG2","PG3","PG4","PG5";
allwinner,function = "mmc1";
- allwinner,drive = <2>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PH2", "PH3";
allwinner,function = "i2c0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c1_pins_a: i2c1@0 {
allwinner,pins = "PH4", "PH5";
allwinner,function = "i2c1";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c2_pins_a: i2c2@0 {
allwinner,pins = "PE12", "PE13";
allwinner,function = "i2c2";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
@@ -349,21 +367,28 @@
timer@01c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0xa0>;
- interrupts = <0 18 4>,
- <0 19 4>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc24M>;
};
wdt0: watchdog@01c20ca0 {
compatible = "allwinner,sun6i-a31-wdt";
reg = <0x01c20ca0 0x20>;
- interrupts = <0 25 4>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-a10-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
};
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
- interrupts = <0 0 4>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 16>;
@@ -376,7 +401,7 @@
uart1: serial@01c28400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28400 0x400>;
- interrupts = <0 1 4>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 17>;
@@ -389,7 +414,7 @@
uart2: serial@01c28800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28800 0x400>;
- interrupts = <0 2 4>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 18>;
@@ -402,7 +427,7 @@
uart3: serial@01c28c00 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28c00 0x400>;
- interrupts = <0 3 4>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 19>;
@@ -415,7 +440,7 @@
uart4: serial@01c29000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29000 0x400>;
- interrupts = <0 4 4>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 20>;
@@ -428,7 +453,7 @@
i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2ac00 0x400>;
- interrupts = <0 6 4>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb2_gates 0>;
resets = <&apb2_rst 0>;
status = "disabled";
@@ -439,7 +464,7 @@
i2c1: i2c@01c2b000 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2b000 0x400>;
- interrupts = <0 7 4>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb2_gates 1>;
resets = <&apb2_rst 1>;
status = "disabled";
@@ -450,7 +475,7 @@
i2c2: i2c@01c2b400 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2b400 0x400>;
- interrupts = <0 8 4>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb2_gates 2>;
resets = <&apb2_rst 2>;
status = "disabled";
@@ -466,13 +491,14 @@
<0x01c86000 0x2000>;
interrupt-controller;
#interrupt-cells = <3>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
rtc: rtc@01f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>;
- interrupts = <0 40 4>, <0 41 4>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
prcm@01f01400 {
@@ -522,7 +548,7 @@
r_uart: serial@01f02800 {
compatible = "snps,dw-apb-uart";
reg = <0x01f02800 0x400>;
- interrupts = <0 38 4>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb0_gates 4>;
@@ -533,7 +559,7 @@
r_pio: pinctrl@01f02c00 {
compatible = "allwinner,sun8i-a23-r-pinctrl";
reg = <0x01f02c00 0x400>;
- interrupts = <0 45 4>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 0>;
resets = <&apb0_rst 0>;
gpio-controller;
@@ -545,8 +571,8 @@
r_uart_pins_a: r_uart@0 {
allwinner,pins = "PL2", "PL3";
allwinner,function = "s_uart";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
};
diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index 11ec71072e81..a3fed2bdf620 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -48,7 +48,11 @@
*/
/dts-v1/;
-/include/ "sun9i-a80.dtsi"
+#include "sun9i-a80.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Merrii A80 Optimus Board";
@@ -63,45 +67,6 @@
bootargs = "earlyprintk console=ttyS0,115200";
};
- soc {
- pio: pinctrl@06000800 {
- i2c3_pins_a: i2c3@0 {
- /* Enable internal pull-up */
- allwinner,pull = <1>;
- };
-
- led_pins_optimus: led-pins@0 {
- allwinner,pins = "PH0", "PH1";
- allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
- };
-
- uart4_pins_a: uart4@0 {
- /* Enable internal pull-up */
- allwinner,pull = <1>;
- };
- };
-
- uart0: serial@07000000 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins_a>;
- status = "okay";
- };
-
- uart4: serial@07001000 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart4_pins_a>;
- status = "okay";
- };
-
- i2c3: i2c@07003400 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c3_pins_a>;
- status = "okay";
- };
- };
-
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -111,14 +76,77 @@
led2 {
label = "optimus:led2:usr";
- gpios = <&pio 7 1 0>;
+ gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>;
};
/* led3 is on PM15, in R_PIO */
led4 {
label = "optimus:led4:usr";
- gpios = <&pio 7 0 0>;
+ gpios = <&pio 7 0 GPIO_ACTIVE_HIGH>;
};
};
};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins_a>;
+ status = "okay";
+};
+
+&i2c3_pins_a {
+ /* Enable internal pull-up */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
+
+&pio {
+ led_pins_optimus: led-pins@0 {
+ allwinner,pins = "PH0", "PH1";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_cd_pin_optimus: mmc0_cd_pin@0 {
+ allwinner,pins = "PH18";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>, <&mmc0_cd_pin_optimus>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <4>;
+ cd-gpios = <&pio 7 18 GPIO_ACTIVE_HIGH>; /* PH8 */
+ cd-inverted;
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_8bit_pins>;
+ vmmc-supply = <&reg_vcc3v0>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ status = "okay";
+};
+
+&uart4_pins_a {
+ /* Enable internal pull-up */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+};
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 9ef4438206a9..f0f6fb91f8c3 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -47,7 +47,11 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/include/ "skeleton64.dtsi"
+#include "skeleton64.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
interrupt-parent = <&gic>;
@@ -205,11 +209,50 @@
clock-output-names = "cci400";
};
+ mmc0_clk: clk@06000410 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x06000410 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc0", "mmc0_output",
+ "mmc0_sample";
+ };
+
+ mmc1_clk: clk@06000414 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x06000414 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc1", "mmc1_output",
+ "mmc1_sample";
+ };
+
+ mmc2_clk: clk@06000418 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x06000418 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc2", "mmc2_output",
+ "mmc2_sample";
+ };
+
+ mmc3_clk: clk@0600041c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun9i-a80-mmc-clk";
+ reg = <0x0600041c 0x4>;
+ clocks = <&osc24M>, <&pll4>;
+ clock-output-names = "mmc3", "mmc3_output",
+ "mmc3_sample";
+ };
+
ahb0_gates: clk@06000580 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-ahb0-gates-clk";
reg = <0x06000580 0x4>;
clocks = <&ahb0>;
+ clock-indices = <0>, <1>, <3>, <5>, <8>, <12>, <13>,
+ <14>, <15>, <16>, <18>, <20>, <21>,
+ <22>, <23>;
clock-output-names = "ahb0_fd", "ahb0_ve", "ahb0_gpu",
"ahb0_ss", "ahb0_sd", "ahb0_nand1",
"ahb0_nand0", "ahb0_sdram",
@@ -223,6 +266,7 @@
compatible = "allwinner,sun9i-a80-ahb1-gates-clk";
reg = <0x06000584 0x4>;
clocks = <&ahb1>;
+ clock-indices = <0>, <1>, <17>, <21>, <22>, <23>, <24>;
clock-output-names = "ahb1_usbotg", "ahb1_usbhci",
"ahb1_gmac", "ahb1_msgbox",
"ahb1_spinlock", "ahb1_hstimer",
@@ -234,6 +278,8 @@
compatible = "allwinner,sun9i-a80-ahb2-gates-clk";
reg = <0x06000588 0x4>;
clocks = <&ahb2>;
+ clock-indices = <0>, <1>, <2>, <4>, <5>, <7>, <8>,
+ <11>;
clock-output-names = "ahb2_lcd0", "ahb2_lcd1",
"ahb2_edp", "ahb2_csi", "ahb2_hdmi",
"ahb2_de", "ahb2_mp", "ahb2_mipi_dsi";
@@ -244,6 +290,8 @@
compatible = "allwinner,sun9i-a80-apb0-gates-clk";
reg = <0x06000590 0x4>;
clocks = <&apb0>;
+ clock-indices = <1>, <5>, <11>, <12>, <13>, <15>,
+ <17>, <18>, <19>;
clock-output-names = "apb0_spdif", "apb0_pio",
"apb0_ac97", "apb0_i2s0", "apb0_i2s1",
"apb0_lradc", "apb0_gpadc", "apb0_twd",
@@ -255,6 +303,8 @@
compatible = "allwinner,sun9i-a80-apb1-gates-clk";
reg = <0x06000594 0x4>;
clocks = <&apb1>;
+ clock-indices = <0>, <1>, <2>, <3>, <4>,
+ <16>, <17>, <18>, <19>, <20>, <21>;
clock-output-names = "apb1_i2c0", "apb1_i2c1",
"apb1_i2c2", "apb1_i2c3", "apb1_i2c4",
"apb1_uart0", "apb1_uart1",
@@ -273,6 +323,67 @@
*/
ranges = <0 0 0 0x20000000>;
+ mmc0: mmc@01c0f000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>,
+ <&mmc0_clk 1>, <&mmc0_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 0>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@01c10000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>,
+ <&mmc1_clk 1>, <&mmc1_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 1>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc2: mmc@01c11000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c11000 0x1000>;
+ clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>,
+ <&mmc2_clk 1>, <&mmc2_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 2>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc3: mmc@01c12000 {
+ compatible = "allwinner,sun5i-a13-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>,
+ <&mmc3_clk 1>, <&mmc3_clk 2>;
+ clock-names = "ahb", "mmc", "output", "sample";
+ resets = <&mmc_config_clk 3>;
+ reset-names = "ahb";
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ mmc_config_clk: clk@01c13000 {
+ compatible = "allwinner,sun9i-a80-mmc-config-clk";
+ reg = <0x01c13000 0x10>;
+ clocks = <&ahb0_gates 8>;
+ clock-names = "ahb";
+ resets = <&ahb0_resets 8>;
+ reset-names = "ahb";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ clock-output-names = "mmc0_config", "mmc1_config",
+ "mmc2_config", "mmc3_config";
+ };
+
gic: interrupt-controller@01c41000 {
compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
reg = <0x01c41000 0x1000>,
@@ -281,7 +392,7 @@
<0x01c46000 0x2000>;
interrupt-controller;
#interrupt-cells = <3>;
- interrupts = <1 9 0xf04>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
ahb0_resets: reset@060005a0 {
@@ -317,12 +428,12 @@
timer@06000c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x06000c00 0xa0>;
- interrupts = <0 18 4>,
- <0 19 4>,
- <0 20 4>,
- <0 21 4>,
- <0 22 4>,
- <0 23 4>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc24M>;
};
@@ -330,11 +441,11 @@
pio: pinctrl@06000800 {
compatible = "allwinner,sun9i-a80-pinctrl";
reg = <0x06000800 0x400>;
- interrupts = <0 11 4>,
- <0 15 4>,
- <0 16 4>,
- <0 17 4>,
- <0 120 4>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 5>;
gpio-controller;
interrupt-controller;
@@ -345,29 +456,46 @@
i2c3_pins_a: i2c3@0 {
allwinner,pins = "PG10", "PG11";
allwinner,function = "i2c3";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc0_pins: mmc0 {
+ allwinner,pins = "PF0", "PF1" ,"PF2", "PF3",
+ "PF4", "PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+
+ mmc2_8bit_pins: mmc2_8bit {
+ allwinner,pins = "PC6", "PC7", "PC8", "PC9",
+ "PC10", "PC11", "PC12",
+ "PC13", "PC14", "PC15";
+ allwinner,function = "mmc2";
+ allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart0_pins_a: uart0@0 {
allwinner,pins = "PH12", "PH13";
allwinner,function = "uart0";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart4_pins_a: uart4@0 {
allwinner,pins = "PG12", "PG13", "PG14", "PG15";
allwinner,function = "uart4";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
uart0: serial@07000000 {
compatible = "snps,dw-apb-uart";
reg = <0x07000000 0x400>;
- interrupts = <0 0 4>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 16>;
@@ -378,7 +506,7 @@
uart1: serial@07000400 {
compatible = "snps,dw-apb-uart";
reg = <0x07000400 0x400>;
- interrupts = <0 1 4>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 17>;
@@ -389,7 +517,7 @@
uart2: serial@07000800 {
compatible = "snps,dw-apb-uart";
reg = <0x07000800 0x400>;
- interrupts = <0 2 4>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 18>;
@@ -400,7 +528,7 @@
uart3: serial@07000c00 {
compatible = "snps,dw-apb-uart";
reg = <0x07000c00 0x400>;
- interrupts = <0 3 4>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 19>;
@@ -411,7 +539,7 @@
uart4: serial@07001000 {
compatible = "snps,dw-apb-uart";
reg = <0x07001000 0x400>;
- interrupts = <0 4 4>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 20>;
@@ -422,7 +550,7 @@
uart5: serial@07001400 {
compatible = "snps,dw-apb-uart";
reg = <0x07001400 0x400>;
- interrupts = <0 5 4>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 21>;
@@ -433,7 +561,7 @@
i2c0: i2c@07002800 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07002800 0x400>;
- interrupts = <0 6 4>;
+ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 0>;
resets = <&apb1_resets 0>;
status = "disabled";
@@ -444,7 +572,7 @@
i2c1: i2c@07002c00 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07002c00 0x400>;
- interrupts = <0 7 4>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 1>;
resets = <&apb1_resets 1>;
status = "disabled";
@@ -455,7 +583,7 @@
i2c2: i2c@07003000 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07003000 0x400>;
- interrupts = <0 8 4>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 2>;
resets = <&apb1_resets 2>;
status = "disabled";
@@ -466,7 +594,7 @@
i2c3: i2c@07003400 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07003400 0x400>;
- interrupts = <0 9 4>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 3>;
resets = <&apb1_resets 3>;
status = "disabled";
@@ -477,7 +605,7 @@
i2c4: i2c@07003800 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07003800 0x400>;
- interrupts = <0 10 4>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 4>;
resets = <&apb1_resets 4>;
status = "disabled";
@@ -488,13 +616,13 @@
r_wdt: watchdog@08001000 {
compatible = "allwinner,sun6i-a31-wdt";
reg = <0x08001000 0x20>;
- interrupts = <0 36 4>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
};
r_uart: serial@08002800 {
compatible = "snps,dw-apb-uart";
reg = <0x08002800 0x400>;
- interrupts = <0 38 4>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&osc24M>;
diff --git a/arch/arm/boot/dts/sunxi-common-regulators.dtsi b/arch/arm/boot/dts/sunxi-common-regulators.dtsi
index d8876634f965..e02baa66b33c 100644
--- a/arch/arm/boot/dts/sunxi-common-regulators.dtsi
+++ b/arch/arm/boot/dts/sunxi-common-regulators.dtsi
@@ -47,39 +47,40 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/ {
- soc@01c00000 {
- pio: pinctrl@01c20800 {
- ahci_pwr_pin_a: ahci_pwr_pin@0 {
- allwinner,pins = "PB8";
- allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
- };
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
- usb0_vbus_pin_a: usb0_vbus_pin@0 {
- allwinner,pins = "PB9";
- allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
- };
+&pio {
+ ahci_pwr_pin_a: ahci_pwr_pin@0 {
+ allwinner,pins = "PB8";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
- usb1_vbus_pin_a: usb1_vbus_pin@0 {
- allwinner,pins = "PH6";
- allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
- };
+ usb0_vbus_pin_a: usb0_vbus_pin@0 {
+ allwinner,pins = "PB9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
- usb2_vbus_pin_a: usb2_vbus_pin@0 {
- allwinner,pins = "PH3";
- allwinner,function = "gpio_out";
- allwinner,drive = <0>;
- allwinner,pull = <0>;
- };
- };
+ usb1_vbus_pin_a: usb1_vbus_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+ usb2_vbus_pin_a: usb2_vbus_pin@0 {
+ allwinner,pins = "PH3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+ };
+};
+
+/ {
reg_ahci_5v: ahci-5v {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -89,7 +90,7 @@
regulator-max-microvolt = <5000000>;
regulator-boot-on;
enable-active-high;
- gpio = <&pio 1 8 0>;
+ gpio = <&pio 1 8 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
@@ -101,7 +102,7 @@
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
- gpio = <&pio 1 9 0>;
+ gpio = <&pio 1 9 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
@@ -113,7 +114,7 @@
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
- gpio = <&pio 7 6 0>;
+ gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
@@ -125,7 +126,7 @@
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
- gpio = <&pio 7 3 0>;
+ gpio = <&pio 7 3 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
index 4eb540be368f..dbfaba09703a 100644
--- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
@@ -1673,6 +1673,13 @@
nvidia,core-pwr-off-time = <61036>;
nvidia,core-power-req-active-high;
nvidia,sys-clock-req-active-high;
+
+ i2c-thermtrip {
+ nvidia,i2c-controller-id = <4>;
+ nvidia,bus-addr = <0x40>;
+ nvidia,reg-addr = <0x36>;
+ nvidia,reg-data = <0x2>;
+ };
};
/* Serial ATA */
diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts
index 53181d310247..004e8e4e1c04 100644
--- a/arch/arm/boot/dts/tegra124-nyan-big.dts
+++ b/arch/arm/boot/dts/tegra124-nyan-big.dts
@@ -1131,6 +1131,8 @@
clock-names = "pll_a", "pll_a_out0", "mclk";
nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(I, 7) GPIO_ACTIVE_HIGH>;
+ nvidia,mic-det-gpios =
+ <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 8acf5d85c99d..e5527f742696 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -68,9 +68,9 @@
reset-names = "2d";
};
- gr3d@54140000 {
+ gr3d@54180000 {
compatible = "nvidia,tegra20-gr3d";
- reg = <0x54140000 0x00040000>;
+ reg = <0x54180000 0x00040000>;
clocks = <&tegra_car TEGRA20_CLK_GR3D>;
resets = <&tegra_car 24>;
reset-names = "3d";
@@ -130,9 +130,9 @@
status = "disabled";
};
- dsi@542c0000 {
+ dsi@54300000 {
compatible = "nvidia,tegra20-dsi";
- reg = <0x542c0000 0x00040000>;
+ reg = <0x54300000 0x00040000>;
clocks = <&tegra_car TEGRA20_CLK_DSI>;
resets = <&tegra_car 48>;
reset-names = "dsi";
@@ -140,7 +140,7 @@
};
};
- timer@50004600 {
+ timer@50040600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0x50040600 0x20>;
interrupts = <GIC_PPI 13
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index cbf5a1ae0ca7..a1b682ea01bd 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -189,7 +189,7 @@
/* ALS and Proximity sensor */
isl29028@44 {
- compatible = "isl,isl29028";
+ compatible = "isil,isl29028";
reg = <0x44>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(L, 0) IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 99475f6e76a3..db4810df142c 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -225,7 +225,7 @@
};
};
- timer@50004600 {
+ timer@50040600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0x50040600 0x20>;
interrupts = <GIC_PPI 13
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
index 27d0d9c8adf3..01f40197ea13 100644
--- a/arch/arm/boot/dts/versatile-ab.dts
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -252,6 +252,11 @@
#size-cells = <1>;
ranges = <0 0x10000000 0x10000>;
+ sysreg@0 {
+ compatible = "arm,versatile-sysreg", "syscon";
+ reg = <0x00000 0x1000>;
+ };
+
aaci@4000 {
compatible = "arm,primecell";
reg = <0x4000 0x1000>;
diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
index 56a452bc326c..36cafbfa1bfa 100644
--- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
@@ -35,7 +35,7 @@
regulator-name = "usbh_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
- gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_LOW>;
vin-supply = <&sys_5v0_reg>;
};
};
diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index 82f5728be5c9..5c2b7320856d 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -31,7 +31,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc1>;
bus-width = <4>;
- cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+ cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
&fec1 {
@@ -121,6 +121,7 @@
pinctrl_fec1: fec1grp {
fsl,pins = <
+ VF610_PAD_PTA6__RMII_CLKOUT 0x30d2
VF610_PAD_PTC9__ENET_RMII1_MDC 0x30d2
VF610_PAD_PTC10__ENET_RMII1_MDIO 0x30d3
VF610_PAD_PTC11__ENET_RMII1_CRS 0x30d1
diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi
index de6700542714..1dbf8d2d1ddf 100644
--- a/arch/arm/boot/dts/vf500.dtsi
+++ b/arch/arm/boot/dts/vf500.dtsi
@@ -94,23 +94,23 @@
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
};
-&gpio1 {
+&gpio0 {
interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
};
-&gpio2 {
+&gpio1 {
interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
};
-&gpio3 {
+&gpio2 {
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
};
-&gpio4 {
+&gpio3 {
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
};
-&gpio5 {
+&gpio4 {
interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -130,6 +130,14 @@
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
};
+&snvsrtc {
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&src {
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+};
+
&uart0 {
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
};
@@ -169,3 +177,8 @@
&usbphy1 {
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
};
+
+&wdoga5 {
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index f2b64b1b00fa..f64fddce3e2a 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -123,7 +123,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc1>;
bus-width = <4>;
- cd-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>;
+ cd-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 505969ae8093..a29c7ce15eaf 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -22,11 +22,11 @@
serial3 = &uart3;
serial4 = &uart4;
serial5 = &uart5;
- gpio0 = &gpio1;
- gpio1 = &gpio2;
- gpio2 = &gpio3;
- gpio3 = &gpio4;
- gpio4 = &gpio5;
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
usbphy0 = &usbphy0;
usbphy1 = &usbphy1;
};
@@ -43,6 +43,13 @@
clock-frequency = <32768>;
};
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&src>;
+ offset = <0x0>;
+ mask = <0x1000>;
+ };
+
soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -184,7 +191,7 @@
status = "disabled";
};
- wdog@4003e000 {
+ wdoga5: wdog@4003e000 {
compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
reg = <0x4003e000 0x1000>;
clocks = <&clks VF610_CLK_WDT>;
@@ -209,7 +216,7 @@
#gpio-range-cells = <3>;
};
- gpio1: gpio@40049000 {
+ gpio0: gpio@40049000 {
compatible = "fsl,vf610-gpio";
reg = <0x40049000 0x1000 0x400ff000 0x40>;
gpio-controller;
@@ -219,7 +226,7 @@
gpio-ranges = <&iomuxc 0 0 32>;
};
- gpio2: gpio@4004a000 {
+ gpio1: gpio@4004a000 {
compatible = "fsl,vf610-gpio";
reg = <0x4004a000 0x1000 0x400ff040 0x40>;
gpio-controller;
@@ -229,7 +236,7 @@
gpio-ranges = <&iomuxc 0 32 32>;
};
- gpio3: gpio@4004b000 {
+ gpio2: gpio@4004b000 {
compatible = "fsl,vf610-gpio";
reg = <0x4004b000 0x1000 0x400ff080 0x40>;
gpio-controller;
@@ -239,7 +246,7 @@
gpio-ranges = <&iomuxc 0 64 32>;
};
- gpio4: gpio@4004c000 {
+ gpio3: gpio@4004c000 {
compatible = "fsl,vf610-gpio";
reg = <0x4004c000 0x1000 0x400ff0c0 0x40>;
gpio-controller;
@@ -249,7 +256,7 @@
gpio-ranges = <&iomuxc 0 96 32>;
};
- gpio5: gpio@4004d000 {
+ gpio4: gpio@4004d000 {
compatible = "fsl,vf610-gpio";
reg = <0x4004d000 0x1000 0x400ff100 0x40>;
gpio-controller;
@@ -318,6 +325,11 @@
clocks = <&clks VF610_CLK_USBC0>;
status = "disabled";
};
+
+ src: src@4006e000 {
+ compatible = "fsl,vf610-src", "syscon";
+ reg = <0x4006e000 0x1000>;
+ };
};
aips1: aips-bus@40080000 {
@@ -339,6 +351,20 @@
status = "disabled";
};
+ snvs0: snvs@400a7000 {
+ compatible = "fsl,sec-v4.0-mon", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x400a7000 0x2000>;
+
+ snvsrtc: snvs-rtc-lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ clocks = <&clks VF610_CLK_SNVS>;
+ clock-names = "snvs-rtc";
+ };
+ };
+
uart4: serial@400a9000 {
compatible = "fsl,vf610-lpuart";
reg = <0x400a9000 0x1000>;
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index ee3e5d675b05..a5cd2eda3edf 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -237,7 +237,7 @@
slcr: slcr@f8000000 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "xlnx,zynq-slcr", "syscon";
+ compatible = "xlnx,zynq-slcr", "syscon", "simple-bus";
reg = <0xF8000000 0x1000>;
ranges;
clkc: clkc@100 {
@@ -257,6 +257,12 @@
"dbg_trc", "dbg_apb";
reg = <0x100 0x100>;
};
+
+ pinctrl0: pinctrl@700 {
+ compatible = "xlnx,pinctrl-zynq";
+ reg = <0x700 0x200>;
+ syscon = <&slcr>;
+ };
};
dmac_s: dmac@f8003000 {
@@ -314,14 +320,32 @@
clocks = <&clkc 4>;
};
+ usb0: usb@e0002000 {
+ compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
+ status = "disabled";
+ clocks = <&clkc 28>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 21 4>;
+ reg = <0xe0002000 0x1000>;
+ phy_type = "ulpi";
+ };
+
+ usb1: usb@e0003000 {
+ compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
+ status = "disabled";
+ clocks = <&clkc 29>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 44 4>;
+ reg = <0xe0003000 0x1000>;
+ phy_type = "ulpi";
+ };
+
watchdog0: watchdog@f8005000 {
clocks = <&clkc 45>;
- compatible = "xlnx,zynq-wdt-r1p2";
- device_type = "watchdog";
+ compatible = "cdns,wdt-r1p2";
interrupt-parent = <&intc>;
interrupts = <0 9 1>;
reg = <0xf8005000 0x1000>;
- reset = <0>;
timeout-sec = <10>;
};
};
diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts
index ab1dc0a56cdd..174571232ea5 100644
--- a/arch/arm/boot/dts/zynq-parallella.dts
+++ b/arch/arm/boot/dts/zynq-parallella.dts
@@ -58,7 +58,7 @@
status = "okay";
isl9305: isl9305@68 {
- compatible = "isl,isl9305";
+ compatible = "isil,isl9305";
reg = <0x68>;
regulators {
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index 280f02dd4ddc..1fc1d3911e9b 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -18,6 +18,12 @@
model = "Zynq ZC702 Development Board";
compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
+ aliases {
+ ethernet0 = &gem0;
+ i2c0 = &i2c0;
+ serial0 = &uart1;
+ };
+
memory {
device_type = "memory";
reg = <0x0 0x40000000>;
@@ -36,10 +42,17 @@
linux,default-trigger = "heartbeat";
};
};
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
};
&can0 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_default>;
};
&clkc {
@@ -50,15 +63,24 @@
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <&ethernet_phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gem0_default>;
ethernet_phy: ethernet-phy@7 {
reg = <7>;
};
};
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
&i2c0 {
status = "okay";
clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
i2cswitch@74 {
compatible = "nxp,pca9548";
@@ -132,10 +154,212 @@
};
};
+&pinctrl0 {
+ pinctrl_can0_default: can0-default {
+ mux {
+ function = "can0";
+ groups = "can0_9_grp";
+ };
+
+ conf {
+ groups = "can0_9_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO46";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO47";
+ bias-disable;
+ };
+ };
+
+ pinctrl_gem0_default: gem0-default {
+ mux {
+ function = "ethernet0";
+ groups = "ethernet0_0_grp";
+ };
+
+ conf {
+ groups = "ethernet0_0_grp";
+ slew-rate = <0>;
+ io-standard = <4>;
+ };
+
+ conf-rx {
+ pins = "MIO22", "MIO23", "MIO24", "MIO25", "MIO26", "MIO27";
+ bias-high-impedance;
+ low-power-disable;
+ };
+
+ conf-tx {
+ pins = "MIO16", "MIO17", "MIO18", "MIO19", "MIO20", "MIO21";
+ bias-disable;
+ low-power-enable;
+ };
+
+ mux-mdio {
+ function = "mdio0";
+ groups = "mdio0_0_grp";
+ };
+
+ conf-mdio {
+ groups = "mdio0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
+ "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
+ "gpio0_13_grp", "gpio0_14_grp";
+ };
+
+ conf {
+ groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
+ "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
+ "gpio0_13_grp", "gpio0_14_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-pull-up {
+ pins = "MIO9", "MIO10", "MIO11", "MIO12", "MIO13", "MIO14";
+ bias-pull-up;
+ };
+
+ conf-pull-none {
+ pins = "MIO7", "MIO8";
+ bias-disable;
+ };
+ };
+
+ pinctrl_i2c0_default: i2c0-default {
+ mux {
+ groups = "i2c0_10_grp";
+ function = "i2c0";
+ };
+
+ conf {
+ groups = "i2c0_10_grp";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+
+ mux-cd {
+ groups = "gpio0_0_grp";
+ function = "sdio0_cd";
+ };
+
+ conf-cd {
+ groups = "gpio0_0_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ mux-wp {
+ groups = "gpio0_15_grp";
+ function = "sdio0_wp";
+ };
+
+ conf-wp {
+ groups = "gpio0_15_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+
+ pinctrl_usb0_default: usb0-default {
+ mux {
+ groups = "usb0_0_grp";
+ function = "usb0";
+ };
+
+ conf {
+ groups = "usb0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO29", "MIO31", "MIO36";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO28", "MIO30", "MIO32", "MIO33", "MIO34",
+ "MIO35", "MIO37", "MIO38", "MIO39";
+ bias-disable;
+ };
+ };
+};
+
&sdhci0 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
};
&uart1 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_default>;
};
diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts
index 34f7812d2ee8..850518d9b8ac 100644
--- a/arch/arm/boot/dts/zynq-zc706.dts
+++ b/arch/arm/boot/dts/zynq-zc706.dts
@@ -18,6 +18,12 @@
model = "Zynq ZC706 Development Board";
compatible = "xlnx,zynq-zc706", "xlnx,zynq-7000";
+ aliases {
+ ethernet0 = &gem0;
+ i2c0 = &i2c0;
+ serial0 = &uart1;
+ };
+
memory {
device_type = "memory";
reg = <0x0 0x40000000>;
@@ -27,6 +33,10 @@
bootargs = "console=ttyPS0,115200 earlyprintk";
};
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
};
&clkc {
@@ -37,15 +47,24 @@
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <&ethernet_phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gem0_default>;
ethernet_phy: ethernet-phy@7 {
reg = <7>;
};
};
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
&i2c0 {
status = "okay";
clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
i2cswitch@74 {
compatible = "nxp,pca9548";
@@ -111,10 +130,185 @@
};
};
+&pinctrl0 {
+ pinctrl_gem0_default: gem0-default {
+ mux {
+ function = "ethernet0";
+ groups = "ethernet0_0_grp";
+ };
+
+ conf {
+ groups = "ethernet0_0_grp";
+ slew-rate = <0>;
+ io-standard = <4>;
+ };
+
+ conf-rx {
+ pins = "MIO22", "MIO23", "MIO24", "MIO25", "MIO26", "MIO27";
+ bias-high-impedance;
+ low-power-disable;
+ };
+
+ conf-tx {
+ pins = "MIO16", "MIO17", "MIO18", "MIO19", "MIO20", "MIO21";
+ low-power-enable;
+ bias-disable;
+ };
+
+ mux-mdio {
+ function = "mdio0";
+ groups = "mdio0_0_grp";
+ };
+
+ conf-mdio {
+ groups = "mdio0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
+ };
+
+ conf {
+ groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-pull-up {
+ pins = "MIO46", "MIO47";
+ bias-pull-up;
+ };
+
+ conf-pull-none {
+ pins = "MIO7";
+ bias-disable;
+ };
+ };
+
+ pinctrl_i2c0_default: i2c0-default {
+ mux {
+ groups = "i2c0_10_grp";
+ function = "i2c0";
+ };
+
+ conf {
+ groups = "i2c0_10_grp";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+
+ mux-cd {
+ groups = "gpio0_14_grp";
+ function = "sdio0_cd";
+ };
+
+ conf-cd {
+ groups = "gpio0_14_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ mux-wp {
+ groups = "gpio0_15_grp";
+ function = "sdio0_wp";
+ };
+
+ conf-wp {
+ groups = "gpio0_15_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+
+ pinctrl_usb0_default: usb0-default {
+ mux {
+ groups = "usb0_0_grp";
+ function = "usb0";
+ };
+
+ conf {
+ groups = "usb0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO29", "MIO31", "MIO36";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO28", "MIO30", "MIO32", "MIO33", "MIO34",
+ "MIO35", "MIO37", "MIO38", "MIO39";
+ bias-disable;
+ };
+ };
+};
+
&sdhci0 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
};
&uart1 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_default>;
};
diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts
index 1c7cc990b47a..5658bc8434de 100644
--- a/arch/arm/boot/dts/zynq-zed.dts
+++ b/arch/arm/boot/dts/zynq-zed.dts
@@ -18,6 +18,11 @@
model = "Zynq Zed Development Board";
compatible = "xlnx,zynq-zed", "xlnx,zynq-7000";
+ aliases {
+ ethernet0 = &gem0;
+ serial0 = &uart1;
+ };
+
memory {
device_type = "memory";
reg = <0x0 0x20000000>;
@@ -27,6 +32,10 @@
bootargs = "console=ttyPS0,115200 earlyprintk";
};
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
};
&clkc {
@@ -50,3 +59,9 @@
&uart1 {
status = "okay";
};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+};
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index a67375f24b21..f2670f638e97 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -15,15 +15,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_AT91=y
CONFIG_SOC_AT91RM9200=y
-CONFIG_SOC_AT91SAM9260=y
-CONFIG_SOC_AT91SAM9261=y
-CONFIG_SOC_AT91SAM9263=y
-CONFIG_SOC_AT91SAM9RL=y
-CONFIG_SOC_AT91SAM9G45=y
-CONFIG_SOC_AT91SAM9X5=y
-CONFIG_SOC_AT91SAM9N12=y
-CONFIG_MACH_AT91RM9200_DT=y
-CONFIG_MACH_AT91SAM9_DT=y
+CONFIG_SOC_AT91SAM9=y
CONFIG_AT91_TIMER_HZ=128
CONFIG_AEABI=y
CONFIG_UACCESS_WITH_MEMCPY=y
diff --git a/arch/arm/configs/efm32_defconfig b/arch/arm/configs/efm32_defconfig
index f59fffb3d0c6..c4c17e3a8e1a 100644
--- a/arch/arm/configs/efm32_defconfig
+++ b/arch/arm/configs/efm32_defconfig
@@ -17,7 +17,6 @@ CONFIG_EMBEDDED=y
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_MMU is not set
CONFIG_ARCH_EFM32=y
-# CONFIG_KUSER_HELPERS is not set
CONFIG_SET_MEM_PARAM=y
CONFIG_DRAM_BASE=0x88000000
CONFIG_DRAM_SIZE=0x00400000
@@ -49,7 +48,6 @@ CONFIG_MTD=y
CONFIG_MTD_BLOCK_RO=y
CONFIG_MTD_ROM=y
CONFIG_MTD_UCLINUX=y
-CONFIG_PROC_DEVICETREE=y
# CONFIG_BLK_DEV is not set
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_ARC is not set
@@ -78,6 +76,9 @@ CONFIG_SERIAL_NONSTANDARD=y
CONFIG_SERIAL_EFM32_UART=y
CONFIG_SERIAL_EFM32_UART_CONSOLE=y
# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_EFM32=y
CONFIG_SPI=y
CONFIG_SPI_EFM32=y
CONFIG_GPIO_SYSFS=y
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 3d0c5d65c741..1d8935359fd0 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -1,4 +1,5 @@
CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_CGROUPS=y
@@ -83,6 +84,10 @@ CONFIG_I2C_S3C2410=y
CONFIG_DEBUG_GPIO=y
CONFIG_POWER_SUPPLY=y
CONFIG_BATTERY_SBS=y
+CONFIG_BATTERY_MAX17040=y
+CONFIG_BATTERY_MAX17042=y
+CONFIG_CHARGER_MAX14577=y
+CONFIG_CHARGER_MAX77693=y
CONFIG_CHARGER_TPS65090=y
CONFIG_HWMON=y
CONFIG_SENSORS_LM90=y
@@ -94,6 +99,7 @@ CONFIG_S3C2410_WATCHDOG=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_I2C=y
CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_MAX14577=y
CONFIG_MFD_MAX77686=y
CONFIG_MFD_MAX77693=y
CONFIG_MFD_MAX8997=y
@@ -102,6 +108,7 @@ CONFIG_MFD_TPS65090=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX14577=y
CONFIG_REGULATOR_MAX8997=y
CONFIG_REGULATOR_MAX77686=y
CONFIG_REGULATOR_MAX77802=y
@@ -168,6 +175,9 @@ CONFIG_COMMON_CLK_MAX77686=y
CONFIG_COMMON_CLK_MAX77802=y
CONFIG_COMMON_CLK_S2MPS11=y
CONFIG_EXYNOS_IOMMU=y
+CONFIG_EXTCON=y
+CONFIG_EXTCON_MAX14577=y
+CONFIG_EXTCON_MAX77693=y
CONFIG_IIO=y
CONFIG_EXYNOS_ADC=y
CONFIG_PWM=y
@@ -198,6 +208,7 @@ CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
+CONFIG_LOCKUP_DETECTOR=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_SHA256=y
diff --git a/arch/arm/configs/hisi_defconfig b/arch/arm/configs/hisi_defconfig
index 112543665dd7..c34da5878b6c 100644
--- a/arch/arm/configs/hisi_defconfig
+++ b/arch/arm/configs/hisi_defconfig
@@ -8,6 +8,7 @@ CONFIG_ARCH_HI3xxx=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_CMDLINE_PARTITION=y
CONFIG_ARCH_HIX5HD2=y
+CONFIG_ARCH_HIP01=y
CONFIG_ARCH_HIP04=y
CONFIG_SMP=y
CONFIG_NR_CPUS=16
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 7c2075a07eba..cf1e71e2f60a 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -97,6 +97,7 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_GPMI_NAND=y
CONFIG_MTD_NAND_MXC=y
CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_FSL_QUADSPI=y
CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
@@ -129,6 +130,11 @@ CONFIG_SMC911X=y
CONFIG_SMSC911X=y
# CONFIG_NET_VENDOR_STMICRO is not set
CONFIG_AT803X_PHY=y
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_CDC_EEM=m
CONFIG_BRCMFMAC=m
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_EVDEV=y
@@ -163,13 +169,14 @@ CONFIG_SPI_IMX=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_MC9S08DZ60=y
CONFIG_GPIO_STMPE=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_IMX=y
+CONFIG_POWER_RESET_SYSCON=y
CONFIG_SENSORS_GPIO_FAN=y
CONFIG_THERMAL=y
CONFIG_CPU_THERMAL=y
CONFIG_IMX_THERMAL=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_IMX=y
CONFIG_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_MFD_DA9052_I2C=y
@@ -189,6 +196,8 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_RC_SUPPORT=y
CONFIG_RC_DEVICES=y
CONFIG_IR_GPIO_CIR=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SOC_CAMERA=y
CONFIG_VIDEO_MX3=y
@@ -198,16 +207,17 @@ CONFIG_SOC_CAMERA_OV2640=y
CONFIG_IMX_IPUV3_CORE=y
CONFIG_DRM=y
CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_L4F00242T03=y
CONFIG_LCD_PLATFORM=y
+CONFIG_FB_MXS=y
CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_GPIO=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=m
CONFIG_SND_SOC=y
CONFIG_SND_SOC_FSL_SAI=y
CONFIG_SND_IMX_SOC=y
@@ -226,11 +236,32 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_EHSET_TEST_FIXTURE=m
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_MXS_PHY=y
CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index a2067cbfe173..f8a1c8f2c7c4 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -201,3 +201,4 @@ CONFIG_KEYSTONE_IRQ=y
CONFIG_GPIO_SYSCON=y
CONFIG_TI_DAVINCI_MDIO=y
CONFIG_MARVELL_PHY=y
+CONFIG_DEVTMPFS=y
diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
index 5d63fc5d2d48..23e8d146dc16 100644
--- a/arch/arm/configs/kzm9g_defconfig
+++ b/arch/arm/configs/kzm9g_defconfig
@@ -126,8 +126,8 @@ CONFIG_DMADEVICES=y
CONFIG_SH_DMAE=y
CONFIG_ASYNC_TX_DMA=y
CONFIG_STAGING=y
-CONFIG_SENSORS_AK8975=y
CONFIG_IIO=y
+CONFIG_AK8975=y
# CONFIG_DNOTIFY is not set
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm/configs/lager_defconfig b/arch/arm/configs/lager_defconfig
deleted file mode 100644
index a82afc916a89..000000000000
--- a/arch/arm/configs/lager_defconfig
+++ /dev/null
@@ -1,150 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_NO_HZ=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_EMBEDDED=y
-CONFIG_PERF_EVENTS=y
-CONFIG_SLAB=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE_LEGACY=y
-CONFIG_ARCH_R8A7790=y
-CONFIG_MACH_LAGER=y
-# CONFIG_SH_TIMER_TMU is not set
-# CONFIG_EM_TIMER_STI is not set
-CONFIG_ARM_ERRATA_430973=y
-CONFIG_ARM_ERRATA_458693=y
-CONFIG_ARM_ERRATA_460075=y
-CONFIG_ARM_ERRATA_743622=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_PCI=y
-CONFIG_PCI_RCAR_GEN2=y
-CONFIG_PCI_RCAR_GEN2_PCIE=y
-CONFIG_HAVE_ARM_ARCH_TIMER=y
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_FORCE_MAX_ZONEORDER=13
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_KEXEC=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_VFP=y
-CONFIG_NEON=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_MTD=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_SATA_RCAR=y
-CONFIG_NETDEVICES=y
-# CONFIG_NET_CORE is not set
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_CADENCE is not set
-# CONFIG_NET_VENDOR_BROADCOM is not set
-# CONFIG_NET_VENDOR_CIRRUS is not set
-# CONFIG_NET_VENDOR_FARADAY is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-CONFIG_SH_ETH=y
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_SMSC is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_VIA is not set
-# CONFIG_NET_VENDOR_WIZNET is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=10
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C_GPIO=y
-CONFIG_I2C_SH_MOBILE=y
-CONFIG_I2C_RCAR=y
-CONFIG_SPI=y
-CONFIG_SPI_RSPI=y
-CONFIG_SPI_SH_MSIOF=y
-CONFIG_GPIO_SH_PFC=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_RCAR=y
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-CONFIG_RCAR_THERMAL=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_DA9210=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_SOC_CAMERA=y
-CONFIG_SOC_CAMERA_PLATFORM=y
-CONFIG_VIDEO_RCAR_VIN=y
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
-CONFIG_VIDEO_ADV7180=y
-CONFIG_DRM=y
-CONFIG_DRM_RCAR_DU=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_RCAR=y
-# CONFIG_USB_SUPPORT is not set
-CONFIG_MMC=y
-CONFIG_MMC_SDHI=y
-CONFIG_MMC_SH_MMCIF=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_RTC_CLASS=y
-CONFIG_DMADEVICES=y
-CONFIG_SH_DMAE=y
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFS_V4_1=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_ARM_UNWIND is not set
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 444685c44055..e8a4c955241b 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -32,6 +32,7 @@ CONFIG_ARCH_HIGHBANK=y
CONFIG_ARCH_HISI=y
CONFIG_ARCH_HI3xxx=y
CONFIG_ARCH_HIX5HD2=y
+CONFIG_ARCH_HIP01=y
CONFIG_ARCH_HIP04=y
CONFIG_ARCH_KEYSTONE=y
CONFIG_ARCH_MESON=y
@@ -60,6 +61,7 @@ CONFIG_MACH_SPEAR1310=y
CONFIG_MACH_SPEAR1340=y
CONFIG_ARCH_STI=y
CONFIG_ARCH_EXYNOS=y
+CONFIG_EXYNOS5420_MCPM=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_SIRF=y
CONFIG_ARCH_TEGRA=y
@@ -78,6 +80,7 @@ CONFIG_ARCH_WM8850=y
CONFIG_ARCH_ZYNQ=y
CONFIG_TRUSTED_FOUNDATIONS=y
CONFIG_PCI=y
+CONFIG_PCI_KEYSTONE=y
CONFIG_PCI_MSI=y
CONFIG_PCI_MVEBU=y
CONFIG_PCI_TEGRA=y
@@ -132,6 +135,7 @@ CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_DAVINCI=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
@@ -189,12 +193,15 @@ CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_TOUCHSCREEN_SUN4I=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_MPU3050=y
+CONFIG_INPUT_AXP20X_PEK=y
CONFIG_SERIO_AMBAKMI=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_MT6577=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_MESON=y
@@ -220,6 +227,7 @@ CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DAVINCI=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
CONFIG_I2C_MUX_PINCTRL=y
@@ -233,6 +241,7 @@ CONFIG_I2C_TEGRA=y
CONFIG_I2C_ST=y
CONFIG_SPI=y
CONFIG_I2C_XILINX=y
+CONFIG_SPI_DAVINCI=y
CONFIG_SPI_CADENCE=y
CONFIG_SPI_OMAP24XX=y
CONFIG_SPI_ORION=y
@@ -251,23 +260,28 @@ CONFIG_PINCTRL_APQ8084=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_DAVINCI=y
CONFIG_GPIO_XILINX=y
CONFIG_GPIO_ZYNQ=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_TWL4030=y
CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_SYSCON=y
CONFIG_GPIO_TPS6586X=y
CONFIG_GPIO_TPS65910=y
CONFIG_BATTERY_SBS=y
CONFIG_CHARGER_TPS65090=y
CONFIG_POWER_RESET_AS3722=y
CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_KEYSTONE=y
CONFIG_POWER_RESET_SUN6I=y
CONFIG_SENSORS_LM90=y
CONFIG_SENSORS_LM95245=y
CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
CONFIG_ARMADA_THERMAL=y
+CONFIG_DAVINCI_WATCHDOG
CONFIG_ST_THERMAL_SYSCFG=y
CONFIG_ST_THERMAL_MEMMAP=y
CONFIG_WATCHDOG=y
@@ -278,6 +292,7 @@ CONFIG_SUNXI_WATCHDOG=y
CONFIG_MESON_WATCHDOG=y
CONFIG_MFD_AS3722=y
CONFIG_MFD_BCM590XX=y
+CONFIG_MFD_AXP20X=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_SPI=y
CONFIG_MFD_MAX77686=y
@@ -290,6 +305,7 @@ CONFIG_MFD_TPS6586X=y
CONFIG_MFD_TPS65910=y
CONFIG_REGULATOR_AB8500=y
CONFIG_REGULATOR_AS3722=y
+CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_BCM590XX=y
CONFIG_REGULATOR_GPIO=y
CONFIG_MFD_SYSCON=y
@@ -347,9 +363,11 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_STI=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_AB8500_USB=y
+CONFIG_KEYSTONE_USB_PHY=y
CONFIG_OMAP_USB3=y
CONFIG_SAMSUNG_USB2PHY=y
CONFIG_SAMSUNG_USB3PHY=y
@@ -445,6 +463,7 @@ CONFIG_MSM_MMCC_8974=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_MEMORY=y
+CONFIG_TI_AEMIF=y
CONFIG_IIO=y
CONFIG_XILINX_XADC=y
CONFIG_AK8975=y
@@ -454,6 +473,7 @@ CONFIG_PWM_VT8500=y
CONFIG_PHY_HIX5HD2_SATA=y
CONFIG_OMAP_USB2=y
CONFIG_TI_PIPE3=y
+CONFIG_PHY_MIPHY28LP=y
CONFIG_PHY_MIPHY365X=y
CONFIG_PHY_STIH41X_USB=y
CONFIG_PHY_STIH407_USB=y
@@ -482,3 +502,4 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_LOCKUP_DETECTOR=y
CONFIG_CRYPTO_DEV_TEGRA_AES=y
CONFIG_CPUFREQ_DT=y
+CONFIG_KEYSTONE_IRQ=y
diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index 2400b9f52403..73673e95f23c 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -26,6 +26,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_CPU_FREQ=y
+CONFIG_CPUFREQ_DT=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_MVEBU_V7_CPUIDLE=y
CONFIG_VFP=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 667d9d52aa01..b7386524c356 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -13,7 +13,6 @@ CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
@@ -103,13 +102,15 @@ CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
CONFIG_OMAP_OCP2SCP=y
-CONFIG_CONNECTOR=y
+CONFIG_CONNECTOR=m
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_OOPS=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_BCH=y
CONFIG_MTD_NAND_OMAP2=y
@@ -122,14 +123,12 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_SENSORS_TSL2550=m
CONFIG_BMP085_I2C=m
-CONFIG_SENSORS_LIS3_I2C=m
CONFIG_SRAM=y
-CONFIG_SCSI=y
+CONFIG_SENSORS_LIS3_I2C=m
CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_ATA=y
CONFIG_SATA_AHCI_PLATFORM=y
-CONFIG_MD=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_ARC is not set
# CONFIG_NET_CADENCE is not set
@@ -149,16 +148,19 @@ CONFIG_KS8851_MLL=y
CONFIG_SMC91X=y
CONFIG_SMSC911X=y
# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_TI_DAVINCI_EMAC=y
CONFIG_TI_CPSW=y
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
CONFIG_AT803X_PHY=y
CONFIG_SMSC_PHY=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_SMSC95XX=y
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_EPSON2888=y
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_OHCI_HCD=m
CONFIG_USB_KC2190=y
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
@@ -172,18 +174,24 @@ CONFIG_WLCORE_SDIO=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
CONFIG_MWIFIEX_USB=m
-CONFIG_INPUT_JOYDEV=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+CONFIG_KEYBOARD_ATKBD=m
+CONFIG_KEYBOARD_GPIO=m
CONFIG_KEYBOARD_MATRIX=m
-CONFIG_KEYBOARD_TWL4030=y
+CONFIG_KEYBOARD_OMAP4=m
+CONFIG_KEYBOARD_TWL4030=m
+# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ADS7846=m
CONFIG_TOUCHSCREEN_EDT_FT5X06=m
CONFIG_TOUCHSCREEN_TSC2005=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_INPUT_MISC=y
-CONFIG_INPUT_TWL4030_PWRBUTTON=y
+CONFIG_INPUT_TPS65218_PWRBUTTON=m
+CONFIG_INPUT_TWL4030_PWRBUTTON=m
+CONFIG_INPUT_PALMAS_PWRBUTTON=m
+CONFIG_SERIO=m
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
@@ -196,15 +204,18 @@ CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_OMAP=y
CONFIG_SERIAL_OMAP_CONSOLE=y
-CONFIG_HW_RANDOM=y
CONFIG_I2C_CHARDEV=y
CONFIG_SPI=y
CONFIG_SPI_OMAP24XX=y
+CONFIG_SPI_TI_QSPI=m
CONFIG_PINCTRL_SINGLE=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCF857X=m
CONFIG_GPIO_TWL4030=y
-CONFIG_W1=y
+CONFIG_GPIO_PALMAS=y
+CONFIG_W1=m
+CONFIG_HDQ_MASTER_OMAP=m
CONFIG_BATTERY_BQ27x00=m
CONFIG_CHARGER_ISP1704=m
CONFIG_CHARGER_TWL4030=m
@@ -213,20 +224,22 @@ CONFIG_CHARGER_BQ24190=m
CONFIG_CHARGER_BQ24735=m
CONFIG_POWER_RESET=y
CONFIG_POWER_AVS=y
+CONFIG_HWMON=m
+CONFIG_SENSORS_GPIO_FAN=m
CONFIG_SENSORS_LM75=m
-CONFIG_THERMAL=y
+CONFIG_SENSORS_TMP102=m
+CONFIG_THERMAL=m
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_CPU_THERMAL=y
-CONFIG_TI_SOC_THERMAL=y
+CONFIG_TI_SOC_THERMAL=m
CONFIG_TI_THERMAL=y
CONFIG_OMAP4_THERMAL=y
CONFIG_OMAP5_THERMAL=y
CONFIG_DRA752_THERMAL=y
CONFIG_WATCHDOG=y
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_TWL4030_WATCHDOG=y
-CONFIG_MFD_SYSCON=y
+CONFIG_OMAP_WATCHDOG=m
+CONFIG_TWL4030_WATCHDOG=m
CONFIG_MFD_PALMAS=y
CONFIG_MFD_TPS65217=y
CONFIG_MFD_TPS65218=y
@@ -289,51 +302,79 @@ CONFIG_SND_OMAP_SOC=m
CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
-CONFIG_USB=y
+CONFIG_HID_GENERIC=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB=m
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_MON=y
+CONFIG_USB_MON=m
CONFIG_USB_XHCI_HCD=m
-CONFIG_USB_WDM=y
-CONFIG_USB_STORAGE=y
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_MUSB_HDRC=m
+CONFIG_USB_MUSB_OMAP2PLUS=m
+CONFIG_USB_MUSB_AM35X=m
+CONFIG_USB_MUSB_DSPS=m
CONFIG_USB_DWC3=m
-CONFIG_USB_TEST=y
+CONFIG_USB_TEST=m
CONFIG_AM335X_PHY_USB=y
-CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET=m
CONFIG_USB_GADGET_DEBUG=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC1=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_ZERO=m
CONFIG_MMC=y
CONFIG_SDIO_UART=y
CONFIG_MMC_OMAP=y
CONFIG_MMC_OMAP_HS=y
CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_GPIO=m
CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_ONESHOT=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
CONFIG_LEDS_TRIGGER_CPU=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_PALMAS=m
CONFIG_RTC_DRV_TWL92330=y
-CONFIG_RTC_DRV_TWL4030=y
-CONFIG_RTC_DRV_OMAP=y
+CONFIG_RTC_DRV_TWL4030=m
+CONFIG_RTC_DRV_OMAP=m
CONFIG_DMADEVICES=y
CONFIG_TI_EDMA=y
CONFIG_DMA_OMAP=y
-CONFIG_EXTCON=y
-CONFIG_EXTCON_PALMAS=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXTCON=m
+CONFIG_EXTCON_PALMAS=m
+CONFIG_TI_EMIF=m
CONFIG_PWM=y
-CONFIG_PWM_TIECAP=y
-CONFIG_PWM_TIEHRPWM=y
-CONFIG_PWM_TWL=y
-CONFIG_PWM_TWL_LED=y
-CONFIG_OMAP_USB2=y
-CONFIG_TI_PIPE3=y
+CONFIG_PWM_TIECAP=m
+CONFIG_PWM_TIEHRPWM=m
+CONFIG_PWM_TWL=m
+CONFIG_PWM_TWL_LED=m
+CONFIG_OMAP_USB2=m
+CONFIG_TI_PIPE3=m
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig
index afa24799477a..41d856effe6c 100644
--- a/arch/arm/configs/sama5_defconfig
+++ b/arch/arm/configs/sama5_defconfig
@@ -139,6 +139,12 @@ CONFIG_POWER_RESET=y
CONFIG_SSB=m
CONFIG_REGULATOR=y
CONFIG_REGULATOR_ACT8865=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_VIDEO_ATMEL_ISI=y
CONFIG_FB=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
@@ -202,8 +208,6 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_FTRACE is not set
CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 3df6ca0c1d1f..b17036088726 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -17,9 +17,8 @@ CONFIG_ARCH_R8A7779=y
CONFIG_ARCH_R8A7790=y
CONFIG_ARCH_R8A7791=y
CONFIG_ARCH_R8A7794=y
-CONFIG_MACH_LAGER=y
+CONFIG_ARCH_SH73A0=y
CONFIG_MACH_MARZEN=y
-# CONFIG_SWP_EMULATE is not set
CONFIG_CPU_BPREDICT_DISABLE=y
CONFIG_PL310_ERRATA_588369=y
CONFIG_ARM_ERRATA_754322=y
@@ -36,10 +35,16 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPUFREQ_DT=y
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -49,7 +54,9 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_SIMPLE_PM_BUS=y
CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
CONFIG_EEPROM_AT24=y
@@ -73,11 +80,15 @@ CONFIG_SMSC911X=y
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
CONFIG_SMSC_PHY=y
+CONFIG_MICREL_PHY=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ST1232=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_ADXL34X=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
@@ -86,6 +97,7 @@ CONFIG_SERIAL_8250_EM=y
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=20
CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_I2C_CHARDEV=y
CONFIG_I2C_GPIO=y
CONFIG_I2C_RIIC=y
CONFIG_I2C_SH_MOBILE=y
@@ -96,11 +108,18 @@ CONFIG_SPI_SH_MSIOF=y
CONFIG_SPI_SH_HSPI=y
CONFIG_GPIO_EM=y
CONFIG_GPIO_RCAR=y
+CONFIG_GPIO_PCF857X=y
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
CONFIG_RCAR_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_DA9063_WATCHDOG=y
+CONFIG_MFD_AS3711=y
+CONFIG_MFD_DA9063=y
CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_AS3711=y
+CONFIG_REGULATOR_DA9210=y
CONFIG_REGULATOR_GPIO=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
@@ -116,10 +135,12 @@ CONFIG_VIDEO_RENESAS_VSP1=y
CONFIG_VIDEO_ADV7180=y
CONFIG_DRM=y
CONFIG_DRM_RCAR_DU=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FB_SH_MOBILE_MERAM=y
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_AS3711=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
@@ -130,6 +151,7 @@ CONFIG_SND_SOC_WM8978=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_R8A66597_HCD=y
CONFIG_USB_RENESAS_USBHS=y
CONFIG_USB_RCAR_PHY=y
CONFIG_USB_RCAR_GEN2_PHY=y
@@ -143,18 +165,20 @@ CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RS5C372=y
CONFIG_RTC_DRV_S35390A=y
CONFIG_DMADEVICES=y
CONFIG_SH_DMAE=y
CONFIG_RCAR_DMAC=y
# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_AK8975=y
CONFIG_PWM=y
CONFIG_PWM_RENESAS_TPU=y
# CONFIG_DNOTIFY is not set
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
@@ -166,16 +190,3 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_ARM_UNWIND is not set
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_GOV_COMMON=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_REGULATOR_DA9210=y
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 7a342d2780a8..38840a812924 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -9,6 +9,8 @@ CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPUFREQ_DT=y
CONFIG_VFP=y
CONFIG_NEON=y
CONFIG_PM=y
@@ -54,6 +56,10 @@ CONFIG_STMMAC_ETH=y
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AXP20X_PEK=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SUN4I=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=8
@@ -71,12 +77,14 @@ CONFIG_GPIO_SYSFS=y
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SUN6I=y
-# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_SUNXI_WATCHDOG=y
CONFIG_MFD_AXP20X=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_AXP20X=y
CONFIG_REGULATOR_GPIO=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 3ea9c3377ccb..d199eb249151 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -8,7 +8,6 @@ CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_DEV_INITRD=y
@@ -46,7 +45,6 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
-CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 4767eb9caa78..ce0786efd26c 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -73,7 +73,7 @@ static inline void set_fs(mm_segment_t fs)
modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
}
-#define segment_eq(a,b) ((a) == (b))
+#define segment_eq(a, b) ((a) == (b))
#define __addr_ok(addr) ({ \
unsigned long flag; \
@@ -84,7 +84,7 @@ static inline void set_fs(mm_segment_t fs)
(flag == 0); })
/* We use 33-bit arithmetic here... */
-#define __range_ok(addr,size) ({ \
+#define __range_ok(addr, size) ({ \
unsigned long flag, roksum; \
__chk_user_ptr(addr); \
__asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
@@ -123,7 +123,7 @@ extern int __get_user_64t_4(void *);
#define __GUP_CLOBBER_32t_8 "lr", "cc"
#define __GUP_CLOBBER_8 "lr", "cc"
-#define __get_user_x(__r2,__p,__e,__l,__s) \
+#define __get_user_x(__r2, __p, __e, __l, __s) \
__asm__ __volatile__ ( \
__asmeq("%0", "r0") __asmeq("%1", "r2") \
__asmeq("%3", "r1") \
@@ -134,7 +134,7 @@ extern int __get_user_64t_4(void *);
/* narrowing a double-word get into a single 32bit word register: */
#ifdef __ARMEB__
-#define __get_user_x_32t(__r2, __p, __e, __l, __s) \
+#define __get_user_x_32t(__r2, __p, __e, __l, __s) \
__get_user_x(__r2, __p, __e, __l, 32t_8)
#else
#define __get_user_x_32t __get_user_x
@@ -158,7 +158,7 @@ extern int __get_user_64t_4(void *);
#endif
-#define __get_user_check(x,p) \
+#define __get_user_check(x, p) \
({ \
unsigned long __limit = current_thread_info()->addr_limit - 1; \
register const typeof(*(p)) __user *__p asm("r0") = (p);\
@@ -196,10 +196,10 @@ extern int __get_user_64t_4(void *);
__e; \
})
-#define get_user(x,p) \
+#define get_user(x, p) \
({ \
might_fault(); \
- __get_user_check(x,p); \
+ __get_user_check(x, p); \
})
extern int __put_user_1(void *, unsigned int);
@@ -207,7 +207,7 @@ extern int __put_user_2(void *, unsigned int);
extern int __put_user_4(void *, unsigned int);
extern int __put_user_8(void *, unsigned long long);
-#define __put_user_x(__r2,__p,__e,__l,__s) \
+#define __put_user_x(__r2, __p, __e, __l, __s) \
__asm__ __volatile__ ( \
__asmeq("%0", "r0") __asmeq("%2", "r2") \
__asmeq("%3", "r1") \
@@ -216,7 +216,7 @@ extern int __put_user_8(void *, unsigned long long);
: "0" (__p), "r" (__r2), "r" (__l) \
: "ip", "lr", "cc")
-#define __put_user_check(x,p) \
+#define __put_user_check(x, p) \
({ \
unsigned long __limit = current_thread_info()->addr_limit - 1; \
const typeof(*(p)) __user *__tmp_p = (p); \
@@ -242,10 +242,10 @@ extern int __put_user_8(void *, unsigned long long);
__e; \
})
-#define put_user(x,p) \
+#define put_user(x, p) \
({ \
might_fault(); \
- __put_user_check(x,p); \
+ __put_user_check(x, p); \
})
#else /* CONFIG_MMU */
@@ -255,21 +255,21 @@ extern int __put_user_8(void *, unsigned long long);
*/
#define USER_DS KERNEL_DS
-#define segment_eq(a,b) (1)
-#define __addr_ok(addr) ((void)(addr),1)
-#define __range_ok(addr,size) ((void)(addr),0)
+#define segment_eq(a, b) (1)
+#define __addr_ok(addr) ((void)(addr), 1)
+#define __range_ok(addr, size) ((void)(addr), 0)
#define get_fs() (KERNEL_DS)
static inline void set_fs(mm_segment_t fs)
{
}
-#define get_user(x,p) __get_user(x,p)
-#define put_user(x,p) __put_user(x,p)
+#define get_user(x, p) __get_user(x, p)
+#define put_user(x, p) __put_user(x, p)
#endif /* CONFIG_MMU */
-#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
+#define access_ok(type, addr, size) (__range_ok(addr, size) == 0)
#define user_addr_max() \
(segment_eq(get_fs(), KERNEL_DS) ? ~0UL : get_fs())
@@ -283,35 +283,35 @@ static inline void set_fs(mm_segment_t fs)
* error occurs, and leave it unchanged on success. Note that these
* versions are void (ie, don't return a value as such).
*/
-#define __get_user(x,ptr) \
+#define __get_user(x, ptr) \
({ \
long __gu_err = 0; \
- __get_user_err((x),(ptr),__gu_err); \
+ __get_user_err((x), (ptr), __gu_err); \
__gu_err; \
})
-#define __get_user_error(x,ptr,err) \
+#define __get_user_error(x, ptr, err) \
({ \
- __get_user_err((x),(ptr),err); \
+ __get_user_err((x), (ptr), err); \
(void) 0; \
})
-#define __get_user_err(x,ptr,err) \
+#define __get_user_err(x, ptr, err) \
do { \
unsigned long __gu_addr = (unsigned long)(ptr); \
unsigned long __gu_val; \
__chk_user_ptr(ptr); \
might_fault(); \
switch (sizeof(*(ptr))) { \
- case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
- case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
- case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \
+ case 1: __get_user_asm_byte(__gu_val, __gu_addr, err); break; \
+ case 2: __get_user_asm_half(__gu_val, __gu_addr, err); break; \
+ case 4: __get_user_asm_word(__gu_val, __gu_addr, err); break; \
default: (__gu_val) = __get_user_bad(); \
} \
(x) = (__typeof__(*(ptr)))__gu_val; \
} while (0)
-#define __get_user_asm_byte(x,addr,err) \
+#define __get_user_asm_byte(x, addr, err) \
__asm__ __volatile__( \
"1: " TUSER(ldrb) " %1,[%2],#0\n" \
"2:\n" \
@@ -330,7 +330,7 @@ do { \
: "cc")
#ifndef __ARMEB__
-#define __get_user_asm_half(x,__gu_addr,err) \
+#define __get_user_asm_half(x, __gu_addr, err) \
({ \
unsigned long __b1, __b2; \
__get_user_asm_byte(__b1, __gu_addr, err); \
@@ -338,7 +338,7 @@ do { \
(x) = __b1 | (__b2 << 8); \
})
#else
-#define __get_user_asm_half(x,__gu_addr,err) \
+#define __get_user_asm_half(x, __gu_addr, err) \
({ \
unsigned long __b1, __b2; \
__get_user_asm_byte(__b1, __gu_addr, err); \
@@ -347,7 +347,7 @@ do { \
})
#endif
-#define __get_user_asm_word(x,addr,err) \
+#define __get_user_asm_word(x, addr, err) \
__asm__ __volatile__( \
"1: " TUSER(ldr) " %1,[%2],#0\n" \
"2:\n" \
@@ -365,35 +365,35 @@ do { \
: "r" (addr), "i" (-EFAULT) \
: "cc")
-#define __put_user(x,ptr) \
+#define __put_user(x, ptr) \
({ \
long __pu_err = 0; \
- __put_user_err((x),(ptr),__pu_err); \
+ __put_user_err((x), (ptr), __pu_err); \
__pu_err; \
})
-#define __put_user_error(x,ptr,err) \
+#define __put_user_error(x, ptr, err) \
({ \
- __put_user_err((x),(ptr),err); \
+ __put_user_err((x), (ptr), err); \
(void) 0; \
})
-#define __put_user_err(x,ptr,err) \
+#define __put_user_err(x, ptr, err) \
do { \
unsigned long __pu_addr = (unsigned long)(ptr); \
__typeof__(*(ptr)) __pu_val = (x); \
__chk_user_ptr(ptr); \
might_fault(); \
switch (sizeof(*(ptr))) { \
- case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
- case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
- case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \
- case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \
+ case 1: __put_user_asm_byte(__pu_val, __pu_addr, err); break; \
+ case 2: __put_user_asm_half(__pu_val, __pu_addr, err); break; \
+ case 4: __put_user_asm_word(__pu_val, __pu_addr, err); break; \
+ case 8: __put_user_asm_dword(__pu_val, __pu_addr, err); break; \
default: __put_user_bad(); \
} \
} while (0)
-#define __put_user_asm_byte(x,__pu_addr,err) \
+#define __put_user_asm_byte(x, __pu_addr, err) \
__asm__ __volatile__( \
"1: " TUSER(strb) " %1,[%2],#0\n" \
"2:\n" \
@@ -411,22 +411,22 @@ do { \
: "cc")
#ifndef __ARMEB__
-#define __put_user_asm_half(x,__pu_addr,err) \
+#define __put_user_asm_half(x, __pu_addr, err) \
({ \
- unsigned long __temp = (unsigned long)(x); \
+ unsigned long __temp = (__force unsigned long)(x); \
__put_user_asm_byte(__temp, __pu_addr, err); \
__put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
})
#else
-#define __put_user_asm_half(x,__pu_addr,err) \
+#define __put_user_asm_half(x, __pu_addr, err) \
({ \
- unsigned long __temp = (unsigned long)(x); \
+ unsigned long __temp = (__force unsigned long)(x); \
__put_user_asm_byte(__temp >> 8, __pu_addr, err); \
__put_user_asm_byte(__temp, __pu_addr + 1, err); \
})
#endif
-#define __put_user_asm_word(x,__pu_addr,err) \
+#define __put_user_asm_word(x, __pu_addr, err) \
__asm__ __volatile__( \
"1: " TUSER(str) " %1,[%2],#0\n" \
"2:\n" \
@@ -451,7 +451,7 @@ do { \
#define __reg_oper1 "%R2"
#endif
-#define __put_user_asm_dword(x,__pu_addr,err) \
+#define __put_user_asm_dword(x, __pu_addr, err) \
__asm__ __volatile__( \
ARM( "1: " TUSER(str) " " __reg_oper1 ", [%1], #4\n" ) \
ARM( "2: " TUSER(str) " " __reg_oper0 ", [%1]\n" ) \
@@ -480,9 +480,9 @@ extern unsigned long __must_check __copy_to_user_std(void __user *to, const void
extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n);
#else
-#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0)
-#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0)
-#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0)
+#define __copy_from_user(to, from, n) (memcpy(to, (void __force *)from, n), 0)
+#define __copy_to_user(to, from, n) (memcpy((void __force *)to, from, n), 0)
+#define __clear_user(addr, n) (memset((void __force *)addr, 0, n), 0)
#endif
static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/include/debug/at91.S
index 2103a90f2261..80a6501b4d50 100644
--- a/arch/arm/mach-at91/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/at91.S
@@ -1,6 +1,4 @@
/*
- * arch/arm/mach-at91/include/mach/debug-macro.S
- *
* Copyright (C) 2003-2005 SAN People
*
* Debugging macro include header
@@ -11,18 +9,23 @@
*
*/
-#include <mach/hardware.h>
-#include <mach/at91_dbgu.h>
-
#if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
-#define AT91_DBGU AT91_BASE_DBGU0
+#define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */
#elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
-#define AT91_DBGU AT91_BASE_DBGU1
+#define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */
#else
/* On sama5d4, use USART3 as low level serial console */
-#define AT91_DBGU SAMA5D4_BASE_USART3
+#define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
#endif
+/* Keep in sync with mach-at91/include/mach/hardware.h */
+#define AT91_IO_P2V(x) ((x) - 0x01000000)
+
+#define AT91_DBGU_SR (0x14) /* Status Register */
+#define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */
+#define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */
+#define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */
+
.macro addruart, rp, rv, tmp
ldr \rp, =AT91_DBGU @ System peripherals (phys address)
ldr \rv, =AT91_IO_P2V(AT91_DBGU) @ System peripherals (virt address)
diff --git a/arch/arm/include/debug/digicolor.S b/arch/arm/include/debug/digicolor.S
new file mode 100644
index 000000000000..c9517150766a
--- /dev/null
+++ b/arch/arm/include/debug/digicolor.S
@@ -0,0 +1,35 @@
+/*
+ * Debugging macro include header for Conexant Digicolor USART
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#define UA0_STATUS 0x0742
+#define UA0_EMI_REC 0x0744
+
+#define UA0_STATUS_TX_READY 0x40
+
+#ifdef CONFIG_DEBUG_UART_PHYS
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+#endif
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UA0_EMI_REC]
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldrb \rd, [\rx, #UA0_STATUS]
+ tst \rd, #UA0_STATUS_TX_READY
+ beq 1001b
+ .endm
diff --git a/arch/arm/include/debug/msm.S b/arch/arm/include/debug/msm.S
index 9ef57612811d..e55a9426b496 100644
--- a/arch/arm/include/debug/msm.S
+++ b/arch/arm/include/debug/msm.S
@@ -23,6 +23,7 @@
.endm
.macro senduart, rd, rx
+ARM_BE8(rev \rd, \rd )
#ifdef CONFIG_DEBUG_QCOM_UARTDM
@ Write the 1 character to UARTDM_TF
str \rd, [\rx, #0x70]
@@ -35,24 +36,29 @@
#ifdef CONFIG_DEBUG_QCOM_UARTDM
@ check for TX_EMT in UARTDM_SR
ldr \rd, [\rx, #0x08]
+ARM_BE8(rev \rd, \rd )
tst \rd, #0x08
bne 1002f
@ wait for TXREADY in UARTDM_ISR
1001: ldr \rd, [\rx, #0x14]
+ARM_BE8(rev \rd, \rd )
tst \rd, #0x80
beq 1001b
1002:
@ Clear TX_READY by writing to the UARTDM_CR register
mov \rd, #0x300
+ARM_BE8(rev \rd, \rd )
str \rd, [\rx, #0x10]
@ Write 0x1 to NCF register
mov \rd, #0x1
+ARM_BE8(rev \rd, \rd )
str \rd, [\rx, #0x40]
@ UARTDM reg. Read to induce delay
ldr \rd, [\rx, #0x08]
#else
@ wait for TX_READY
1001: ldr \rd, [\rx, #0x08]
+ARM_BE8(rev \rd, \rd )
tst \rd, #0x04
beq 1001b
#endif
diff --git a/arch/arm/include/debug/sirf.S b/arch/arm/include/debug/sirf.S
index dbf250cf18e6..630f231f2f37 100644
--- a/arch/arm/include/debug/sirf.S
+++ b/arch/arm/include/debug/sirf.S
@@ -6,37 +6,33 @@
* Licensed under GPLv2 or later.
*/
-#if defined(CONFIG_DEBUG_SIRFPRIMA2_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xb0060000
-#elif defined(CONFIG_DEBUG_SIRFMARCO_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xcc060000
-#else
-#define SIRFSOC_UART1_PA_BASE 0
-#endif
+#define SIRF_LLUART_TXFIFO_STATUS 0x0114
+#define SIRF_LLUART_TXFIFO_DATA 0x0118
-#define SIRFSOC_UART1_VA_BASE 0xFEC60000
+#define SIRF_LLUART_TXFIFO_FULL (1 << 5)
-#define SIRFSOC_UART_TXFIFO_STATUS 0x0114
-#define SIRFSOC_UART_TXFIFO_DATA 0x0118
+#ifdef CONFIG_DEBUG_SIRFATLAS7_UART0
+#define SIRF_LLUART_TXFIFO_EMPTY (1 << 8)
+#else
+#define SIRF_LLUART_TXFIFO_EMPTY (1 << 6)
+#endif
-#define SIRFSOC_UART1_TXFIFO_FULL (1 << 5)
-#define SIRFSOC_UART1_TXFIFO_EMPTY (1 << 6)
.macro addruart, rp, rv, tmp
- ldr \rp, =SIRFSOC_UART1_PA_BASE @ physical
- ldr \rv, =SIRFSOC_UART1_VA_BASE @ virtual
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virtual
.endm
.macro senduart,rd,rx
- str \rd, [\rx, #SIRFSOC_UART_TXFIFO_DATA]
+ str \rd, [\rx, #SIRF_LLUART_TXFIFO_DATA]
.endm
.macro busyuart,rd,rx
.endm
.macro waituart,rd,rx
-1001: ldr \rd, [\rx, #SIRFSOC_UART_TXFIFO_STATUS]
- tst \rd, #SIRFSOC_UART1_TXFIFO_EMPTY
+1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS]
+ tst \rd, #SIRF_LLUART_TXFIFO_EMPTY
beq 1001b
.endm
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 2395c68b3e32..c6740e359a44 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -6,15 +6,6 @@ config HAVE_AT91_UTMI
config HAVE_AT91_USB_CLK
bool
-config HAVE_AT91_DBGU0
- bool
-
-config HAVE_AT91_DBGU1
- bool
-
-config HAVE_AT91_DBGU2
- bool
-
config COMMON_CLK_AT91
bool
select COMMON_CLK
@@ -25,15 +16,6 @@ config HAVE_AT91_SMD
config HAVE_AT91_H32MX
bool
-config SOC_AT91SAM9
- bool
- select ATMEL_AIC_IRQ
- select COMMON_CLK_AT91
- select CPU_ARM926T
- select GENERIC_CLOCKEVENTS
- select MEMORY
- select ATMEL_SDRAMC
-
config SOC_SAMA5
bool
select ATMEL_AIC5_IRQ
@@ -70,7 +52,6 @@ config SOC_SAMA5D3
bool "SAMA5D3 family"
select SOC_SAMA5
select HAVE_FB_ATMEL
- select HAVE_AT91_DBGU1
select HAVE_AT91_UTMI
select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
@@ -81,7 +62,6 @@ config SOC_SAMA5D3
config SOC_SAMA5D4
bool "SAMA5D4 family"
select SOC_SAMA5
- select HAVE_AT91_DBGU2
select CLKSRC_MMIO
select CACHE_L2X0
select CACHE_PL310
@@ -101,91 +81,45 @@ config SOC_AT91RM9200
select COMMON_CLK_AT91
select CPU_ARM920T
select GENERIC_CLOCKEVENTS
- select HAVE_AT91_DBGU0
- select HAVE_AT91_USB_CLK
-
-config SOC_AT91SAM9260
- bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
- select HAVE_AT91_DBGU0
- select SOC_AT91SAM9
- select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
- or AT91SAM9G20 SoC.
-
-config SOC_AT91SAM9261
- bool "AT91SAM9261 or AT91SAM9G10"
- select HAVE_AT91_DBGU0
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC.
-
-config SOC_AT91SAM9263
- bool "AT91SAM9263"
- select HAVE_AT91_DBGU1
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
select HAVE_AT91_USB_CLK
-config SOC_AT91SAM9RL
- bool "AT91SAM9RL"
- select HAVE_AT91_DBGU0
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_UTMI
-
-config SOC_AT91SAM9G45
- bool "AT91SAM9G45 or AT91SAM9M10 families"
- select HAVE_AT91_DBGU1
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_UTMI
- select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
- This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11.
-
-config SOC_AT91SAM9X5
- bool "AT91SAM9x5 family"
- select HAVE_AT91_DBGU0
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_UTMI
+config SOC_AT91SAM9
+ bool "AT91SAM9"
+ select ATMEL_AIC_IRQ
+ select ATMEL_SDRAMC
+ select COMMON_CLK_AT91
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
- This means that your SAM9 name finishes with a '5' (except if it is
- AT91SAM9G45!).
- This support covers AT91SAM9G15, AT91SAM9G25, AT91SAM9X25, AT91SAM9G35
- and AT91SAM9X35.
-
-config SOC_AT91SAM9N12
- bool "AT91SAM9N12 family"
- select HAVE_AT91_DBGU0
+ select HAVE_AT91_UTMI
select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_USB_CLK
+ select MEMORY
help
- Select this if you are using Atmel's AT91SAM9N12 SoC.
-
-# ----------------------------------------------------------
+ Select this if you are using one of those Atmel SoC:
+ AT91SAM9260
+ AT91SAM9261
+ AT91SAM9263
+ AT91SAM9G15
+ AT91SAM9G20
+ AT91SAM9G25
+ AT91SAM9G35
+ AT91SAM9G45
+ AT91SAM9G46
+ AT91SAM9M10
+ AT91SAM9M11
+ AT91SAM9N12
+ AT91SAM9RL
+ AT91SAM9X25
+ AT91SAM9X35
+ AT91SAM9XE
endif # SOC_SAM_V4_V5
-config MACH_AT91RM9200_DT
- def_bool SOC_AT91RM9200
-
-config MACH_AT91SAM9_DT
- def_bool SOC_AT91SAM9
-
-# ----------------------------------------------------------
-
comment "AT91 Feature Selections"
config AT91_SLOW_CLOCK
bool "Suspend-to-RAM disables main oscillator"
+ select SRAM
depends on SUSPEND
help
Select this if you want Suspend-to-RAM to save the most power
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 7b6424d40764..827fdbcce1c7 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -2,28 +2,14 @@
# Makefile for the linux kernel.
#
-obj-y := setup.o sysirq_mask.o
+obj-y := setup.o
obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
# CPU-specific support
obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o at91rm9200_time.o
-obj-$(CONFIG_SOC_AT91SAM9260) += at91sam9260.o
-obj-$(CONFIG_SOC_AT91SAM9261) += at91sam9261.o
-obj-$(CONFIG_SOC_AT91SAM9263) += at91sam9263.o
-obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o
-obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o
-obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o
-obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o
-obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o
-obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
-
-# AT91SAM board with device-tree
-obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o
-obj-$(CONFIG_MACH_AT91SAM9_DT) += board-dt-sam9.o
-
-# SAMA5 board with device-tree
-obj-$(CONFIG_SOC_SAMA5) += board-dt-sama5.o
+obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o
+obj-$(CONFIG_SOC_SAMA5) += sama5.o
# Power Management
obj-$(CONFIG_PM) += pm.o
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index b52916947535..8fcfb70f7124 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -1,35 +1,33 @@
/*
- * arch/arm/mach-at91/at91rm9200.c
+ * Setup code for AT91RM9200
*
- * Copyright (C) 2005 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ * 2012 Joachim Eastwood <manabian@gmail.com>
*
+ * Licensed under GPLv2 or later.
*/
+#include <linux/types.h>
+#include <linux/init.h>
#include <linux/module.h>
-#include <linux/clk/at91_pmc.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
#include <asm/system_misc.h>
+
#include <mach/at91_st.h>
-#include <mach/hardware.h>
-#include "soc.h"
#include "generic.h"
-static void at91rm9200_idle(void)
-{
- /*
- * Disable the processor clock. The processor will be automatically
- * re-enabled by an interrupt or by a reset.
- */
- at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-}
-
static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
{
/*
@@ -39,23 +37,31 @@ static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
}
-/* --------------------------------------------------------------------
- * AT91RM9200 processor initialization
- * -------------------------------------------------------------------- */
-static void __init at91rm9200_map_io(void)
+static void __init at91rm9200_dt_timer_init(void)
{
- /* Map peripherals */
- at91_init_sram(0, AT91RM9200_SRAM_BASE, AT91RM9200_SRAM_SIZE);
+ of_clk_init(NULL);
+ at91rm9200_timer_init();
}
-static void __init at91rm9200_initialize(void)
+static void __init at91rm9200_dt_device_init(void)
{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
arm_pm_idle = at91rm9200_idle;
arm_pm_restart = at91rm9200_restart;
+ at91rm9200_pm_init();
}
-AT91_SOC_START(at91rm9200)
- .map_io = at91rm9200_map_io,
- .init = at91rm9200_initialize,
-AT91_SOC_END
+
+static const char *at91rm9200_dt_board_compat[] __initconst = {
+ "atmel,at91rm9200",
+ NULL
+};
+
+DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200")
+ .init_time = at91rm9200_dt_timer_init,
+ .map_io = at91_map_io,
+ .init_machine = at91rm9200_dt_device_init,
+ .dt_compat = at91rm9200_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
new file mode 100644
index 000000000000..56e3ba73ec40
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -0,0 +1,87 @@
+/*
+ * Setup code for AT91SAM9
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+
+#include <asm/system_misc.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "generic.h"
+
+static void __init at91sam9_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ arm_pm_idle = at91sam9_idle;
+ at91sam9260_pm_init();
+}
+
+static const char *at91_dt_board_compat[] __initconst = {
+ "atmel,at91sam9",
+ NULL
+};
+
+DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
+ /* Maintainer: Atmel */
+ .map_io = at91_map_io,
+ .init_machine = at91sam9_dt_device_init,
+ .dt_compat = at91_dt_board_compat,
+MACHINE_END
+
+static void __init at91sam9g45_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ arm_pm_idle = at91sam9_idle;
+ at91sam9g45_pm_init();
+}
+
+static const char *at91sam9g45_board_compat[] __initconst = {
+ "atmel,at91sam9g45",
+ NULL
+};
+
+DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
+ /* Maintainer: Atmel */
+ .map_io = at91_map_io,
+ .init_machine = at91sam9g45_dt_device_init,
+ .dt_compat = at91sam9g45_board_compat,
+MACHINE_END
+
+static void __init at91sam9x5_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ arm_pm_idle = at91sam9_idle;
+ at91sam9x5_pm_init();
+}
+
+static const char *at91sam9x5_board_compat[] __initconst = {
+ "atmel,at91sam9x5",
+ "atmel,at91sam9n12",
+ NULL
+};
+
+DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
+ /* Maintainer: Atmel */
+ .map_io = at91_map_io,
+ .init_machine = at91sam9x5_dt_device_init,
+ .dt_compat = at91sam9x5_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
deleted file mode 100644
index 78137c24d90b..000000000000
--- a/arch/arm/mach-at91/at91sam9260.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9260.c
- *
- * Copyright (C) 2006 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <asm/system_misc.h>
-#include <mach/cpu.h>
-#include <mach/at91_dbgu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9260 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9xe_map_io(void)
-{
- unsigned long sram_size;
-
- switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
- case AT91_CIDR_SRAMSIZ_32K:
- sram_size = 2 * SZ_16K;
- break;
- case AT91_CIDR_SRAMSIZ_16K:
- default:
- sram_size = SZ_16K;
- }
-
- at91_init_sram(0, AT91SAM9XE_SRAM_BASE, sram_size);
-}
-
-static void __init at91sam9260_map_io(void)
-{
- if (cpu_is_at91sam9xe())
- at91sam9xe_map_io();
- else if (cpu_is_at91sam9g20())
- at91_init_sram(0, AT91SAM9G20_SRAM_BASE, AT91SAM9G20_SRAM_SIZE);
- else
- at91_init_sram(0, AT91SAM9260_SRAM_BASE, AT91SAM9260_SRAM_SIZE);
-}
-
-static void __init at91sam9260_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9260)
- .map_io = at91sam9260_map_io,
- .init = at91sam9260_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
deleted file mode 100644
index d29953ecb0c4..000000000000
--- a/arch/arm/mach-at91/at91sam9261.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9261.c
- *
- * Copyright (C) 2005 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <asm/system_misc.h>
-#include <mach/cpu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9261 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9261_map_io(void)
-{
- if (cpu_is_at91sam9g10())
- at91_init_sram(0, AT91SAM9G10_SRAM_BASE, AT91SAM9G10_SRAM_SIZE);
- else
- at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE);
-}
-
-static void __init at91sam9261_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9261)
- .map_io = at91sam9261_map_io,
- .init = at91sam9261_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
deleted file mode 100644
index e7ad14864083..000000000000
--- a/arch/arm/mach-at91/at91sam9263.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9263.c
- *
- * Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <asm/system_misc.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9263 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9263_map_io(void)
-{
- at91_init_sram(0, AT91SAM9263_SRAM0_BASE, AT91SAM9263_SRAM0_SIZE);
- at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE);
-}
-
-static void __init at91sam9263_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
- at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
-}
-
-AT91_SOC_START(at91sam9263)
- .map_io = at91sam9263_map_io,
- .init = at91sam9263_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
deleted file mode 100644
index b6117bea9a6f..000000000000
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Chip-specific setup code for the AT91SAM9G45 family
- *
- * Copyright (C) 2009 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <asm/system_misc.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9G45 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9g45_map_io(void)
-{
- at91_init_sram(0, AT91SAM9G45_SRAM_BASE, AT91SAM9G45_SRAM_SIZE);
-}
-
-static void __init at91sam9g45_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
- at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9g45)
- .map_io = at91sam9g45_map_io,
- .init = at91sam9g45_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
deleted file mode 100644
index dee569b1987e..000000000000
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SoC specific setup code for the AT91SAM9N12
- *
- * Copyright (C) 2012 Atmel Corporation.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <asm/system_misc.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9N12 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9n12_map_io(void)
-{
- at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);
-}
-
-static void __init at91sam9n12_initialize(void)
-{
- at91_sysirq_mask_rtc(AT91SAM9N12_BASE_RTC);
-}
-
-AT91_SOC_START(at91sam9n12)
- .map_io = at91sam9n12_map_io,
- .init = at91sam9n12_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
deleted file mode 100644
index f25b9aec9c50..000000000000
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9rl.c
- *
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2007 Atmel Corporation
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <asm/system_misc.h>
-#include <asm/irq.h>
-#include <mach/cpu.h>
-#include <mach/at91_dbgu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9RL processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9rl_map_io(void)
-{
- unsigned long sram_size;
-
- switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
- case AT91_CIDR_SRAMSIZ_32K:
- sram_size = 2 * SZ_16K;
- break;
- case AT91_CIDR_SRAMSIZ_16K:
- default:
- sram_size = SZ_16K;
- }
-
- /* Map SRAM */
- at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size);
-}
-
-static void __init at91sam9rl_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
- at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9rl)
- .map_io = at91sam9rl_map_io,
- .init = at91sam9rl_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
deleted file mode 100644
index f0d5a69a7237..000000000000
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Chip-specific setup code for the AT91SAM9x5 family
- *
- * Copyright (C) 2010-2012 Atmel Corporation.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <asm/system_misc.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9x5 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9x5_map_io(void)
-{
- at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
-}
-
-static void __init at91sam9x5_initialize(void)
-{
- at91_sysirq_mask_rtc(AT91SAM9X5_BASE_RTC);
-}
-
-/* --------------------------------------------------------------------
- * Interrupt initialization
- * -------------------------------------------------------------------- */
-
-AT91_SOC_START(at91sam9x5)
- .map_io = at91sam9x5_map_io,
- .init = at91sam9x5_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c
deleted file mode 100644
index 76dfe8f9af50..000000000000
--- a/arch/arm/mach-at91/board-dt-rm9200.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Setup code for AT91RM9200 Evaluation Kits with Device Tree support
- *
- * Copyright (C) 2011 Atmel,
- * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
- * 2012 Joachim Eastwood <manabian@gmail.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/clk-provider.h>
-
-#include <asm/setup.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include "generic.h"
-
-static void __init at91rm9200_dt_timer_init(void)
-{
- of_clk_init(NULL);
- at91rm9200_timer_init();
-}
-
-static const char *at91rm9200_dt_board_compat[] __initdata = {
- "atmel,at91rm9200",
- NULL
-};
-
-DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
- .init_time = at91rm9200_dt_timer_init,
- .map_io = at91_map_io,
- .init_early = at91rm9200_dt_initialize,
- .dt_compat = at91rm9200_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c
deleted file mode 100644
index f99246aa9b38..000000000000
--- a/arch/arm/mach-at91/board-dt-sam9.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Setup code for AT91SAM Evaluation Kits with Device Tree support
- *
- * Copyright (C) 2011 Atmel,
- * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/clk-provider.h>
-
-#include <asm/setup.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include "generic.h"
-
-static const char *at91_dt_board_compat[] __initdata = {
- "atmel,at91sam9",
- NULL
-};
-
-DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
- /* Maintainer: Atmel */
- .map_io = at91_map_io,
- .init_early = at91_dt_initialize,
- .dt_compat = at91_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index d53324210adf..a6e726a6e0b5 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -17,24 +17,28 @@
/* Map io */
extern void __init at91_map_io(void);
extern void __init at91_alt_map_io(void);
-extern void __init at91_init_sram(int bank, unsigned long base,
- unsigned int length);
-
- /* Processors */
-extern void __init at91rm9200_set_type(int type);
-extern void __init at91rm9200_dt_initialize(void);
-extern void __init at91_dt_initialize(void);
-
- /* Interrupts */
-extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
-extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
/* Timer */
extern void at91rm9200_timer_init(void);
/* idle */
+extern void at91rm9200_idle(void);
extern void at91sam9_idle(void);
/* Matrix */
extern void at91_ioremap_matrix(u32 base_addr);
+
+
+#ifdef CONFIG_PM
+extern void __init at91rm9200_pm_init(void);
+extern void __init at91sam9260_pm_init(void);
+extern void __init at91sam9g45_pm_init(void);
+extern void __init at91sam9x5_pm_init(void);
+#else
+void __init at91rm9200_pm_init(void) { }
+void __init at91sam9260_pm_init(void) { }
+void __init at91sam9g45_pm_init(void) { }
+void __init at91sam9x5_pm_init(void) { }
+#endif
+
#endif /* _AT91_GENERIC_H */
diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h
deleted file mode 100644
index 7b7366253ceb..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_pio.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_pio.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Parallel I/O Controller (PIO) - System peripherals registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91_PIO_H
-#define AT91_PIO_H
-
-#define PIO_PER 0x00 /* Enable Register */
-#define PIO_PDR 0x04 /* Disable Register */
-#define PIO_PSR 0x08 /* Status Register */
-#define PIO_OER 0x10 /* Output Enable Register */
-#define PIO_ODR 0x14 /* Output Disable Register */
-#define PIO_OSR 0x18 /* Output Status Register */
-#define PIO_IFER 0x20 /* Glitch Input Filter Enable */
-#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */
-#define PIO_IFSR 0x28 /* Glitch Input Filter Status */
-#define PIO_SODR 0x30 /* Set Output Data Register */
-#define PIO_CODR 0x34 /* Clear Output Data Register */
-#define PIO_ODSR 0x38 /* Output Data Status Register */
-#define PIO_PDSR 0x3c /* Pin Data Status Register */
-#define PIO_IER 0x40 /* Interrupt Enable Register */
-#define PIO_IDR 0x44 /* Interrupt Disable Register */
-#define PIO_IMR 0x48 /* Interrupt Mask Register */
-#define PIO_ISR 0x4c /* Interrupt Status Register */
-#define PIO_MDER 0x50 /* Multi-driver Enable Register */
-#define PIO_MDDR 0x54 /* Multi-driver Disable Register */
-#define PIO_MDSR 0x58 /* Multi-driver Status Register */
-#define PIO_PUDR 0x60 /* Pull-up Disable Register */
-#define PIO_PUER 0x64 /* Pull-up Enable Register */
-#define PIO_PUSR 0x68 /* Pull-up Status Register */
-#define PIO_ASR 0x70 /* Peripheral A Select Register */
-#define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */
-#define PIO_BSR 0x74 /* Peripheral B Select Register */
-#define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */
-#define PIO_ABSR 0x78 /* AB Status Register */
-#define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */
-#define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */
-#define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */
-#define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */
-#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */
-#define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */
-#define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */
-#define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */
-#define PIO_OWER 0xa0 /* Output Write Enable Register */
-#define PIO_OWDR 0xa4 /* Output Write Disable Register */
-#define PIO_OWSR 0xa8 /* Output Write Status Register */
-#define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */
-#define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */
-#define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */
-#define PIO_ESR 0xc0 /* Edge Select Register */
-#define PIO_LSR 0xc4 /* Level Select Register */
-#define PIO_ELSR 0xc8 /* Edge/Level Status Register */
-#define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */
-#define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */
-#define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */
-#define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */
-
-#define ABCDSR_PERIPH_A 0x0
-#define ABCDSR_PERIPH_B 0x1
-#define ABCDSR_PERIPH_C 0x2
-#define ABCDSR_PERIPH_D 0x3
-
-#define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/
-#define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/
-
-#define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/
-#define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_rtt.h b/arch/arm/mach-at91/include/mach/at91_rtt.h
deleted file mode 100644
index 7ec75de8bbb6..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_rtt.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_rtt.h
- *
- * Copyright (C) 2007 Andrew Victor
- * Copyright (C) 2007 Atmel Corporation.
- *
- * Real-time Timer (RTT) - System peripherals regsters.
- * Based on AT91SAM9261 datasheet revision D.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91_RTT_H
-#define AT91_RTT_H
-
-#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
-#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */
-#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
-#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
-#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */
-
-#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */
-#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */
-
-#define AT91_RTT_VR 0x08 /* Real-time Value Register */
-#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */
-
-#define AT91_RTT_SR 0x0c /* Real-time Status Register */
-#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */
-#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 61914fb35f5d..ce7c80a44983 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -152,69 +152,45 @@ static inline int at91_soc_is_detected(void)
#define cpu_is_at91rm9200_pqfp() (0)
#endif
-#ifdef CONFIG_SOC_AT91SAM9260
+#ifdef CONFIG_SOC_AT91SAM9
#define cpu_is_at91sam9xe() (at91_soc_initdata.subtype == AT91_SOC_SAM9XE)
#define cpu_is_at91sam9260() (at91_soc_initdata.type == AT91_SOC_SAM9260)
#define cpu_is_at91sam9g20() (at91_soc_initdata.type == AT91_SOC_SAM9G20)
-#else
-#define cpu_is_at91sam9xe() (0)
-#define cpu_is_at91sam9260() (0)
-#define cpu_is_at91sam9g20() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9261
#define cpu_is_at91sam9261() (at91_soc_initdata.type == AT91_SOC_SAM9261)
#define cpu_is_at91sam9g10() (at91_soc_initdata.type == AT91_SOC_SAM9G10)
-#else
-#define cpu_is_at91sam9261() (0)
-#define cpu_is_at91sam9g10() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9263
#define cpu_is_at91sam9263() (at91_soc_initdata.type == AT91_SOC_SAM9263)
-#else
-#define cpu_is_at91sam9263() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9RL
#define cpu_is_at91sam9rl() (at91_soc_initdata.type == AT91_SOC_SAM9RL)
-#else
-#define cpu_is_at91sam9rl() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9G45
#define cpu_is_at91sam9g45() (at91_soc_initdata.type == AT91_SOC_SAM9G45)
#define cpu_is_at91sam9g45es() (at91_soc_initdata.subtype == AT91_SOC_SAM9G45ES)
#define cpu_is_at91sam9m10() (at91_soc_initdata.subtype == AT91_SOC_SAM9M10)
#define cpu_is_at91sam9g46() (at91_soc_initdata.subtype == AT91_SOC_SAM9G46)
#define cpu_is_at91sam9m11() (at91_soc_initdata.subtype == AT91_SOC_SAM9M11)
-#else
-#define cpu_is_at91sam9g45() (0)
-#define cpu_is_at91sam9g45es() (0)
-#define cpu_is_at91sam9m10() (0)
-#define cpu_is_at91sam9g46() (0)
-#define cpu_is_at91sam9m11() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9X5
#define cpu_is_at91sam9x5() (at91_soc_initdata.type == AT91_SOC_SAM9X5)
#define cpu_is_at91sam9g15() (at91_soc_initdata.subtype == AT91_SOC_SAM9G15)
#define cpu_is_at91sam9g35() (at91_soc_initdata.subtype == AT91_SOC_SAM9G35)
#define cpu_is_at91sam9x35() (at91_soc_initdata.subtype == AT91_SOC_SAM9X35)
#define cpu_is_at91sam9g25() (at91_soc_initdata.subtype == AT91_SOC_SAM9G25)
#define cpu_is_at91sam9x25() (at91_soc_initdata.subtype == AT91_SOC_SAM9X25)
+#define cpu_is_at91sam9n12() (at91_soc_initdata.type == AT91_SOC_SAM9N12)
#else
+#define cpu_is_at91sam9xe() (0)
+#define cpu_is_at91sam9260() (0)
+#define cpu_is_at91sam9g20() (0)
+#define cpu_is_at91sam9261() (0)
+#define cpu_is_at91sam9g10() (0)
+#define cpu_is_at91sam9263() (0)
+#define cpu_is_at91sam9rl() (0)
+#define cpu_is_at91sam9g45() (0)
+#define cpu_is_at91sam9g45es() (0)
+#define cpu_is_at91sam9m10() (0)
+#define cpu_is_at91sam9g46() (0)
+#define cpu_is_at91sam9m11() (0)
#define cpu_is_at91sam9x5() (0)
#define cpu_is_at91sam9g15() (0)
#define cpu_is_at91sam9g35() (0)
#define cpu_is_at91sam9x35() (0)
#define cpu_is_at91sam9g25() (0)
#define cpu_is_at91sam9x25() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9N12
-#define cpu_is_at91sam9n12() (at91_soc_initdata.type == AT91_SOC_SAM9N12)
-#else
#define cpu_is_at91sam9n12() (0)
#endif
diff --git a/arch/arm/mach-at91/include/mach/system_rev.h b/arch/arm/mach-at91/include/mach/system_rev.h
deleted file mode 100644
index ef79a9aafc08..000000000000
--- a/arch/arm/mach-at91/include/mach/system_rev.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * Under GPLv2 only
- */
-
-#ifndef __ARCH_SYSTEM_REV_H__
-#define __ARCH_SYSTEM_REV_H__
-
-#include <asm/system_info.h>
-
-/*
- * board revision encoding
- * mach specific
- * the 16-31 bit are reserved for at91 generic information
- *
- * bit 31:
- * 0 => nand 8 bit
- * 1 => nand 16 bit
- */
-#define BOARD_HAVE_NAND_16BIT (1 << 31)
-static inline int board_have_nand_16bit(void)
-{
- return (system_rev & BOARD_HAVE_NAND_16BIT) ? 1 : 0;
-}
-
-#endif /* __ARCH_SYSTEM_REV_H__ */
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 9b15169a1c62..af8d8afc2e12 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -14,9 +14,13 @@
#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
+#include <linux/genalloc.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/clk/at91_pmc.h>
@@ -32,7 +36,13 @@
#include "generic.h"
#include "pm.h"
+static struct {
+ unsigned long uhp_udp_mask;
+ int memctrl;
+} at91_pm_data;
+
static void (*at91_pm_standby)(void);
+void __iomem *at91_ramc_base[2];
static int at91_pm_valid_state(suspend_state_t state)
{
@@ -71,17 +81,9 @@ static int at91_pm_verify_clocks(void)
scsr = at91_pmc_read(AT91_PMC_SCSR);
/* USB must not be using PLLB */
- if (cpu_is_at91rm9200()) {
- if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
- pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
- return 0;
- }
- } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
- || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
- if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
- pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
- return 0;
- }
+ if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ return 0;
}
/* PCK0..PCK3 must be disabled, or configured to use clk32k */
@@ -149,18 +151,13 @@ static int at91_pm_enter(suspend_state_t state)
* turning off the main oscillator; reverse on wakeup.
*/
if (slow_clock) {
- int memctrl = AT91_MEMCTRL_SDRAMC;
-
- if (cpu_is_at91rm9200())
- memctrl = AT91_MEMCTRL_MC;
- else if (cpu_is_at91sam9g45())
- memctrl = AT91_MEMCTRL_DDRSDR;
#ifdef CONFIG_AT91_SLOW_CLOCK
/* copy slow_clock handler to SRAM, and call it */
memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
#endif
slow_clock(at91_pmc_base, at91_ramc_base[0],
- at91_ramc_base[1], memctrl);
+ at91_ramc_base[1],
+ at91_pm_data.memctrl);
break;
} else {
pr_info("AT91: PM - no slow clock mode enabled ...\n");
@@ -229,23 +226,134 @@ void at91_pm_set_standby(void (*at91_standby)(void))
}
}
-static int __init at91_pm_init(void)
+static struct of_device_id ramc_ids[] = {
+ { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
+ { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
+ { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
+ { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
+ { /*sentinel*/ }
+};
+
+static void at91_dt_ramc(void)
{
+ struct device_node *np;
+ const struct of_device_id *of_id;
+ int idx = 0;
+ const void *standby = NULL;
+
+ for_each_matching_node_and_match(np, ramc_ids, &of_id) {
+ at91_ramc_base[idx] = of_iomap(np, 0);
+ if (!at91_ramc_base[idx])
+ panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
+
+ if (!standby)
+ standby = of_id->data;
+
+ idx++;
+ }
+
+ if (!idx)
+ panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
+
+ if (!standby) {
+ pr_warn("ramc no standby function available\n");
+ return;
+ }
+
+ at91_pm_set_standby(standby);
+}
+
#ifdef CONFIG_AT91_SLOW_CLOCK
- slow_clock = (void *) (AT91_IO_VIRT_BASE - at91_slow_clock_sz);
+static void __init at91_pm_sram_init(void)
+{
+ struct gen_pool *sram_pool;
+ phys_addr_t sram_pbase;
+ unsigned long sram_base;
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+ if (!node) {
+ pr_warn("%s: failed to find sram node!\n", __func__);
+ return;
+ }
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev) {
+ pr_warn("%s: failed to find sram device!\n", __func__);
+ goto put_node;
+ }
+
+ sram_pool = dev_get_gen_pool(&pdev->dev);
+ if (!sram_pool) {
+ pr_warn("%s: sram pool unavailable!\n", __func__);
+ goto put_node;
+ }
+
+ sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz);
+ if (!sram_base) {
+ pr_warn("%s: unable to alloc ocram!\n", __func__);
+ goto put_node;
+ }
+
+ sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
+ slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false);
+
+put_node:
+ of_node_put(node);
+}
+#endif
+
+
+static void __init at91_pm_init(void)
+{
+#ifdef CONFIG_AT91_SLOW_CLOCK
+ at91_pm_sram_init();
#endif
pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : ""));
- /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */
- if (cpu_is_at91rm9200())
- at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0);
-
if (at91_cpuidle_device.dev.platform_data)
platform_device_register(&at91_cpuidle_device);
suspend_set_ops(&at91_pm_ops);
+}
- return 0;
+void __init at91rm9200_pm_init(void)
+{
+ at91_dt_ramc();
+
+ /*
+ * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
+ */
+ at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0);
+
+ at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_MC;
+
+ at91_pm_init();
+}
+
+void __init at91sam9260_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ return at91_pm_init();
+}
+
+void __init at91sam9g45_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ return at91_pm_init();
+}
+
+void __init at91sam9x5_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ return at91_pm_init();
}
-arch_initcall(at91_pm_init);
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 20018779bae7..556151e85ec4 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -17,15 +17,6 @@
#include <mach/hardware.h>
#include <mach/at91_ramc.h>
-
-#ifdef CONFIG_SOC_AT91SAM9263
-/*
- * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
- * handle those cases both here and in the Suspend-To-RAM support.
- */
-#warning Assuming EB1 SDRAM controller is *NOT* used
-#endif
-
/*
* When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
* clock during suspend by adjusting its prescalar and divisor.
diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/sama5.c
index 97f7367d32b8..03dcb441f3d2 100644
--- a/arch/arm/mach-at91/board-dt-sama5.c
+++ b/arch/arm/mach-at91/sama5.c
@@ -1,5 +1,5 @@
/*
- * Setup code for SAMA5 Evaluation Kits with Device Tree support
+ * Setup code for SAMA5
*
* Copyright (C) 2013 Atmel,
* 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
@@ -19,6 +19,8 @@
#include <linux/clk-provider.h>
#include <linux/phy.h>
+#include <mach/hardware.h>
+
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
@@ -47,6 +49,7 @@ static void __init sama5_dt_device_init(void)
}
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ at91sam9x5_pm_init();
}
static const char *sama5_dt_board_compat[] __initconst = {
@@ -54,23 +57,54 @@ static const char *sama5_dt_board_compat[] __initconst = {
NULL
};
-DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
+DT_MACHINE_START(sama5_dt, "Atmel SAMA5")
/* Maintainer: Atmel */
.map_io = at91_map_io,
- .init_early = at91_dt_initialize,
.init_machine = sama5_dt_device_init,
.dt_compat = sama5_dt_board_compat,
MACHINE_END
+static struct map_desc at91_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_MPDDRC),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_MPDDRC),
+ .length = SZ_512,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_PMC),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_PMC),
+ .length = SZ_512,
+ .type = MT_DEVICE,
+ },
+ { /* On sama5d4, we use USART3 as serial console */
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_USART3),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_USART3),
+ .length = SZ_256,
+ .type = MT_DEVICE,
+ },
+ { /* A bunch of peripheral with fine grained IO space */
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_SYS2),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_SYS2),
+ .length = SZ_2K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init sama5_alt_map_io(void)
+{
+ at91_alt_map_io();
+ iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc));
+}
+
static const char *sama5_alt_dt_board_compat[] __initconst = {
"atmel,sama5d4",
NULL
};
-DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5 (Device Tree)")
+DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5")
/* Maintainer: Atmel */
- .map_io = at91_alt_map_io,
- .init_early = at91_dt_initialize,
+ .map_io = sama5_alt_map_io,
.init_machine = sama5_dt_device_init,
.dt_compat = sama5_alt_dt_board_compat,
.l2c_aux_mask = ~0UL,
diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c
deleted file mode 100644
index 3d775d08de08..000000000000
--- a/arch/arm/mach-at91/sama5d3.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Chip-specific setup code for the SAMA5D3 family
- *
- * Copyright (C) 2013 Atmel,
- * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk/at91_pmc.h>
-
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/sama5d3.h>
-#include <mach/cpu.h>
-
-#include "soc.h"
-#include "generic.h"
-#include "sam9_smc.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9x5 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init sama5d3_map_io(void)
-{
- at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE);
-}
-
-static void __init sama5d3_initialize(void)
-{
- at91_sysirq_mask_rtc(SAMA5D3_BASE_RTC);
-}
-
-AT91_SOC_START(sama5d3)
- .map_io = sama5d3_map_io,
- .init = sama5d3_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/sama5d4.c b/arch/arm/mach-at91/sama5d4.c
deleted file mode 100644
index 7638509639f4..000000000000
--- a/arch/arm/mach-at91/sama5d4.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Chip-specific setup code for the SAMA5D4 family
- *
- * Copyright (C) 2013 Atmel Corporation,
- * Nicolas Ferre <nicolas.ferre@atmel.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk/at91_pmc.h>
-
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/sama5d4.h>
-#include <mach/cpu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-#include "sam9_smc.h"
-
-/* --------------------------------------------------------------------
- * Processor initialization
- * -------------------------------------------------------------------- */
-static struct map_desc at91_io_desc[] __initdata = {
- {
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_MPDDRC),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_MPDDRC),
- .length = SZ_512,
- .type = MT_DEVICE,
- },
- {
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_PMC),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_PMC),
- .length = SZ_512,
- .type = MT_DEVICE,
- },
- { /* On sama5d4, we use USART3 as serial console */
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_USART3),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_USART3),
- .length = SZ_256,
- .type = MT_DEVICE,
- },
- { /* A bunch of peripheral with fine grained IO space */
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_SYS2),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_SYS2),
- .length = SZ_2K,
- .type = MT_DEVICE,
- },
-};
-
-
-static void __init sama5d4_map_io(void)
-{
- iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc));
- at91_init_sram(0, SAMA5D4_NS_SRAM_BASE, SAMA5D4_NS_SRAM_SIZE);
-}
-
-AT91_SOC_START(sama5d4)
- .map_io = sama5d4_map_io,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index ce25e85720fb..4e58bc90ed21 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -22,49 +22,12 @@
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
-#include "soc.h"
#include "generic.h"
#include "pm.h"
-struct at91_init_soc __initdata at91_boot_soc;
-
struct at91_socinfo at91_soc_initdata;
EXPORT_SYMBOL(at91_soc_initdata);
-void __init at91rm9200_set_type(int type)
-{
- if (type == ARCH_REVISON_9200_PQFP)
- at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP;
- else
- at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
-
- pr_info("filled in soc subtype: %s\n",
- at91_get_soc_subtype(&at91_soc_initdata));
-}
-
-void __iomem *at91_ramc_base[2];
-EXPORT_SYMBOL_GPL(at91_ramc_base);
-
-static struct map_desc sram_desc[2] __initdata;
-
-void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
-{
- struct map_desc *desc = &sram_desc[bank];
-
- desc->virtual = (unsigned long)AT91_IO_VIRT_BASE - length;
- if (bank > 0)
- desc->virtual -= sram_desc[bank - 1].length;
-
- desc->pfn = __phys_to_pfn(base);
- desc->length = length;
- desc->type = MT_MEMORY_RWX_NONCACHED;
-
- pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n",
- base, length, desc->virtual);
-
- iotable_init(desc, 1);
-}
-
static struct map_desc at91_io_desc __initdata __maybe_unused = {
.virtual = (unsigned long)AT91_VA_BASE_SYS,
.pfn = __phys_to_pfn(AT91_BASE_SYS),
@@ -91,61 +54,51 @@ static void __init soc_detect(u32 dbgu_base)
at91_soc_initdata.type = AT91_SOC_RM9200;
if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_UNKNOWN)
at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
- at91_boot_soc = at91rm9200_soc;
break;
case ARCH_ID_AT91SAM9260:
at91_soc_initdata.type = AT91_SOC_SAM9260;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9260_soc;
break;
case ARCH_ID_AT91SAM9261:
at91_soc_initdata.type = AT91_SOC_SAM9261;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9261_soc;
break;
case ARCH_ID_AT91SAM9263:
at91_soc_initdata.type = AT91_SOC_SAM9263;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9263_soc;
break;
case ARCH_ID_AT91SAM9G20:
at91_soc_initdata.type = AT91_SOC_SAM9G20;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9260_soc;
break;
case ARCH_ID_AT91SAM9G45:
at91_soc_initdata.type = AT91_SOC_SAM9G45;
if (cidr == ARCH_ID_AT91SAM9G45ES)
at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES;
- at91_boot_soc = at91sam9g45_soc;
break;
case ARCH_ID_AT91SAM9RL64:
at91_soc_initdata.type = AT91_SOC_SAM9RL;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9rl_soc;
break;
case ARCH_ID_AT91SAM9X5:
at91_soc_initdata.type = AT91_SOC_SAM9X5;
- at91_boot_soc = at91sam9x5_soc;
break;
case ARCH_ID_AT91SAM9N12:
at91_soc_initdata.type = AT91_SOC_SAM9N12;
- at91_boot_soc = at91sam9n12_soc;
break;
case ARCH_ID_SAMA5:
at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
- at91_boot_soc = sama5d3_soc;
}
break;
}
@@ -154,13 +107,11 @@ static void __init soc_detect(u32 dbgu_base)
if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
at91_soc_initdata.type = AT91_SOC_SAM9G10;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9261_soc;
}
/* at91sam9xe */
else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
at91_soc_initdata.type = AT91_SOC_SAM9260;
at91_soc_initdata.subtype = AT91_SOC_SAM9XE;
- at91_boot_soc = at91sam9260_soc;
}
if (!at91_soc_is_detected())
@@ -240,10 +191,8 @@ static void __init alt_soc_detect(u32 dbgu_base)
at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
- at91_boot_soc = sama5d3_soc;
} else if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) {
at91_soc_initdata.type = AT91_SOC_SAMA5D4;
- at91_boot_soc = sama5d4_soc;
}
break;
}
@@ -349,12 +298,6 @@ void __init at91_map_io(void)
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
pr_info("Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
-
- if (!at91_soc_is_enabled())
- panic(pr_fmt("Soc not enabled"));
-
- if (at91_boot_soc.map_io)
- at91_boot_soc.map_io();
}
void __init at91_alt_map_io(void)
@@ -374,12 +317,6 @@ void __init at91_alt_map_io(void)
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
pr_info("AT91: Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
-
- if (!at91_soc_is_enabled())
- panic("AT91: Soc not enabled");
-
- if (at91_boot_soc.map_io)
- at91_boot_soc.map_io();
}
void __iomem *at91_matrix_base;
@@ -391,55 +328,3 @@ void __init at91_ioremap_matrix(u32 base_addr)
if (!at91_matrix_base)
panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
}
-
-static struct of_device_id ramc_ids[] = {
- { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
- { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
- { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
- { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
- { /*sentinel*/ }
-};
-
-static void at91_dt_ramc(void)
-{
- struct device_node *np;
- const struct of_device_id *of_id;
- int idx = 0;
- const void *standby = NULL;
-
- for_each_matching_node_and_match(np, ramc_ids, &of_id) {
- at91_ramc_base[idx] = of_iomap(np, 0);
- if (!at91_ramc_base[idx])
- panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
-
- if (!standby)
- standby = of_id->data;
-
- idx++;
- }
-
- if (!idx)
- panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
-
- if (!standby) {
- pr_warn("ramc no standby function available\n");
- return;
- }
-
- at91_pm_set_standby(standby);
-}
-
-void __init at91rm9200_dt_initialize(void)
-{
- at91_dt_ramc();
-
- at91_boot_soc.init();
-}
-
-void __init at91_dt_initialize(void)
-{
- at91_dt_ramc();
-
- if (at91_boot_soc.init)
- at91_boot_soc.init();
-}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
deleted file mode 100644
index ae6c0b2f1146..000000000000
--- a/arch/arm/mach-at91/soc.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * Under GPLv2
- */
-
-struct at91_init_soc {
- int builtin;
- void (*map_io)(void);
- void (*init)(void);
-};
-
-extern struct at91_init_soc at91_boot_soc;
-extern struct at91_init_soc at91rm9200_soc;
-extern struct at91_init_soc at91sam9260_soc;
-extern struct at91_init_soc at91sam9261_soc;
-extern struct at91_init_soc at91sam9263_soc;
-extern struct at91_init_soc at91sam9g45_soc;
-extern struct at91_init_soc at91sam9rl_soc;
-extern struct at91_init_soc at91sam9x5_soc;
-extern struct at91_init_soc at91sam9n12_soc;
-extern struct at91_init_soc sama5d3_soc;
-extern struct at91_init_soc sama5d4_soc;
-
-#define AT91_SOC_START(_name) \
-struct at91_init_soc __initdata _name##_soc \
- __used \
- = { \
- .builtin = 1, \
-
-#define AT91_SOC_END \
-};
-
-static inline int at91_soc_is_enabled(void)
-{
- return at91_boot_soc.builtin;
-}
-
-#if !defined(CONFIG_SOC_AT91RM9200)
-#define at91rm9200_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9260)
-#define at91sam9260_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9261)
-#define at91sam9261_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9263)
-#define at91sam9263_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9G45)
-#define at91sam9g45_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9RL)
-#define at91sam9rl_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9X5)
-#define at91sam9x5_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9N12)
-#define at91sam9n12_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_SAMA5D3)
-#define sama5d3_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_SAMA5D4)
-#define sama5d4_soc at91_boot_soc
-#endif
diff --git a/arch/arm/mach-at91/sysirq_mask.c b/arch/arm/mach-at91/sysirq_mask.c
deleted file mode 100644
index f8bc3511a8c8..000000000000
--- a/arch/arm/mach-at91/sysirq_mask.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * sysirq_mask.c - System-interrupt masking
- *
- * Copyright (C) 2013 Johan Hovold <jhovold@gmail.com>
- *
- * Functions to disable system interrupts from backup-powered peripherals.
- *
- * The RTC and RTT-peripherals are generally powered by backup power (VDDBU)
- * and are not reset on wake-up, user, watchdog or software reset. This means
- * that their interrupts may be enabled during early boot (e.g. after a user
- * reset).
- *
- * As the RTC and RTT share the system-interrupt line with the PIT, an
- * interrupt occurring before a handler has been installed would lead to the
- * system interrupt being disabled and prevent the system from booting.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/io.h>
-#include <mach/at91_rtt.h>
-
-#include "generic.h"
-
-#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
-#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
-#define AT91_RTC_IRQ_MASK 0x1f /* Available IRQs mask */
-
-void __init at91_sysirq_mask_rtc(u32 rtc_base)
-{
- void __iomem *base;
-
- base = ioremap(rtc_base, 64);
- if (!base)
- return;
-
- /*
- * sam9x5 SoCs have the following errata:
- * "RTC: Interrupt Mask Register cannot be used
- * Interrupt Mask Register read always returns 0."
- *
- * Hence we're not relying on IMR values to disable
- * interrupts.
- */
- writel_relaxed(AT91_RTC_IRQ_MASK, base + AT91_RTC_IDR);
- (void)readl_relaxed(base + AT91_RTC_IMR); /* flush */
-
- iounmap(base);
-}
-
-void __init at91_sysirq_mask_rtt(u32 rtt_base)
-{
- void __iomem *base;
- void __iomem *reg;
- u32 mode;
-
- base = ioremap(rtt_base, 16);
- if (!base)
- return;
-
- reg = base + AT91_RTT_MR;
-
- mode = readl_relaxed(reg);
- if (mode & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)) {
- pr_info("AT91: Disabling rtt irq\n");
- mode &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
- writel_relaxed(mode, reg);
- (void)readl_relaxed(reg); /* flush */
- }
-
- iounmap(base);
-}
diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c
index 31c87a284a34..e209e6fc7caf 100644
--- a/arch/arm/mach-bcm/platsmp-brcmstb.c
+++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/jiffies.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/printk.h>
@@ -94,10 +95,35 @@ static u32 pwr_ctrl_rd(u32 cpu)
return readl_relaxed(base);
}
-static void pwr_ctrl_wr(u32 cpu, u32 val)
+static void pwr_ctrl_set(unsigned int cpu, u32 val, u32 mask)
{
void __iomem *base = pwr_ctrl_get_base(cpu);
- writel(val, base);
+ writel((readl(base) & mask) | val, base);
+}
+
+static void pwr_ctrl_clr(unsigned int cpu, u32 val, u32 mask)
+{
+ void __iomem *base = pwr_ctrl_get_base(cpu);
+ writel((readl(base) & mask) & ~val, base);
+}
+
+#define POLL_TMOUT_MS 500
+static int pwr_ctrl_wait_tmout(unsigned int cpu, u32 set, u32 mask)
+{
+ const unsigned long timeo = jiffies + msecs_to_jiffies(POLL_TMOUT_MS);
+ u32 tmp;
+
+ do {
+ tmp = pwr_ctrl_rd(cpu) & mask;
+ if (!set == !tmp)
+ return 0;
+ } while (time_before(jiffies, timeo));
+
+ tmp = pwr_ctrl_rd(cpu) & mask;
+ if (!set == !tmp)
+ return 0;
+
+ return -ETIMEDOUT;
}
static void cpu_rst_cfg_set(u32 cpu, int set)
@@ -139,15 +165,22 @@ static void brcmstb_cpu_power_on(u32 cpu)
* The secondary cores power was cut, so we must go through
* power-on initialization.
*/
- u32 tmp;
+ pwr_ctrl_set(cpu, ZONE_MAN_ISO_CNTL_MASK, 0xffffff00);
+ pwr_ctrl_set(cpu, ZONE_MANUAL_CONTROL_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_RESERVED_1_MASK, -1);
- /* Request zone power up */
- pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK);
+ pwr_ctrl_set(cpu, ZONE_MAN_MEM_PWR_MASK, -1);
- /* Wait for the power up FSM to complete */
- do {
- tmp = pwr_ctrl_rd(cpu);
- } while (!(tmp & ZONE_PWR_ON_STATE_MASK));
+ if (pwr_ctrl_wait_tmout(cpu, 1, ZONE_MEM_PWR_STATE_MASK))
+ panic("ZONE_MEM_PWR_STATE_MASK set timeout");
+
+ pwr_ctrl_set(cpu, ZONE_MAN_CLKEN_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 1, ZONE_DPG_PWR_STATE_MASK))
+ panic("ZONE_DPG_PWR_STATE_MASK set timeout");
+
+ pwr_ctrl_clr(cpu, ZONE_MAN_ISO_CNTL_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_MAN_RESET_CNTL_MASK, -1);
}
static int brcmstb_cpu_get_power_state(u32 cpu)
@@ -174,25 +207,33 @@ static void brcmstb_cpu_die(u32 cpu)
static int brcmstb_cpu_kill(u32 cpu)
{
- u32 tmp;
+ /*
+ * Ordinarily, the hardware forbids power-down of CPU0 (which is good
+ * because it is the boot CPU), but this is not true when using BPCM
+ * manual mode. Consequently, we must avoid turning off CPU0 here to
+ * ensure that TI2C master reset will work.
+ */
+ if (cpu == 0) {
+ pr_warn("SMP: refusing to power off CPU0\n");
+ return 1;
+ }
while (per_cpu_sw_state_rd(cpu))
;
- /* Program zone reset */
- pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK |
- ZONE_PWR_DN_REQ_MASK);
+ pwr_ctrl_set(cpu, ZONE_MANUAL_CONTROL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_RESET_CNTL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_CLKEN_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_MAN_ISO_CNTL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_MEM_PWR_MASK, -1);
- /* Verify zone reset */
- tmp = pwr_ctrl_rd(cpu);
- if (!(tmp & ZONE_RESET_STATE_MASK))
- pr_err("%s: Zone reset bit for CPU %d not asserted!\n",
- __func__, cpu);
+ if (pwr_ctrl_wait_tmout(cpu, 0, ZONE_MEM_PWR_STATE_MASK))
+ panic("ZONE_MEM_PWR_STATE_MASK clear timeout");
- /* Wait for power down */
- do {
- tmp = pwr_ctrl_rd(cpu);
- } while (!(tmp & ZONE_PWR_OFF_STATE_MASK));
+ pwr_ctrl_clr(cpu, ZONE_RESERVED_1_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 0, ZONE_DPG_PWR_STATE_MASK))
+ panic("ZONE_DPG_PWR_STATE_MASK clear timeout");
/* Flush pipeline before resetting CPU */
mb();
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 2204239ed243..2e3464b8bab4 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o
obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o
-obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
+obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o
obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index ae129bc49273..846a84ddc28e 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -45,7 +45,6 @@
#include <mach/irqs.h>
#include <mach/serial.h>
#include <mach/clock.h>
-#include <mach/cdce949.h>
#include "davinci.h"
#include "clock.h"
@@ -399,9 +398,6 @@ static struct i2c_board_info __initdata i2c_info[] = {
{
I2C_BOARD_INFO("cpld_video", 0x3b),
},
- {
- I2C_BOARD_INFO("cdce949", 0x6c),
- },
};
static struct davinci_i2c_platform_data i2c_pdata = {
@@ -715,31 +711,6 @@ static void __init evm_init_i2c(void)
evm_init_video();
}
-#define CDCE949_XIN_RATE 27000000
-
-/* CDCE949 support - "lpsc" field is overridden to work as clock number */
-static struct clk cdce_clk_in = {
- .name = "cdce_xin",
- .rate = CDCE949_XIN_RATE,
-};
-
-static struct clk_lookup cdce_clks[] = {
- CLK(NULL, "xin", &cdce_clk_in),
- CLK(NULL, NULL, NULL),
-};
-
-static void __init cdce_clk_init(void)
-{
- struct clk_lookup *c;
- struct clk *clk;
-
- for (c = cdce_clks; c->clk; c++) {
- clk = c->clk;
- clkdev_add(c);
- clk_register(clk);
- }
-}
-
#define DM6467T_EVM_REF_FREQ 33000000
static void __init davinci_map_io(void)
@@ -748,8 +719,6 @@ static void __init davinci_map_io(void)
if (machine_is_davinci_dm6467tevm())
davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
-
- cdce_clk_init();
}
#define DM646X_EVM_PHY_ID "davinci_mdio-0:01"
diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-davinci/cdce949.c
deleted file mode 100644
index abafb92031c0..000000000000
--- a/arch/arm/mach-davinci/cdce949.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * TI CDCE949 clock synthesizer driver
- *
- * Note: This implementation assumes an input of 27MHz to the CDCE.
- * This is by no means constrained by CDCE hardware although the datasheet
- * does use this as an example for all illustrations and more importantly:
- * that is the crystal input on boards it is currently used on.
- *
- * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-
-#include <mach/clock.h>
-#include <mach/cdce949.h>
-
-#include "clock.h"
-
-static struct i2c_client *cdce_i2c_client;
-static DEFINE_MUTEX(cdce_mutex);
-
-/* CDCE register descriptor */
-struct cdce_reg {
- u8 addr;
- u8 val;
-};
-
-/* Per-Output (Y1, Y2 etc.) frequency descriptor */
-struct cdce_freq {
- /* Frequency in KHz */
- unsigned long frequency;
- /*
- * List of registers to program to obtain a particular frequency.
- * 0x0 in register address and value is the end of list marker.
- */
- struct cdce_reg *reglist;
-};
-
-#define CDCE_FREQ_TABLE_ENTRY(line, out) \
-{ \
- .reglist = cdce_y ##line## _ ##out, \
- .frequency = out, \
-}
-
-/* List of CDCE outputs */
-struct cdce_output {
- /* List of frequencies on this output */
- struct cdce_freq *freq_table;
- /* Number of possible frequencies */
- int size;
-};
-
-/*
- * Finding out the values to program into CDCE949 registers for a particular
- * frequency output is not a simple calculation. Have a look at the datasheet
- * for the details. There is desktop software available to help users with
- * the calculations. Here, we just depend on the output of that software
- * (or hand calculations) instead trying to runtime calculate the register
- * values and inflicting misery on ourselves.
- */
-static struct cdce_reg cdce_y1_148500[] = {
- { 0x13, 0x00 },
- /* program PLL1_0 multiplier */
- { 0x18, 0xaf },
- { 0x19, 0x50 },
- { 0x1a, 0x02 },
- { 0x1b, 0xc9 },
- /* program PLL1_11 multiplier */
- { 0x1c, 0x00 },
- { 0x1d, 0x40 },
- { 0x1e, 0x02 },
- { 0x1f, 0xc9 },
- /* output state selection */
- { 0x15, 0x00 },
- { 0x14, 0xef },
- /* switch MUX to PLL1 output */
- { 0x14, 0x6f },
- { 0x16, 0x06 },
- /* set P2DIV divider, P3DIV and input crystal */
- { 0x17, 0x06 },
- { 0x01, 0x00 },
- { 0x05, 0x48 },
- { 0x02, 0x80 },
- /* enable and disable PLL */
- { 0x02, 0xbc },
- { 0x03, 0x01 },
- { },
-};
-
-static struct cdce_reg cdce_y1_74250[] = {
- { 0x13, 0x00 },
- { 0x18, 0xaf },
- { 0x19, 0x50 },
- { 0x1a, 0x02 },
- { 0x1b, 0xc9 },
- { 0x1c, 0x00 },
- { 0x1d, 0x40 },
- { 0x1e, 0x02 },
- { 0x1f, 0xc9 },
- /* output state selection */
- { 0x15, 0x00 },
- { 0x14, 0xef },
- /* switch MUX to PLL1 output */
- { 0x14, 0x6f },
- { 0x16, 0x06 },
- /* set P2DIV divider, P3DIV and input crystal */
- { 0x17, 0x06 },
- { 0x01, 0x00 },
- { 0x05, 0x48 },
- { 0x02, 0x80 },
- /* enable and disable PLL */
- { 0x02, 0xbc },
- { 0x03, 0x02 },
- { },
-};
-
-static struct cdce_reg cdce_y1_27000[] = {
- { 0x13, 0x00 },
- { 0x18, 0x00 },
- { 0x19, 0x40 },
- { 0x1a, 0x02 },
- { 0x1b, 0x08 },
- { 0x1c, 0x00 },
- { 0x1d, 0x40 },
- { 0x1e, 0x02 },
- { 0x1f, 0x08 },
- { 0x15, 0x02 },
- { 0x14, 0xed },
- { 0x16, 0x01 },
- { 0x17, 0x01 },
- { 0x01, 0x00 },
- { 0x05, 0x50 },
- { 0x02, 0xb4 },
- { 0x03, 0x01 },
- { },
-};
-
-static struct cdce_freq cdce_y1_freqs[] = {
- CDCE_FREQ_TABLE_ENTRY(1, 148500),
- CDCE_FREQ_TABLE_ENTRY(1, 74250),
- CDCE_FREQ_TABLE_ENTRY(1, 27000),
-};
-
-static struct cdce_reg cdce_y5_13500[] = {
- { 0x27, 0x08 },
- { 0x28, 0x00 },
- { 0x29, 0x40 },
- { 0x2a, 0x02 },
- { 0x2b, 0x08 },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_reg cdce_y5_16875[] = {
- { 0x27, 0x08 },
- { 0x28, 0x9f },
- { 0x29, 0xb0 },
- { 0x2a, 0x02 },
- { 0x2b, 0x89 },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_reg cdce_y5_27000[] = {
- { 0x27, 0x04 },
- { 0x28, 0x00 },
- { 0x29, 0x40 },
- { 0x2a, 0x02 },
- { 0x2b, 0x08 },
- { 0x24, 0x6f },
- { },
-};
-static struct cdce_reg cdce_y5_54000[] = {
- { 0x27, 0x04 },
- { 0x28, 0xff },
- { 0x29, 0x80 },
- { 0x2a, 0x02 },
- { 0x2b, 0x07 },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_reg cdce_y5_81000[] = {
- { 0x27, 0x02 },
- { 0x28, 0xbf },
- { 0x29, 0xa0 },
- { 0x2a, 0x03 },
- { 0x2b, 0x0a },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_freq cdce_y5_freqs[] = {
- CDCE_FREQ_TABLE_ENTRY(5, 13500),
- CDCE_FREQ_TABLE_ENTRY(5, 16875),
- CDCE_FREQ_TABLE_ENTRY(5, 27000),
- CDCE_FREQ_TABLE_ENTRY(5, 54000),
- CDCE_FREQ_TABLE_ENTRY(5, 81000),
-};
-
-
-static struct cdce_output output_list[] = {
- [1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
- [5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
-};
-
-int cdce_set_rate(struct clk *clk, unsigned long rate)
-{
- int i, ret = 0;
- struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
- struct cdce_reg *regs = NULL;
-
- if (!cdce_i2c_client)
- return -ENODEV;
-
- if (!freq_table)
- return -EINVAL;
-
- for (i = 0; i < output_list[clk->lpsc].size; i++) {
- if (freq_table[i].frequency == rate / 1000) {
- regs = freq_table[i].reglist;
- break;
- }
- }
-
- if (!regs)
- return -EINVAL;
-
- mutex_lock(&cdce_mutex);
- for (i = 0; regs[i].addr; i++) {
- ret = i2c_smbus_write_byte_data(cdce_i2c_client,
- regs[i].addr | 0x80, regs[i].val);
- if (ret)
- break;
- }
- mutex_unlock(&cdce_mutex);
-
- if (!ret)
- clk->rate = rate;
-
- return ret;
-}
-
-static int cdce_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- cdce_i2c_client = client;
- return 0;
-}
-
-static int cdce_remove(struct i2c_client *client)
-{
- cdce_i2c_client = NULL;
- return 0;
-}
-
-static const struct i2c_device_id cdce_id[] = {
- {"cdce949", 0},
- {},
-};
-MODULE_DEVICE_TABLE(i2c, cdce_id);
-
-static struct i2c_driver cdce_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "cdce949",
- },
- .probe = cdce_probe,
- .remove = cdce_remove,
- .id_table = cdce_id,
-};
-
-static int __init cdce_init(void)
-{
- return i2c_add_driver(&cdce_driver);
-}
-subsys_initcall(cdce_init);
-
-static void __exit cdce_exit(void)
-{
- i2c_del_driver(&cdce_driver);
-}
-module_exit(cdce_exit);
-
-MODULE_AUTHOR("Texas Instruments");
-MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-davinci/include/mach/cdce949.h b/arch/arm/mach-davinci/include/mach/cdce949.h
deleted file mode 100644
index c73331fae341..000000000000
--- a/arch/arm/mach-davinci/include/mach/cdce949.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * TI CDCE949 off-chip clock synthesizer support
- *
- * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-#ifndef _MACH_DAVINCI_CDCE949_H
-#define _MACH_DAVINCI_CDCE949_H
-
-#include <linux/clk.h>
-
-#include <mach/clock.h>
-
-int cdce_set_rate(struct clk *clk, unsigned long rate);
-
-#endif
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
index 5e93a734c858..951b620bfa73 100644
--- a/arch/arm/mach-davinci/serial.c
+++ b/arch/arm/mach-davinci/serial.c
@@ -31,16 +31,6 @@
#include <mach/serial.h>
#include <mach/cputype.h>
-static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
- int offset)
-{
- offset <<= up->regshift;
-
- WARN_ONCE(!up->membase, "unmapped read: uart[%d]\n", offset);
-
- return (unsigned int)__raw_readl(up->membase + offset);
-}
-
static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
int value)
{
diff --git a/arch/arm/mach-digicolor/Kconfig b/arch/arm/mach-digicolor/Kconfig
new file mode 100644
index 000000000000..4f36d8d2bc57
--- /dev/null
+++ b/arch/arm/mach-digicolor/Kconfig
@@ -0,0 +1,7 @@
+config ARCH_DIGICOLOR
+ bool "Conexant Digicolor SoC Support"
+ depends on ARCH_MULTI_V7
+ select CLKSRC_MMIO
+ select DIGICOLOR_TIMER
+ select GENERIC_IRQ_CHIP
+ select MFD_SYSCON
diff --git a/arch/arm/mach-digicolor/Makefile b/arch/arm/mach-digicolor/Makefile
new file mode 100644
index 000000000000..3d8a1d228408
--- /dev/null
+++ b/arch/arm/mach-digicolor/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_DIGICOLOR) += digicolor.o
diff --git a/arch/arm/mach-digicolor/digicolor.c b/arch/arm/mach-digicolor/digicolor.c
new file mode 100644
index 000000000000..cfc88d1caa47
--- /dev/null
+++ b/arch/arm/mach-digicolor/digicolor.c
@@ -0,0 +1,18 @@
+/*
+ * Support for Conexant Digicolor SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <asm/mach/arch.h>
+
+static const char *digicolor_dt_compat[] __initconst = {
+ "cnxt,cx92755",
+ NULL,
+};
+
+DT_MACHINE_START(DIGICOLOR, "Conexant Digicolor (Flattened Device Tree)")
+ .dt_compat = digicolor_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 865f878063cc..f70eca7ee705 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -13,6 +13,7 @@
#define __ARCH_ARM_MACH_EXYNOS_COMMON_H
#include <linux/of.h>
+#include <linux/platform_data/cpuidle-exynos.h>
#define EXYNOS3250_SOC_ID 0xE3472000
#define EXYNOS3_SOC_MASK 0xFFFFF000
@@ -150,8 +151,11 @@ extern void exynos_pm_central_suspend(void);
extern int exynos_pm_central_resume(void);
extern void exynos_enter_aftr(void);
+extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
+
extern void s5p_init_cpu(void __iomem *cpuid_addr);
extern unsigned int samsung_rev(void);
+extern void __iomem *cpu_boot_reg_base(void);
static inline void pmu_raw_writel(u32 val, u32 offset)
{
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index c13d0837fa8c..2013f73797ed 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -27,20 +27,16 @@
#include <asm/mach/map.h>
#include <asm/memory.h>
+#include <mach/map.h>
+
#include "common.h"
#include "mfc.h"
#include "regs-pmu.h"
-#include "regs-sys.h"
void __iomem *pmu_base_addr;
static struct map_desc exynos4_iodesc[] __initdata = {
{
- .virtual = (unsigned long)S3C_VA_SYS,
- .pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON),
- .length = SZ_64K,
- .type = MT_DEVICE,
- }, {
.virtual = (unsigned long)S5P_VA_SROMC,
.pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
.length = SZ_4K,
@@ -70,11 +66,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
static struct map_desc exynos5_iodesc[] __initdata = {
{
- .virtual = (unsigned long)S3C_VA_SYS,
- .pfn = __phys_to_pfn(EXYNOS5_PA_SYSCON),
- .length = SZ_64K,
- .type = MT_DEVICE,
- }, {
.virtual = (unsigned long)S5P_VA_SROMC,
.pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
.length = SZ_4K,
@@ -213,32 +204,6 @@ static void __init exynos_init_irq(void)
static void __init exynos_dt_machine_init(void)
{
- struct device_node *i2c_np;
- const char *i2c_compat = "samsung,s3c2440-i2c";
- unsigned int tmp;
- int id;
-
- /*
- * Exynos5's legacy i2c controller and new high speed i2c
- * controller have muxed interrupt sources. By default the
- * interrupts for 4-channel HS-I2C controller are enabled.
- * If node for first four channels of legacy i2c controller
- * are available then re-configure the interrupts via the
- * system register.
- */
- if (soc_is_exynos5()) {
- for_each_compatible_node(i2c_np, NULL, i2c_compat) {
- if (of_device_is_available(i2c_np)) {
- id = of_alias_get_id(i2c_np, "i2c");
- if (id < 4) {
- tmp = readl(EXYNOS5_SYS_I2C_CFG);
- writel(tmp & ~(0x1 << id),
- EXYNOS5_SYS_I2C_CFG);
- }
- }
- }
- }
-
/*
* This is called from smp_prepare_cpus if we've built for SMP, but
* we still need to set it up for PM and firmware ops if not.
@@ -246,6 +211,10 @@ static void __init exynos_dt_machine_init(void)
if (!IS_ENABLED(CONFIG_SMP))
exynos_sysram_init();
+#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
+ if (of_machine_is_compatible("samsung,exynos4210"))
+ exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data;
+#endif
if (of_machine_is_compatible("samsung,exynos4210") ||
of_machine_is_compatible("samsung,exynos4212") ||
(of_machine_is_compatible("samsung,exynos4412") &&
@@ -282,6 +251,7 @@ static void __init exynos_reserve(void)
"samsung,mfc-v5",
"samsung,mfc-v6",
"samsung,mfc-v7",
+ "samsung,mfc-v8",
};
for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
diff --git a/arch/arm/mach-exynos/include/mach/dma.h b/arch/arm/mach-exynos/include/mach/dma.h
deleted file mode 100644
index 201842a3769e..000000000000
--- a/arch/arm/mach-exynos/include/mach/dma.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MACH_DMA_H
-#define __MACH_DMA_H
-
-/* This platform uses the common DMA API driver for PL330 */
-#include <plat/dma-pl330.h>
-
-#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 1ad3f496ef56..de3ae59e1cfb 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -24,9 +24,6 @@
#define EXYNOS_PA_CHIPID 0x10000000
-#define EXYNOS4_PA_SYSCON 0x10010000
-#define EXYNOS5_PA_SYSCON 0x10050100
-
#define EXYNOS4_PA_CMU 0x10030000
#define EXYNOS5_PA_CMU 0x10010000
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 7a1ebfeeeeb8..3f32c47a6d74 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -194,7 +194,7 @@ int exynos_cluster_power_state(int cluster)
S5P_CORE_LOCAL_PWR_EN);
}
-static inline void __iomem *cpu_boot_reg_base(void)
+void __iomem *cpu_boot_reg_base(void)
{
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
return pmu_base_addr + S5P_INFORM5;
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 86f3ecd88f78..e6209dadc00d 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -23,12 +23,13 @@
#include <asm/smp_scu.h>
#include <asm/suspend.h>
+#include <mach/map.h>
+
#include <plat/pm-common.h>
#include "common.h"
#include "exynos-pmu.h"
#include "regs-pmu.h"
-#include "regs-sys.h"
static inline void __iomem *exynos_boot_vector_addr(void)
{
@@ -97,10 +98,6 @@ void exynos_pm_central_suspend(void)
tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-
- /* Setting SEQ_OPTION register */
- pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
- S5P_CENTRAL_SEQ_OPTION);
}
int exynos_pm_central_resume(void)
@@ -164,6 +161,13 @@ void exynos_enter_aftr(void)
exynos_pm_central_suspend();
+ if (of_machine_is_compatible("samsung,exynos4212") ||
+ of_machine_is_compatible("samsung,exynos4412")) {
+ /* Setting SEQ_OPTION register */
+ pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
+ S5P_CENTRAL_SEQ_OPTION);
+ }
+
cpu_suspend(0, exynos_aftr_finisher);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
@@ -176,3 +180,125 @@ void exynos_enter_aftr(void)
cpu_pm_exit();
}
+
+static atomic_t cpu1_wakeup = ATOMIC_INIT(0);
+
+static int exynos_cpu0_enter_aftr(void)
+{
+ int ret = -1;
+
+ /*
+ * If the other cpu is powered on, we have to power it off, because
+ * the AFTR state won't work otherwise
+ */
+ if (cpu_online(1)) {
+ /*
+ * We reach a sync point with the coupled idle state, we know
+ * the other cpu will power down itself or will abort the
+ * sequence, let's wait for one of these to happen
+ */
+ while (exynos_cpu_power_state(1)) {
+ /*
+ * The other cpu may skip idle and boot back
+ * up again
+ */
+ if (atomic_read(&cpu1_wakeup))
+ goto abort;
+
+ /*
+ * The other cpu may bounce through idle and
+ * boot back up again, getting stuck in the
+ * boot rom code
+ */
+ if (__raw_readl(cpu_boot_reg_base()) == 0)
+ goto abort;
+
+ cpu_relax();
+ }
+ }
+
+ exynos_enter_aftr();
+ ret = 0;
+
+abort:
+ if (cpu_online(1)) {
+ /*
+ * Set the boot vector to something non-zero
+ */
+ __raw_writel(virt_to_phys(exynos_cpu_resume),
+ cpu_boot_reg_base());
+ dsb();
+
+ /*
+ * Turn on cpu1 and wait for it to be on
+ */
+ exynos_cpu_power_up(1);
+ while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
+ cpu_relax();
+
+ while (!atomic_read(&cpu1_wakeup)) {
+ /*
+ * Poke cpu1 out of the boot rom
+ */
+ __raw_writel(virt_to_phys(exynos_cpu_resume),
+ cpu_boot_reg_base());
+
+ arch_send_wakeup_ipi_mask(cpumask_of(1));
+ }
+ }
+
+ return ret;
+}
+
+static int exynos_wfi_finisher(unsigned long flags)
+{
+ cpu_do_idle();
+
+ return -1;
+}
+
+static int exynos_cpu1_powerdown(void)
+{
+ int ret = -1;
+
+ /*
+ * Idle sequence for cpu1
+ */
+ if (cpu_pm_enter())
+ goto cpu1_aborted;
+
+ /*
+ * Turn off cpu 1
+ */
+ exynos_cpu_power_down(1);
+
+ ret = cpu_suspend(0, exynos_wfi_finisher);
+
+ cpu_pm_exit();
+
+cpu1_aborted:
+ dsb();
+ /*
+ * Notify cpu 0 that cpu 1 is awake
+ */
+ atomic_set(&cpu1_wakeup, 1);
+
+ return ret;
+}
+
+static void exynos_pre_enter_aftr(void)
+{
+ __raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base());
+}
+
+static void exynos_post_enter_aftr(void)
+{
+ atomic_set(&cpu1_wakeup, 0);
+}
+
+struct cpuidle_exynos_data cpuidle_coupled_exynos_data = {
+ .cpu0_enter_aftr = exynos_cpu0_enter_aftr,
+ .cpu1_powerdown = exynos_cpu1_powerdown,
+ .pre_enter_aftr = exynos_pre_enter_aftr,
+ .post_enter_aftr = exynos_post_enter_aftr,
+};
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index b5f4406fc1b5..eb461e1c325a 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -160,12 +160,14 @@
#define EXYNOS5_L2RSTDISABLE_VALUE BIT(3)
#define S5P_PAD_RET_MAUDIO_OPTION 0x3028
+#define S5P_PAD_RET_MMC2_OPTION 0x30c8
#define S5P_PAD_RET_GPIO_OPTION 0x3108
#define S5P_PAD_RET_UART_OPTION 0x3128
#define S5P_PAD_RET_MMCA_OPTION 0x3148
#define S5P_PAD_RET_MMCB_OPTION 0x3168
#define S5P_PAD_RET_EBIA_OPTION 0x3188
#define S5P_PAD_RET_EBIB_OPTION 0x31A8
+#define S5P_PAD_RET_SPI_OPTION 0x31c8
#define S5P_PS_HOLD_CONTROL 0x330C
#define S5P_PS_HOLD_EN (1 << 31)
@@ -326,6 +328,7 @@
(EXYNOS3_ARM_CORE0_OPTION + ((_nr) * 0x80))
#define EXYNOS3_ARM_COMMON_OPTION 0x2408
+#define EXYNOS3_ARM_L2_OPTION 0x2608
#define EXYNOS3_TOP_PWR_OPTION 0x2C48
#define EXYNOS3_CORE_TOP_PWR_OPTION 0x2CA8
#define EXYNOS3_XUSBXTI_DURATION 0x341C
diff --git a/arch/arm/mach-exynos/regs-sys.h b/arch/arm/mach-exynos/regs-sys.h
deleted file mode 100644
index 84332b0dd7a6..000000000000
--- a/arch/arm/mach-exynos/regs-sys.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS - system register definition
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_SYS_H
-#define __ASM_ARCH_REGS_SYS_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_SYSREG(x) (S3C_VA_SYS + (x))
-
-/* For EXYNOS5 */
-#define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x0234)
-
-#endif /* __ASM_ARCH_REGS_SYS_H */
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index f8e7dcd17055..666ec3e5b03f 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -34,7 +34,6 @@
#include "common.h"
#include "regs-pmu.h"
-#include "regs-sys.h"
#include "exynos-pmu.h"
#define S5P_CHECK_SLEEP 0x00000BAD
@@ -53,10 +52,6 @@ struct exynos_wkup_irq {
u32 mask;
};
-static struct sleep_save exynos5_sys_save[] = {
- SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
-};
-
static struct sleep_save exynos_core_save[] = {
/* SROM side */
SAVE_ITEM(S5P_SROM_BW),
@@ -91,6 +86,12 @@ static unsigned int exynos_pmu_spare3;
static u32 exynos_irqwake_intmask = 0xffffffff;
+static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
+ { 73, BIT(1) }, /* RTC alarm */
+ { 74, BIT(2) }, /* RTC tick */
+ { /* sentinel */ },
+};
+
static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
{ 76, BIT(1) }, /* RTC alarm */
{ 77, BIT(2) }, /* RTC tick */
@@ -114,6 +115,19 @@ unsigned int exynos_release_ret_regs[] = {
REG_TABLE_END,
};
+unsigned int exynos3250_release_ret_regs[] = {
+ S5P_PAD_RET_MAUDIO_OPTION,
+ S5P_PAD_RET_GPIO_OPTION,
+ S5P_PAD_RET_UART_OPTION,
+ S5P_PAD_RET_MMCA_OPTION,
+ S5P_PAD_RET_MMCB_OPTION,
+ S5P_PAD_RET_EBIA_OPTION,
+ S5P_PAD_RET_EBIB_OPTION,
+ S5P_PAD_RET_MMC2_OPTION,
+ S5P_PAD_RET_SPI_OPTION,
+ REG_TABLE_END,
+};
+
unsigned int exynos5420_release_ret_regs[] = {
EXYNOS_PAD_RET_DRAM_OPTION,
EXYNOS_PAD_RET_MAUDIO_OPTION,
@@ -173,6 +187,12 @@ static int exynos_cpu_suspend(unsigned long arg)
return exynos_cpu_do_idle();
}
+static int exynos3250_cpu_suspend(unsigned long arg)
+{
+ flush_cache_all();
+ return exynos_cpu_do_idle();
+}
+
static int exynos5420_cpu_suspend(unsigned long arg)
{
/* MCPM works with HW CPU identifiers */
@@ -230,6 +250,23 @@ static void exynos_pm_prepare(void)
pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
}
+static void exynos3250_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ /* Set wake-up mask registers */
+ exynos_pm_set_wakeup_mask();
+
+ tmp = pmu_raw_readl(EXYNOS3_ARM_L2_OPTION);
+ tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
+ pmu_raw_writel(tmp, EXYNOS3_ARM_L2_OPTION);
+
+ exynos_pm_enter_sleep_mode();
+
+ /* ensure at least INFORM0 has the resume address */
+ pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
+}
+
static void exynos5420_pm_prepare(void)
{
unsigned int tmp;
@@ -282,6 +319,10 @@ static int exynos_pm_suspend(void)
{
exynos_pm_central_suspend();
+ /* Setting SEQ_OPTION register */
+ pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
+ S5P_CENTRAL_SEQ_OPTION);
+
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_save_register();
@@ -344,6 +385,28 @@ early_wakeup:
pmu_raw_writel(0x0, S5P_INFORM1);
}
+static void exynos3250_pm_resume(void)
+{
+ u32 cpuid = read_cpuid_part();
+
+ if (exynos_pm_central_resume())
+ goto early_wakeup;
+
+ /* For release retention */
+ exynos_pm_release_retention();
+
+ pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
+
+ if (call_firmware_op(resume) == -ENOSYS
+ && cpuid == ARM_CPU_PART_CORTEX_A9)
+ exynos_cpu_restore_register();
+
+early_wakeup:
+
+ /* Clear SLEEP mode set in INFORM1 */
+ pmu_raw_writel(0x0, S5P_INFORM1);
+}
+
static void exynos5420_prepare_pm_resume(void)
{
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
@@ -483,6 +546,16 @@ static const struct platform_suspend_ops exynos_suspend_ops = {
.valid = suspend_valid_only_mem,
};
+static const struct exynos_pm_data exynos3250_pm_data = {
+ .wkup_irq = exynos3250_wkup_irq,
+ .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
+ .release_ret_regs = exynos3250_release_ret_regs,
+ .pm_suspend = exynos_pm_suspend,
+ .pm_resume = exynos3250_pm_resume,
+ .pm_prepare = exynos3250_pm_prepare,
+ .cpu_suspend = exynos3250_cpu_suspend,
+};
+
static const struct exynos_pm_data exynos4_pm_data = {
.wkup_irq = exynos4_wkup_irq,
.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
@@ -497,8 +570,6 @@ static const struct exynos_pm_data exynos5250_pm_data = {
.wkup_irq = exynos5250_wkup_irq,
.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
.release_ret_regs = exynos_release_ret_regs,
- .extra_save = exynos5_sys_save,
- .num_extra_save = ARRAY_SIZE(exynos5_sys_save),
.pm_suspend = exynos_pm_suspend,
.pm_resume = exynos_pm_resume,
.pm_prepare = exynos_pm_prepare,
@@ -518,6 +589,9 @@ static struct exynos_pm_data exynos5420_pm_data = {
static struct of_device_id exynos_pmu_of_device_ids[] = {
{
+ .compatible = "samsung,exynos3250-pmu",
+ .data = &exynos3250_pm_data,
+ }, {
.compatible = "samsung,exynos4210-pmu",
.data = &exynos4_pm_data,
}, {
diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
index cd19433f76d3..83061ad0e282 100644
--- a/arch/arm/mach-hisi/Kconfig
+++ b/arch/arm/mach-hisi/Kconfig
@@ -22,6 +22,14 @@ config ARCH_HI3xxx
help
Support for Hisilicon Hi36xx SoC family
+config ARCH_HIP01
+ bool "Hisilicon HIP01 family" if ARCH_MULTI_V7
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select ARM_GLOBAL_TIMER
+ help
+ Support for Hisilicon HIP01 SoC family
+
config ARCH_HIP04
bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
select ARM_ERRATA_798181 if SMP
diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h
index 88b1f487d065..92a682d8e939 100644
--- a/arch/arm/mach-hisi/core.h
+++ b/arch/arm/mach-hisi/core.h
@@ -12,9 +12,12 @@ extern void hi3xxx_cpu_die(unsigned int cpu);
extern int hi3xxx_cpu_kill(unsigned int cpu);
extern void hi3xxx_set_cpu(int cpu, bool enable);
-extern void hix5hd2_secondary_startup(void);
+extern void hisi_secondary_startup(void);
extern struct smp_operations hix5hd2_smp_ops;
extern void hix5hd2_set_cpu(int cpu, bool enable);
extern void hix5hd2_cpu_die(unsigned int cpu);
+extern struct smp_operations hip01_smp_ops;
+extern void hip01_set_cpu(int cpu, bool enable);
+extern void hip01_cpu_die(unsigned int cpu);
#endif
diff --git a/arch/arm/mach-hisi/headsmp.S b/arch/arm/mach-hisi/headsmp.S
index 278889c00b77..81e35b159e75 100644
--- a/arch/arm/mach-hisi/headsmp.S
+++ b/arch/arm/mach-hisi/headsmp.S
@@ -11,6 +11,6 @@
__CPUINIT
-ENTRY(hix5hd2_secondary_startup)
+ENTRY(hisi_secondary_startup)
bl v7_invalidate_l1
b secondary_startup
diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c
index 7744c351bbfd..76b907078b58 100644
--- a/arch/arm/mach-hisi/hisilicon.c
+++ b/arch/arm/mach-hisi/hisilicon.c
@@ -72,3 +72,13 @@ static const char *hip04_compat[] __initconst = {
DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)")
.dt_compat = hip04_compat,
MACHINE_END
+
+static const char *hip01_compat[] __initconst = {
+ "hisilicon,hip01",
+ "hisilicon,hip01-ca9x2",
+ NULL,
+};
+
+DT_MACHINE_START(HIP01, "Hisilicon HIP01 (Flattened Device Tree)")
+ .dt_compat = hip01_compat,
+MACHINE_END
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c
index 84e6919f68c7..a129aae72602 100644
--- a/arch/arm/mach-hisi/hotplug.c
+++ b/arch/arm/mach-hisi/hotplug.c
@@ -65,6 +65,9 @@
#define PMC0_CPU1_PMC_ENABLE (1 << 7)
#define PMC0_CPU1_POWERDOWN (1 << 3)
+#define HIP01_PERI9 0x50
+#define PERI9_CPU1_RESET (1 << 1)
+
enum {
HI3620_CTRL,
ERROR_CTRL,
@@ -209,6 +212,34 @@ void hix5hd2_set_cpu(int cpu, bool enable)
}
}
+void hip01_set_cpu(int cpu, bool enable)
+{
+ unsigned int temp;
+ struct device_node *np;
+
+ if (!ctrl_base) {
+ np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
+ if (np)
+ ctrl_base = of_iomap(np, 0);
+ else
+ BUG();
+ }
+
+ if (enable) {
+ /* reset on CPU1 */
+ temp = readl_relaxed(ctrl_base + HIP01_PERI9);
+ temp |= PERI9_CPU1_RESET;
+ writel_relaxed(temp, ctrl_base + HIP01_PERI9);
+
+ udelay(50);
+
+ /* unreset on CPU1 */
+ temp = readl_relaxed(ctrl_base + HIP01_PERI9);
+ temp &= ~PERI9_CPU1_RESET;
+ writel_relaxed(temp, ctrl_base + HIP01_PERI9);
+ }
+}
+
static inline void cpu_enter_lowpower(void)
{
unsigned int v;
diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c
index 575dd8285f1f..8880c8e8b296 100644
--- a/arch/arm/mach-hisi/platsmp.c
+++ b/arch/arm/mach-hisi/platsmp.c
@@ -10,10 +10,12 @@
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of_address.h>
+#include <linux/delay.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
+#include <asm/mach/map.h>
#include "core.h"
@@ -96,7 +98,7 @@ struct smp_operations hi3xxx_smp_ops __initdata = {
#endif
};
-static void __init hix5hd2_smp_prepare_cpus(unsigned int max_cpus)
+static void __init hisi_common_smp_prepare_cpus(unsigned int max_cpus)
{
hisi_enable_scu_a9();
}
@@ -116,7 +118,7 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
phys_addr_t jumpaddr;
- jumpaddr = virt_to_phys(hix5hd2_secondary_startup);
+ jumpaddr = virt_to_phys(hisi_secondary_startup);
hix5hd2_set_scu_boot_addr(HIX5HD2_BOOT_ADDRESS, jumpaddr);
hix5hd2_set_cpu(cpu, true);
arch_send_wakeup_ipi_mask(cpumask_of(cpu));
@@ -125,12 +127,60 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
struct smp_operations hix5hd2_smp_ops __initdata = {
- .smp_prepare_cpus = hix5hd2_smp_prepare_cpus,
+ .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
.smp_boot_secondary = hix5hd2_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = hix5hd2_cpu_die,
#endif
};
+
+#define SC_SCTL_REMAP_CLR 0x00000100
+#define HIP01_BOOT_ADDRESS 0x80000000
+#define REG_SC_CTRL 0x000
+
+void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr)
+{
+ void __iomem *virt;
+
+ virt = phys_to_virt(start_addr);
+
+ writel_relaxed(0xe51ff004, virt);
+ writel_relaxed(jump_addr, virt + 4);
+}
+
+static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ phys_addr_t jumpaddr;
+ unsigned int remap_reg_value = 0;
+ struct device_node *node;
+
+
+ jumpaddr = virt_to_phys(hisi_secondary_startup);
+ hip01_set_boot_addr(HIP01_BOOT_ADDRESS, jumpaddr);
+
+ node = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
+ if (WARN_ON(!node))
+ return -1;
+ ctrl_base = of_iomap(node, 0);
+
+ /* set the secondary core boot from DDR */
+ remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL);
+ barrier();
+ remap_reg_value |= SC_SCTL_REMAP_CLR;
+ barrier();
+ writel_relaxed(remap_reg_value, ctrl_base + REG_SC_CTRL);
+
+ hip01_set_cpu(cpu, true);
+
+ return 0;
+}
+
+struct smp_operations hip01_smp_ops __initdata = {
+ .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
+ .smp_boot_secondary = hip01_boot_secondary,
+};
+
CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops);
CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops);
+CPU_METHOD_OF_DECLARE(hip01_smp, "hisilicon,hip01-smp", &hip01_smp_ops);
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index f5ac685a29fc..8d1b10180908 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -32,8 +32,7 @@ ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
-# i.MX6SX reuses i.MX6Q cpuidle driver
-obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6q.o
+obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
endif
ifdef CONFIG_SND_IMX_SOC
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index 5a75cdc81891..8935bff99fe7 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -96,15 +96,30 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
{
struct clk_gate2 *gate = to_clk_gate2(hw);
- if (gate->share_count)
- return !!__clk_get_enable_count(hw->clk);
- else
- return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
+ return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
+}
+
+static void clk_gate2_disable_unused(struct clk_hw *hw)
+{
+ struct clk_gate2 *gate = to_clk_gate2(hw);
+ unsigned long flags = 0;
+ u32 reg;
+
+ spin_lock_irqsave(gate->lock, flags);
+
+ if (!gate->share_count || *gate->share_count == 0) {
+ reg = readl(gate->reg);
+ reg &= ~(3 << gate->bit_idx);
+ writel(reg, gate->reg);
+ }
+
+ spin_unlock_irqrestore(gate->lock, flags);
}
static struct clk_ops clk_gate2_ops = {
.enable = clk_gate2_enable,
.disable = clk_gate2_disable,
+ .disable_unused = clk_gate2_disable_unused,
.is_enabled = clk_gate2_is_enabled,
};
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 2daef619d053..d04a430607b8 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -386,7 +386,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai);
- clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ipg", base + 0x6c, 16, &share_count_esai);
+ clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai);
clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai);
clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
index 0ad6e5442fd8..641ebc508920 100644
--- a/arch/arm/mach-imx/clk-pllv3.c
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -31,6 +31,7 @@
* @base: base address of PLL registers
* @powerup_set: set POWER bit to power up the PLL
* @div_mask: mask of divider bits
+ * @div_shift: shift of divider bits
*
* IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
* is actually a multiplier, and always sits at bit 0.
@@ -40,6 +41,7 @@ struct clk_pllv3 {
void __iomem *base;
bool powerup_set;
u32 div_mask;
+ u32 div_shift;
};
#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
@@ -97,7 +99,7 @@ static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(hw);
- u32 div = readl_relaxed(pll->base) & pll->div_mask;
+ u32 div = (readl_relaxed(pll->base) >> pll->div_shift) & pll->div_mask;
return (div == 1) ? parent_rate * 22 : parent_rate * 20;
}
@@ -125,8 +127,8 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
return -EINVAL;
val = readl_relaxed(pll->base);
- val &= ~pll->div_mask;
- val |= div;
+ val &= ~(pll->div_mask << pll->div_shift);
+ val |= (div << pll->div_shift);
writel_relaxed(val, pll->base);
return clk_pllv3_wait_lock(pll);
@@ -295,6 +297,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
case IMX_PLLV3_SYS:
ops = &clk_pllv3_sys_ops;
break;
+ case IMX_PLLV3_USB_VF610:
+ pll->div_shift = 1;
case IMX_PLLV3_USB:
ops = &clk_pllv3_ops;
pll->powerup_set = true;
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
index 5937ddee1a99..61876ed6e11e 100644
--- a/arch/arm/mach-imx/clk-vf610.c
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -172,11 +172,11 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1);
clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1);
- clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x1);
+ clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2);
clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f);
clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3);
clk[VF610_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_AV, "pll6", "pll6_bypass_src", PLL6_CTRL, 0x7f);
- clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x1);
+ clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x2);
clk[VF610_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", PLL1_CTRL, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
clk[VF610_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", PLL2_CTRL, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
@@ -267,6 +267,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8));
clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9));
clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10));
+ clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9));
+ clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10));
clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
@@ -380,6 +382,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1));
clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2));
+ clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
+
imx_check_clocks(clk, ARRAY_SIZE(clk));
clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 5ef82e2f8fc5..6a07903a28bc 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -20,6 +20,7 @@ enum imx_pllv3_type {
IMX_PLLV3_GENERIC,
IMX_PLLV3_SYS,
IMX_PLLV3_USB,
+ IMX_PLLV3_USB_VF610,
IMX_PLLV3_AV,
IMX_PLLV3_ENET,
};
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index cfcdb623d78f..1028b6c505c4 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -70,6 +70,10 @@ void imx_set_soc_revision(unsigned int rev);
unsigned int imx_get_soc_revision(void);
void imx_init_revision_from_anatop(void);
struct device *imx_soc_device_init(void);
+void imx6_enable_rbc(bool enable);
+void imx_gpc_set_arm_power_in_lpm(bool power_off);
+void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw);
+void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw);
enum mxc_cpu_pwr_mode {
WAIT_CLOCKED, /* wfi only */
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
new file mode 100644
index 000000000000..5a36722b089d
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/module.h>
+#include <asm/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static int imx6sx_idle_finish(unsigned long val)
+{
+ cpu_do_idle();
+
+ return 0;
+}
+
+static int imx6sx_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ imx6q_set_lpm(WAIT_UNCLOCKED);
+
+ switch (index) {
+ case 1:
+ cpu_do_idle();
+ break;
+ case 2:
+ imx6_enable_rbc(true);
+ imx_gpc_set_arm_power_in_lpm(true);
+ imx_set_cpu_jump(0, v7_cpu_resume);
+ /* Need to notify there is a cpu pm operation. */
+ cpu_pm_enter();
+ cpu_cluster_pm_enter();
+
+ cpu_suspend(0, imx6sx_idle_finish);
+
+ cpu_cluster_pm_exit();
+ cpu_pm_exit();
+ imx_gpc_set_arm_power_in_lpm(false);
+ imx6_enable_rbc(false);
+ break;
+ default:
+ break;
+ }
+
+ imx6q_set_lpm(WAIT_CLOCKED);
+
+ return index;
+}
+
+static struct cpuidle_driver imx6sx_cpuidle_driver = {
+ .name = "imx6sx_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ /* WFI */
+ ARM_CPUIDLE_WFI_STATE,
+ /* WAIT */
+ {
+ .exit_latency = 50,
+ .target_residency = 75,
+ .flags = CPUIDLE_FLAG_TIMER_STOP,
+ .enter = imx6sx_enter_wait,
+ .name = "WAIT",
+ .desc = "Clock off",
+ },
+ /* WAIT + ARM power off */
+ {
+ /*
+ * ARM gating 31us * 5 + RBC clear 65us
+ * and some margin for SW execution, here set it
+ * to 300us.
+ */
+ .exit_latency = 300,
+ .target_residency = 500,
+ .enter = imx6sx_enter_wait,
+ .name = "LOW-POWER-IDLE",
+ .desc = "ARM power off",
+ },
+ },
+ .state_count = 3,
+ .safe_state_index = 0,
+};
+
+int __init imx6sx_cpuidle_init(void)
+{
+ imx6_enable_rbc(false);
+ /*
+ * set ARM power up/down timing to the fastest,
+ * sw2iso and sw can be set to one 32K cycle = 31us
+ * except for power up sw2iso which need to be
+ * larger than LDO ramp up time.
+ */
+ imx_gpc_set_arm_power_up_timing(2, 1);
+ imx_gpc_set_arm_power_down_timing(1, 1);
+
+ return cpuidle_register(&imx6sx_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
index 24e33670417c..f9140128ba05 100644
--- a/arch/arm/mach-imx/cpuidle.h
+++ b/arch/arm/mach-imx/cpuidle.h
@@ -14,6 +14,7 @@
extern int imx5_cpuidle_init(void);
extern int imx6q_cpuidle_init(void);
extern int imx6sl_cpuidle_init(void);
+extern int imx6sx_cpuidle_init(void);
#else
static inline int imx5_cpuidle_init(void)
{
@@ -27,4 +28,8 @@ static inline int imx6sl_cpuidle_init(void)
{
return 0;
}
+static inline int imx6sx_cpuidle_init(void)
+{
+ return 0;
+}
#endif
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 5f3602ec74fa..745caa18ab2c 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -20,6 +20,10 @@
#define GPC_IMR1 0x008
#define GPC_PGC_CPU_PDN 0x2a0
+#define GPC_PGC_CPU_PUPSCR 0x2a4
+#define GPC_PGC_CPU_PDNSCR 0x2a8
+#define GPC_PGC_SW2ISO_SHIFT 0x8
+#define GPC_PGC_SW_SHIFT 0x0
#define IMR_NUM 4
@@ -27,6 +31,23 @@ static void __iomem *gpc_base;
static u32 gpc_wake_irqs[IMR_NUM];
static u32 gpc_saved_imrs[IMR_NUM];
+void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw)
+{
+ writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) |
+ (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PUPSCR);
+}
+
+void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw)
+{
+ writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) |
+ (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PDNSCR);
+}
+
+void imx_gpc_set_arm_power_in_lpm(bool power_off)
+{
+ writel_relaxed(power_off, gpc_base + GPC_PGC_CPU_PDN);
+}
+
void imx_gpc_pre_suspend(bool arm_power_off)
{
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
@@ -34,7 +55,7 @@ void imx_gpc_pre_suspend(bool arm_power_off)
/* Tell GPC to power off ARM core when suspend */
if (arm_power_off)
- writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
+ imx_gpc_set_arm_power_in_lpm(arm_power_off);
for (i = 0; i < IMR_NUM; i++) {
gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
@@ -48,7 +69,7 @@ void imx_gpc_post_resume(void)
int i;
/* Keep ARM core powered on for other low-power modes */
- writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN);
+ imx_gpc_set_arm_power_in_lpm(false);
for (i = 0; i < IMR_NUM; i++)
writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 5057d61298b7..4ad6e473cf83 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -329,7 +329,7 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
if (dev_pm_opp_disable(cpu_dev, 852000000))
pr_warn("failed to disable 852 MHz OPP\n");
}
-
+ iounmap(base);
put_node:
of_node_put(np);
}
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index 7a96c6577234..66988eb6a3a4 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -90,7 +90,7 @@ static void __init imx6sx_init_irq(void)
static void __init imx6sx_init_late(void)
{
- imx6q_cpuidle_init();
+ imx6sx_cpuidle_init();
if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index c11ab6a1dc87..2e7c75b66fe0 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -13,11 +13,14 @@
#include <asm/hardware/cache-l2x0.h>
static const char * const vf610_dt_compat[] __initconst = {
+ "fsl,vf500",
+ "fsl,vf510",
+ "fsl,vf600",
"fsl,vf610",
NULL,
};
-DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)")
+DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF5xx/VF6xx (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
.dt_compat = vf610_dt_compat,
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 5d2c1bd5f5ef..46fd695203c7 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -205,7 +205,7 @@ void imx6q_set_int_mem_clk_lpm(bool enable)
writel_relaxed(val, ccm_base + CGPR);
}
-static void imx6q_enable_rbc(bool enable)
+void imx6_enable_rbc(bool enable)
{
u32 val;
@@ -359,17 +359,16 @@ static int imx6q_pm_enter(suspend_state_t state)
* RBC setting, so we do NOT need to do that here.
*/
if (!imx6_suspend_in_ocram_fn)
- imx6q_enable_rbc(true);
+ imx6_enable_rbc(true);
imx_gpc_pre_suspend(true);
imx_anatop_pre_suspend();
- imx_set_cpu_jump(0, v7_cpu_resume);
/* Zzz ... */
cpu_suspend(0, imx6q_suspend_finish);
if (cpu_is_imx6q() || cpu_is_imx6dl())
imx_smp_prepare();
imx_anatop_post_resume();
imx_gpc_post_resume();
- imx6q_enable_rbc(false);
+ imx6_enable_rbc(false);
imx6q_enable_wb(false);
imx6q_set_int_mem_clk_lpm(true);
imx6q_set_lpm(WAIT_CLOCKED);
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index f73f588f649c..f7e463ca0287 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -1,6 +1,26 @@
-config ARCH_MEDIATEK
+menuconfig ARCH_MEDIATEK
bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
select ARM_GIC
select MTK_TIMER
help
Support for Mediatek MT65xx & MT81xx SoCs
+
+if ARCH_MEDIATEK
+
+config MACH_MT6589
+ bool "MediaTek MT6589 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT6592
+ bool "MediaTek MT6592 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT8127
+ bool "MediaTek MT8127 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT8135
+ bool "MediaTek MT8135 SoCs support"
+ default ARCH_MEDIATEK
+
+endif
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index ccef8806bb58..b5895f040caa 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -33,6 +33,7 @@
#include <asm/smp_plat.h>
#include <asm/cacheflush.h>
#include <asm/mach/map.h>
+#include <asm/dma-mapping.h>
#include "coherency.h"
#include "mvebu-soc-id.h"
@@ -76,54 +77,6 @@ int set_cpu_coherent(void)
return ll_enable_coherency();
}
-static inline void mvebu_hwcc_sync_io_barrier(void)
-{
- writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET);
- while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1);
-}
-
-static dma_addr_t mvebu_hwcc_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir,
- struct dma_attrs *attrs)
-{
- if (dir != DMA_TO_DEVICE)
- mvebu_hwcc_sync_io_barrier();
- return pfn_to_dma(dev, page_to_pfn(page)) + offset;
-}
-
-
-static void mvebu_hwcc_dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir,
- struct dma_attrs *attrs)
-{
- if (dir != DMA_TO_DEVICE)
- mvebu_hwcc_sync_io_barrier();
-}
-
-static void mvebu_hwcc_dma_sync(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir)
-{
- if (dir != DMA_TO_DEVICE)
- mvebu_hwcc_sync_io_barrier();
-}
-
-static struct dma_map_ops mvebu_hwcc_dma_ops = {
- .alloc = arm_dma_alloc,
- .free = arm_dma_free,
- .mmap = arm_dma_mmap,
- .map_page = mvebu_hwcc_dma_map_page,
- .unmap_page = mvebu_hwcc_dma_unmap_page,
- .get_sgtable = arm_dma_get_sgtable,
- .map_sg = arm_dma_map_sg,
- .unmap_sg = arm_dma_unmap_sg,
- .sync_single_for_cpu = mvebu_hwcc_dma_sync,
- .sync_single_for_device = mvebu_hwcc_dma_sync,
- .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
- .sync_sg_for_device = arm_dma_sync_sg_for_device,
- .set_dma_mask = arm_dma_set_mask,
-};
-
static int mvebu_hwcc_notifier(struct notifier_block *nb,
unsigned long event, void *__dev)
{
@@ -131,7 +84,7 @@ static int mvebu_hwcc_notifier(struct notifier_block *nb,
if (event != BUS_NOTIFY_ADD_DEVICE)
return NOTIFY_DONE;
- set_dma_ops(dev, &mvebu_hwcc_dma_ops);
+ set_dma_ops(dev, &arm_coherent_dma_ops);
return NOTIFY_OK;
}
@@ -253,14 +206,9 @@ static int coherency_type(void)
return type;
}
-/*
- * As a precaution, we currently completely disable hardware I/O
- * coherency, until enough testing is done with automatic I/O
- * synchronization barriers to validate that it is a proper solution.
- */
int coherency_available(void)
{
- return false;
+ return coherency_type() != COHERENCY_FABRIC_TYPE_NONE;
}
int __init coherency_init(void)
diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.h b/arch/arm/mach-mvebu/mvebu-soc-id.h
index c16bb68ca81f..e124a0b82a3e 100644
--- a/arch/arm/mach-mvebu/mvebu-soc-id.h
+++ b/arch/arm/mach-mvebu/mvebu-soc-id.h
@@ -20,10 +20,28 @@
#define MV78XX0_A0_REV 0x1
#define MV78XX0_B0_REV 0x2
+/* Amada 370 ID */
+#define ARMADA_370_DEV_ID 0x6710
+
+/* Amada 370 Revision */
+#define ARMADA_370_A1_REV 0x1
+
+/* Armada 375 ID */
+#define ARMADA_375_DEV_ID 0x6720
+
/* Armada 375 */
#define ARMADA_375_Z1_REV 0x0
#define ARMADA_375_A0_REV 0x3
+/* Armada 38x ID */
+#define ARMADA_380_DEV_ID 0x6810
+#define ARMADA_385_DEV_ID 0x6820
+#define ARMADA_388_DEV_ID 0x6828
+
+/* Armada 38x Revision */
+#define ARMADA_38x_Z1_REV 0x0
+#define ARMADA_38x_A0_REV 0x4
+
#ifdef CONFIG_ARCH_MVEBU
int mvebu_get_soc_id(u32 *dev, u32 *rev);
#else
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 122ef67939a2..a8a533df24e1 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -64,11 +64,6 @@ u32 omap_irq_flags;
static unsigned int irq_bank_count;
static struct omap_irq_bank *irq_banks;
-static inline unsigned int irq_bank_readl(int bank, int offset)
-{
- return omap_readl(irq_banks[bank].base_reg + offset);
-}
-
static inline void irq_bank_writel(unsigned long value, int bank, int offset)
{
omap_writel(value, irq_banks[bank].base_reg + offset);
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 107e7ab3edba..36bf174b3fac 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -91,11 +91,6 @@ static inline void omap_32k_timer_write(int val, int reg)
omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
}
-static inline unsigned long omap_32k_timer_read(int reg)
-{
- return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
-}
-
static inline void omap_32k_timer_start(unsigned long load_val)
{
if (!load_val)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 6ab656cc4f16..2b8e47788062 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -217,12 +217,6 @@ config MACH_OMAP3517EVM
bool "OMAP3517/ AM3517 EVM board"
depends on ARCH_OMAP3
default y
- select OMAP_PACKAGE_CBB
-
-config MACH_CRANEBOARD
- bool "AM3517/05 CRANE board"
- depends on ARCH_OMAP3
- select OMAP_PACKAGE_CBB
config MACH_OMAP3_PANDORA
bool "OMAP3 Pandora"
@@ -263,12 +257,6 @@ config MACH_CM_T35
select MACH_CM_T3730
select OMAP_PACKAGE_CUS
-config MACH_CM_T3517
- bool "CompuLab CM-T3517 module"
- depends on ARCH_OMAP3
- default y
- select OMAP_PACKAGE_CBB
-
config MACH_CM_T3730
bool
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 5d27dfdef66b..00d5d8f9f150 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -58,6 +58,7 @@ AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
# Restart code (OMAP4/5 currently in omap4-common.c)
obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o
obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o
+obj-$(CONFIG_SOC_TI81XX) += ti81xx-restart.o
obj-$(CONFIG_SOC_AM33XX) += am33xx-restart.o
obj-$(CONFIG_SOC_AM43XX) += omap4-restart.o
obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o
@@ -120,6 +121,7 @@ obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common)
obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common)
obj-$(CONFIG_SOC_DRA7XX) += $(omap-prcm-4-5-common)
am33xx-43xx-prcm-common += prm33xx.o cm33xx.o
+obj-$(CONFIG_SOC_TI81XX) += $(am33xx-43xx-prcm-common)
obj-$(CONFIG_SOC_AM33XX) += $(am33xx-43xx-prcm-common)
obj-$(CONFIG_SOC_AM43XX) += $(omap-prcm-4-5-common) \
$(am33xx-43xx-prcm-common)
@@ -170,6 +172,8 @@ obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common)
obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o
+obj-$(CONFIG_SOC_TI81XX) += $(clockdomain-common)
+obj-$(CONFIG_SOC_TI81XX) += clockdomains81xx_data.o
obj-$(CONFIG_SOC_AM43XX) += $(clockdomain-common)
obj-$(CONFIG_SOC_AM43XX) += clockdomains43xx_data.o
obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common)
@@ -181,7 +185,6 @@ obj-$(CONFIG_SOC_DRA7XX) += clockdomains7xx_data.o
obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
-obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
@@ -223,6 +226,7 @@ obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_ipblock_data.o
obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_43xx_data.o
obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_interconnect_data.o
obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_ipblock_data.o
+obj-$(CONFIG_SOC_TI81XX) += omap_hwmod_81xx_data.o
obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o
obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o
@@ -250,13 +254,8 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o
obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
-obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o
-obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o
-
-obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
-
obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o
# Platform specific device init code
@@ -286,7 +285,4 @@ ifneq ($(CONFIG_HWSPINLOCK_OMAP),)
obj-y += hwspinlock.o
endif
-emac-$(CONFIG_TI_DAVINCI_EMAC) := am35xx-emac.o
-obj-y += $(emac-m) $(emac-y)
-
obj-y += common-board-devices.o twl-common.o dss-common.o
diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
deleted file mode 100644
index 6a6935caac1e..000000000000
--- a/arch/arm/mach-omap2/am35xx-emac.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
- *
- * Based on mach-omap2/board-am3517evm.c
- * Copyright (C) 2009 Texas Instruments Incorporated
- * Author: Ranjith Lohithakshan <ranjithl@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/err.h>
-#include <linux/davinci_emac.h>
-#include "omap_device.h"
-#include "am35xx.h"
-#include "control.h"
-#include "am35xx-emac.h"
-
-static void am35xx_enable_emac_int(void)
-{
- u32 v;
-
- v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
- v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR |
- AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR);
- omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
- omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
-}
-
-static void am35xx_disable_emac_int(void)
-{
- u32 v;
-
- v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
- v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR);
- omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
- omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
-}
-
-static struct emac_platform_data am35xx_emac_pdata = {
- .ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET,
- .ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET,
- .ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET,
- .ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE,
- .hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR,
- .version = EMAC_VERSION_2,
- .interrupt_enable = am35xx_enable_emac_int,
- .interrupt_disable = am35xx_disable_emac_int,
-};
-
-static struct mdio_platform_data am35xx_mdio_pdata;
-
-static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh,
- void *pdata, int pdata_len)
-{
- struct platform_device *pdev;
-
- pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len);
- if (IS_ERR(pdev)) {
- WARN(1, "Can't build omap_device for %s:%s.\n",
- oh->class->name, oh->name);
- return PTR_ERR(pdev);
- }
-
- return 0;
-}
-
-void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
-{
- struct omap_hwmod *oh;
- u32 v;
- int ret;
-
- oh = omap_hwmod_lookup("davinci_mdio");
- if (!oh) {
- pr_err("Could not find davinci_mdio hwmod\n");
- return;
- }
-
- am35xx_mdio_pdata.bus_freq = mdio_bus_freq;
-
- ret = omap_davinci_emac_dev_init(oh, &am35xx_mdio_pdata,
- sizeof(am35xx_mdio_pdata));
- if (ret) {
- pr_err("Could not build davinci_mdio hwmod device\n");
- return;
- }
-
- oh = omap_hwmod_lookup("davinci_emac");
- if (!oh) {
- pr_err("Could not find davinci_emac hwmod\n");
- return;
- }
-
- am35xx_emac_pdata.rmii_en = rmii_en;
-
- ret = omap_davinci_emac_dev_init(oh, &am35xx_emac_pdata,
- sizeof(am35xx_emac_pdata));
- if (ret) {
- pr_err("Could not build davinci_emac hwmod device\n");
- return;
- }
-
- v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
- v &= ~AM35XX_CPGMACSS_SW_RST;
- omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
- omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
-}
diff --git a/arch/arm/mach-omap2/am35xx-emac.h b/arch/arm/mach-omap2/am35xx-emac.h
deleted file mode 100644
index 15c6f9ce59a2..000000000000
--- a/arch/arm/mach-omap2/am35xx-emac.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#define AM35XX_DEFAULT_MDIO_FREQUENCY 1000000
-
-#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
-void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en);
-#else
-static inline void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) {}
-#endif
diff --git a/arch/arm/mach-omap2/am35xx.h b/arch/arm/mach-omap2/am35xx.h
deleted file mode 100644
index 95594495fcf6..000000000000
--- a/arch/arm/mach-omap2/am35xx.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*:
- * Address mappings and base address for AM35XX specific interconnects
- * and peripherals.
- *
- * Copyright (C) 2009 Texas Instruments
- *
- * Author: Sriramakrishnan <srk@ti.com>
- * Vaibhav Hiremath <hvaibhav@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARCH_AM35XX_H
-#define __ASM_ARCH_AM35XX_H
-
-/*
- * Base addresses
- * Note: OMAP3430 IVA2 memory space is being used for AM35xx IPSS modules
- */
-#define AM35XX_IPSS_EMAC_BASE 0x5C000000
-#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000
-#define AM35XX_IPSS_HECC_BASE 0x5C050000
-#define AM35XX_IPSS_VPFE_BASE 0x5C060000
-
-
-/* HECC module specifc offset definitions */
-#define AM35XX_HECC_SCC_HECC_OFFSET (0x0)
-#define AM35XX_HECC_SCC_RAM_OFFSET (0x3000)
-#define AM35XX_HECC_RAM_OFFSET (0x3000)
-#define AM35XX_HECC_MBOX_OFFSET (0x2000)
-#define AM35XX_HECC_INT_LINE (0x0)
-#define AM35XX_HECC_VERSION (0x1)
-
-#define AM35XX_EMAC_CNTRL_OFFSET (0x10000)
-#define AM35XX_EMAC_CNTRL_MOD_OFFSET (0x0)
-#define AM35XX_EMAC_CNTRL_RAM_OFFSET (0x20000)
-#define AM35XX_EMAC_MDIO_OFFSET (0x30000)
-#define AM35XX_IPSS_MDIO_BASE (AM35XX_IPSS_EMAC_BASE + \
- AM35XX_EMAC_MDIO_OFFSET)
-#define AM35XX_EMAC_CNTRL_RAM_SIZE (0x2000)
-#define AM35XX_EMAC_RAM_ADDR (AM3517_EMAC_BASE + \
- AM3517_EMAC_CNTRL_RAM_OFFSET)
-#define AM35XX_EMAC_HW_RAM_ADDR (0x01E20000)
-
-#endif /* __ASM_ARCH_AM35XX_H */
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
deleted file mode 100644
index 8168ddabaeda..000000000000
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Support for AM3517/05 Craneboard
- * http://www.mistralsolutions.com/products/craneboard.php
- *
- * Copyright (C) 2010 Mistral Solutions Pvt Ltd. <www.mistralsolutions.com>
- * Author: R.Srinath <srinath@mistralsolutions.com>
- *
- * Based on mach-omap2/board-am3517evm.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/mfd/tps65910.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/omap-gpmc.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include "common-board-devices.h"
-#include "board-flash.h"
-
-#include "am35xx-emac.h"
-#include "mux.h"
-#include "control.h"
-
-#define GPIO_USB_POWER 35
-#define GPIO_USB_NRESET 38
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static struct usbhs_phy_data phy_data[] __initdata = {
- {
- .port = 1,
- .reset_gpio = GPIO_USB_NRESET,
- .vcc_gpio = GPIO_USB_POWER,
- .vcc_polarity = 1,
- },
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-static struct mtd_partition crane_nand_partitions[] = {
- {
- .name = "X-Loader",
- .offset = 0,
- .size = 4 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE,
- },
- {
- .name = "U-Boot",
- .offset = MTDPART_OFS_APPEND,
- .size = 14 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE,
- },
- {
- .name = "U-Boot Env",
- .offset = MTDPART_OFS_APPEND,
- .size = 2 * NAND_BLOCK_SIZE,
- },
- {
- .name = "Kernel",
- .offset = MTDPART_OFS_APPEND,
- .size = 40 * NAND_BLOCK_SIZE,
- },
- {
- .name = "File System",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct tps65910_board tps65910_pdata = {
- .irq = 7 + OMAP_INTC_START,
- .en_ck32k_xtal = true,
-};
-
-static struct i2c_board_info __initdata tps65910_board_info[] = {
- {
- I2C_BOARD_INFO("tps65910", 0x2d),
- .platform_data = &tps65910_pdata,
- },
-};
-
-static void __init am3517_crane_i2c_init(void)
-{
- omap_register_i2c_bus(1, 2600, tps65910_board_info,
- ARRAY_SIZE(tps65910_board_info));
-}
-
-static void __init am3517_crane_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
- omap_serial_init();
- omap_sdrc_init(NULL, NULL);
- board_nand_init(crane_nand_partitions,
- ARRAY_SIZE(crane_nand_partitions), 0,
- NAND_BUSWIDTH_16, NULL);
- am3517_crane_i2c_init();
-
- /* Configure GPIO for EHCI port */
- if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) {
- pr_err("Can not configure mux for GPIO_USB_NRESET %d\n",
- GPIO_USB_NRESET);
- return;
- }
-
- if (omap_mux_init_gpio(GPIO_USB_POWER, OMAP_PIN_OUTPUT)) {
- pr_err("Can not configure mux for GPIO_USB_POWER %d\n",
- GPIO_USB_POWER);
- return;
- }
-
- usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
- usbhs_init(&usbhs_bdata);
- am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
-}
-
-MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
- .atag_offset = 0x100,
- .reserve = omap_reserve,
- .map_io = omap3_map_io,
- .init_early = am35xx_init_early,
- .init_irq = omap3_init_irq,
- .init_machine = am3517_crane_init,
- .init_late = am35xx_init_late,
- .init_time = omap3_sync32k_timer_init,
- .restart = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
deleted file mode 100644
index 1c091b3fa312..000000000000
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/board-am3517evm.c
- *
- * Copyright (C) 2009 Texas Instruments Incorporated
- * Author: Ranjith Lohithakshan <ranjithl@ti.com>
- *
- * Based on mach-omap2/board-omap3evm.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/platform_data/pca953x.h>
-#include <linux/can/platform/ti_hecc.h>
-#include <linux/davinci_emac.h>
-#include <linux/mmc/host.h>
-#include <linux/usb/musb.h>
-#include <linux/platform_data/gpio-omap.h>
-
-#include "am35xx.h"
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include <video/omapdss.h>
-#include <video/omap-panel-data.h>
-
-#include "am35xx-emac.h"
-#include "mux.h"
-#include "control.h"
-#include "hsmmc.h"
-
-#define LCD_PANEL_PWR 176
-#define LCD_PANEL_BKLIGHT_PWR 182
-#define LCD_PANEL_PWM 181
-
-static struct i2c_board_info __initdata am3517evm_i2c1_boardinfo[] = {
- {
- I2C_BOARD_INFO("s35390a", 0x30),
- },
-};
-
-/*
- * RTC - S35390A
- */
-#define GPIO_RTCS35390A_IRQ 55
-
-static void __init am3517_evm_rtc_init(void)
-{
- int r;
-
- omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP);
-
- r = gpio_request_one(GPIO_RTCS35390A_IRQ, GPIOF_IN, "rtcs35390a-irq");
- if (r < 0) {
- printk(KERN_WARNING "failed to request GPIO#%d\n",
- GPIO_RTCS35390A_IRQ);
- return;
- }
-
- am3517evm_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ);
-}
-
-/*
- * I2C GPIO Expander - TCA6416
- */
-
-/* Mounted on Base-Board */
-static struct pca953x_platform_data am3517evm_gpio_expander_info_0 = {
- .gpio_base = OMAP_MAX_GPIO_LINES,
-};
-static struct i2c_board_info __initdata am3517evm_i2c2_boardinfo[] = {
- {
- I2C_BOARD_INFO("tlv320aic23", 0x1A),
- },
- {
- I2C_BOARD_INFO("tca6416", 0x21),
- .platform_data = &am3517evm_gpio_expander_info_0,
- },
-};
-
-/* Mounted on UI Card */
-static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_1 = {
- .gpio_base = OMAP_MAX_GPIO_LINES + 16,
-};
-static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_2 = {
- .gpio_base = OMAP_MAX_GPIO_LINES + 32,
-};
-static struct i2c_board_info __initdata am3517evm_i2c3_boardinfo[] = {
- {
- I2C_BOARD_INFO("tca6416", 0x20),
- .platform_data = &am3517evm_ui_gpio_expander_info_1,
- },
- {
- I2C_BOARD_INFO("tca6416", 0x21),
- .platform_data = &am3517evm_ui_gpio_expander_info_2,
- },
-};
-
-static int __init am3517_evm_i2c_init(void)
-{
- omap_register_i2c_bus(1, 400, NULL, 0);
- omap_register_i2c_bus(2, 400, am3517evm_i2c2_boardinfo,
- ARRAY_SIZE(am3517evm_i2c2_boardinfo));
- omap_register_i2c_bus(3, 400, am3517evm_i2c3_boardinfo,
- ARRAY_SIZE(am3517evm_i2c3_boardinfo));
-
- return 0;
-}
-
-static const struct display_timing am3517_evm_lcd_videomode = {
- .pixelclock = { 0, 9000000, 0 },
-
- .hactive = { 0, 480, 0 },
- .hfront_porch = { 0, 3, 0 },
- .hback_porch = { 0, 2, 0 },
- .hsync_len = { 0, 42, 0 },
-
- .vactive = { 0, 272, 0 },
- .vfront_porch = { 0, 3, 0 },
- .vback_porch = { 0, 2, 0 },
- .vsync_len = { 0, 11, 0 },
-
- .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
- DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_POSEDGE,
-};
-
-static struct panel_dpi_platform_data am3517_evm_lcd_pdata = {
- .name = "lcd",
- .source = "dpi.0",
-
- .data_lines = 16,
-
- .display_timing = &am3517_evm_lcd_videomode,
-
- .enable_gpio = LCD_PANEL_PWR,
- .backlight_gpio = LCD_PANEL_BKLIGHT_PWR,
-};
-
-static struct platform_device am3517_evm_lcd_device = {
- .name = "panel-dpi",
- .id = 0,
- .dev.platform_data = &am3517_evm_lcd_pdata,
-};
-
-static struct connector_dvi_platform_data am3517_evm_dvi_connector_pdata = {
- .name = "dvi",
- .source = "tfp410.0",
- .i2c_bus_num = -1,
-};
-
-static struct platform_device am3517_evm_dvi_connector_device = {
- .name = "connector-dvi",
- .id = 0,
- .dev.platform_data = &am3517_evm_dvi_connector_pdata,
-};
-
-static struct encoder_tfp410_platform_data am3517_evm_tfp410_pdata = {
- .name = "tfp410.0",
- .source = "dpi.0",
- .data_lines = 24,
- .power_down_gpio = -1,
-};
-
-static struct platform_device am3517_evm_tfp410_device = {
- .name = "tfp410",
- .id = 0,
- .dev.platform_data = &am3517_evm_tfp410_pdata,
-};
-
-static struct connector_atv_platform_data am3517_evm_tv_pdata = {
- .name = "tv",
- .source = "venc.0",
- .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
- .invert_polarity = false,
-};
-
-static struct platform_device am3517_evm_tv_connector_device = {
- .name = "connector-analog-tv",
- .id = 0,
- .dev.platform_data = &am3517_evm_tv_pdata,
-};
-
-static struct omap_dss_board_info am3517_evm_dss_data = {
- .default_display_name = "lcd",
-};
-
-static void __init am3517_evm_display_init(void)
-{
- gpio_request_one(LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd panel pwm");
-
- omap_display_init(&am3517_evm_dss_data);
-
- platform_device_register(&am3517_evm_tfp410_device);
- platform_device_register(&am3517_evm_dvi_connector_device);
- platform_device_register(&am3517_evm_lcd_device);
- platform_device_register(&am3517_evm_tv_connector_device);
-}
-
-/*
- * Board initialization
- */
-
-static struct omap_musb_board_data musb_board_data = {
- .interface_type = MUSB_INTERFACE_ULPI,
- .mode = MUSB_OTG,
- .power = 500,
- .set_phy_power = am35x_musb_phy_power,
- .clear_irq = am35x_musb_clear_irq,
- .set_mode = am35x_set_mode,
- .reset = am35x_musb_reset,
-};
-
-static __init void am3517_evm_musb_init(void)
-{
- u32 devconf2;
-
- /*
- * Set up USB clock/mode in the DEVCONF2 register.
- */
- devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
-
- /* USB2.0 PHY reference clock is 13 MHz */
- devconf2 &= ~(CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE);
- devconf2 |= CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN
- | CONF2_DATPOL;
-
- omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
-
- usb_musb_init(&musb_board_data);
-}
-
-static __init void am3517_evm_mcbsp1_init(void)
-{
- u32 devconf0;
-
- /* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */
- devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- devconf0 |= OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK;
- omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
-}
-
-static struct usbhs_phy_data phy_data[] __initdata = {
- {
- .port = 1,
- .reset_gpio = 57,
- .vcc_gpio = -EINVAL,
- },
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* USB OTG DRVVBUS offset = 0x212 */
- OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-
-static struct resource am3517_hecc_resources[] = {
- {
- .start = AM35XX_IPSS_HECC_BASE,
- .end = AM35XX_IPSS_HECC_BASE + 0x3FFF,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = 24 + OMAP_INTC_START,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device am3517_hecc_device = {
- .name = "ti_hecc",
- .id = -1,
- .num_resources = ARRAY_SIZE(am3517_hecc_resources),
- .resource = am3517_hecc_resources,
-};
-
-static struct ti_hecc_platform_data am3517_evm_hecc_pdata = {
- .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
- .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
- .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
- .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
- .int_line = AM35XX_HECC_INT_LINE,
- .version = AM35XX_HECC_VERSION,
-};
-
-static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata)
-{
- am3517_hecc_device.dev.platform_data = pdata;
- platform_device_register(&am3517_hecc_device);
-}
-
-static struct omap2_hsmmc_info mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = 127,
- .gpio_wp = 126,
- },
- {
- .mmc = 2,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = 128,
- .gpio_wp = 129,
- },
- {} /* Terminator */
-};
-
-static void __init am3517_evm_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-
- am3517_evm_i2c_init();
-
- am3517_evm_display_init();
-
- omap_serial_init();
- omap_sdrc_init(NULL, NULL);
-
- /* Configure GPIO for EHCI port */
- omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
-
- usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
- usbhs_init(&usbhs_bdata);
- am3517_evm_hecc_init(&am3517_evm_hecc_pdata);
-
- /* RTC - S35390A */
- am3517_evm_rtc_init();
-
- i2c_register_board_info(1, am3517evm_i2c1_boardinfo,
- ARRAY_SIZE(am3517evm_i2c1_boardinfo));
- /*Ethernet*/
- am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
-
- /* MUSB */
- am3517_evm_musb_init();
-
- /* McBSP1 */
- am3517_evm_mcbsp1_init();
-
- /* MMC init function */
- omap_hsmmc_init(mmc);
-}
-
-MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
- .atag_offset = 0x100,
- .reserve = omap_reserve,
- .map_io = omap3_map_io,
- .init_early = am35xx_init_early,
- .init_irq = omap3_init_irq,
- .init_machine = am3517_evm_init,
- .init_late = am35xx_init_late,
- .init_time = omap3_sync32k_timer_init,
- .restart = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
deleted file mode 100644
index 794756df8529..000000000000
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/board-cm-t3517.c
- *
- * Support for the CompuLab CM-T3517 modules
- *
- * Copyright (C) 2010 CompuLab, Ltd.
- * Author: Igor Grinberg <grinberg@compulab.co.il>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/omap-gpmc.h>
-#include <linux/rtc-v3020.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mmc/host.h>
-#include <linux/can/platform/ti_hecc.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include <linux/platform_data/mtd-nand-omap2.h>
-
-#include "am35xx.h"
-
-#include "mux.h"
-#include "control.h"
-#include "hsmmc.h"
-#include "common-board-devices.h"
-#include "am35xx-emac.h"
-
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-static struct gpio_led cm_t3517_leds[] = {
- [0] = {
- .gpio = 186,
- .name = "cm-t3517:green",
- .default_trigger = "heartbeat",
- .active_low = 0,
- },
-};
-
-static struct gpio_led_platform_data cm_t3517_led_pdata = {
- .num_leds = ARRAY_SIZE(cm_t3517_leds),
- .leds = cm_t3517_leds,
-};
-
-static struct platform_device cm_t3517_led_device = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &cm_t3517_led_pdata,
- },
-};
-
-static void __init cm_t3517_init_leds(void)
-{
- platform_device_register(&cm_t3517_led_device);
-}
-#else
-static inline void cm_t3517_init_leds(void) {}
-#endif
-
-#if defined(CONFIG_CAN_TI_HECC) || defined(CONFIG_CAN_TI_HECC_MODULE)
-static struct resource cm_t3517_hecc_resources[] = {
- {
- .start = AM35XX_IPSS_HECC_BASE,
- .end = AM35XX_IPSS_HECC_BASE + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = 24 + OMAP_INTC_START,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct ti_hecc_platform_data cm_t3517_hecc_pdata = {
- .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
- .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
- .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
- .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
- .int_line = AM35XX_HECC_INT_LINE,
- .version = AM35XX_HECC_VERSION,
-};
-
-static struct platform_device cm_t3517_hecc_device = {
- .name = "ti_hecc",
- .id = 1,
- .num_resources = ARRAY_SIZE(cm_t3517_hecc_resources),
- .resource = cm_t3517_hecc_resources,
- .dev = {
- .platform_data = &cm_t3517_hecc_pdata,
- },
-};
-
-static void cm_t3517_init_hecc(void)
-{
- platform_device_register(&cm_t3517_hecc_device);
-}
-#else
-static inline void cm_t3517_init_hecc(void) {}
-#endif
-
-#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-static struct omap2_hsmmc_info cm_t3517_mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = 144,
- .gpio_wp = 59,
- },
- {
- .mmc = 2,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = -EINVAL,
- .gpio_wp = -EINVAL,
- },
- {} /* Terminator */
-};
-#else
-#define cm_t3517_mmc NULL
-#endif
-
-#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
-#define RTC_IO_GPIO (153)
-#define RTC_WR_GPIO (154)
-#define RTC_RD_GPIO (53)
-#define RTC_CS_GPIO (163)
-#define RTC_CS_EN_GPIO (160)
-
-struct v3020_platform_data cm_t3517_v3020_pdata = {
- .use_gpio = 1,
- .gpio_cs = RTC_CS_GPIO,
- .gpio_wr = RTC_WR_GPIO,
- .gpio_rd = RTC_RD_GPIO,
- .gpio_io = RTC_IO_GPIO,
-};
-
-static struct platform_device cm_t3517_rtc_device = {
- .name = "v3020",
- .id = -1,
- .dev = {
- .platform_data = &cm_t3517_v3020_pdata,
- }
-};
-
-static void __init cm_t3517_init_rtc(void)
-{
- int err;
-
- err = gpio_request_one(RTC_CS_EN_GPIO, GPIOF_OUT_INIT_HIGH,
- "rtc cs en");
- if (err) {
- pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err);
- return;
- }
-
- platform_device_register(&cm_t3517_rtc_device);
-}
-#else
-static inline void cm_t3517_init_rtc(void) {}
-#endif
-
-#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
-#define HSUSB1_RESET_GPIO (146)
-#define HSUSB2_RESET_GPIO (147)
-#define USB_HUB_RESET_GPIO (152)
-
-static struct usbhs_phy_data phy_data[] __initdata = {
- {
- .port = 1,
- .reset_gpio = HSUSB1_RESET_GPIO,
- .vcc_gpio = -EINVAL,
- },
- {
- .port = 2,
- .reset_gpio = HSUSB2_RESET_GPIO,
- .vcc_gpio = -EINVAL,
- },
-};
-
-static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-static int __init cm_t3517_init_usbh(void)
-{
- int err;
-
- err = gpio_request_one(USB_HUB_RESET_GPIO, GPIOF_OUT_INIT_LOW,
- "usb hub rst");
- if (err) {
- pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err);
- } else {
- udelay(10);
- gpio_set_value(USB_HUB_RESET_GPIO, 1);
- msleep(1);
- }
-
- usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
- usbhs_init(&cm_t3517_ehci_pdata);
-
- return 0;
-}
-#else
-static inline int cm_t3517_init_usbh(void)
-{
- return 0;
-}
-#endif
-
-#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-static struct mtd_partition cm_t3517_nand_partitions[] = {
- {
- .name = "xloader",
- .offset = 0, /* Offset = 0x00000 */
- .size = 4 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE
- },
- {
- .name = "uboot",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
- .size = 15 * NAND_BLOCK_SIZE,
- },
- {
- .name = "uboot environment",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
- .size = 2 * NAND_BLOCK_SIZE,
- },
- {
- .name = "linux",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */
- .size = 32 * NAND_BLOCK_SIZE,
- },
- {
- .name = "rootfs",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct omap_nand_platform_data cm_t3517_nand_data = {
- .parts = cm_t3517_nand_partitions,
- .nr_parts = ARRAY_SIZE(cm_t3517_nand_partitions),
- .cs = 0,
-};
-
-static void __init cm_t3517_init_nand(void)
-{
- if (gpmc_nand_init(&cm_t3517_nand_data, NULL) < 0)
- pr_err("CM-T3517: NAND initialization failed\n");
-}
-#else
-static inline void cm_t3517_init_nand(void) {}
-#endif
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* GPIO186 - Green LED */
- OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-
- /* RTC GPIOs: */
- /* IO - GPIO153 */
- OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* WR# - GPIO154 */
- OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* RD# - GPIO53 */
- OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* CS# - GPIO163 */
- OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* CS EN - GPIO160 */
- OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-
- /* HSUSB1 RESET */
- OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
- /* HSUSB2 RESET */
- OMAP3_MUX(UART2_RX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
- /* CM-T3517 USB HUB nRESET */
- OMAP3_MUX(MCBSP4_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-
- /* CD - GPIO144 and WP - GPIO59 for MMC1 - SB-T35 */
- OMAP3_MUX(UART2_CTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(GPMC_CLK, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
-
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static void __init cm_t3517_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
- omap_serial_init();
- omap_sdrc_init(NULL, NULL);
- cm_t3517_init_leds();
- cm_t3517_init_nand();
- cm_t3517_init_rtc();
- cm_t3517_init_usbh();
- cm_t3517_init_hecc();
- am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
- omap_hsmmc_init(cm_t3517_mmc);
-}
-
-MACHINE_START(CM_T3517, "Compulab CM-T3517")
- .atag_offset = 0x100,
- .reserve = omap_reserve,
- .map_io = omap3_map_io,
- .init_early = am35xx_init_early,
- .init_irq = omap3_init_irq,
- .init_machine = cm_t3517_init,
- .init_late = am35xx_init_late,
- .init_time = omap3_gptimer_timer_init,
- .restart = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 42b7f4c9169b..34ff14b7beab 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -162,6 +162,42 @@ DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)")
MACHINE_END
#endif
+#ifdef CONFIG_SOC_TI81XX
+static const char *const ti814x_boards_compat[] __initconst = {
+ "ti,dm8148",
+ "ti,dm814",
+ NULL,
+};
+
+DT_MACHINE_START(TI81XX_DT, "Generic ti814x (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = ti81xx_map_io,
+ .init_early = ti814x_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = ti81xx_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = ti814x_boards_compat,
+ .restart = ti81xx_restart,
+MACHINE_END
+
+static const char *const ti816x_boards_compat[] __initconst = {
+ "ti,dm8168",
+ "ti,dm816",
+ NULL,
+};
+
+DT_MACHINE_START(TI816X_DT, "Generic ti816x (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = ti81xx_map_io,
+ .init_early = ti816x_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = ti81xx_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = ti816x_boards_compat,
+ .restart = ti81xx_restart,
+MACHINE_END
+#endif
+
#ifdef CONFIG_SOC_AM33XX
static const char *const am33xx_boards_compat[] __initconst = {
"ti,am33xx",
diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c
index 644ff3231bb8..e79c80bbc755 100644
--- a/arch/arm/mach-omap2/cclock3xxx_data.c
+++ b/arch/arm/mach-omap2/cclock3xxx_data.c
@@ -3634,10 +3634,6 @@ int __init omap3xxx_clk_init(void)
omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks,
ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks));
omap_clocks_register(omap3xxx_clks, ARRAY_SIZE(omap3xxx_clks));
- } else if (soc_is_am33xx()) {
- cpu_mask = RATE_IN_AM33XX;
- } else if (cpu_is_ti814x()) {
- cpu_mask = RATE_IN_TI814X;
} else if (cpu_is_omap34xx()) {
if (omap_rev() == OMAP3430_REV_ES1_0) {
cpu_mask = RATE_IN_3430ES1;
@@ -3681,7 +3677,7 @@ int __init omap3xxx_clk_init(void)
* Lock DPLL5 -- here only until other device init code can
* handle this
*/
- if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0))
+ if (omap_rev() >= OMAP3430_REV_ES2_0)
omap3_clk_lock_dpll5();
/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
deleted file mode 100644
index c78e893eba7d..000000000000
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * OMAP2xxx APLL clock control functions
- *
- * Copyright (C) 2005-2008 Texas Instruments, Inc.
- * Copyright (C) 2004-2010 Nokia Corporation
- *
- * Contacts:
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
- *
- * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
- * Gordon McNutt and RidgeRun, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#undef DEBUG
-
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-
-#include "clock.h"
-#include "clock2xxx.h"
-#include "cm2xxx.h"
-#include "cm-regbits-24xx.h"
-
-/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
-#define EN_APLL_STOPPED 0
-#define EN_APLL_LOCKED 3
-
-/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
-#define APLLS_CLKIN_19_2MHZ 0
-#define APLLS_CLKIN_13MHZ 2
-#define APLLS_CLKIN_12MHZ 3
-
-/* Private functions */
-
-/**
- * omap2xxx_clk_apll_locked - is the APLL locked?
- * @hw: struct clk_hw * of the APLL to check
- *
- * If the APLL IP block referred to by @hw indicates that it's locked,
- * return true; otherwise, return false.
- */
-static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
-{
- struct clk_hw_omap *clk = to_clk_hw_omap(hw);
- u32 r, apll_mask;
-
- apll_mask = EN_APLL_LOCKED << clk->enable_bit;
-
- r = omap2xxx_cm_get_pll_status();
-
- return ((r & apll_mask) == apll_mask) ? true : false;
-}
-
-int omap2_clk_apll96_enable(struct clk_hw *hw)
-{
- return omap2xxx_cm_apll96_enable();
-}
-
-int omap2_clk_apll54_enable(struct clk_hw *hw)
-{
- return omap2xxx_cm_apll54_enable();
-}
-
-static void _apll96_allow_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll96_auto_low_power_stop();
-}
-
-static void _apll96_deny_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll96_disable_autoidle();
-}
-
-static void _apll54_allow_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll54_auto_low_power_stop();
-}
-
-static void _apll54_deny_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll54_disable_autoidle();
-}
-
-void omap2_clk_apll96_disable(struct clk_hw *hw)
-{
- omap2xxx_cm_apll96_disable();
-}
-
-void omap2_clk_apll54_disable(struct clk_hw *hw)
-{
- omap2xxx_cm_apll54_disable();
-}
-
-unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0;
-}
-
-unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0;
-}
-
-/* Public data */
-const struct clk_hw_omap_ops clkhwops_apll54 = {
- .allow_idle = _apll54_allow_idle,
- .deny_idle = _apll54_deny_idle,
-};
-
-const struct clk_hw_omap_ops clkhwops_apll96 = {
- .allow_idle = _apll96_allow_idle,
- .deny_idle = _apll96_deny_idle,
-};
-
-/* Public functions */
-
-u32 omap2xxx_get_apll_clkin(void)
-{
- u32 aplls, srate = 0;
-
- aplls = omap2xxx_cm_get_pll_config();
- aplls &= OMAP24XX_APLLS_CLKIN_MASK;
- aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
-
- if (aplls == APLLS_CLKIN_19_2MHZ)
- srate = 19200000;
- else if (aplls == APLLS_CLKIN_13MHZ)
- srate = 13000000;
- else if (aplls == APLLS_CLKIN_12MHZ)
- srate = 12000000;
-
- return srate;
-}
-
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 6ad5b4dbd33e..4ae4ccebced2 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -620,6 +620,9 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
for (i = 0; i < num_clocks; i++) {
init_clk = clk_get(NULL, clk_names[i]);
+ if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
+ clk_names[i]))
+ continue;
clk_prepare_enable(init_clk);
}
}
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index a4282e79143e..1cf9dd85248a 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -177,7 +177,6 @@ struct clksel {
u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
-int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk);
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index a090225ceeba..125c37614848 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -22,12 +22,7 @@ unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
unsigned long parent_rate);
void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
-unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
- unsigned long parent_rate);
-unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
- unsigned long parent_rate);
unsigned long omap2xxx_clk_get_core_rate(void);
-u32 omap2xxx_get_apll_clkin(void);
u32 omap2xxx_get_sysclkdiv(void);
void omap2xxx_clk_prepare_for_reboot(void);
void omap2xxx_clkt_vps_check_bootloader_rates(void);
@@ -46,11 +41,5 @@ int omap2430_clk_init(void);
#endif
extern struct clk_hw *dclk_hw;
-int omap2_enable_osc_ck(struct clk_hw *hw);
-void omap2_disable_osc_ck(struct clk_hw *hw);
-int omap2_clk_apll96_enable(struct clk_hw *hw);
-int omap2_clk_apll54_enable(struct clk_hw *hw);
-void omap2_clk_apll96_disable(struct clk_hw *hw);
-void omap2_clk_apll54_disable(struct clk_hw *hw);
#endif
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 82c37b1becc4..77bab5fb6814 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -216,6 +216,7 @@ extern void __init omap242x_clockdomains_init(void);
extern void __init omap243x_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);
extern void __init am33xx_clockdomains_init(void);
+extern void __init ti81xx_clockdomains_init(void);
extern void __init omap44xx_clockdomains_init(void);
extern void __init omap54xx_clockdomains_init(void);
extern void __init dra7xx_clockdomains_init(void);
diff --git a/arch/arm/mach-omap2/clockdomains81xx_data.c b/arch/arm/mach-omap2/clockdomains81xx_data.c
new file mode 100644
index 000000000000..ce2a82001d0d
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains81xx_data.c
@@ -0,0 +1,194 @@
+/*
+ * TI81XX Clock Domain data.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_81XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_81XX_H
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "cm81xx.h"
+
+/*
+ * Note that 814x seems to have HWSUP_SWSUP for many clockdomains
+ * while 816x does not. According to the TRM, 816x only has HWSUP
+ * for ALWON_L3_FAST. Also note that the TI tree clockdomains81xx.h
+ * seems to have the related ifdef the wrong way around claiming
+ * 816x supports HWSUP while 814x does not. For now, we only set
+ * HWSUP for ALWON_L3_FAST as that seems to be supported for both
+ * dm814x and dm816x.
+ */
+
+/* Common for 81xx */
+
+static struct clockdomain alwon_l3_slow_81xx_clkdm = {
+ .name = "alwon_l3s_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_SLOW_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain alwon_l3_med_81xx_clkdm = {
+ .name = "alwon_l3_med_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_MED_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain alwon_l3_fast_81xx_clkdm = {
+ .name = "alwon_l3_fast_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_FAST_CLKDM,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain alwon_ethernet_81xx_clkdm = {
+ .name = "alwon_ethernet_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ETHERNET_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mmu_81xx_clkdm = {
+ .name = "mmu_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_MMU_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mmu_cfg_81xx_clkdm = {
+ .name = "mmu_cfg_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_MMUCFG_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+/* 816x only */
+
+static struct clockdomain alwon_mpu_816x_clkdm = {
+ .name = "alwon_mpu_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_MPU_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain active_gem_816x_clkdm = {
+ .name = "active_gem_clkdm",
+ .pwrdm = { .name = "active_pwrdm" },
+ .cm_inst = TI816X_CM_ACTIVE_MOD,
+ .clkdm_offs = TI816X_CM_ACTIVE_GEM_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd0_816x_clkdm = {
+ .name = "ivahd0_clkdm",
+ .pwrdm = { .name = "ivahd0_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD0_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD0_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd1_816x_clkdm = {
+ .name = "ivahd1_clkdm",
+ .pwrdm = { .name = "ivahd1_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD1_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD1_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd2_816x_clkdm = {
+ .name = "ivahd2_clkdm",
+ .pwrdm = { .name = "ivahd2_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD2_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD2_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain sgx_816x_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
+ .cm_inst = TI816X_CM_SGX_MOD,
+ .clkdm_offs = TI816X_CM_SGX_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_l3_med_816x_clkdm = {
+ .name = "default_l3_med_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_L3_MED_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_ducati_816x_clkdm = {
+ .name = "default_ducati_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_DUCATI_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_pci_816x_clkdm = {
+ .name = "default_pci_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_PCI_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_l3_slow_816x_clkdm = {
+ .name = "default_l3_slow_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_L3_SLOW_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain *clockdomains_ti81xx[] __initdata = {
+ &alwon_mpu_816x_clkdm,
+ &alwon_l3_slow_81xx_clkdm,
+ &alwon_l3_med_81xx_clkdm,
+ &alwon_l3_fast_81xx_clkdm,
+ &alwon_ethernet_81xx_clkdm,
+ &mmu_81xx_clkdm,
+ &mmu_cfg_81xx_clkdm,
+ &active_gem_816x_clkdm,
+ &ivahd0_816x_clkdm,
+ &ivahd1_816x_clkdm,
+ &ivahd2_816x_clkdm,
+ &sgx_816x_clkdm,
+ &default_l3_med_816x_clkdm,
+ &default_ducati_816x_clkdm,
+ &default_pci_816x_clkdm,
+ &default_l3_slow_816x_clkdm,
+ NULL,
+};
+
+void __init ti81xx_clockdomains_init(void)
+{
+ clkdm_register_platform_funcs(&am33xx_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_ti81xx);
+ clkdm_complete_init();
+}
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index a96d901b1d5d..ef62ac9dcd05 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -370,16 +370,6 @@ u32 omap2xxx_cm_get_core_pll_config(void)
return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
}
-u32 omap2xxx_cm_get_pll_config(void)
-{
- return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
-}
-
-u32 omap2xxx_cm_get_pll_status(void)
-{
- return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-}
-
void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm)
{
u32 tmp;
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
index c89502b168ae..83b6c597b0e1 100644
--- a/arch/arm/mach-omap2/cm2xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx.h
@@ -60,8 +60,6 @@ extern int omap2xxx_cm_fclks_active(void);
extern int omap2xxx_cm_mpu_retention_allowed(void);
extern u32 omap2xxx_cm_get_core_clk_src(void);
extern u32 omap2xxx_cm_get_core_pll_config(void);
-extern u32 omap2xxx_cm_get_pll_config(void);
-extern u32 omap2xxx_cm_get_pll_status(void);
extern void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core,
u32 mdm);
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index b9ad463a368a..cc5aac784278 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -72,27 +72,6 @@ static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
return v;
}
-static inline u32 am33xx_cm_set_reg_bits(u32 bits, s16 inst, s16 idx)
-{
- return am33xx_cm_rmw_reg_bits(bits, bits, inst, idx);
-}
-
-static inline u32 am33xx_cm_clear_reg_bits(u32 bits, s16 inst, s16 idx)
-{
- return am33xx_cm_rmw_reg_bits(bits, 0x0, inst, idx);
-}
-
-static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask)
-{
- u32 v;
-
- v = am33xx_cm_read_reg(inst, idx);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
/**
* _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
* @inst: CM instance register offset (*_INST macro)
diff --git a/arch/arm/mach-omap2/cm81xx.h b/arch/arm/mach-omap2/cm81xx.h
new file mode 100644
index 000000000000..45cb407da222
--- /dev/null
+++ b/arch/arm/mach-omap2/cm81xx.h
@@ -0,0 +1,61 @@
+/*
+ * Clock domain register offsets for TI81XX.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
+
+/* TI81XX common CM module offsets */
+#define TI81XX_CM_ALWON_MOD 0x1400 /* 1KB */
+
+/* TI816X CM module offsets */
+#define TI816X_CM_ACTIVE_MOD 0x0400 /* 256B */
+#define TI816X_CM_DEFAULT_MOD 0x0500 /* 256B */
+#define TI816X_CM_IVAHD0_MOD 0x0600 /* 256B */
+#define TI816X_CM_IVAHD1_MOD 0x0700 /* 256B */
+#define TI816X_CM_IVAHD2_MOD 0x0800 /* 256B */
+#define TI816X_CM_SGX_MOD 0x0900 /* 256B */
+
+/* ALWON */
+#define TI81XX_CM_ALWON_L3_SLOW_CLKDM 0x0000
+#define TI81XX_CM_ALWON_L3_MED_CLKDM 0x0004
+#define TI81XX_CM_ETHERNET_CLKDM 0x0004
+#define TI81XX_CM_MMU_CLKDM 0x000C
+#define TI81XX_CM_MMUCFG_CLKDM 0x0010
+#define TI81XX_CM_ALWON_MPU_CLKDM 0x001C
+#define TI81XX_CM_ALWON_L3_FAST_CLKDM 0x0030
+
+/* ACTIVE */
+#define TI816X_CM_ACTIVE_GEM_CLKDM 0x0000
+
+/* IVAHD0 */
+#define TI816X_CM_IVAHD0_CLKDM 0x0000
+
+/* IVAHD1 */
+#define TI816X_CM_IVAHD1_CLKDM 0x0000
+
+/* IVAHD2 */
+#define TI816X_CM_IVAHD2_CLKDM 0x0000
+
+/* SGX */
+#define TI816X_CM_SGX_CLKDM 0x0000
+
+/* DEFAULT */
+#define TI816X_CM_DEFAULT_L3_MED_CLKDM 0x0004
+#define TI816X_CM_DEFAULT_PCI_CLKDM 0x0010
+#define TI816X_CM_DEFAULT_L3_SLOW_CLKDM 0x0014
+#define TI816X_CM_DEFAULT_DUCATI_CLKDM 0x0018
+
+#endif
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 3933b8aa4f01..46e24581d624 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -118,7 +118,8 @@ void omap3630_init_early(void);
void omap3_init_early(void); /* Do not use this one */
void am33xx_init_early(void);
void am35xx_init_early(void);
-void ti81xx_init_early(void);
+void ti814x_init_early(void);
+void ti816x_init_early(void);
void am33xx_init_early(void);
void am43xx_init_early(void);
void am43xx_init_late(void);
@@ -171,6 +172,14 @@ static inline void omap3xxx_restart(enum reboot_mode mode, const char *cmd)
}
#endif
+#ifdef CONFIG_SOC_TI81XX
+void ti81xx_restart(enum reboot_mode mode, const char *cmd);
+#else
+static inline void ti81xx_restart(enum reboot_mode mode, const char *cmd)
+{
+}
+#endif
+
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
void omap44xx_restart(enum reboot_mode mode, const char *cmd);
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a80ac2d70bb1..b8a487181210 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -53,6 +53,7 @@
#define OMAP343X_CONTROL_GENERAL_WKUP 0xa60
/* TI81XX spefic control submodules */
+#define TI81XX_CONTROL_DEVBOOT 0x040
#define TI81XX_CONTROL_DEVCONF 0x600
/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
@@ -246,6 +247,9 @@
#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
+/* TI81XX CONTROL_DEVBOOT register offsets */
+#define TI81XX_CONTROL_STATUS (TI81XX_CONTROL_DEVBOOT + 0x000)
+
/* TI81XX CONTROL_DEVCONF register offsets */
#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000)
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 0e58e5a85d53..fc712240e5fd 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -36,26 +36,6 @@
/* Static rate multiplier for OMAP4 REGM4XEN clocks */
#define OMAP4430_REGM4XEN_MULT 4
-/* Supported only on OMAP4 */
-int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
-{
- u32 v;
- u32 mask;
-
- if (!clk || !clk->clksel_reg)
- return -EINVAL;
-
- mask = clk->flags & CLOCK_CLKOUTX2 ?
- OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
- OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
-
- v = omap2_clk_readl(clk, clk->clksel_reg);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk)
{
u32 v;
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index c25feba05818..2a2f4d56e4c8 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -56,6 +56,8 @@ int omap_type(void)
if (cpu_is_omap24xx()) {
val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
+ } else if (cpu_is_ti81xx()) {
+ val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
} else if (soc_is_am33xx() || soc_is_am43xx()) {
val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
} else if (cpu_is_omap34xx()) {
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index a1bd6affb508..e60780f05374 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -492,27 +492,6 @@ void __init am35xx_init_early(void)
omap_clk_soc_init = am35xx_dt_clk_init;
}
-void __init ti81xx_init_early(void)
-{
- omap2_set_globals_tap(OMAP343X_CLASS,
- OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
- omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
- NULL);
- omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
- omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
- omap3xxx_check_revision();
- ti81xx_check_features();
- omap3xxx_voltagedomains_init();
- omap3xxx_powerdomains_init();
- omap3xxx_clockdomains_init();
- omap3xxx_hwmod_init();
- omap_hwmod_init_postsetup();
- if (of_have_populated_dt())
- omap_clk_soc_init = ti81xx_dt_clk_init;
- else
- omap_clk_soc_init = omap3xxx_clk_init;
-}
-
void __init omap3_init_late(void)
{
omap_common_late_init();
@@ -551,11 +530,54 @@ void __init am35xx_init_late(void)
void __init ti81xx_init_late(void)
{
omap_common_late_init();
- omap3_pm_init();
omap2_clk_enable_autoidle_all();
}
#endif
+#ifdef CONFIG_SOC_TI81XX
+void __init ti814x_init_early(void)
+{
+ omap2_set_globals_tap(TI814X_CLASS,
+ OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
+ omap3xxx_check_revision();
+ ti81xx_check_features();
+ am33xx_prm_init();
+ am33xx_cm_init();
+ omap3xxx_voltagedomains_init();
+ omap3xxx_powerdomains_init();
+ ti81xx_clockdomains_init();
+ ti81xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = ti81xx_dt_clk_init;
+}
+
+void __init ti816x_init_early(void)
+{
+ omap2_set_globals_tap(TI816X_CLASS,
+ OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
+ omap3xxx_check_revision();
+ ti81xx_check_features();
+ am33xx_prm_init();
+ am33xx_cm_init();
+ omap3xxx_voltagedomains_init();
+ omap3xxx_powerdomains_init();
+ ti81xx_clockdomains_init();
+ ti81xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = ti81xx_dt_clk_init;
+}
+#endif
+
#ifdef CONFIG_SOC_AM33XX
void __init am33xx_init_early(void)
{
diff --git a/arch/arm/mach-omap2/omap-pm-noop.c b/arch/arm/mach-omap2/omap-pm-noop.c
index 6a3be2bebddb..a1ee8066958e 100644
--- a/arch/arm/mach-omap2/omap-pm-noop.c
+++ b/arch/arm/mach-omap2/omap-pm-noop.c
@@ -86,200 +86,10 @@ int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
return 0;
}
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
- long t)
-{
- if (!req_dev || !dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (t == -1)
- pr_debug("OMAP PM: remove max device latency constraint: dev %s\n",
- dev_name(dev));
- else
- pr_debug("OMAP PM: add max device latency constraint: dev %s, t = %ld usec\n",
- dev_name(dev), t);
-
- /*
- * For current Linux, this needs to map the device to a
- * powerdomain, then go through the list of current max lat
- * constraints on that powerdomain and find the smallest. If
- * the latency constraint has changed, the code should
- * recompute the state to enter for the next powerdomain
- * state. Conceivably, this code should also determine
- * whether to actually disable the device clocks or not,
- * depending on how long it takes to re-enable the clocks.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
-{
- if (!dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (t == -1)
- pr_debug("OMAP PM: remove max DMA latency constraint: dev %s\n",
- dev_name(dev));
- else
- pr_debug("OMAP PM: add max DMA latency constraint: dev %s, t = %ld usec\n",
- dev_name(dev), t);
-
- /*
- * For current Linux PM QOS params, this code should scan the
- * list of maximum CPU and DMA latencies and select the
- * smallest, then set cpu_dma_latency pm_qos_param
- * accordingly.
- *
- * For future Linux PM QOS params, with separate CPU and DMA
- * latency params, this code should just set the dma_latency param.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
-{
- if (!dev || !c || r < 0) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (r == 0)
- pr_debug("OMAP PM: remove min clk rate constraint: dev %s\n",
- dev_name(dev));
- else
- pr_debug("OMAP PM: add min clk rate constraint: dev %s, rate = %ld Hz\n",
- dev_name(dev), r);
-
- /*
- * Code in a real implementation should keep track of these
- * constraints on the clock, and determine the highest minimum
- * clock rate. It should iterate over each OPP and determine
- * whether the OPP will result in a clock rate that would
- * satisfy this constraint (and any other PM constraint in effect
- * at that time). Once it finds the lowest-voltage OPP that
- * meets those conditions, it should switch to it, or return
- * an error if the code is not capable of doing so.
- */
-
- return 0;
-}
-
/*
* DSP Bridge-specific constraints
*/
-const struct omap_opp *omap_pm_dsp_get_opp_table(void)
-{
- pr_debug("OMAP PM: DSP request for OPP table\n");
-
- /*
- * Return DSP frequency table here: The final item in the
- * array should have .rate = .opp_id = 0.
- */
-
- return NULL;
-}
-
-void omap_pm_dsp_set_min_opp(u8 opp_id)
-{
- if (opp_id == 0) {
- WARN_ON(1);
- return;
- }
-
- pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
-
- /*
- *
- * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
- * can just test to see which is higher, the CPU's desired OPP
- * ID or the DSP's desired OPP ID, and use whichever is
- * highest.
- *
- * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
- * rate is keyed on MPU speed, not the OPP ID. So we need to
- * map the OPP ID to the MPU speed for use with clk_set_rate()
- * if it is higher than the current OPP clock rate.
- *
- */
-}
-
-
-u8 omap_pm_dsp_get_opp(void)
-{
- pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
-
- /*
- * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
- *
- * CDP12.14+:
- * Call clk_get_rate() on the OPP custom clock, map that to an
- * OPP ID using the tables defined in board-*.c/chip-*.c files.
- */
-
- return 0;
-}
-
-/*
- * CPUFreq-originated constraint
- *
- * In the future, this should be handled by custom OPP clocktype
- * functions.
- */
-
-struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
-{
- pr_debug("OMAP PM: CPUFreq request for frequency table\n");
-
- /*
- * Return CPUFreq frequency table here: loop over
- * all VDD1 clkrates, pull out the mpu_ck frequencies, build
- * table
- */
-
- return NULL;
-}
-
-void omap_pm_cpu_set_freq(unsigned long f)
-{
- if (f == 0) {
- WARN_ON(1);
- return;
- }
-
- pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
- f);
-
- /*
- * For l-o dev tree, determine whether MPU freq or DSP OPP id
- * freq is higher. Find the OPP ID corresponding to the
- * higher frequency. Call clk_round_rate() and clk_set_rate()
- * on the OPP custom clock.
- *
- * CDP should just be able to set the VDD1 OPP clock rate here.
- */
-}
-
-unsigned long omap_pm_cpu_get_freq(void)
-{
- pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
-
- /*
- * Call clk_get_rate() on the mpu_ck.
- */
-
- return 0;
-}
/**
* omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
@@ -363,9 +173,3 @@ int __init omap_pm_if_init(void)
{
return 0;
}
-
-void omap_pm_if_exit(void)
-{
- /* Deallocate CPUFreq frequency table here */
-}
-
diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h
index 1d777e63e05c..109bef5538eb 100644
--- a/arch/arm/mach-omap2/omap-pm.h
+++ b/arch/arm/mach-omap2/omap-pm.h
@@ -50,14 +50,6 @@ int __init omap_pm_if_early_init(void);
*/
int __init omap_pm_if_init(void);
-/**
- * omap_pm_if_exit - OMAP PM exit code
- *
- * Exit code; currently unused. The "_if_" is to avoid name
- * collisions with the PM idle-loop code.
- */
-void omap_pm_if_exit(void);
-
/*
* Device-driver-originated constraints (via board-*.c files, platform_data)
*/
@@ -132,163 +124,6 @@ int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
-/**
- * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
- * @req_dev: struct device * requesting the constraint, or NULL if none
- * @dev: struct device * to set the constraint one
- * @t: maximum device wakeup latency in microseconds
- *
- * Request that the maximum amount of time necessary for a device @dev
- * to become accessible after its clocks are enabled should be no
- * greater than @t microseconds. Specifically, this represents the
- * time from when a device driver enables device clocks with
- * clk_enable(), to when the register reads and writes on the device
- * will succeed. This function should be called before clk_disable()
- * is called, since the power state transition decision may be made
- * during clk_disable().
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the powerdomain enclosing this
- * device into.
- *
- * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
- * previous wakeup latency values for this device. To remove the
- * wakeup latency restriction for this device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
- long t);
-
-
-/**
- * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
- * @dev: struct device *
- * @t: maximum DMA transfer start latency in microseconds
- *
- * Request that the maximum system DMA transfer start latency for this
- * device 'dev' should be no greater than 't' microseconds. "DMA
- * transfer start latency" here is defined as the elapsed time from
- * when a device (e.g., McBSP) requests that a system DMA transfer
- * start or continue, to the time at which data starts to flow into
- * that device from the system DMA controller.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the CORE powerdomain into.
- *
- * Since system DMA transfers may not involve the MPU, this function
- * will not affect MPU wakeup latency. Use set_max_cpu_lat() to do
- * so. Similarly, this function will not affect device wakeup latency
- * -- use set_max_dev_wakeup_lat() to affect that.
- *
- * Multiple calls to set_max_sdma_lat() will replace the previous t
- * value for this device. To remove the maximum DMA latency for this
- * device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_sdma_lat(struct device *dev, long t);
-
-
-/**
- * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
- * @dev: struct device * requesting the constraint
- * @clk: struct clk * to set the minimum rate constraint on
- * @r: minimum rate in Hz
- *
- * Request that the minimum clock rate on the device @dev's clk @clk
- * be no less than @r Hz.
- *
- * It is expected that the OMAP PM code will use this information to
- * find an OPP or clock setting that will satisfy this clock rate
- * constraint, along with any other applicable system constraints on
- * the clock rate or corresponding voltage, etc.
- *
- * omap_pm_set_min_clk_rate() differs from the clock code's
- * clk_set_rate() in that it considers other constraints before taking
- * any hardware action, and may change a system OPP rather than just a
- * clock rate. clk_set_rate() is intended to be a low-level
- * interface.
- *
- * omap_pm_set_min_clk_rate() is easily open to abuse. A better API
- * would be something like "omap_pm_set_min_dev_performance()";
- * however, there is no easily-generalizable concept of performance
- * that applies to all devices. Only a device (and possibly the
- * device subsystem) has both the subsystem-specific knowledge, and
- * the hardware IP block-specific knowledge, to translate a constraint
- * on "touchscreen sampling accuracy" or "number of pixels or polygons
- * rendered per second" to a clock rate. This translation can be
- * dependent on the hardware IP block's revision, or firmware version,
- * and the driver is the only code on the system that has this
- * information and can know how to translate that into a clock rate.
- *
- * The intended use-case for this function is for userspace or other
- * kernel code to communicate a particular performance requirement to
- * a subsystem; then for the subsystem to communicate that requirement
- * to something that is meaningful to the device driver; then for the
- * device driver to convert that requirement to a clock rate, and to
- * then call omap_pm_set_min_clk_rate().
- *
- * Users of this function (such as device drivers) should not simply
- * call this function with some high clock rate to ensure "high
- * performance." Rather, the device driver should take a performance
- * constraint from its subsystem, such as "render at least X polygons
- * per second," and use some formula or table to convert that into a
- * clock rate constraint given the hardware type and hardware
- * revision. Device drivers or subsystems should not assume that they
- * know how to make a power/performance tradeoff - some device use
- * cases may tolerate a lower-fidelity device function for lower power
- * consumption; others may demand a higher-fidelity device function,
- * no matter what the power consumption.
- *
- * Multiple calls to omap_pm_set_min_clk_rate() will replace the
- * previous rate value for the device @dev. To remove the minimum clock
- * rate constraint for the device, call with r = 0.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
-
-/*
- * DSP Bridge-specific constraints
- */
-
-/**
- * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
- *
- * Intended for use by DSPBridge. Returns an array of OPP->DSP clock
- * frequency entries. The final item in the array should have .rate =
- * .opp_id = 0.
- */
-const struct omap_opp *omap_pm_dsp_get_opp_table(void);
-
-/**
- * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
- * @opp_id: target DSP OPP ID
- *
- * Set a minimum OPP ID for the DSP. This is intended to be called
- * only from the DSP Bridge MPU-side driver. Unfortunately, the only
- * information that code receives from the DSP/BIOS load estimator is the
- * target OPP ID; hence, this interface. No return value.
- */
-void omap_pm_dsp_set_min_opp(u8 opp_id);
-
-/**
- * omap_pm_dsp_get_opp - report the current DSP OPP ID
- *
- * Report the current OPP for the DSP. Since on OMAP3, the DSP and
- * MPU share a single voltage domain, the OPP ID returned back may
- * represent a higher DSP speed than the OPP requested via
- * omap_pm_dsp_set_min_opp().
- *
- * Returns the current VDD1 OPP ID, or 0 upon error.
- */
-u8 omap_pm_dsp_get_opp(void);
-
-
/*
* CPUFreq-originated constraint
*
@@ -296,33 +131,6 @@ u8 omap_pm_dsp_get_opp(void);
* functions.
*/
-/**
- * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
- *
- * Provide a frequency table usable by CPUFreq for the current chip/board.
- * Returns a pointer to a struct cpufreq_frequency_table array or NULL
- * upon error.
- */
-struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
-
-/**
- * omap_pm_cpu_set_freq - set the current minimum MPU frequency
- * @f: MPU frequency in Hz
- *
- * Set the current minimum CPU frequency. The actual CPU frequency
- * used could end up higher if the DSP requested a higher OPP.
- * Intended to be called by plat-omap/cpu_omap.c:omap_target(). No
- * return value.
- */
-void omap_pm_cpu_set_freq(unsigned long f);
-
-/**
- * omap_pm_cpu_get_freq - report the current CPU frequency
- *
- * Returns the current MPU frequency, or 0 upon error.
- */
-unsigned long omap_pm_cpu_get_freq(void);
-
/*
* Device context loss tracking
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 9025ffffd2dc..92afb723dcfc 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2155,8 +2155,8 @@ static int _enable(struct omap_hwmod *oh)
if (soc_ops.disable_module)
soc_ops.disable_module(oh);
_disable_clocks(oh);
- pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
- oh->name, r);
+ pr_err("omap_hwmod: %s: _wait_target_ready failed: %d\n",
+ oh->name, r);
if (oh->clkdm)
clkdm_hwmod_disable(oh->clkdm, oh);
@@ -3384,91 +3384,6 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
return 0;
}
-/**
- * omap_hwmod_enable_clocks - enable main_clk, all interface clocks
- * @oh: struct omap_hwmod *oh
- *
- * Intended to be called by the omap_device code.
- */
-int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&oh->_lock, flags);
- _enable_clocks(oh);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return 0;
-}
-
-/**
- * omap_hwmod_disable_clocks - disable main_clk, all interface clocks
- * @oh: struct omap_hwmod *oh
- *
- * Intended to be called by the omap_device code.
- */
-int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&oh->_lock, flags);
- _disable_clocks(oh);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return 0;
-}
-
-/**
- * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete
- * @oh: struct omap_hwmod *oh
- *
- * Intended to be called by drivers and core code when all posted
- * writes to a device must complete before continuing further
- * execution (for example, after clearing some device IRQSTATUS
- * register bits)
- *
- * XXX what about targets with multiple OCP threads?
- */
-void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
-{
- BUG_ON(!oh);
-
- if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
- WARN(1, "omap_device: %s: OCP barrier impossible due to device configuration\n",
- oh->name);
- return;
- }
-
- /*
- * Forces posted writes to complete on the OCP thread handling
- * register writes
- */
- omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
-}
-
-/**
- * omap_hwmod_reset - reset the hwmod
- * @oh: struct omap_hwmod *
- *
- * Under some conditions, a driver may wish to reset the entire device.
- * Called from omap_device code. Returns -EINVAL on error or passes along
- * the return value from _reset().
- */
-int omap_hwmod_reset(struct omap_hwmod *oh)
-{
- int r;
- unsigned long flags;
-
- if (!oh)
- return -EINVAL;
-
- spin_lock_irqsave(&oh->_lock, flags);
- r = _reset(oh);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return r;
-}
-
/*
* IP block data retrieval functions
*/
@@ -3729,52 +3644,12 @@ void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
return oh->_mpu_rt_va;
}
-/**
- * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
- * @oh: struct omap_hwmod *
- * @init_oh: struct omap_hwmod * (initiator)
- *
- * Add a sleep dependency between the initiator @init_oh and @oh.
- * Intended to be called by DSP/Bridge code via platform_data for the
- * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
- * code needs to add/del initiator dependencies dynamically
- * before/after accessing a device. Returns the return value from
- * _add_initiator_dep().
- *
- * XXX Keep a usecount in the clockdomain code
- */
-int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh)
-{
- return _add_initiator_dep(oh, init_oh);
-}
-
/*
* XXX what about functions for drivers to save/restore ocp_sysconfig
* for context save/restore operations?
*/
/**
- * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh
- * @oh: struct omap_hwmod *
- * @init_oh: struct omap_hwmod * (initiator)
- *
- * Remove a sleep dependency between the initiator @init_oh and @oh.
- * Intended to be called by DSP/Bridge code via platform_data for the
- * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
- * code needs to add/del initiator dependencies dynamically
- * before/after accessing a device. Returns the return value from
- * _del_initiator_dep().
- *
- * XXX Keep a usecount in the clockdomain code
- */
-int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh)
-{
- return _del_initiator_dep(oh, init_oh);
-}
-
-/**
* omap_hwmod_enable_wakeup - allow device to wake up the system
* @oh: struct omap_hwmod *
*
@@ -3895,33 +3770,6 @@ int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
}
/**
- * omap_hwmod_read_hardreset - read the HW reset line state of submodules
- * contained in the hwmod module
- * @oh: struct omap_hwmod *
- * @name: name of the reset line to look up and read
- *
- * Return the current state of the hwmod @oh's reset line named @name:
- * returns -EINVAL upon parameter error or if this operation
- * is unsupported on the current OMAP; otherwise, passes along the return
- * value from _read_hardreset().
- */
-int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
-{
- int ret;
- unsigned long flags;
-
- if (!oh)
- return -EINVAL;
-
- spin_lock_irqsave(&oh->_lock, flags);
- ret = _read_hardreset(oh, name);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return ret;
-}
-
-
-/**
* omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
* @classname: struct omap_hwmod_class name to search for
* @fn: callback function pointer to call for each hwmod in class @classname
@@ -4031,86 +3879,6 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
}
/**
- * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup
- * @oh: struct omap_hwmod *
- *
- * Prevent the hwmod @oh from being reset during the setup process.
- * Intended for use by board-*.c files on boards with devices that
- * cannot tolerate being reset. Must be called before the hwmod has
- * been set up. Returns 0 upon success or negative error code upon
- * failure.
- */
-int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
-{
- if (!oh)
- return -EINVAL;
-
- if (oh->_state != _HWMOD_STATE_REGISTERED) {
- pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n",
- oh->name);
- return -EINVAL;
- }
-
- oh->flags |= HWMOD_INIT_NO_RESET;
-
- return 0;
-}
-
-/**
- * omap_hwmod_pad_route_irq - route an I/O pad wakeup to a particular MPU IRQ
- * @oh: struct omap_hwmod * containing hwmod mux entries
- * @pad_idx: array index in oh->mux of the hwmod mux entry to route wakeup
- * @irq_idx: the hwmod mpu_irqs array index of the IRQ to trigger on wakeup
- *
- * When an I/O pad wakeup arrives for the dynamic or wakeup hwmod mux
- * entry number @pad_idx for the hwmod @oh, trigger the interrupt
- * service routine for the hwmod's mpu_irqs array index @irq_idx. If
- * this function is not called for a given pad_idx, then the ISR
- * associated with @oh's first MPU IRQ will be triggered when an I/O
- * pad wakeup occurs on that pad. Note that @pad_idx is the index of
- * the _dynamic or wakeup_ entry: if there are other entries not
- * marked with OMAP_DEVICE_PAD_WAKEUP or OMAP_DEVICE_PAD_REMUX, these
- * entries are NOT COUNTED in the dynamic pad index. This function
- * must be called separately for each pad that requires its interrupt
- * to be re-routed this way. Returns -EINVAL if there is an argument
- * problem or if @oh does not have hwmod mux entries or MPU IRQs;
- * returns -ENOMEM if memory cannot be allocated; or 0 upon success.
- *
- * XXX This function interface is fragile. Rather than using array
- * indexes, which are subject to unpredictable change, it should be
- * using hwmod IRQ names, and some other stable key for the hwmod mux
- * pad records.
- */
-int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
-{
- int nr_irqs;
-
- might_sleep();
-
- if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
- pad_idx >= oh->mux->nr_pads_dynamic)
- return -EINVAL;
-
- /* Check the number of available mpu_irqs */
- for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
- ;
-
- if (irq_idx >= nr_irqs)
- return -EINVAL;
-
- if (!oh->mux->irqs) {
- /* XXX What frees this? */
- oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
- GFP_KERNEL);
- if (!oh->mux->irqs)
- return -ENOMEM;
- }
- oh->mux->irqs[pad_idx] = irq_idx;
-
- return 0;
-}
-
-/**
* omap_hwmod_init - initialize the hwmod code
*
* Sets up some function pointers needed by the hwmod code to operate on the
@@ -4148,7 +3916,7 @@ void __init omap_hwmod_init(void)
soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
soc_ops.init_clkdm = _init_clkdm;
- } else if (soc_is_am33xx()) {
+ } else if (cpu_is_ti816x() || soc_is_am33xx()) {
soc_ops.enable_module = _omap4_enable_module;
soc_ops.disable_module = _omap4_disable_module;
soc_ops.wait_target_ready = _omap4_wait_target_ready;
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 5b42fafcaf55..9d4bec6ee742 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -703,13 +703,6 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh);
int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name);
int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name);
-int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);
-
-int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
-int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
-
-int omap_hwmod_reset(struct omap_hwmod *oh);
-void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
@@ -724,11 +717,6 @@ int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
-int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh);
-int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh);
-
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
@@ -740,10 +728,6 @@ int omap_hwmod_for_each_by_class(const char *classname,
int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
-int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
-
-int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
-
extern void __init omap_hwmod_init(void);
const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
@@ -764,6 +748,7 @@ extern int omap3xxx_hwmod_init(void);
extern int omap44xx_hwmod_init(void);
extern int omap54xx_hwmod_init(void);
extern int am33xx_hwmod_init(void);
+extern int ti81xx_hwmod_init(void);
extern int dra7xx_hwmod_init(void);
int am43xx_hwmod_init(void);
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 11468eea3871..4e8e93c398db 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -29,8 +29,6 @@
#include <linux/platform_data/mailbox-omap.h>
#include <plat/dmtimer.h>
-#include "am35xx.h"
-
#include "soc.h"
#include "omap_hwmod.h"
#include "omap_hwmod_common_data.h"
@@ -50,6 +48,8 @@
* elsewhere.
*/
+#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000
+
/*
* IP blocks
*/
@@ -3459,15 +3459,6 @@ static struct omap_hwmod_ocp_if am35xx_mdio__l3 = {
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space am35xx_mdio_addrs[] = {
- {
- .pa_start = AM35XX_IPSS_MDIO_BASE,
- .pa_end = AM35XX_IPSS_MDIO_BASE + SZ_4K - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
/* l4_core -> davinci mdio */
/*
* XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
@@ -3478,25 +3469,15 @@ static struct omap_hwmod_ocp_if am35xx_l4_core__mdio = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &am35xx_mdio_hwmod,
.clk = "emac_fck",
- .addr = am35xx_mdio_addrs,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_irq_info am35xx_emac_mpu_irqs[] = {
- { .name = "rxthresh", .irq = 67 + OMAP_INTC_START, },
- { .name = "rx_pulse", .irq = 68 + OMAP_INTC_START, },
- { .name = "tx_pulse", .irq = 69 + OMAP_INTC_START },
- { .name = "misc_pulse", .irq = 70 + OMAP_INTC_START },
- { .irq = -1 },
-};
-
static struct omap_hwmod_class am35xx_emac_class = {
.name = "davinci_emac",
};
static struct omap_hwmod am35xx_emac_hwmod = {
.name = "davinci_emac",
- .mpu_irqs = am35xx_emac_mpu_irqs,
.class = &am35xx_emac_class,
/*
* According to Mark Greer, the MPU will not return from WFI
@@ -3519,15 +3500,6 @@ static struct omap_hwmod_ocp_if am35xx_emac__l3 = {
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space am35xx_emac_addrs[] = {
- {
- .pa_start = AM35XX_IPSS_EMAC_BASE,
- .pa_end = AM35XX_IPSS_EMAC_BASE + 0x30000 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
/* l4_core -> davinci emac */
/*
* XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
@@ -3538,7 +3510,6 @@ static struct omap_hwmod_ocp_if am35xx_l4_core__emac = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &am35xx_emac_hwmod,
.clk = "emac_ick",
- .addr = am35xx_emac_addrs,
.user = OCP_USER_MPU,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
index 5c6c8410160e..8eb85925e444 100644
--- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -498,6 +498,7 @@ static struct omap_hwmod am43xx_dss_dispc_hwmod = {
},
},
.dev_attr = &am43xx_dss_dispc_dev_attr,
+ .parent_hwmod = &am43xx_dss_core_hwmod,
};
/* rfbi */
@@ -512,6 +513,7 @@ static struct omap_hwmod am43xx_dss_rfbi_hwmod = {
.clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET,
},
},
+ .parent_hwmod = &am43xx_dss_core_hwmod,
};
/* Interfaces */
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index ffd6604cd546..e8692e7675b8 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -819,7 +819,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = {
.name = "gpmc",
.class = &dra7xx_gpmc_hwmod_class,
.clkdm_name = "l3main1_clkdm",
- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+ HWMOD_SWSUP_SIDLE),
.main_clk = "l3_iclk_div",
.prcm = {
.omap4 = {
@@ -2017,7 +2018,7 @@ static struct omap_hwmod dra7xx_uart3_hwmod = {
.class = &dra7xx_uart_hwmod_class,
.clkdm_name = "l4per_clkdm",
.main_clk = "uart3_gfclk_mux",
- .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .flags = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP4UART3_FLAGS,
.prcm = {
.omap4 = {
.clkctrl_offs = DRA7XX_CM_L4PER_UART3_CLKCTRL_OFFSET,
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
new file mode 100644
index 000000000000..cab1eb61ac96
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -0,0 +1,1136 @@
+/*
+ * DM81xx hwmod data.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod_common_data.h"
+#include "cm81xx.h"
+#include "ti81xx.h"
+#include "wd_timer.h"
+
+/*
+ * DM816X hardware modules integration data
+ *
+ * Note: This is incomplete and at present, not generated from h/w database.
+ */
+
+/*
+ * The alwon .clkctrl_offs field is offset from the CM_ALWON, that's
+ * TRM 18.7.17 CM_ALWON device register values minus 0x1400.
+ */
+#define DM816X_DM_ALWON_BASE 0x1400
+#define DM816X_CM_ALWON_MCASP0_CLKCTRL (0x1540 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCASP1_CLKCTRL (0x1544 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCASP2_CLKCTRL (0x1548 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCBSP_CLKCTRL (0x154c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_0_CLKCTRL (0x1550 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_1_CLKCTRL (0x1554 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_2_CLKCTRL (0x1558 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPIO_0_CLKCTRL (0x155c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPIO_1_CLKCTRL (0x1560 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_I2C_0_CLKCTRL (0x1564 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_I2C_1_CLKCTRL (0x1568 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_1_CLKCTRL (0x1570 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_2_CLKCTRL (0x1574 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_3_CLKCTRL (0x1578 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_4_CLKCTRL (0x157c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_5_CLKCTRL (0x1580 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_6_CLKCTRL (0x1584 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_7_CLKCTRL (0x1588 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_WDTIMER_CLKCTRL (0x158c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SPI_CLKCTRL (0x1590 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MAILBOX_CLKCTRL (0x1594 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SPINBOX_CLKCTRL (0x1598 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MMUDATA_CLKCTRL (0x159c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MMUCFG_CLKCTRL (0x15a8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SDIO_CLKCTRL (0x15b0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_OCMC_0_CLKCTRL (0x15b4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_OCMC_1_CLKCTRL (0x15b8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_CONTRL_CLKCTRL (0x15c4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPMC_CLKCTRL (0x15d0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_ETHERNET_0_CLKCTRL (0x15d4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_ETHERNET_1_CLKCTRL (0x15d8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MPU_CLKCTRL (0x15dc - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L3_CLKCTRL (0x15e4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L4HS_CLKCTRL (0x15e8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L4LS_CLKCTRL (0x15ec - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_RTC_CLKCTRL (0x15f0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPCC_CLKCTRL (0x15f4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC0_CLKCTRL (0x15f8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC1_CLKCTRL (0x15fc - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC2_CLKCTRL (0x1600 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC3_CLKCTRL (0x1604 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SR_0_CLKCTRL (0x1608 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SR_1_CLKCTRL (0x160c - DM816X_DM_ALWON_BASE)
+
+/*
+ * The default .clkctrl_offs field is offset from CM_DEFAULT, that's
+ * TRM 18.7.6 CM_DEFAULT device register values minus 0x500
+ */
+#define DM816X_CM_DEFAULT_OFFSET 0x500
+#define DM816X_CM_DEFAULT_USB_CLKCTRL (0x558 - DM816X_CM_DEFAULT_OFFSET)
+
+/* L3 Interconnect entries clocked at 125, 250 and 500MHz */
+static struct omap_hwmod dm816x_alwon_l3_slow_hwmod = {
+ .name = "alwon_l3_slow",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_default_l3_slow_hwmod = {
+ .name = "default_l3_slow",
+ .clkdm_name = "default_l3_slow_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_alwon_l3_med_hwmod = {
+ .name = "l3_med",
+ .clkdm_name = "alwon_l3_med_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_alwon_l3_fast_hwmod = {
+ .name = "l3_fast",
+ .clkdm_name = "alwon_l3_fast_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * L4 standard peripherals, see TRM table 1-12 for devices using this.
+ * See TRM table 1-73 for devices using the 125MHz SYSCLK6 clock.
+ */
+static struct omap_hwmod dm816x_l4_ls_hwmod = {
+ .name = "l4_ls",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &l4_hwmod_class,
+};
+
+/*
+ * L4 high-speed peripherals. For devices using this, please see the TRM
+ * table 1-13. On dm816x, only EMAC, MDIO and SATA use this. See also TRM
+ * table 1-73 for devices using 250MHz SYSCLK5 clock.
+ */
+static struct omap_hwmod dm816x_l4_hs_hwmod = {
+ .name = "l4_hs",
+ .clkdm_name = "alwon_l3_med_clkdm",
+ .class = &l4_hwmod_class,
+};
+
+/* L3 slow -> L4 ls peripheral interface running at 125MHz */
+static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_ls = {
+ .master = &dm816x_alwon_l3_slow_hwmod,
+ .slave = &dm816x_l4_ls_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* L3 med -> L4 fast peripheral interface running at 250MHz */
+static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_hs = {
+ .master = &dm816x_alwon_l3_med_hwmod,
+ .slave = &dm816x_l4_hs_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* MPU */
+static struct omap_hwmod dm816x_mpu_hwmod = {
+ .name = "mpu",
+ .clkdm_name = "alwon_mpu_clkdm",
+ .class = &mpu_hwmod_class,
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "mpu_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_MPU_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_slow = {
+ .master = &dm816x_mpu_hwmod,
+ .slave = &dm816x_alwon_l3_slow_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* L3 med peripheral interface running at 250MHz */
+static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_med = {
+ .master = &dm816x_mpu_hwmod,
+ .slave = &dm816x_alwon_l3_med_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* UART common */
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_SMART_WKUP,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+static struct omap_hwmod dm816x_uart1_hwmod = {
+ .name = "uart1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART1_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_uart2_hwmod = {
+ .name = "uart2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART2_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_uart3_hwmod = {
+ .name = "uart3",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART3_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart3 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart3_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig wd_timer_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class wd_timer_class = {
+ .name = "wd_timer",
+ .sysc = &wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+ .reset = &omap2_wd_timer_reset,
+};
+
+static struct omap_hwmod dm816x_wd_timer_hwmod = {
+ .name = "wd_timer",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk18_ck",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_WDTIMER_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &wd_timer_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__wd_timer1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_wd_timer_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x90,
+ .sysc_flags = SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+static struct omap_hwmod dm81xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_I2C_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &i2c_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_i2c1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_i2c2_hwmod = {
+ .name = "i2c2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_I2C_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &i2c_class,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_elm_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_i2c2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm81xx_elm_hwmod_class = {
+ .name = "elm",
+ .sysc = &dm81xx_elm_sysc,
+};
+
+static struct omap_hwmod dm81xx_elm_hwmod = {
+ .name = "elm",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_elm_hwmod_class,
+ .main_clk = "sysclk6_ck",
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__elm = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_elm_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0114,
+ .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm81xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &dm81xx_gpio_sysc,
+ .rev = 2,
+};
+
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "sysclk18_ck" },
+};
+
+static struct omap_hwmod dm81xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpio_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPIO_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_gpio1_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "sysclk18_ck" },
+};
+
+static struct omap_hwmod dm81xx_gpio2_hwmod = {
+ .name = "gpio2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpio_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPIO_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_gpio2_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_gpmc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm81xx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &dm81xx_gpmc_sysc,
+};
+
+static struct omap_hwmod dm81xx_gpmc_hwmod = {
+ .name = "gpmc",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpmc_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = {
+ .master = &dm816x_alwon_l3_slow_hwmod,
+ .slave = &dm81xx_gpmc_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_usbhsotg_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET,
+ .idlemodes = SIDLE_SMART | MSTANDBY_FORCE | MSTANDBY_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm81xx_usbotg_class = {
+ .name = "usbotg",
+ .sysc = &dm81xx_usbhsotg_sysc,
+};
+
+static struct omap_hwmod dm81xx_usbss_hwmod = {
+ .name = "usb_otg_hs",
+ .clkdm_name = "default_l3_slow_clkdm",
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_DEFAULT_USB_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm81xx_usbotg_class,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_default_l3_slow__usbss = {
+ .master = &dm816x_default_l3_slow_hwmod,
+ .slave = &dm81xx_usbss_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm816x_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &dm816x_timer_sysc,
+};
+
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+static struct omap_hwmod dm816x_timer1_hwmod = {
+ .name = "timer1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer2_hwmod = {
+ .name = "timer2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer3_hwmod = {
+ .name = "timer3",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_3_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer3 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer3_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer4_hwmod = {
+ .name = "timer4",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_4_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer4 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer4_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer5_hwmod = {
+ .name = "timer5",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer5_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_5_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer5 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer5_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer6_hwmod = {
+ .name = "timer6",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer6_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_6_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer6 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer6_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer7_hwmod = {
+ .name = "timer7",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer7_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_7_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer7 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer7_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* EMAC Ethernet */
+static struct omap_hwmod_class_sysconfig dm816x_emac_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x4,
+ .sysc_flags = SYSC_HAS_SOFTRESET,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm816x_emac_hwmod_class = {
+ .name = "emac",
+ .sysc = &dm816x_emac_sysc,
+};
+
+/*
+ * On dm816x the MDIO is within EMAC0. As the MDIO driver is a separate
+ * driver probed before EMAC0, we let MDIO do the clock idling.
+ */
+static struct omap_hwmod dm816x_emac0_hwmod = {
+ .name = "emac0",
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .class = &dm816x_emac_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_hs__emac0 = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac0_hwmod,
+ .clk = "sysclk5_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm816x_mdio_hwmod_class = {
+ .name = "davinci_mdio",
+ .sysc = &dm816x_emac_sysc,
+};
+
+struct omap_hwmod dm816x_emac0_mdio_hwmod = {
+ .name = "davinci_mdio",
+ .class = &dm816x_mdio_hwmod_class,
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .main_clk = "sysclk24_ck",
+ .flags = HWMOD_NO_IDLEST,
+ /*
+ * REVISIT: This should be moved to the emac0_hwmod
+ * once we have a better way to handle device slaves.
+ */
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_emac0__mdio = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac0_mdio_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_emac1_hwmod = {
+ .name = "emac1",
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .main_clk = "sysclk24_ck",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm816x_emac_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac1_hwmod,
+ .clk = "sysclk5_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mmc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm816x_mmc_class = {
+ .name = "mmc",
+ .sysc = &dm816x_mmc_sysc,
+};
+
+static struct omap_hwmod_opt_clk dm816x_mmc1_opt_clks[] = {
+ { .role = "dbck", .clk = "sysclk18_ck", },
+};
+
+static struct omap_hsmmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod dm816x_mmc1_hwmod = {
+ .name = "mmc1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .opt_clks = dm816x_mmc1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dm816x_mmc1_opt_clks),
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_SDIO_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mmc1_dev_attr,
+ .class = &dm816x_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mmc1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mmc1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+ .flags = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mcspi_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm816x_mcspi_class = {
+ .name = "mcspi",
+ .sysc = &dm816x_mcspi_sysc,
+ .rev = OMAP3_MCSPI_REV,
+};
+
+static struct omap2_mcspi_dev_attr dm816x_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod dm816x_mcspi1_hwmod = {
+ .name = "mcspi1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_SPI_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm816x_mcspi_class,
+ .dev_attr = &dm816x_mcspi1_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mcspi1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mcspi1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mailbox_sysc = {
+ .rev_offs = 0x000,
+ .sysc_offs = 0x010,
+ .syss_offs = 0x014,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm816x_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &dm816x_mailbox_sysc,
+};
+
+static struct omap_hwmod dm816x_mailbox_hwmod = {
+ .name = "mailbox",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm816x_mailbox_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_MAILBOX_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mailbox = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mailbox_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm816x_tpcc_hwmod_class = {
+ .name = "tpcc",
+};
+
+struct omap_hwmod dm816x_tpcc_hwmod = {
+ .name = "tpcc",
+ .class = &dm816x_tpcc_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPCC_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tpcc = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tpcc_hwmod,
+ .clk = "sysclk4_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc0_addr_space[] = {
+ {
+ .pa_start = 0x49800000,
+ .pa_end = 0x49800000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc0_hwmod_class = {
+ .name = "tptc0",
+};
+
+struct omap_hwmod dm816x_tptc0_hwmod = {
+ .name = "tptc0",
+ .class = &dm816x_tptc0_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc0_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc0__alwon_l3_fast = {
+ .master = &dm816x_tptc0_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc1_addr_space[] = {
+ {
+ .pa_start = 0x49900000,
+ .pa_end = 0x49900000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc1_hwmod_class = {
+ .name = "tptc1",
+};
+
+struct omap_hwmod dm816x_tptc1_hwmod = {
+ .name = "tptc1",
+ .class = &dm816x_tptc1_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc1_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc1__alwon_l3_fast = {
+ .master = &dm816x_tptc1_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc2_addr_space[] = {
+ {
+ .pa_start = 0x49a00000,
+ .pa_end = 0x49a00000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc2_hwmod_class = {
+ .name = "tptc2",
+};
+
+struct omap_hwmod dm816x_tptc2_hwmod = {
+ .name = "tptc2",
+ .class = &dm816x_tptc2_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc2_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc2__alwon_l3_fast = {
+ .master = &dm816x_tptc2_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc3_addr_space[] = {
+ {
+ .pa_start = 0x49b00000,
+ .pa_end = 0x49b00000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc3_hwmod_class = {
+ .name = "tptc3",
+};
+
+struct omap_hwmod dm816x_tptc3_hwmod = {
+ .name = "tptc3",
+ .class = &dm816x_tptc3_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC3_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc3_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc3_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc3__alwon_l3_fast = {
+ .master = &dm816x_tptc3_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc3_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
+ &dm816x_mpu__alwon_l3_slow,
+ &dm816x_mpu__alwon_l3_med,
+ &dm816x_alwon_l3_slow__l4_ls,
+ &dm816x_alwon_l3_slow__l4_hs,
+ &dm816x_l4_ls__uart1,
+ &dm816x_l4_ls__uart2,
+ &dm816x_l4_ls__uart3,
+ &dm816x_l4_ls__wd_timer1,
+ &dm816x_l4_ls__i2c1,
+ &dm816x_l4_ls__i2c2,
+ &dm81xx_l4_ls__gpio1,
+ &dm81xx_l4_ls__gpio2,
+ &dm81xx_l4_ls__elm,
+ &dm816x_l4_ls__mmc1,
+ &dm816x_l4_ls__timer1,
+ &dm816x_l4_ls__timer2,
+ &dm816x_l4_ls__timer3,
+ &dm816x_l4_ls__timer4,
+ &dm816x_l4_ls__timer5,
+ &dm816x_l4_ls__timer6,
+ &dm816x_l4_ls__timer7,
+ &dm816x_l4_ls__mcspi1,
+ &dm816x_l4_ls__mailbox,
+ &dm816x_l4_hs__emac0,
+ &dm816x_emac0__mdio,
+ &dm816x_l4_hs__emac1,
+ &dm816x_alwon_l3_fast__tpcc,
+ &dm816x_alwon_l3_fast__tptc0,
+ &dm816x_alwon_l3_fast__tptc1,
+ &dm816x_alwon_l3_fast__tptc2,
+ &dm816x_alwon_l3_fast__tptc3,
+ &dm816x_tptc0__alwon_l3_fast,
+ &dm816x_tptc1__alwon_l3_fast,
+ &dm816x_tptc2__alwon_l3_fast,
+ &dm816x_tptc3__alwon_l3_fast,
+ &dm81xx_alwon_l3_slow__gpmc,
+ &dm81xx_default_l3_slow__usbss,
+ NULL,
+};
+
+int __init ti81xx_hwmod_init(void)
+{
+ omap_hwmod_init();
+ return omap_hwmod_register_links(dm816x_hwmod_ocp_ifs);
+}
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c
index 1a19fa096bab..8e903564ede2 100644
--- a/arch/arm/mach-omap2/omap_phy_internal.c
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -152,38 +152,3 @@ void am35x_set_mode(u8 musb_mode)
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
}
-
-void ti81xx_musb_phy_power(u8 on)
-{
- void __iomem *scm_base = NULL;
- u32 usbphycfg;
-
- scm_base = ioremap(TI81XX_SCM_BASE, SZ_2K);
- if (!scm_base) {
- pr_err("system control module ioremap failed\n");
- return;
- }
-
- usbphycfg = readl_relaxed(scm_base + USBCTRL0);
-
- if (on) {
- if (cpu_is_ti816x()) {
- usbphycfg |= TI816X_USBPHY0_NORMAL_MODE;
- usbphycfg &= ~TI816X_USBPHY_REFCLK_OSC;
- } else if (cpu_is_ti814x()) {
- usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN
- | USBPHY_DPINPUT | USBPHY_DMINPUT);
- usbphycfg |= (USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN
- | USBPHY_DPOPBUFCTL | USBPHY_DMOPBUFCTL);
- }
- } else {
- if (cpu_is_ti816x())
- usbphycfg &= ~TI816X_USBPHY0_NORMAL_MODE;
- else if (cpu_is_ti814x())
- usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
-
- }
- writel_relaxed(usbphycfg, scm_base + USBCTRL0);
-
- iounmap(scm_base);
-}
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 3d7eee1d3cfa..190fa43e7479 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -19,7 +19,6 @@
#include <linux/platform_data/pinctrl-single.h>
#include <linux/platform_data/iommu-omap.h>
-#include "am35xx.h"
#include "common.h"
#include "common-board-devices.h"
#include "dss-common.h"
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 33c8846b4193..a69e9a33cb6d 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -13,7 +13,7 @@
*/
#include <linux/of.h>
-#include <asm/pmu.h>
+#include <asm/system_info.h>
#include "soc.h"
#include "omap_hwmod.h"
@@ -37,7 +37,8 @@ static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
{
int i;
struct omap_hwmod *oh[3];
- char *dev_name = "arm-pmu";
+ char *dev_name = cpu_architecture() == CPU_ARCH_ARMv6 ?
+ "armv6-pmu" : "armv7-pmu";
if ((!oh_num) || (oh_num > 3))
return -EINVAL;
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 7fb033eca0a5..78af6d8cf2e2 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -115,7 +115,6 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
}
pwrdm->voltdm.ptr = voltdm;
INIT_LIST_HEAD(&pwrdm->voltdm_node);
- voltdm_add_pwrdm(voltdm, pwrdm);
skip_voltdm:
spin_lock_init(&pwrdm->_lock);
@@ -484,87 +483,6 @@ pac_exit:
}
/**
- * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
- * @pwrdm: struct powerdomain * to add the clockdomain to
- * @clkdm: struct clockdomain * to associate with a powerdomain
- *
- * Dissociate the clockdomain @clkdm from the powerdomain
- * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
- * if @clkdm was not associated with the powerdomain, or 0 upon
- * success.
- */
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
-{
- int ret = -EINVAL;
- int i;
-
- if (!pwrdm || !clkdm)
- return -EINVAL;
-
- pr_debug("powerdomain: %s: dissociating clockdomain %s\n",
- pwrdm->name, clkdm->name);
-
- for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
- if (pwrdm->pwrdm_clkdms[i] == clkdm)
- break;
-
- if (i == PWRDM_MAX_CLKDMS) {
- pr_debug("powerdomain: %s: clkdm %s not associated?!\n",
- pwrdm->name, clkdm->name);
- ret = -ENOENT;
- goto pdc_exit;
- }
-
- pwrdm->pwrdm_clkdms[i] = NULL;
-
- ret = 0;
-
-pdc_exit:
- return ret;
-}
-
-/**
- * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
- * @pwrdm: struct powerdomain * to iterate over
- * @fn: callback function *
- *
- * Call the supplied function @fn for each clockdomain in the powerdomain
- * @pwrdm. The callback function can return anything but 0 to bail
- * out early from the iterator. Returns -EINVAL if presented with
- * invalid pointers; or passes along the last return value of the
- * callback function, which should be 0 for success or anything else
- * to indicate failure.
- */
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
- int (*fn)(struct powerdomain *pwrdm,
- struct clockdomain *clkdm))
-{
- int ret = 0;
- int i;
-
- if (!fn)
- return -EINVAL;
-
- for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
- if (pwrdm->pwrdm_clkdms[i])
- ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
-
- return ret;
-}
-
-/**
- * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
- * @pwrdm: struct powerdomain *
- *
- * Return a pointer to the struct voltageomain that the specified powerdomain
- * @pwrdm exists in.
- */
-struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
-{
- return pwrdm->voltdm.ptr;
-}
-
-/**
* pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
* @pwrdm: struct powerdomain *
*
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 11bd4dd7d8d6..28a796ce07d7 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -212,11 +212,6 @@ int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
void *user);
int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
- int (*fn)(struct powerdomain *pwrdm,
- struct clockdomain *clkdm));
-struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 328c1037cb60..70bc7066a4c2 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -464,7 +464,7 @@ void __init omap3xxx_powerdomains_init(void)
{
unsigned int rev;
- if (!cpu_is_omap34xx())
+ if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
return;
pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index cfde3f4a03cc..ed8a3d8b739a 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -145,7 +145,6 @@ extern void omap3_prm_vcvp_write(u32 val, u8 offset);
extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
extern int __init omap3xxx_prm_init(void);
-extern u32 omap3xxx_prm_get_reset_sources(void);
int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits);
void omap3xxx_prm_iva_idle(void);
void omap3_prm_reset_modem(void);
diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h
index f7512515fde5..714329565b90 100644
--- a/arch/arm/mach-omap2/prm44xx_54xx.h
+++ b/arch/arm/mach-omap2/prm44xx_54xx.h
@@ -39,7 +39,6 @@ extern void omap4_prm_vcvp_write(u32 val, u8 offset);
extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
extern int __init omap44xx_prm_init(void);
-extern u32 omap44xx_prm_get_reset_sources(void);
#endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index dea2833ca627..264b5e29404d 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -581,6 +581,10 @@ static const struct of_device_id omap_prcm_dt_match_table[] = {
{ .compatible = "ti,am3-scrm" },
{ .compatible = "ti,am4-prcm" },
{ .compatible = "ti,am4-scrm" },
+ { .compatible = "ti,dm814-prcm" },
+ { .compatible = "ti,dm814-scrm" },
+ { .compatible = "ti,dm816-prcm" },
+ { .compatible = "ti,dm816-scrm" },
{ .compatible = "ti,omap2-prcm" },
{ .compatible = "ti,omap2-scrm" },
{ .compatible = "ti,omap3-prm" },
diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h
index c1a3b4416311..f97654d11ea5 100644
--- a/arch/arm/mach-omap2/soc.h
+++ b/arch/arm/mach-omap2/soc.h
@@ -423,13 +423,13 @@ IS_OMAP_TYPE(3430, 0x3430)
#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8))
#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8))
-#define TI816X_CLASS 0x81600034
+#define TI816X_CLASS 0x81600081
#define TI8168_REV_ES1_0 TI816X_CLASS
#define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8))
#define TI8168_REV_ES2_0 (TI816X_CLASS | (0x2 << 8))
#define TI8168_REV_ES2_1 (TI816X_CLASS | (0x3 << 8))
-#define TI814X_CLASS 0x81400034
+#define TI814X_CLASS 0x81400081
#define TI8148_REV_ES1_0 TI814X_CLASS
#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8))
#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8))
diff --git a/arch/arm/mach-omap2/ti81xx-restart.c b/arch/arm/mach-omap2/ti81xx-restart.c
new file mode 100644
index 000000000000..6c3ce7c46ddd
--- /dev/null
+++ b/arch/arm/mach-omap2/ti81xx-restart.c
@@ -0,0 +1,34 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "control.h"
+#include "prm3xxx.h"
+
+#define TI81XX_PRM_DEVICE_RSTCTRL 0x00a0
+#define TI81XX_GLOBAL_RST_COLD BIT(1)
+
+/**
+ * ti81xx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ *
+ * NOTE: Warm reset does not seem to work, may require resetting
+ * clocks to bypass mode.
+ */
+void ti81xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ omap2_prm_set_mod_reg_bits(TI81XX_GLOBAL_RST_COLD, 0,
+ TI81XX_PRM_DEVICE_RSTCTRL);
+ while (1);
+}
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 7d45c84c69ba..cef67af9e9b8 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -147,6 +147,8 @@ static const struct of_device_id omap_timer_match[] __initconst = {
{ .compatible = "ti,omap3430-timer", },
{ .compatible = "ti,omap4430-timer", },
{ .compatible = "ti,omap5430-timer", },
+ { .compatible = "ti,dm814-timer", },
+ { .compatible = "ti,dm816-timer", },
{ .compatible = "ti,am335x-timer", },
{ .compatible = "ti,am335x-timer-1ms", },
{ }
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index bc897231bd10..e4562b2b973b 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -82,16 +82,8 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
musb_plat.mode = board_data->mode;
musb_plat.extvbus = board_data->extvbus;
- if (soc_is_am35xx()) {
- oh_name = "am35x_otg_hs";
- name = "musb-am35x";
- } else if (cpu_is_ti81xx()) {
- oh_name = "usb_otg_hs";
- name = "musb-ti81xx";
- } else {
- oh_name = "usb_otg_hs";
- name = "musb-omap2430";
- }
+ oh_name = "usb_otg_hs";
+ name = "musb-omap2430";
oh = omap_hwmod_lookup(oh_name);
if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h
index 4ba2ae759895..3395365ef1db 100644
--- a/arch/arm/mach-omap2/usb.h
+++ b/arch/arm/mach-omap2/usb.h
@@ -68,5 +68,3 @@ extern void am35x_musb_reset(void);
extern void am35x_musb_phy_power(u8 on);
extern void am35x_musb_clear_irq(void);
extern void am35x_set_mode(u8 musb_mode);
-extern void ti81xx_musb_phy_power(u8 on);
-
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 3783b8625f0f..cba8cada8c81 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -224,37 +224,6 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm,
}
/**
- * omap_change_voltscale_method() - API to change the voltage scaling method.
- * @voltdm: pointer to the VDD whose voltage scaling method
- * has to be changed.
- * @voltscale_method: the method to be used for voltage scaling.
- *
- * This API can be used by the board files to change the method of voltage
- * scaling between vpforceupdate and vcbypass. The parameter values are
- * defined in voltage.h
- */
-void omap_change_voltscale_method(struct voltagedomain *voltdm,
- int voltscale_method)
-{
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warn("%s: VDD specified does not exist!\n", __func__);
- return;
- }
-
- switch (voltscale_method) {
- case VOLTSCALE_VPFORCEUPDATE:
- voltdm->scale = omap_vp_forceupdate_scale;
- return;
- case VOLTSCALE_VCBYPASS:
- voltdm->scale = omap_vc_bypass_scale;
- return;
- default:
- pr_warn("%s: Trying to change the method of voltage scaling to an unsupported one!\n",
- __func__);
- }
-}
-
-/**
* omap_voltage_late_init() - Init the various voltage parameters
*
* This API is to be called in the later stages of the
@@ -316,90 +285,11 @@ static struct voltagedomain *_voltdm_lookup(const char *name)
return voltdm;
}
-/**
- * voltdm_add_pwrdm - add a powerdomain to a voltagedomain
- * @voltdm: struct voltagedomain * to add the powerdomain to
- * @pwrdm: struct powerdomain * to associate with a voltagedomain
- *
- * Associate the powerdomain @pwrdm with a voltagedomain @voltdm. This
- * enables the use of voltdm_for_each_pwrdm(). Returns -EINVAL if
- * presented with invalid pointers; -ENOMEM if memory could not be allocated;
- * or 0 upon success.
- */
-int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)
-{
- if (!voltdm || !pwrdm)
- return -EINVAL;
-
- pr_debug("voltagedomain: %s: associating powerdomain %s\n",
- voltdm->name, pwrdm->name);
-
- list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list);
-
- return 0;
-}
-
-/**
- * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm
- * @voltdm: struct voltagedomain * to iterate over
- * @fn: callback function *
- *
- * Call the supplied function @fn for each powerdomain in the
- * voltagedomain @voltdm. Returns -EINVAL if presented with invalid
- * pointers; or passes along the last return value of the callback
- * function, which should be 0 for success or anything else to
- * indicate failure.
- */
-int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
- int (*fn)(struct voltagedomain *voltdm,
- struct powerdomain *pwrdm))
-{
- struct powerdomain *pwrdm;
- int ret = 0;
-
- if (!fn)
- return -EINVAL;
-
- list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node)
- ret = (*fn)(voltdm, pwrdm);
-
- return ret;
-}
-
-/**
- * voltdm_for_each - call function on each registered voltagedomain
- * @fn: callback function *
- *
- * Call the supplied function @fn for each registered voltagedomain.
- * The callback function @fn can return anything but 0 to bail out
- * early from the iterator. Returns the last return value of the
- * callback function, which should be 0 for success or anything else
- * to indicate failure; or -EINVAL if the function pointer is null.
- */
-int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
- void *user)
-{
- struct voltagedomain *temp_voltdm;
- int ret = 0;
-
- if (!fn)
- return -EINVAL;
-
- list_for_each_entry(temp_voltdm, &voltdm_list, node) {
- ret = (*fn)(temp_voltdm, user);
- if (ret)
- break;
- }
-
- return ret;
-}
-
static int _voltdm_register(struct voltagedomain *voltdm)
{
if (!voltdm || !voltdm->name)
return -EINVAL;
- INIT_LIST_HEAD(&voltdm->pwrdm_list);
list_add(&voltdm->node, &voltdm_list);
pr_debug("voltagedomain: registered %s\n", voltdm->name);
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index f7f2879b31b0..e64550321510 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -23,10 +23,6 @@
struct powerdomain;
-/* XXX document */
-#define VOLTSCALE_VPFORCEUPDATE 1
-#define VOLTSCALE_VCBYPASS 2
-
/*
* OMAP3 GENERIC setup times. Revisit to see if these needs to be
* passed from board or PMIC file
@@ -55,7 +51,6 @@ struct omap_vfsm_instance {
* @name: Name of the voltage domain which can be used as a unique identifier.
* @scalable: Whether or not this voltage domain is scalable
* @node: list_head linking all voltage domains
- * @pwrdm_list: list_head linking all powerdomains in this voltagedomain
* @vc: pointer to VC channel associated with this voltagedomain
* @vp: pointer to VP associated with this voltagedomain
* @read: read a VC/VP register
@@ -71,7 +66,6 @@ struct voltagedomain {
char *name;
bool scalable;
struct list_head node;
- struct list_head pwrdm_list;
struct omap_vc_channel *vc;
const struct omap_vfsm_instance *vfsm;
struct omap_vp_instance *vp;
@@ -163,8 +157,6 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
unsigned long volt);
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_voltdm_pmic *pmic);
-void omap_change_voltscale_method(struct voltagedomain *voltdm,
- int voltscale_method);
int omap_voltage_late_init(void);
extern void omap2xxx_voltagedomains_init(void);
@@ -175,11 +167,6 @@ extern void omap54xx_voltagedomains_init(void);
struct voltagedomain *voltdm_lookup(const char *name);
void voltdm_init(struct voltagedomain **voltdm_list);
int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm);
-int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
- void *user);
-int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
- int (*fn)(struct voltagedomain *voltdm,
- struct powerdomain *pwrdm));
int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
void voltdm_reset(struct voltagedomain *voltdm);
unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig
index 042f693ef423..a219dc310d5d 100644
--- a/arch/arm/mach-prima2/Kconfig
+++ b/arch/arm/mach-prima2/Kconfig
@@ -11,7 +11,7 @@ menuconfig ARCH_SIRF
if ARCH_SIRF
-comment "CSR SiRF atlas6/primaII/Marco/Polo Specific Features"
+comment "CSR SiRF atlas6/primaII/Atlas7 Specific Features"
config ARCH_ATLAS6
bool "CSR SiRFSoC ATLAS6 ARM Cortex A9 Platform"
@@ -20,6 +20,17 @@ config ARCH_ATLAS6
help
Support for CSR SiRFSoC ARM Cortex A9 Platform
+config ARCH_ATLAS7
+ bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform"
+ default y
+ select ARM_GIC
+ select CPU_V7
+ select HAVE_ARM_SCU if SMP
+ select HAVE_SMP
+ select SMP_ON_UP if SMP
+ help
+ Support for CSR SiRFSoC ARM Cortex A7 Platform
+
config ARCH_PRIMA2
bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
default y
@@ -28,15 +39,6 @@ config ARCH_PRIMA2
help
Support for CSR SiRFSoC ARM Cortex A9 Platform
-config ARCH_MARCO
- bool "CSR SiRFSoC MARCO ARM Cortex A9 Platform"
- default y
- select ARM_GIC
- select HAVE_ARM_SCU if SMP
- select SMP_ON_UP if SMP
- help
- Support for CSR SiRFSoC ARM Cortex A9 Platform
-
config SIRF_IRQ
bool
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
index 8846e7d87ea5..d7d02b043449 100644
--- a/arch/arm/mach-prima2/Makefile
+++ b/arch/arm/mach-prima2/Makefile
@@ -1,7 +1,6 @@
obj-y += rstc.o
obj-y += common.o
obj-y += rtciobrg.o
-obj-$(CONFIG_DEBUG_LL) += lluart.o
obj-$(CONFIG_SUSPEND) += pm.o sleep.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c
index a860ea27e8ae..0c819bb88418 100644
--- a/arch/arm/mach-prima2/common.c
+++ b/arch/arm/mach-prima2/common.c
@@ -20,12 +20,6 @@ static void __init sirfsoc_init_late(void)
sirfsoc_pm_init();
}
-static __init void sirfsoc_map_io(void)
-{
- sirfsoc_map_lluart();
- sirfsoc_map_scu();
-}
-
#ifdef CONFIG_ARCH_ATLAS6
static const char *atlas6_dt_match[] __initconst = {
"sirf,atlas6",
@@ -36,7 +30,6 @@ DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)")
/* Maintainer: Barry Song <baohua.song@csr.com> */
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
- .map_io = sirfsoc_map_io,
.init_late = sirfsoc_init_late,
.dt_compat = atlas6_dt_match,
MACHINE_END
@@ -52,26 +45,21 @@ DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
/* Maintainer: Barry Song <baohua.song@csr.com> */
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
- .map_io = sirfsoc_map_io,
.dma_zone_size = SZ_256M,
.init_late = sirfsoc_init_late,
.dt_compat = prima2_dt_match,
MACHINE_END
#endif
-#ifdef CONFIG_ARCH_MARCO
-static const char *marco_dt_match[] __initconst = {
- "sirf,marco",
+#ifdef CONFIG_ARCH_ATLAS7
+static const char *atlas7_dt_match[] __initdata = {
+ "sirf,atlas7",
NULL
};
-DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)")
+DT_MACHINE_START(ATLAS7_DT, "Generic ATLAS7 (Flattened Device Tree)")
/* Maintainer: Barry Song <baohua.song@csr.com> */
- .l2c_aux_val = 0,
- .l2c_aux_mask = ~0,
.smp = smp_ops(sirfsoc_smp_ops),
- .map_io = sirfsoc_map_io,
- .init_late = sirfsoc_init_late,
- .dt_compat = marco_dt_match,
+ .dt_compat = atlas7_dt_match,
MACHINE_END
#endif
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
index 07d3e5ed9264..3916a6665100 100644
--- a/arch/arm/mach-prima2/common.h
+++ b/arch/arm/mach-prima2/common.h
@@ -15,9 +15,6 @@
#include <asm/mach/time.h>
#include <asm/exception.h>
-#define SIRFSOC_VA_BASE _AC(0xFEC00000, UL)
-#define SIRFSOC_VA(x) (SIRFSOC_VA_BASE + ((x) & 0x00FFF000))
-
extern struct smp_operations sirfsoc_smp_ops;
extern void sirfsoc_secondary_startup(void);
extern void sirfsoc_cpu_die(unsigned int cpu);
@@ -25,18 +22,6 @@ extern void sirfsoc_cpu_die(unsigned int cpu);
extern void __init sirfsoc_of_irq_init(void);
extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs);
-#ifndef CONFIG_DEBUG_LL
-static inline void sirfsoc_map_lluart(void) {}
-#else
-extern void __init sirfsoc_map_lluart(void);
-#endif
-
-#ifndef CONFIG_SMP
-static inline void sirfsoc_map_scu(void) {}
-#else
-extern void sirfsoc_map_scu(void);
-#endif
-
#ifdef CONFIG_SUSPEND
extern int sirfsoc_pm_init(void);
#else
diff --git a/arch/arm/mach-prima2/lluart.c b/arch/arm/mach-prima2/lluart.c
deleted file mode 100644
index 99c0c927ca4a..000000000000
--- a/arch/arm/mach-prima2/lluart.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Static memory mapping for DEBUG_LL
- *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/kernel.h>
-#include <asm/page.h>
-#include <asm/mach/map.h>
-#include "common.h"
-
-#if defined(CONFIG_DEBUG_SIRFPRIMA2_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xb0060000
-#elif defined(CONFIG_DEBUG_SIRFMARCO_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xcc060000
-#else
-#define SIRFSOC_UART1_PA_BASE 0
-#endif
-
-#define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000)
-#define SIRFSOC_UART1_SIZE SZ_4K
-
-void __init sirfsoc_map_lluart(void)
-{
- struct map_desc sirfsoc_lluart_map = {
- .virtual = SIRFSOC_UART1_VA_BASE,
- .pfn = __phys_to_pfn(SIRFSOC_UART1_PA_BASE),
- .length = SIRFSOC_UART1_SIZE,
- .type = MT_DEVICE,
- };
-
- iotable_init(&sirfsoc_lluart_map, 1);
-}
diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c
index 335c12e92262..fc2b03c81e5f 100644
--- a/arch/arm/mach-prima2/platsmp.c
+++ b/arch/arm/mach-prima2/platsmp.c
@@ -20,30 +20,10 @@
#include "common.h"
-static void __iomem *scu_base;
-static void __iomem *rsc_base;
+static void __iomem *clk_base;
static DEFINE_SPINLOCK(boot_lock);
-static struct map_desc scu_io_desc __initdata = {
- .length = SZ_4K,
- .type = MT_DEVICE,
-};
-
-void __init sirfsoc_map_scu(void)
-{
- unsigned long base;
-
- /* Get SCU base */
- asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
-
- scu_io_desc.virtual = SIRFSOC_VA(base);
- scu_io_desc.pfn = __phys_to_pfn(base);
- iotable_init(&scu_io_desc, 1);
-
- scu_base = (void __iomem *)SIRFSOC_VA(base);
-}
-
static void sirfsoc_secondary_init(unsigned int cpu)
{
/*
@@ -60,8 +40,8 @@ static void sirfsoc_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
-static struct of_device_id rsc_ids[] = {
- { .compatible = "sirf,marco-rsc" },
+static struct of_device_id clk_ids[] = {
+ { .compatible = "sirf,atlas7-clkc" },
{},
};
@@ -70,27 +50,27 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
unsigned long timeout;
struct device_node *np;
- np = of_find_matching_node(NULL, rsc_ids);
+ np = of_find_matching_node(NULL, clk_ids);
if (!np)
return -ENODEV;
- rsc_base = of_iomap(np, 0);
- if (!rsc_base)
+ clk_base = of_iomap(np, 0);
+ if (!clk_base)
return -ENOMEM;
/*
- * write the address of secondary startup into the sram register
- * at offset 0x2C, then write the magic number 0x3CAF5D62 to the
- * RSC register at offset 0x28, which is what boot rom code is
+ * write the address of secondary startup into the clkc register
+ * at offset 0x2bC, then write the magic number 0x3CAF5D62 to the
+ * clkc register at offset 0x2b8, which is what boot rom code is
* waiting for. This would wake up the secondary core from WFE
*/
-#define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2C
+#define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2bc
__raw_writel(virt_to_phys(sirfsoc_secondary_startup),
- rsc_base + SIRFSOC_CPU1_JUMPADDR_OFFSET);
+ clk_base + SIRFSOC_CPU1_JUMPADDR_OFFSET);
-#define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x28
+#define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x2b8
__raw_writel(0x3CAF5D62,
- rsc_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET);
+ clk_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET);
/* make sure write buffer is drained */
mb();
@@ -132,13 +112,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
return pen_release != -1 ? -ENOSYS : 0;
}
-static void __init sirfsoc_smp_prepare_cpus(unsigned int max_cpus)
-{
- scu_enable(scu_base);
-}
-
struct smp_operations sirfsoc_smp_ops __initdata = {
- .smp_prepare_cpus = sirfsoc_smp_prepare_cpus,
.smp_secondary_init = sirfsoc_secondary_init,
.smp_boot_secondary = sirfsoc_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c
index e1f1f86f6a95..7c251eb11d01 100644
--- a/arch/arm/mach-prima2/rstc.c
+++ b/arch/arm/mach-prima2/rstc.c
@@ -34,36 +34,20 @@ static int sirfsoc_reset_module(struct reset_controller_dev *rcdev,
mutex_lock(&rstc_lock);
- if (of_device_is_compatible(rcdev->of_node, "sirf,prima2-rstc")) {
- /*
- * Writing 1 to this bit resets corresponding block.
- * Writing 0 to this bit de-asserts reset signal of the
- * corresponding block. datasheet doesn't require explicit
- * delay between the set and clear of reset bit. it could
- * be shorter if tests pass.
- */
- writel(readl(sirfsoc_rstc_base +
+ /*
+ * Writing 1 to this bit resets corresponding block.
+ * Writing 0 to this bit de-asserts reset signal of the
+ * corresponding block. datasheet doesn't require explicit
+ * delay between the set and clear of reset bit. it could
+ * be shorter if tests pass.
+ */
+ writel(readl(sirfsoc_rstc_base +
(reset_bit / 32) * 4) | (1 << reset_bit),
- sirfsoc_rstc_base + (reset_bit / 32) * 4);
- msleep(20);
- writel(readl(sirfsoc_rstc_base +
+ sirfsoc_rstc_base + (reset_bit / 32) * 4);
+ msleep(20);
+ writel(readl(sirfsoc_rstc_base +
(reset_bit / 32) * 4) & ~(1 << reset_bit),
- sirfsoc_rstc_base + (reset_bit / 32) * 4);
- } else {
- /*
- * For MARCO and POLO
- * Writing 1 to SET register resets corresponding block.
- * Writing 1 to CLEAR register de-asserts reset signal of the
- * corresponding block.
- * datasheet doesn't require explicit delay between the set and
- * clear of reset bit. it could be shorter if tests pass.
- */
- writel(1 << reset_bit,
- sirfsoc_rstc_base + (reset_bit / 32) * 8);
- msleep(20);
- writel(1 << reset_bit,
- sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4);
- }
+ sirfsoc_rstc_base + (reset_bit / 32) * 4);
mutex_unlock(&rstc_lock);
@@ -106,7 +90,6 @@ static int sirfsoc_rstc_probe(struct platform_device *pdev)
static const struct of_device_id rstc_ids[] = {
{ .compatible = "sirf,prima2-rstc" },
- { .compatible = "sirf,marco-rstc" },
{},
};
diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c
index 70a0b475062b..8f66d8f7ca75 100644
--- a/arch/arm/mach-prima2/rtciobrg.c
+++ b/arch/arm/mach-prima2/rtciobrg.c
@@ -104,7 +104,6 @@ EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel);
static const struct of_device_id rtciobrg_ids[] = {
{ .compatible = "sirf,prima2-rtciobg" },
- { .compatible = "sirf,marco-rtciobg" },
{}
};
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 83efe914bf7d..8896e71586f5 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -6,7 +6,6 @@ comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
config MACH_PXA27X_DT
bool "Support PXA27x platforms from device tree"
- select CPU_PXA27x
select POWER_SUPPLY
select PXA27x
select USE_OF
@@ -84,14 +83,12 @@ config ARCH_VIPER
select I2C_GPIO if I2C=y
select ISA
select PXA25x
- select PXA_HAVE_ISA_IRQS
config MACH_ARCOM_ZEUS
bool "Arcom/Eurotech ZEUS SBC"
select ARCOM_PCMCIA
select ISA
select PXA27x
- select PXA_HAVE_ISA_IRQS
config MACH_BALLOON3
bool "Balloon 3 board"
@@ -691,9 +688,6 @@ config SHARPSL_PM_MAX1111
select SPI
select SPI_MASTER
-config PXA_HAVE_ISA_IRQS
- bool
-
config PXA310_ULPI
bool
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 06022b235730..89f790dda93e 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/i2c/pxa-i2c.h>
#include <linux/io.h>
+#include <linux/regulator/machine.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/corgi_lcd.h>
@@ -752,6 +753,8 @@ static void __init corgi_init(void)
sharpsl_nand_partitions[1].size = 53 * 1024 * 1024;
platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ regulator_has_full_constraints();
}
static void __init fixup_corgi(struct tag *tags, char **cmdline)
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index ac7b3eabbd85..35434662dc7c 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -40,7 +40,7 @@ static struct resource pxa_resource_pmu = {
};
struct platform_device pxa_device_pmu = {
- .name = "arm-pmu",
+ .name = "xscale-pmu",
.id = -1,
.resource = &pxa_resource_pmu,
.num_resources = 1,
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index c66ad4edc5e3..5fb41ad6e3bc 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -893,6 +893,8 @@ static void __init hx4700_init(void)
mdelay(10);
gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
mdelay(10);
+
+ regulator_has_full_constraints();
}
MACHINE_START(H4700, "HP iPAQ HX4700")
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 48c2fd851686..7e3ea351f3c7 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -12,14 +12,10 @@
#ifndef __ASM_MACH_IRQS_H
#define __ASM_MACH_IRQS_H
-#ifdef CONFIG_PXA_HAVE_ISA_IRQS
-#define PXA_ISA_IRQ(x) (x)
-#define PXA_ISA_IRQ_NUM (16)
-#else
-#define PXA_ISA_IRQ_NUM (0)
-#endif
+#include <asm/irq.h>
-#define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x))
+#define PXA_ISA_IRQ(x) (x)
+#define PXA_IRQ(x) (NR_IRQS_LEGACY + (x))
#define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */
#define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 29019beae591..195b1121c8f1 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -25,6 +25,7 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c/pxa-i2c.h>
+#include <linux/regulator/machine.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/pxa2xx_spi.h>
@@ -455,6 +456,7 @@ static void __init poodle_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
poodle_init_spi();
+ regulator_has_full_constraints();
}
static void __init fixup_poodle(struct tag *tags, char **cmdline)
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 962a7f31f596..f4e2e2719580 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -979,6 +979,8 @@ static void __init spitz_init(void)
spitz_nand_init();
spitz_i2c_init();
spitz_audio_init();
+
+ regulator_has_full_constraints();
}
static void __init spitz_fixup(struct tag *tags, char **cmdline)
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index ee5697ba05bc..48003ea652b9 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -1,9 +1,8 @@
menuconfig ARCH_QCOM
bool "Qualcomm Support" if ARCH_MULTI_V7
- select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_GIC
select ARM_AMBA
- select CLKSRC_OF
select PINCTRL
select QCOM_SCM if SMP
help
diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
index 45cee3e469a5..e8ff7beb6218 100644
--- a/arch/arm/mach-qcom/scm-boot.c
+++ b/arch/arm/mach-qcom/scm-boot.c
@@ -24,15 +24,15 @@
/*
* Set the cold/warm boot address for one of the CPU cores.
*/
-int scm_set_boot_addr(phys_addr_t addr, int flags)
+int scm_set_boot_addr(u32 addr, int flags)
{
struct {
- unsigned int flags;
- phys_addr_t addr;
+ __le32 flags;
+ __le32 addr;
} cmd;
- cmd.addr = addr;
- cmd.flags = flags;
+ cmd.addr = cpu_to_le32(addr);
+ cmd.flags = cpu_to_le32(flags);
return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
&cmd, sizeof(cmd), NULL, 0);
}
diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
index 6aabb2428176..3e210fb818bb 100644
--- a/arch/arm/mach-qcom/scm-boot.h
+++ b/arch/arm/mach-qcom/scm-boot.h
@@ -18,7 +18,9 @@
#define SCM_FLAG_COLDBOOT_CPU3 0x20
#define SCM_FLAG_WARMBOOT_CPU0 0x04
#define SCM_FLAG_WARMBOOT_CPU1 0x02
+#define SCM_FLAG_WARMBOOT_CPU2 0x10
+#define SCM_FLAG_WARMBOOT_CPU3 0x40
-int scm_set_boot_addr(phys_addr_t addr, int flags);
+int scm_set_boot_addr(u32 addr, int flags);
#endif
diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
index c536fd6bf827..1d9cf18c7091 100644
--- a/arch/arm/mach-qcom/scm.c
+++ b/arch/arm/mach-qcom/scm.c
@@ -22,13 +22,11 @@
#include <linux/errno.h>
#include <linux/err.h>
+#include <asm/outercache.h>
#include <asm/cacheflush.h>
#include "scm.h"
-/* Cache line size for msm8x60 */
-#define CACHELINESIZE 32
-
#define SCM_ENOMEM -5
#define SCM_EOPNOTSUPP -4
#define SCM_EINVAL_ADDR -3
@@ -63,11 +61,11 @@ static DEFINE_MUTEX(scm_lock);
* to access the buffers in a safe manner.
*/
struct scm_command {
- u32 len;
- u32 buf_offset;
- u32 resp_hdr_offset;
- u32 id;
- u32 buf[0];
+ __le32 len;
+ __le32 buf_offset;
+ __le32 resp_hdr_offset;
+ __le32 id;
+ __le32 buf[0];
};
/**
@@ -77,9 +75,9 @@ struct scm_command {
* @is_complete: indicates if the command has finished processing
*/
struct scm_response {
- u32 len;
- u32 buf_offset;
- u32 is_complete;
+ __le32 len;
+ __le32 buf_offset;
+ __le32 is_complete;
};
/**
@@ -97,12 +95,14 @@ static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
struct scm_command *cmd;
size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
resp_size;
+ u32 offset;
cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
if (cmd) {
- cmd->len = len;
- cmd->buf_offset = offsetof(struct scm_command, buf);
- cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
+ cmd->len = cpu_to_le32(len);
+ offset = offsetof(struct scm_command, buf);
+ cmd->buf_offset = cpu_to_le32(offset);
+ cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_size);
}
return cmd;
}
@@ -127,7 +127,7 @@ static inline void free_scm_command(struct scm_command *cmd)
static inline struct scm_response *scm_command_to_response(
const struct scm_command *cmd)
{
- return (void *)cmd + cmd->resp_hdr_offset;
+ return (void *)cmd + le32_to_cpu(cmd->resp_hdr_offset);
}
/**
@@ -149,11 +149,12 @@ static inline void *scm_get_command_buffer(const struct scm_command *cmd)
*/
static inline void *scm_get_response_buffer(const struct scm_response *rsp)
{
- return (void *)rsp + rsp->buf_offset;
+ return (void *)rsp + le32_to_cpu(rsp->buf_offset);
}
static int scm_remap_error(int err)
{
+ pr_err("scm_call failed with error code %d\n", err);
switch (err) {
case SCM_ERROR:
return -EIO;
@@ -198,11 +199,12 @@ static int __scm_call(const struct scm_command *cmd)
u32 cmd_addr = virt_to_phys(cmd);
/*
- * Flush the entire cache here so callers don't have to remember
- * to flush the cache when passing physical addresses to the secure
- * side in the buffer.
+ * Flush the command buffer so that the secure world sees
+ * the correct data.
*/
- flush_cache_all();
+ __cpuc_flush_dcache_area((void *)cmd, cmd->len);
+ outer_flush_range(cmd_addr, cmd_addr + cmd->len);
+
ret = smc(cmd_addr);
if (ret < 0)
ret = scm_remap_error(ret);
@@ -210,6 +212,25 @@ static int __scm_call(const struct scm_command *cmd)
return ret;
}
+static void scm_inv_range(unsigned long start, unsigned long end)
+{
+ u32 cacheline_size, ctr;
+
+ asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
+ cacheline_size = 4 << ((ctr >> 16) & 0xf);
+
+ start = round_down(start, cacheline_size);
+ end = round_up(end, cacheline_size);
+ outer_inv_range(start, end);
+ while (start < end) {
+ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
+ : "memory");
+ start += cacheline_size;
+ }
+ dsb();
+ isb();
+}
+
/**
* scm_call() - Send an SCM command
* @svc_id: service identifier
@@ -220,6 +241,13 @@ static int __scm_call(const struct scm_command *cmd)
* @resp_len: length of the response buffer
*
* Sends a command to the SCM and waits for the command to finish processing.
+ *
+ * A note on cache maintenance:
+ * Note that any buffers that are expected to be accessed by the secure world
+ * must be flushed before invoking scm_call and invalidated in the cache
+ * immediately after scm_call returns. Cache maintenance on the command and
+ * response buffers is taken care of by scm_call; however, callers are
+ * responsible for any other cached buffers passed over to the secure world.
*/
int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
void *resp_buf, size_t resp_len)
@@ -227,12 +255,13 @@ int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
int ret;
struct scm_command *cmd;
struct scm_response *rsp;
+ unsigned long start, end;
cmd = alloc_scm_command(cmd_len, resp_len);
if (!cmd)
return -ENOMEM;
- cmd->id = (svc_id << 10) | cmd_id;
+ cmd->id = cpu_to_le32((svc_id << 10) | cmd_id);
if (cmd_buf)
memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
@@ -243,17 +272,15 @@ int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
goto out;
rsp = scm_command_to_response(cmd);
+ start = (unsigned long)rsp;
+
do {
- u32 start = (u32)rsp;
- u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
- start &= ~(CACHELINESIZE - 1);
- while (start < end) {
- asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
- : "memory");
- start += CACHELINESIZE;
- }
+ scm_inv_range(start, start + sizeof(*rsp));
} while (!rsp->is_complete);
+ end = (unsigned long)scm_get_response_buffer(rsp) + resp_len;
+ scm_inv_range(start, end);
+
if (resp_buf)
memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
out:
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 739d4f113097..64c88d657f9e 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -37,6 +37,7 @@
#include <asm/pgtable.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/smp_twd.h>
+#include <asm/system_info.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -296,7 +297,6 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
@@ -451,6 +451,7 @@ static void __init realview_eb_init(void)
*/
l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
#endif
+ pmu_device.name = core_tile_a9mp() ? "armv7-pmu" : "armv6-pmu";
platform_device_register(&pmu_device);
}
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index b0e0dcaed944..ce92c1823494 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -280,7 +280,7 @@ static struct resource pmu_resource = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv6-pmu",
.id = -1,
.num_resources = 1,
.resource = &pmu_resource,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 47bf55fdbf27..15c45e25095f 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -262,7 +262,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv6-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 4e57a8599265..4c64662f5437 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -240,7 +240,7 @@ static struct resource pmu_resource = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = 1,
.resource = &pmu_resource,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index d89eb4023467..9a22b864219f 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -280,7 +280,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index ac5803cac98d..5078932c1683 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -11,6 +11,7 @@ config ARCH_ROCKCHIP
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select DW_APB_TIMER_OF
+ select ROCKCHIP_TIMER
select ARM_GLOBAL_TIMER
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index b29d8ead4cf2..5c3a9b2de920 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -1,4 +1,5 @@
CFLAGS_platsmp.o := -march=armv7-a
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o
+obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
new file mode 100644
index 000000000000..50cb781aaa36
--- /dev/null
+++ b/arch/arm/mach-rockchip/pm.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/suspend.h>
+
+#include "pm.h"
+
+/* These enum are option of low power mode */
+enum {
+ ROCKCHIP_ARM_OFF_LOGIC_NORMAL = 0,
+ ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
+};
+
+struct rockchip_pm_data {
+ const struct platform_suspend_ops *ops;
+ int (*init)(struct device_node *np);
+};
+
+static void __iomem *rk3288_bootram_base;
+static phys_addr_t rk3288_bootram_phy;
+
+static struct regmap *pmu_regmap;
+static struct regmap *sgrf_regmap;
+
+static u32 rk3288_pmu_pwr_mode_con;
+static u32 rk3288_sgrf_soc_con0;
+
+static inline u32 rk3288_l2_config(void)
+{
+ u32 l2ctlr;
+
+ asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (l2ctlr));
+ return l2ctlr;
+}
+
+static void rk3288_config_bootdata(void)
+{
+ rkpm_bootdata_cpusp = rk3288_bootram_phy + (SZ_4K - 8);
+ rkpm_bootdata_cpu_code = virt_to_phys(cpu_resume);
+
+ rkpm_bootdata_l2ctlr_f = 1;
+ rkpm_bootdata_l2ctlr = rk3288_l2_config();
+}
+
+static void rk3288_slp_mode_set(int level)
+{
+ u32 mode_set, mode_set1;
+
+ regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
+
+ regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
+ &rk3288_pmu_pwr_mode_con);
+
+ /* set bit 8 so that system will resume to FAST_BOOT_ADDR */
+ regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
+ SGRF_FAST_BOOT_EN | SGRF_FAST_BOOT_EN_WRITE);
+
+ /* booting address of resuming system is from this register value */
+ regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
+ rk3288_bootram_phy);
+
+ regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
+ PMU_ARMINT_WAKEUP_EN);
+
+ mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) |
+ BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) |
+ BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) |
+ BIT(PMU_PWR_MODE_EN) | BIT(PMU_CHIP_PD_EN) |
+ BIT(PMU_SCU_EN);
+
+ mode_set1 = BIT(PMU_CLR_CORE) | BIT(PMU_CLR_CPUP);
+
+ if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
+ /* arm off, logic deep sleep */
+ mode_set |= BIT(PMU_BUS_PD_EN) |
+ BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
+ BIT(PMU_OSC_24M_DIS) | BIT(PMU_PMU_USE_LF) |
+ BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
+
+ mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
+ BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
+ } else {
+ /*
+ * arm off, logic normal
+ * if pmu_clk_core_src_gate_en is not set,
+ * wakeup will be error
+ */
+ mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
+ }
+
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set);
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON1, mode_set1);
+}
+
+static void rk3288_slp_mode_set_resume(void)
+{
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON,
+ rk3288_pmu_pwr_mode_con);
+
+ regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
+ rk3288_sgrf_soc_con0 | SGRF_FAST_BOOT_EN_WRITE);
+}
+
+static int rockchip_lpmode_enter(unsigned long arg)
+{
+ flush_cache_all();
+
+ cpu_do_idle();
+
+ pr_err("%s: Failed to suspend\n", __func__);
+
+ return 1;
+}
+
+static int rk3288_suspend_enter(suspend_state_t state)
+{
+ local_fiq_disable();
+
+ rk3288_slp_mode_set(ROCKCHIP_ARM_OFF_LOGIC_NORMAL);
+
+ cpu_suspend(0, rockchip_lpmode_enter);
+
+ rk3288_slp_mode_set_resume();
+
+ local_fiq_enable();
+
+ return 0;
+}
+
+static int rk3288_suspend_prepare(void)
+{
+ return regulator_suspend_prepare(PM_SUSPEND_MEM);
+}
+
+static void rk3288_suspend_finish(void)
+{
+ if (regulator_suspend_finish())
+ pr_err("%s: Suspend finish failed\n", __func__);
+}
+
+static int rk3288_suspend_init(struct device_node *np)
+{
+ struct device_node *sram_np;
+ struct resource res;
+ int ret;
+
+ pmu_regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(pmu_regmap)) {
+ pr_err("%s: could not find pmu regmap\n", __func__);
+ return PTR_ERR(pmu_regmap);
+ }
+
+ sgrf_regmap = syscon_regmap_lookup_by_compatible(
+ "rockchip,rk3288-sgrf");
+ if (IS_ERR(sgrf_regmap)) {
+ pr_err("%s: could not find sgrf regmap\n", __func__);
+ return PTR_ERR(pmu_regmap);
+ }
+
+ sram_np = of_find_compatible_node(NULL, NULL,
+ "rockchip,rk3288-pmu-sram");
+ if (!sram_np) {
+ pr_err("%s: could not find bootram dt node\n", __func__);
+ return -ENODEV;
+ }
+
+ rk3288_bootram_base = of_iomap(sram_np, 0);
+ if (!rk3288_bootram_base) {
+ pr_err("%s: could not map bootram base\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = of_address_to_resource(sram_np, 0, &res);
+ if (ret) {
+ pr_err("%s: could not get bootram phy addr\n", __func__);
+ return ret;
+ }
+ rk3288_bootram_phy = res.start;
+
+ of_node_put(sram_np);
+
+ rk3288_config_bootdata();
+
+ /* copy resume code and data to bootsram */
+ memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume,
+ rk3288_bootram_sz);
+
+ return 0;
+}
+
+static const struct platform_suspend_ops rk3288_suspend_ops = {
+ .enter = rk3288_suspend_enter,
+ .valid = suspend_valid_only_mem,
+ .prepare = rk3288_suspend_prepare,
+ .finish = rk3288_suspend_finish,
+};
+
+static const struct rockchip_pm_data rk3288_pm_data __initconst = {
+ .ops = &rk3288_suspend_ops,
+ .init = rk3288_suspend_init,
+};
+
+static const struct of_device_id rockchip_pmu_of_device_ids[] __initconst = {
+ {
+ .compatible = "rockchip,rk3288-pmu",
+ .data = &rk3288_pm_data,
+ },
+ { /* sentinel */ },
+};
+
+void __init rockchip_suspend_init(void)
+{
+ const struct rockchip_pm_data *pm_data;
+ const struct of_device_id *match;
+ struct device_node *np;
+ int ret;
+
+ np = of_find_matching_node_and_match(NULL, rockchip_pmu_of_device_ids,
+ &match);
+ if (!match) {
+ pr_err("Failed to find PMU node\n");
+ return;
+ }
+ pm_data = (struct rockchip_pm_data *) match->data;
+
+ if (pm_data->init) {
+ ret = pm_data->init(np);
+
+ if (ret) {
+ pr_err("%s: matches init error %d\n", __func__, ret);
+ return;
+ }
+ }
+
+ suspend_set_ops(pm_data->ops);
+}
diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
new file mode 100644
index 000000000000..7d752ff39f91
--- /dev/null
+++ b/arch/arm/mach-rockchip/pm.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __MACH_ROCKCHIP_PM_H
+#define __MACH_ROCKCHIP_PM_H
+
+extern unsigned long rkpm_bootdata_cpusp;
+extern unsigned long rkpm_bootdata_cpu_code;
+extern unsigned long rkpm_bootdata_l2ctlr_f;
+extern unsigned long rkpm_bootdata_l2ctlr;
+extern unsigned long rkpm_bootdata_ddr_code;
+extern unsigned long rkpm_bootdata_ddr_data;
+extern unsigned long rk3288_bootram_sz;
+
+void rockchip_slp_cpu_resume(void);
+void __init rockchip_suspend_init(void);
+
+/****** following is rk3288 defined **********/
+#define RK3288_PMU_WAKEUP_CFG0 0x00
+#define RK3288_PMU_WAKEUP_CFG1 0x04
+#define RK3288_PMU_PWRMODE_CON 0x18
+#define RK3288_PMU_OSC_CNT 0x20
+#define RK3288_PMU_PLL_CNT 0x24
+#define RK3288_PMU_STABL_CNT 0x28
+#define RK3288_PMU_DDR0IO_PWRON_CNT 0x2c
+#define RK3288_PMU_DDR1IO_PWRON_CNT 0x30
+#define RK3288_PMU_CORE_PWRDWN_CNT 0x34
+#define RK3288_PMU_CORE_PWRUP_CNT 0x38
+#define RK3288_PMU_GPU_PWRDWN_CNT 0x3c
+#define RK3288_PMU_GPU_PWRUP_CNT 0x40
+#define RK3288_PMU_WAKEUP_RST_CLR_CNT 0x44
+#define RK3288_PMU_PWRMODE_CON1 0x90
+
+#define RK3288_SGRF_SOC_CON0 (0x0000)
+#define RK3288_SGRF_FAST_BOOT_ADDR (0x0120)
+#define SGRF_FAST_BOOT_EN BIT(8)
+#define SGRF_FAST_BOOT_EN_WRITE BIT(24)
+
+#define RK3288_CRU_MODE_CON 0x50
+#define RK3288_CRU_SEL0_CON 0x60
+#define RK3288_CRU_SEL1_CON 0x64
+#define RK3288_CRU_SEL10_CON 0x88
+#define RK3288_CRU_SEL33_CON 0xe4
+#define RK3288_CRU_SEL37_CON 0xf4
+
+/* PMU_WAKEUP_CFG1 bits */
+#define PMU_ARMINT_WAKEUP_EN BIT(0)
+
+enum rk3288_pwr_mode_con {
+ PMU_PWR_MODE_EN = 0,
+ PMU_CLK_CORE_SRC_GATE_EN,
+ PMU_GLOBAL_INT_DISABLE,
+ PMU_L2FLUSH_EN,
+ PMU_BUS_PD_EN,
+ PMU_A12_0_PD_EN,
+ PMU_SCU_EN,
+ PMU_PLL_PD_EN,
+ PMU_CHIP_PD_EN, /* POWER OFF PIN ENABLE */
+ PMU_PWROFF_COMB,
+ PMU_ALIVE_USE_LF,
+ PMU_PMU_USE_LF,
+ PMU_OSC_24M_DIS,
+ PMU_INPUT_CLAMP_EN,
+ PMU_WAKEUP_RESET_EN,
+ PMU_SREF0_ENTER_EN,
+ PMU_SREF1_ENTER_EN,
+ PMU_DDR0IO_RET_EN,
+ PMU_DDR1IO_RET_EN,
+ PMU_DDR0_GATING_EN,
+ PMU_DDR1_GATING_EN,
+ PMU_DDR0IO_RET_DE_REQ,
+ PMU_DDR1IO_RET_DE_REQ
+};
+
+enum rk3288_pwr_mode_con1 {
+ PMU_CLR_BUS = 0,
+ PMU_CLR_CORE,
+ PMU_CLR_CPUP,
+ PMU_CLR_ALIVE,
+ PMU_CLR_DMA,
+ PMU_CLR_PERI,
+ PMU_CLR_GPU,
+ PMU_CLR_VIDEO,
+ PMU_CLR_HEVC,
+ PMU_CLR_VIO,
+};
+
+#endif /* __MACH_ROCKCHIP_PM_H */
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index a611f4852582..d360ec044b66 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -27,6 +27,7 @@
#include <asm/mach/map.h>
#include <asm/hardware/cache-l2x0.h>
#include "core.h"
+#include "pm.h"
#define RK3288_GRF_SOC_CON0 0x244
@@ -52,6 +53,7 @@ static void __init rockchip_timer_init(void)
static void __init rockchip_dt_init(void)
{
+ rockchip_suspend_init();
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
platform_device_register_simple("cpufreq-dt", 0, NULL, 0);
}
@@ -65,7 +67,7 @@ static const char * const rockchip_board_dt_compat[] = {
NULL,
};
-DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
+DT_MACHINE_START(ROCKCHIP_DT, "Rockchip (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
.init_time = rockchip_timer_init,
diff --git a/arch/arm/mach-rockchip/sleep.S b/arch/arm/mach-rockchip/sleep.S
new file mode 100644
index 000000000000..2eec9a341f05
--- /dev/null
+++ b/arch/arm/mach-rockchip/sleep.S
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+.data
+/*
+ * this code will be copied from
+ * ddr to sram for system resumeing.
+ * so it is ".data section".
+ */
+.align
+
+ENTRY(rockchip_slp_cpu_resume)
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set svc, irqs off
+ mrc p15, 0, r1, c0, c0, 5
+ and r1, r1, #0xf
+ cmp r1, #0
+ /* olny cpu0 can continue to run, the others is halt here */
+ beq cpu0run
+secondary_loop:
+ wfe
+ b secondary_loop
+cpu0run:
+ ldr r3, rkpm_bootdata_l2ctlr_f
+ cmp r3, #0
+ beq sp_set
+ ldr r3, rkpm_bootdata_l2ctlr
+ mcr p15, 1, r3, c9, c0, 2
+sp_set:
+ ldr sp, rkpm_bootdata_cpusp
+ ldr r1, rkpm_bootdata_cpu_code
+ bx r1
+ENDPROC(rockchip_slp_cpu_resume)
+
+/* Parameters filled in by the kernel */
+
+/* Flag for whether to restore L2CTLR on resume */
+ .global rkpm_bootdata_l2ctlr_f
+rkpm_bootdata_l2ctlr_f:
+ .long 0
+
+/* Saved L2CTLR to restore on resume */
+ .global rkpm_bootdata_l2ctlr
+rkpm_bootdata_l2ctlr:
+ .long 0
+
+/* CPU resume SP addr */
+ .globl rkpm_bootdata_cpusp
+rkpm_bootdata_cpusp:
+ .long 0
+
+/* CPU resume function (physical address) */
+ .globl rkpm_bootdata_cpu_code
+rkpm_bootdata_cpu_code:
+ .long 0
+
+ENTRY(rk3288_bootram_sz)
+ .word . - rockchip_slp_cpu_resume
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 9eb22297cbe1..79c49ff77f6e 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -29,7 +29,6 @@ config CPU_S3C2410
default y
select CPU_ARM920T
select S3C2410_COMMON_CLK
- select S3C2410_DMA if S3C24XX_DMA
select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
select S3C2410_PM if PM
help
@@ -40,7 +39,6 @@ config CPU_S3C2412
bool "SAMSUNG S3C2412"
select CPU_ARM926T
select S3C2412_COMMON_CLK
- select S3C2412_DMA if S3C24XX_DMA
select S3C2412_PM if PM
help
Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
@@ -50,7 +48,6 @@ config CPU_S3C2416
select CPU_ARM926T
select S3C2416_PM if PM
select S3C2443_COMMON_CLK
- select S3C2443_DMA if S3C24XX_DMA
help
Support for the S3C2416 SoC from the S3C24XX line
@@ -59,7 +56,6 @@ config CPU_S3C2440
select CPU_ARM920T
select S3C2410_COMMON_CLK
select S3C2410_PM if PM
- select S3C2440_DMA if S3C24XX_DMA
help
Support for S3C2440 Samsung Mobile CPU based systems.
@@ -67,7 +63,6 @@ config CPU_S3C2442
bool "SAMSUNG S3C2442"
select CPU_ARM920T
select S3C2410_COMMON_CLK
- select S3C2410_DMA if S3C24XX_DMA
select S3C2410_PM if PM
help
Support for S3C2442 Samsung Mobile CPU based systems.
@@ -80,7 +75,6 @@ config CPU_S3C2443
bool "SAMSUNG S3C2443"
select CPU_ARM920T
select S3C2443_COMMON_CLK
- select S3C2443_DMA if S3C24XX_DMA
help
Support for the S3C2443 SoC from the S3C24XX line
@@ -114,27 +108,6 @@ config S3C24XX_SETUP_TS
help
Compile in platform device definition for Samsung TouchScreen.
-config S3C24XX_DMA
- bool "S3C2410 DMA support (deprecated)"
- select S3C_DMA
- help
- S3C2410 DMA support. This is needed for drivers like sound which
- use the S3C2410's DMA system to move data to and from the
- peripheral blocks.
-
-config S3C2410_DMA_DEBUG
- bool "S3C2410 DMA support debug"
- depends on S3C2410_DMA
- help
- Enable debugging output for the DMA code. This option sends info
- to the kernel log, at priority KERN_DEBUG.
-
-config S3C2410_DMA
- bool
- depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442)
- help
- DMA device selection for S3C2410 and compatible CPUs
-
config S3C2410_PM
bool
help
@@ -325,11 +298,6 @@ config CPU_S3C2412_ONLY
!CPU_S3C2442 && !CPU_S3C2443
default y
-config S3C2412_DMA
- bool
- help
- Internal config node for S3C2412 DMA support
-
config S3C2412_PM
bool
select S3C2412_PM_SLEEP
@@ -438,11 +406,6 @@ endif # CPU_S3C2416
if CPU_S3C2440
-config S3C2440_DMA
- bool
- help
- Support for S3C2440 specific DMA code5A
-
config S3C2440_XTAL_12000000
bool
help
@@ -601,11 +564,6 @@ endif # CPU_S3C2442
if CPU_S3C2443 || CPU_S3C2416
-config S3C2443_DMA
- bool
- help
- Internal config node for S3C2443 DMA support
-
config S3C2443_SETUP_SPI
bool
help
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index b92071638733..b40a22fe082a 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -12,12 +12,10 @@
obj-y += common.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
-obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o
obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o
obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
-obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o
obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o
obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
@@ -27,7 +25,6 @@ obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o
obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
-obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o
obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
@@ -39,15 +36,11 @@ obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o
# common code
-obj-$(CONFIG_S3C24XX_DMA) += dma.o
-
obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o
obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o
-obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o
-
#
# machine support
# following is ordered alphabetically by option text.
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2410.c b/arch/arm/mach-s3c24xx/dma-s3c2410.c
deleted file mode 100644
index 09aa12da1789..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2410.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include <plat/cpu.h>
-#include <plat/dma-s3c24xx.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
- },
- [DMACH_SDI] = {
- .name = "sdi",
- .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
- },
- [DMACH_SPI0] = {
- .name = "spi0",
- .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
- },
- [DMACH_SPI1] = {
- .name = "spi1",
- .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
- },
- [DMACH_USB_EP1] = {
- .name = "usb-ep1",
- .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
- },
- [DMACH_USB_EP2] = {
- .name = "usb-ep2",
- .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
- },
- [DMACH_USB_EP3] = {
- .name = "usb-ep3",
- .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
- },
- [DMACH_USB_EP4] = {
- .name = "usb-ep4",
- .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
- },
-};
-
-static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
- .select = s3c2410_dma_select,
- .dcon_mask = 7 << 24,
- .map = s3c2410_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2410_dma_mappings),
-};
-
-static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
- .channels = {
- [DMACH_SDI] = {
- .list = {
- [0] = 3 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- [2] = 0 | DMA_CH_VALID,
- },
- },
- [DMACH_I2S_IN] = {
- .list = {
- [0] = 1 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- },
- },
- },
-};
-
-static int __init s3c2410_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c2410_dma_init();
- s3c24xx_dma_order_set(&s3c2410_dma_order);
- return s3c24xx_dma_init_map(&s3c2410_dma_sel);
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct subsys_interface s3c2410_dma_interface = {
- .name = "s3c2410_dma",
- .subsys = &s3c2410_subsys,
- .add_dev = s3c2410_dma_add,
-};
-
-static int __init s3c2410_dma_drvinit(void)
-{
- return subsys_interface_register(&s3c2410_dma_interface);
-}
-
-arch_initcall(s3c2410_dma_drvinit);
-
-static struct subsys_interface s3c2410a_dma_interface = {
- .name = "s3c2410a_dma",
- .subsys = &s3c2410a_subsys,
- .add_dev = s3c2410_dma_add,
-};
-
-static int __init s3c2410a_dma_drvinit(void)
-{
- return subsys_interface_register(&s3c2410a_dma_interface);
-}
-
-arch_initcall(s3c2410a_dma_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-/* S3C2442 DMA contains the same selection table as the S3C2410 */
-static struct subsys_interface s3c2442_dma_interface = {
- .name = "s3c2442_dma",
- .subsys = &s3c2442_subsys,
- .add_dev = s3c2410_dma_add,
-};
-
-static int __init s3c2442_dma_drvinit(void)
-{
- return subsys_interface_register(&s3c2442_dma_interface);
-}
-
-arch_initcall(s3c2442_dma_drvinit);
-#endif
-
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2412.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c
deleted file mode 100644
index 0c0106d1a4d1..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2412.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
-
-static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels = MAP(S3C2412_DMAREQSEL_XDREQ0),
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels = MAP(S3C2412_DMAREQSEL_XDREQ1),
- },
- [DMACH_SDI] = {
- .name = "sdi",
- .channels = MAP(S3C2412_DMAREQSEL_SDI),
- },
- [DMACH_SPI0_RX] = {
- .name = "spi0-rx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI0RX),
- },
- [DMACH_SPI0_TX] = {
- .name = "spi0-tx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI0TX),
- },
- [DMACH_SPI1_RX] = {
- .name = "spi1-rx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI1RX),
- },
- [DMACH_SPI1_TX] = {
- .name = "spi1-tx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI1TX),
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels = MAP(S3C2412_DMAREQSEL_UART0_0),
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels = MAP(S3C2412_DMAREQSEL_UART1_0),
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels = MAP(S3C2412_DMAREQSEL_UART2_0),
- },
- [DMACH_UART0_SRC2] = {
- .name = "uart0",
- .channels = MAP(S3C2412_DMAREQSEL_UART0_1),
- },
- [DMACH_UART1_SRC2] = {
- .name = "uart1",
- .channels = MAP(S3C2412_DMAREQSEL_UART1_1),
- },
- [DMACH_UART2_SRC2] = {
- .name = "uart2",
- .channels = MAP(S3C2412_DMAREQSEL_UART2_1),
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels = MAP(S3C2412_DMAREQSEL_TIMER),
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels = MAP(S3C2412_DMAREQSEL_I2STX),
- },
- [DMACH_USB_EP1] = {
- .name = "usb-ep1",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP1),
- },
- [DMACH_USB_EP2] = {
- .name = "usb-ep2",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP2),
- },
- [DMACH_USB_EP3] = {
- .name = "usb-ep3",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP3),
- },
- [DMACH_USB_EP4] = {
- .name = "usb-ep4",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP4),
- },
-};
-
-static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- unsigned long chsel = map->channels[0] & (~DMA_CH_VALID);
- writel(chsel | S3C2412_DMAREQSEL_HW,
- chan->regs + S3C2412_DMA_DMAREQSEL);
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
- .select = s3c2412_dma_select,
- .dcon_mask = 0,
- .map = s3c2412_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
-};
-
-static int __init s3c2412_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c2410_dma_init();
- return s3c24xx_dma_init_map(&s3c2412_dma_sel);
-}
-
-static struct subsys_interface s3c2412_dma_interface = {
- .name = "s3c2412_dma",
- .subsys = &s3c2412_subsys,
- .add_dev = s3c2412_dma_add,
-};
-
-static int __init s3c2412_dma_init(void)
-{
- return subsys_interface_register(&s3c2412_dma_interface);
-}
-
-arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2440.c b/arch/arm/mach-s3c24xx/dma-s3c2440.c
deleted file mode 100644
index 2f8e8a3017df..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2440.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
- },
- [DMACH_SDI] = {
- .name = "sdi",
- .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
- .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
- },
- [DMACH_SPI0] = {
- .name = "spi0",
- .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
- },
- [DMACH_SPI1] = {
- .name = "spi1",
- .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
- },
- [DMACH_PCM_IN] = {
- .name = "pcm-in",
- .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
- .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
- },
- [DMACH_PCM_OUT] = {
- .name = "pcm-out",
- .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
- .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
- },
- [DMACH_MIC_IN] = {
- .name = "mic-in",
- .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
- .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
- },
- [DMACH_USB_EP1] = {
- .name = "usb-ep1",
- .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
- },
- [DMACH_USB_EP2] = {
- .name = "usb-ep2",
- .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
- },
- [DMACH_USB_EP3] = {
- .name = "usb-ep3",
- .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
- },
- [DMACH_USB_EP4] = {
- .name = "usb-ep4",
- .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
- },
-};
-
-static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
- .select = s3c2440_dma_select,
- .dcon_mask = 7 << 24,
- .map = s3c2440_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2440_dma_mappings),
-};
-
-static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
- .channels = {
- [DMACH_SDI] = {
- .list = {
- [0] = 3 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- [2] = 1 | DMA_CH_VALID,
- [3] = 0 | DMA_CH_VALID,
- },
- },
- [DMACH_I2S_IN] = {
- .list = {
- [0] = 1 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- },
- },
- [DMACH_I2S_OUT] = {
- .list = {
- [0] = 2 | DMA_CH_VALID,
- [1] = 1 | DMA_CH_VALID,
- },
- },
- [DMACH_PCM_IN] = {
- .list = {
- [0] = 2 | DMA_CH_VALID,
- [1] = 1 | DMA_CH_VALID,
- },
- },
- [DMACH_PCM_OUT] = {
- .list = {
- [0] = 1 | DMA_CH_VALID,
- [1] = 3 | DMA_CH_VALID,
- },
- },
- [DMACH_MIC_IN] = {
- .list = {
- [0] = 3 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- },
- },
- },
-};
-
-static int __init s3c2440_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c2410_dma_init();
- s3c24xx_dma_order_set(&s3c2440_dma_order);
- return s3c24xx_dma_init_map(&s3c2440_dma_sel);
-}
-
-static struct subsys_interface s3c2440_dma_interface = {
- .name = "s3c2440_dma",
- .subsys = &s3c2440_subsys,
- .add_dev = s3c2440_dma_add,
-};
-
-static int __init s3c2440_dma_init(void)
-{
- return subsys_interface_register(&s3c2440_dma_interface);
-}
-
-arch_initcall(s3c2440_dma_init);
-
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c
deleted file mode 100644
index f4096ec0700a..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2443.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/dma.c
- *
- * Copyright (c) 2007 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2443 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-#define MAP(x) { \
- [0] = (x) | DMA_CH_VALID, \
- [1] = (x) | DMA_CH_VALID, \
- [2] = (x) | DMA_CH_VALID, \
- [3] = (x) | DMA_CH_VALID, \
- [4] = (x) | DMA_CH_VALID, \
- [5] = (x) | DMA_CH_VALID, \
- }
-
-static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels = MAP(S3C2443_DMAREQSEL_XDREQ0),
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels = MAP(S3C2443_DMAREQSEL_XDREQ1),
- },
- [DMACH_SDI] = { /* only on S3C2443 */
- .name = "sdi",
- .channels = MAP(S3C2443_DMAREQSEL_SDI),
- },
- [DMACH_SPI0_RX] = {
- .name = "spi0-rx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI0RX),
- },
- [DMACH_SPI0_TX] = {
- .name = "spi0-tx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI0TX),
- },
- [DMACH_SPI1_RX] = { /* only on S3C2443/S3C2450 */
- .name = "spi1-rx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI1RX),
- },
- [DMACH_SPI1_TX] = { /* only on S3C2443/S3C2450 */
- .name = "spi1-tx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI1TX),
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels = MAP(S3C2443_DMAREQSEL_UART0_0),
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels = MAP(S3C2443_DMAREQSEL_UART1_0),
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels = MAP(S3C2443_DMAREQSEL_UART2_0),
- },
- [DMACH_UART3] = {
- .name = "uart3",
- .channels = MAP(S3C2443_DMAREQSEL_UART3_0),
- },
- [DMACH_UART0_SRC2] = {
- .name = "uart0",
- .channels = MAP(S3C2443_DMAREQSEL_UART0_1),
- },
- [DMACH_UART1_SRC2] = {
- .name = "uart1",
- .channels = MAP(S3C2443_DMAREQSEL_UART1_1),
- },
- [DMACH_UART2_SRC2] = {
- .name = "uart2",
- .channels = MAP(S3C2443_DMAREQSEL_UART2_1),
- },
- [DMACH_UART3_SRC2] = {
- .name = "uart3",
- .channels = MAP(S3C2443_DMAREQSEL_UART3_1),
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels = MAP(S3C2443_DMAREQSEL_TIMER),
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels = MAP(S3C2443_DMAREQSEL_I2SRX),
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels = MAP(S3C2443_DMAREQSEL_I2STX),
- },
- [DMACH_PCM_IN] = {
- .name = "pcm-in",
- .channels = MAP(S3C2443_DMAREQSEL_PCMIN),
- },
- [DMACH_PCM_OUT] = {
- .name = "pcm-out",
- .channels = MAP(S3C2443_DMAREQSEL_PCMOUT),
- },
- [DMACH_MIC_IN] = {
- .name = "mic-in",
- .channels = MAP(S3C2443_DMAREQSEL_MICIN),
- },
-};
-
-static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- unsigned long chsel = map->channels[0] & (~DMA_CH_VALID);
- writel(chsel | S3C2443_DMAREQSEL_HW,
- chan->regs + S3C2443_DMA_DMAREQSEL);
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
- .select = s3c2443_dma_select,
- .dcon_mask = 0,
- .map = s3c2443_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2443_dma_mappings),
-};
-
-static int __init s3c2443_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
- return s3c24xx_dma_init_map(&s3c2443_dma_sel);
-}
-
-#ifdef CONFIG_CPU_S3C2416
-/* S3C2416 DMA contains the same selection table as the S3C2443 */
-static struct subsys_interface s3c2416_dma_interface = {
- .name = "s3c2416_dma",
- .subsys = &s3c2416_subsys,
- .add_dev = s3c2443_dma_add,
-};
-
-static int __init s3c2416_dma_init(void)
-{
- return subsys_interface_register(&s3c2416_dma_interface);
-}
-
-arch_initcall(s3c2416_dma_init);
-#endif
-
-#ifdef CONFIG_CPU_S3C2443
-static struct subsys_interface s3c2443_dma_interface = {
- .name = "s3c2443_dma",
- .subsys = &s3c2443_subsys,
- .add_dev = s3c2443_dma_add,
-};
-
-static int __init s3c2443_dma_init(void)
-{
- return subsys_interface_register(&s3c2443_dma_interface);
-}
-
-arch_initcall(s3c2443_dma_init);
-#endif
diff --git a/arch/arm/mach-s3c24xx/dma.c b/arch/arm/mach-s3c24xx/dma.c
deleted file mode 100644
index a8dafc174fe3..000000000000
--- a/arch/arm/mach-s3c24xx/dma.c
+++ /dev/null
@@ -1,1465 +0,0 @@
-/*
- * Copyright 2003-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 DMA core
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-#define DEBUG
-#endif
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/syscore_ops.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/dma.h>
-#include <mach/map.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/regs-dma.h>
-
-/* io map for dma */
-static void __iomem *dma_base;
-static struct kmem_cache *dma_kmem;
-
-static int dma_channels;
-
-static struct s3c24xx_dma_selection dma_sel;
-
-
-/* debugging functions */
-
-#define BUF_MAGIC (0xcafebabe)
-
-#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
-
-#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
-
-#if 1
-#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
-#else
-static inline void
-dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
-{
- pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
- writel(val, dma_regaddr(chan, reg));
-}
-#endif
-
-#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
-
-/* captured register state for debug */
-
-struct s3c2410_dma_regstate {
- unsigned long dcsrc;
- unsigned long disrc;
- unsigned long dstat;
- unsigned long dcon;
- unsigned long dmsktrig;
-};
-
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-
-/* dmadbg_showregs
- *
- * simple debug routine to print the current state of the dma registers
-*/
-
-static void
-dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
-{
- regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
- regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
- regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT);
- regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON);
- regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-}
-
-static void
-dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
- struct s3c2410_dma_regstate *regs)
-{
- printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
- chan->number, fname, line,
- regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
- regs->dcon);
-}
-
-static void
-dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
- struct s3c2410_dma_regstate state;
-
- dmadbg_capture(chan, &state);
-
- printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
- chan->number, fname, line, chan->load_state,
- chan->curr, chan->next, chan->end);
-
- dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-static void
-dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
- struct s3c2410_dma_regstate state;
-
- dmadbg_capture(chan, &state);
- dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-#define dbg_showregs(chan) dmadbg_showregs(__func__, __LINE__, (chan))
-#define dbg_showchan(chan) dmadbg_showchan(__func__, __LINE__, (chan))
-#else
-#define dbg_showregs(chan) do { } while(0)
-#define dbg_showchan(chan) do { } while(0)
-#endif /* CONFIG_S3C2410_DMA_DEBUG */
-
-/* s3c2410_dma_stats_timeout
- *
- * Update DMA stats from timeout info
-*/
-
-static void
-s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
-{
- if (stats == NULL)
- return;
-
- if (val > stats->timeout_longest)
- stats->timeout_longest = val;
- if (val < stats->timeout_shortest)
- stats->timeout_shortest = val;
-
- stats->timeout_avg += val;
-}
-
-/* s3c2410_dma_waitforload
- *
- * wait for the DMA engine to load a buffer, and update the state accordingly
-*/
-
-static int
-s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
-{
- int timeout = chan->load_timeout;
- int took;
-
- if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
- printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
- return 0;
- }
-
- if (chan->stats != NULL)
- chan->stats->loads++;
-
- while (--timeout > 0) {
- if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
- took = chan->load_timeout - timeout;
-
- s3c2410_dma_stats_timeout(chan->stats, took);
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_1LOADED:
- chan->load_state = S3C2410_DMALOAD_1RUNNING;
- break;
-
- default:
- printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
- }
-
- return 1;
- }
- }
-
- if (chan->stats != NULL) {
- chan->stats->timeout_failed++;
- }
-
- return 0;
-}
-
-/* s3c2410_dma_loadbuffer
- *
- * load a buffer, and update the channel state
-*/
-
-static inline int
-s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
- struct s3c2410_dma_buf *buf)
-{
- unsigned long reload;
-
- if (buf == NULL) {
- dmawarn("buffer is NULL\n");
- return -EINVAL;
- }
-
- pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
- buf, (unsigned long)buf->data, buf->size);
-
- /* check the state of the channel before we do anything */
-
- if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
- dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
- }
-
- if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
- dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
- }
-
- /* it would seem sensible if we are the last buffer to not bother
- * with the auto-reload bit, so that the DMA engine will not try
- * and load another transfer after this one has finished...
- */
- if (chan->load_state == S3C2410_DMALOAD_NONE) {
- pr_debug("load_state is none, checking for noreload (next=%p)\n",
- buf->next);
- reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
- } else {
- //pr_debug("load_state is %d => autoreload\n", chan->load_state);
- reload = S3C2410_DCON_AUTORELOAD;
- }
-
- if ((buf->data & 0xf0000000) != 0x30000000) {
- dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
- }
-
- writel(buf->data, chan->addr_reg);
-
- dma_wrreg(chan, S3C2410_DMA_DCON,
- chan->dcon | reload | (buf->size/chan->xfer_unit));
-
- chan->next = buf->next;
-
- /* update the state of the channel */
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_NONE:
- chan->load_state = S3C2410_DMALOAD_1LOADED;
- break;
-
- case S3C2410_DMALOAD_1RUNNING:
- chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
- break;
-
- default:
- dmawarn("dmaload: unknown state %d in loadbuffer\n",
- chan->load_state);
- break;
- }
-
- return 0;
-}
-
-/* s3c2410_dma_call_op
- *
- * small routine to call the op routine with the given op if it has been
- * registered
-*/
-
-static void
-s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
-{
- if (chan->op_fn != NULL) {
- (chan->op_fn)(chan, op);
- }
-}
-
-/* s3c2410_dma_buffdone
- *
- * small wrapper to check if callback routine needs to be called, and
- * if so, call it
-*/
-
-static inline void
-s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
- enum s3c2410_dma_buffresult result)
-{
-#if 0
- pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
- chan->callback_fn, buf, buf->id, buf->size, result);
-#endif
-
- if (chan->callback_fn != NULL) {
- (chan->callback_fn)(chan, buf->id, buf->size, result);
- }
-}
-
-/* s3c2410_dma_start
- *
- * start a dma channel going
-*/
-
-static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
-{
- unsigned long tmp;
- unsigned long flags;
-
- pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
-
- local_irq_save(flags);
-
- if (chan->state == S3C2410_DMA_RUNNING) {
- pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
- local_irq_restore(flags);
- return 0;
- }
-
- chan->state = S3C2410_DMA_RUNNING;
-
- /* check whether there is anything to load, and if not, see
- * if we can find anything to load
- */
-
- if (chan->load_state == S3C2410_DMALOAD_NONE) {
- if (chan->next == NULL) {
- printk(KERN_ERR "dma%d: channel has nothing loaded\n",
- chan->number);
- chan->state = S3C2410_DMA_IDLE;
- local_irq_restore(flags);
- return -EINVAL;
- }
-
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
-
- dbg_showchan(chan);
-
- /* enable the channel */
-
- if (!chan->irq_enabled) {
- enable_irq(chan->irq);
- chan->irq_enabled = 1;
- }
-
- /* start the channel going */
-
- tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
- tmp &= ~S3C2410_DMASKTRIG_STOP;
- tmp |= S3C2410_DMASKTRIG_ON;
- dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
- pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
-
-#if 0
- /* the dma buffer loads should take care of clearing the AUTO
- * reloading feature */
- tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
- tmp &= ~S3C2410_DCON_NORELOAD;
- dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
- s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
-
- dbg_showchan(chan);
-
- /* if we've only loaded one buffer onto the channel, then chec
- * to see if we have another, and if so, try and load it so when
- * the first buffer is finished, the new one will be loaded onto
- * the channel */
-
- if (chan->next != NULL) {
- if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- pr_debug("%s: buff not yet loaded, no more todo\n",
- __func__);
- } else {
- chan->load_state = S3C2410_DMALOAD_1RUNNING;
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
-
- } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
- }
-
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-/* s3c2410_dma_canload
- *
- * work out if we can queue another buffer into the DMA engine
-*/
-
-static int
-s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
-{
- if (chan->load_state == S3C2410_DMALOAD_NONE ||
- chan->load_state == S3C2410_DMALOAD_1RUNNING)
- return 1;
-
- return 0;
-}
-
-/* s3c2410_dma_enqueue
- *
- * queue an given buffer for dma transfer.
- *
- * id the device driver's id information for this buffer
- * data the physical address of the buffer data
- * size the size of the buffer in bytes
- *
- * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
- * is checked, and if set, the channel is started. If this flag isn't set,
- * then an error will be returned.
- *
- * It is possible to queue more than one DMA buffer onto a channel at
- * once, and the code will deal with the re-loading of the next buffer
- * when necessary.
-*/
-
-int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
- dma_addr_t data, int size)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- struct s3c2410_dma_buf *buf;
- unsigned long flags;
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: id=%p, data=%08x, size=%d\n",
- __func__, id, (unsigned int)data, size);
-
- buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
- if (buf == NULL) {
- pr_debug("%s: out of memory (%ld alloc)\n",
- __func__, (long)sizeof(*buf));
- return -ENOMEM;
- }
-
- //pr_debug("%s: new buffer %p\n", __func__, buf);
- //dbg_showchan(chan);
-
- buf->next = NULL;
- buf->data = buf->ptr = data;
- buf->size = size;
- buf->id = id;
- buf->magic = BUF_MAGIC;
-
- local_irq_save(flags);
-
- if (chan->curr == NULL) {
- /* we've got nothing loaded... */
- pr_debug("%s: buffer %p queued onto empty channel\n",
- __func__, buf);
-
- chan->curr = buf;
- chan->end = buf;
- chan->next = NULL;
- } else {
- pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
- chan->number, __func__, buf);
-
- if (chan->end == NULL) {
- pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
- chan->number, __func__, chan);
- } else {
- chan->end->next = buf;
- chan->end = buf;
- }
- }
-
- /* if necessary, update the next buffer field */
- if (chan->next == NULL)
- chan->next = buf;
-
- /* check to see if we can load a buffer */
- if (chan->state == S3C2410_DMA_RUNNING) {
- if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- printk(KERN_ERR "dma%d: loadbuffer:"
- "timeout loading buffer\n",
- chan->number);
- dbg_showchan(chan);
- local_irq_restore(flags);
- return -EINVAL;
- }
- }
-
- while (s3c2410_dma_canload(chan) && chan->next != NULL) {
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
- } else if (chan->state == S3C2410_DMA_IDLE) {
- if (chan->flags & S3C2410_DMAF_AUTOSTART) {
- s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
- S3C2410_DMAOP_START);
- }
- }
-
- local_irq_restore(flags);
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
-
-static inline void
-s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
-{
- int magicok = (buf->magic == BUF_MAGIC);
-
- buf->magic = -1;
-
- if (magicok) {
- kmem_cache_free(dma_kmem, buf);
- } else {
- printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
- }
-}
-
-/* s3c2410_dma_lastxfer
- *
- * called when the system is out of buffers, to ensure that the channel
- * is prepared for shutdown.
-*/
-
-static inline void
-s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
-{
-#if 0
- pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
- chan->number, chan->load_state);
-#endif
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_NONE:
- break;
-
- case S3C2410_DMALOAD_1LOADED:
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- /* flag error? */
- printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
- chan->number, __func__);
- return;
- }
- break;
-
- case S3C2410_DMALOAD_1LOADED_1RUNNING:
- /* I believe in this case we do not have anything to do
- * until the next buffer comes along, and we turn off the
- * reload */
- return;
-
- default:
- pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
- chan->number, chan->load_state);
- return;
-
- }
-
- /* hopefully this'll shut the damned thing up after the transfer... */
- dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
-}
-
-
-#define dmadbg2(x...)
-
-static irqreturn_t
-s3c2410_dma_irq(int irq, void *devpw)
-{
- struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
- struct s3c2410_dma_buf *buf;
-
- buf = chan->curr;
-
- dbg_showchan(chan);
-
- /* modify the channel state */
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_1RUNNING:
- /* TODO - if we are running only one buffer, we probably
- * want to reload here, and then worry about the buffer
- * callback */
-
- chan->load_state = S3C2410_DMALOAD_NONE;
- break;
-
- case S3C2410_DMALOAD_1LOADED:
- /* iirc, we should go back to NONE loaded here, we
- * had a buffer, and it was never verified as being
- * loaded.
- */
-
- chan->load_state = S3C2410_DMALOAD_NONE;
- break;
-
- case S3C2410_DMALOAD_1LOADED_1RUNNING:
- /* we'll worry about checking to see if another buffer is
- * ready after we've called back the owner. This should
- * ensure we do not wait around too long for the DMA
- * engine to start the next transfer
- */
-
- chan->load_state = S3C2410_DMALOAD_1LOADED;
- break;
-
- case S3C2410_DMALOAD_NONE:
- printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
- chan->number);
- break;
-
- default:
- printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
- chan->number, chan->load_state);
- break;
- }
-
- if (buf != NULL) {
- /* update the chain to make sure that if we load any more
- * buffers when we call the callback function, things should
- * work properly */
-
- chan->curr = buf->next;
- buf->next = NULL;
-
- if (buf->magic != BUF_MAGIC) {
- printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
- chan->number, __func__, buf);
- return IRQ_HANDLED;
- }
-
- s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
-
- /* free resouces */
- s3c2410_dma_freebuf(buf);
- } else {
- }
-
- /* only reload if the channel is still running... our buffer done
- * routine may have altered the state by requesting the dma channel
- * to stop or shutdown... */
-
- /* todo: check that when the channel is shut-down from inside this
- * function, we cope with unsetting reload, etc */
-
- if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
- unsigned long flags;
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_1RUNNING:
- /* don't need to do anything for this state */
- break;
-
- case S3C2410_DMALOAD_NONE:
- /* can load buffer immediately */
- break;
-
- case S3C2410_DMALOAD_1LOADED:
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- /* flag error? */
- printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
- chan->number, __func__);
- return IRQ_HANDLED;
- }
-
- break;
-
- case S3C2410_DMALOAD_1LOADED_1RUNNING:
- goto no_load;
-
- default:
- printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
- chan->number, chan->load_state);
- return IRQ_HANDLED;
- }
-
- local_irq_save(flags);
- s3c2410_dma_loadbuffer(chan, chan->next);
- local_irq_restore(flags);
- } else {
- s3c2410_dma_lastxfer(chan);
-
- /* see if we can stop this channel.. */
- if (chan->load_state == S3C2410_DMALOAD_NONE) {
- pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
- chan->number, jiffies);
- s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
- S3C2410_DMAOP_STOP);
- }
- }
-
- no_load:
- return IRQ_HANDLED;
-}
-
-static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
-
-/* s3c2410_request_dma
- *
- * get control of an dma channel
-*/
-
-int s3c2410_dma_request(enum dma_ch channel,
- struct s3c2410_dma_client *client,
- void *dev)
-{
- struct s3c2410_dma_chan *chan;
- unsigned long flags;
- int err;
-
- pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
- channel, client->name, dev);
-
- local_irq_save(flags);
-
- chan = s3c2410_dma_map_channel(channel);
- if (chan == NULL) {
- local_irq_restore(flags);
- return -EBUSY;
- }
-
- dbg_showchan(chan);
-
- chan->client = client;
- chan->in_use = 1;
-
- if (!chan->irq_claimed) {
- pr_debug("dma%d: %s : requesting irq %d\n",
- channel, __func__, chan->irq);
-
- chan->irq_claimed = 1;
- local_irq_restore(flags);
-
- err = request_irq(chan->irq, s3c2410_dma_irq, 0,
- client->name, (void *)chan);
-
- local_irq_save(flags);
-
- if (err) {
- chan->in_use = 0;
- chan->irq_claimed = 0;
- local_irq_restore(flags);
-
- printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
- client->name, chan->irq, chan->number);
- return err;
- }
-
- chan->irq_enabled = 1;
- }
-
- local_irq_restore(flags);
-
- /* need to setup */
-
- pr_debug("%s: channel initialised, %p\n", __func__, chan);
-
- return chan->number | DMACH_LOW_LEVEL;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_request);
-
-/* s3c2410_dma_free
- *
- * release the given channel back to the system, will stop and flush
- * any outstanding transfers, and ensure the channel is ready for the
- * next claimant.
- *
- * Note, although a warning is currently printed if the freeing client
- * info is not the same as the registrant's client info, the free is still
- * allowed to go through.
-*/
-
-int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- unsigned long flags;
-
- if (chan == NULL)
- return -EINVAL;
-
- local_irq_save(flags);
-
- if (chan->client != client) {
- printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
- channel, chan->client, client);
- }
-
- /* sort out stopping and freeing the channel */
-
- if (chan->state != S3C2410_DMA_IDLE) {
- pr_debug("%s: need to stop dma channel %p\n",
- __func__, chan);
-
- /* possibly flush the channel */
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
- }
-
- chan->client = NULL;
- chan->in_use = 0;
-
- if (chan->irq_claimed)
- free_irq(chan->irq, (void *)chan);
-
- chan->irq_claimed = 0;
-
- if (!(channel & DMACH_LOW_LEVEL))
- s3c_dma_chan_map[channel] = NULL;
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_free);
-
-static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
-{
- unsigned long flags;
- unsigned long tmp;
-
- pr_debug("%s:\n", __func__);
-
- dbg_showchan(chan);
-
- local_irq_save(flags);
-
- s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP);
-
- tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
- tmp |= S3C2410_DMASKTRIG_STOP;
- //tmp &= ~S3C2410_DMASKTRIG_ON;
- dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
-#if 0
- /* should also clear interrupts, according to WinCE BSP */
- tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
- tmp |= S3C2410_DCON_NORELOAD;
- dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
- /* should stop do this, or should we wait for flush? */
- chan->state = S3C2410_DMA_IDLE;
- chan->load_state = S3C2410_DMALOAD_NONE;
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
-{
- unsigned long tmp;
- unsigned int timeout = 0x10000;
-
- while (timeout-- > 0) {
- tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-
- if (!(tmp & S3C2410_DMASKTRIG_ON))
- return;
- }
-
- pr_debug("dma%d: failed to stop?\n", chan->number);
-}
-
-
-/* s3c2410_dma_flush
- *
- * stop the channel, and remove all current and pending transfers
-*/
-
-static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
-{
- struct s3c2410_dma_buf *buf, *next;
- unsigned long flags;
-
- pr_debug("%s: chan %p (%d)\n", __func__, chan, chan->number);
-
- dbg_showchan(chan);
-
- local_irq_save(flags);
-
- if (chan->state != S3C2410_DMA_IDLE) {
- pr_debug("%s: stopping channel...\n", __func__ );
- s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
- }
-
- buf = chan->curr;
- if (buf == NULL)
- buf = chan->next;
-
- chan->curr = chan->next = chan->end = NULL;
-
- if (buf != NULL) {
- for ( ; buf != NULL; buf = next) {
- next = buf->next;
-
- pr_debug("%s: free buffer %p, next %p\n",
- __func__, buf, buf->next);
-
- s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
- s3c2410_dma_freebuf(buf);
- }
- }
-
- dbg_showregs(chan);
-
- s3c2410_dma_waitforstop(chan);
-
-#if 0
- /* should also clear interrupts, according to WinCE BSP */
- {
- unsigned long tmp;
-
- tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
- tmp |= S3C2410_DCON_NORELOAD;
- dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
- }
-#endif
-
- dbg_showregs(chan);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
-{
- unsigned long flags;
-
- local_irq_save(flags);
-
- dbg_showchan(chan);
-
- /* if we've only loaded one buffer onto the channel, then chec
- * to see if we have another, and if so, try and load it so when
- * the first buffer is finished, the new one will be loaded onto
- * the channel */
-
- if (chan->next != NULL) {
- if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- pr_debug("%s: buff not yet loaded, no more todo\n",
- __func__);
- } else {
- chan->load_state = S3C2410_DMALOAD_1RUNNING;
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
-
- } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
- }
-
-
- local_irq_restore(flags);
-
- return 0;
-
-}
-
-int
-s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- switch (op) {
- case S3C2410_DMAOP_START:
- return s3c2410_dma_start(chan);
-
- case S3C2410_DMAOP_STOP:
- return s3c2410_dma_dostop(chan);
-
- case S3C2410_DMAOP_PAUSE:
- case S3C2410_DMAOP_RESUME:
- return -ENOENT;
-
- case S3C2410_DMAOP_FLUSH:
- return s3c2410_dma_flush(chan);
-
- case S3C2410_DMAOP_STARTED:
- return s3c2410_dma_started(chan);
-
- case S3C2410_DMAOP_TIMEOUT:
- return 0;
-
- }
-
- return -ENOENT; /* unknown, don't bother */
-}
-
-EXPORT_SYMBOL(s3c2410_dma_ctrl);
-
-/* DMA configuration for each channel
- *
- * DISRCC -> source of the DMA (AHB,APB)
- * DISRC -> source address of the DMA
- * DIDSTC -> destination of the DMA (AHB,APD)
- * DIDST -> destination address of the DMA
-*/
-
-/* s3c2410_dma_config
- *
- * xfersize: size of unit in bytes (1,2,4)
-*/
-
-int s3c2410_dma_config(enum dma_ch channel,
- int xferunit)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- unsigned int dcon;
-
- pr_debug("%s: chan=%d, xfer_unit=%d\n", __func__, channel, xferunit);
-
- if (chan == NULL)
- return -EINVAL;
-
- dcon = chan->dcon & dma_sel.dcon_mask;
- pr_debug("%s: dcon is %08x\n", __func__, dcon);
-
- switch (chan->req_ch) {
- case DMACH_I2S_IN:
- case DMACH_I2S_OUT:
- case DMACH_PCM_IN:
- case DMACH_PCM_OUT:
- case DMACH_MIC_IN:
- default:
- dcon |= S3C2410_DCON_HANDSHAKE;
- dcon |= S3C2410_DCON_SYNC_PCLK;
- break;
-
- case DMACH_SDI:
- /* note, ensure if need HANDSHAKE or not */
- dcon |= S3C2410_DCON_SYNC_PCLK;
- break;
-
- case DMACH_XD0:
- case DMACH_XD1:
- dcon |= S3C2410_DCON_HANDSHAKE;
- dcon |= S3C2410_DCON_SYNC_HCLK;
- break;
- }
-
- switch (xferunit) {
- case 1:
- dcon |= S3C2410_DCON_BYTE;
- break;
-
- case 2:
- dcon |= S3C2410_DCON_HALFWORD;
- break;
-
- case 4:
- dcon |= S3C2410_DCON_WORD;
- break;
-
- default:
- pr_debug("%s: bad transfer size %d\n", __func__, xferunit);
- return -EINVAL;
- }
-
- dcon |= S3C2410_DCON_HWTRIG;
- dcon |= S3C2410_DCON_INTREQ;
-
- pr_debug("%s: dcon now %08x\n", __func__, dcon);
-
- chan->dcon = dcon;
- chan->xfer_unit = xferunit;
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_config);
-
-
-/* s3c2410_dma_devconfig
- *
- * configure the dma source/destination hardware type and address
- *
- * source: DMA_FROM_DEVICE: source is hardware
- * DMA_TO_DEVICE: source is memory
- *
- * devaddr: physical address of the source
-*/
-
-int s3c2410_dma_devconfig(enum dma_ch channel,
- enum dma_data_direction source,
- unsigned long devaddr)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- unsigned int hwcfg;
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: source=%d, devaddr=%08lx\n",
- __func__, (int)source, devaddr);
-
- chan->source = source;
- chan->dev_addr = devaddr;
-
- switch (chan->req_ch) {
- case DMACH_XD0:
- case DMACH_XD1:
- hwcfg = 0; /* AHB */
- break;
-
- default:
- hwcfg = S3C2410_DISRCC_APB;
- }
-
- /* always assume our peripheral desintation is a fixed
- * address in memory. */
- hwcfg |= S3C2410_DISRCC_INC;
-
- switch (source) {
- case DMA_FROM_DEVICE:
- /* source is hardware */
- pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
- __func__, devaddr, hwcfg);
- dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
- dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr);
- dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
-
- chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
- break;
-
- case DMA_TO_DEVICE:
- /* source is memory */
- pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
- __func__, devaddr, hwcfg);
- dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
- dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr);
- dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
-
- chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
- break;
-
- default:
- printk(KERN_ERR "dma%d: invalid source type (%d)\n",
- channel, source);
-
- return -EINVAL;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_devconfig);
-
-/* s3c2410_dma_getposition
- *
- * returns the current transfer points for the dma source and destination
-*/
-
-int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- if (src != NULL)
- *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
-
- if (dst != NULL)
- *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_getposition);
-
-/* system core operations */
-
-#ifdef CONFIG_PM
-
-static void s3c2410_dma_suspend_chan(struct s3c2410_dma_chan *cp)
-{
- printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
-
- if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
- /* the dma channel is still working, which is probably
- * a bad thing to do over suspend/resume. We stop the
- * channel and assume that the client is either going to
- * retry after resume, or that it is broken.
- */
-
- printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
- cp->number);
-
- s3c2410_dma_dostop(cp);
- }
-}
-
-static int s3c2410_dma_suspend(void)
-{
- struct s3c2410_dma_chan *cp = s3c2410_chans;
- int channel;
-
- for (channel = 0; channel < dma_channels; cp++, channel++)
- s3c2410_dma_suspend_chan(cp);
-
- return 0;
-}
-
-static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp)
-{
- unsigned int no = cp->number | DMACH_LOW_LEVEL;
-
- /* restore channel's hardware configuration */
-
- if (!cp->in_use)
- return;
-
- printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
-
- s3c2410_dma_config(no, cp->xfer_unit);
- s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);
-
- /* re-select the dma source for this channel */
-
- if (cp->map != NULL)
- dma_sel.select(cp, cp->map);
-}
-
-static void s3c2410_dma_resume(void)
-{
- struct s3c2410_dma_chan *cp = s3c2410_chans + dma_channels - 1;
- int channel;
-
- for (channel = dma_channels - 1; channel >= 0; cp--, channel--)
- s3c2410_dma_resume_chan(cp);
-}
-
-#else
-#define s3c2410_dma_suspend NULL
-#define s3c2410_dma_resume NULL
-#endif /* CONFIG_PM */
-
-struct syscore_ops dma_syscore_ops = {
- .suspend = s3c2410_dma_suspend,
- .resume = s3c2410_dma_resume,
-};
-
-/* kmem cache implementation */
-
-static void s3c2410_dma_cache_ctor(void *p)
-{
- memset(p, 0, sizeof(struct s3c2410_dma_buf));
-}
-
-/* initialisation code */
-
-static int __init s3c24xx_dma_syscore_init(void)
-{
- register_syscore_ops(&dma_syscore_ops);
-
- return 0;
-}
-
-late_initcall(s3c24xx_dma_syscore_init);
-
-int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
- unsigned int stride)
-{
- struct s3c2410_dma_chan *cp;
- int channel;
- int ret;
-
- printk("S3C24XX DMA Driver, Copyright 2003-2006 Simtec Electronics\n");
-
- dma_channels = channels;
-
- dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
- if (dma_base == NULL) {
- printk(KERN_ERR "dma failed to remap register block\n");
- return -ENOMEM;
- }
-
- dma_kmem = kmem_cache_create("dma_desc",
- sizeof(struct s3c2410_dma_buf), 0,
- SLAB_HWCACHE_ALIGN,
- s3c2410_dma_cache_ctor);
-
- if (dma_kmem == NULL) {
- printk(KERN_ERR "dma failed to make kmem cache\n");
- ret = -ENOMEM;
- goto err;
- }
-
- for (channel = 0; channel < channels; channel++) {
- cp = &s3c2410_chans[channel];
-
- memset(cp, 0, sizeof(struct s3c2410_dma_chan));
-
- /* dma channel irqs are in order.. */
- cp->number = channel;
- cp->irq = channel + irq;
- cp->regs = dma_base + (channel * stride);
-
- /* point current stats somewhere */
- cp->stats = &cp->stats_store;
- cp->stats_store.timeout_shortest = LONG_MAX;
-
- /* basic channel configuration */
-
- cp->load_timeout = 1<<18;
-
- printk("DMA channel %d at %p, irq %d\n",
- cp->number, cp->regs, cp->irq);
- }
-
- return 0;
-
- err:
- kmem_cache_destroy(dma_kmem);
- iounmap(dma_base);
- dma_base = NULL;
- return ret;
-}
-
-int __init s3c2410_dma_init(void)
-{
- return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
-}
-
-static inline int is_channel_valid(unsigned int channel)
-{
- return (channel & DMA_CH_VALID);
-}
-
-static struct s3c24xx_dma_order *dma_order;
-
-
-/* s3c2410_dma_map_channel()
- *
- * turn the virtual channel number into a real, and un-used hardware
- * channel.
- *
- * first, try the dma ordering given to us by either the relevant
- * dma code, or the board. Then just find the first usable free
- * channel
-*/
-
-static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
-{
- struct s3c24xx_dma_order_ch *ord = NULL;
- struct s3c24xx_dma_map *ch_map;
- struct s3c2410_dma_chan *dmach;
- int ch;
-
- if (dma_sel.map == NULL || channel > dma_sel.map_size)
- return NULL;
-
- ch_map = dma_sel.map + channel;
-
- /* first, try the board mapping */
-
- if (dma_order) {
- ord = &dma_order->channels[channel];
-
- for (ch = 0; ch < dma_channels; ch++) {
- int tmp;
- if (!is_channel_valid(ord->list[ch]))
- continue;
-
- tmp = ord->list[ch] & ~DMA_CH_VALID;
- if (s3c2410_chans[tmp].in_use == 0) {
- ch = tmp;
- goto found;
- }
- }
-
- if (ord->flags & DMA_CH_NEVER)
- return NULL;
- }
-
- /* second, search the channel map for first free */
-
- for (ch = 0; ch < dma_channels; ch++) {
- if (!is_channel_valid(ch_map->channels[ch]))
- continue;
-
- if (s3c2410_chans[ch].in_use == 0) {
- printk("mapped channel %d to %d\n", channel, ch);
- break;
- }
- }
-
- if (ch >= dma_channels)
- return NULL;
-
- /* update our channel mapping */
-
- found:
- dmach = &s3c2410_chans[ch];
- dmach->map = ch_map;
- dmach->req_ch = channel;
- s3c_dma_chan_map[channel] = dmach;
-
- /* select the channel */
-
- (dma_sel.select)(dmach, ch_map);
-
- return dmach;
-}
-
-static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
-{
- return 0;
-}
-
-int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
-{
- struct s3c24xx_dma_map *nmap;
- size_t map_sz = sizeof(*nmap) * sel->map_size;
- int ptr;
-
- nmap = kmemdup(sel->map, map_sz, GFP_KERNEL);
- if (nmap == NULL)
- return -ENOMEM;
-
- memcpy(&dma_sel, sel, sizeof(*sel));
-
- dma_sel.map = nmap;
-
- for (ptr = 0; ptr < sel->map_size; ptr++)
- s3c24xx_dma_check_entry(nmap+ptr, ptr);
-
- return 0;
-}
-
-int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
-{
- struct s3c24xx_dma_order *nord = dma_order;
-
- if (nord == NULL)
- nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
-
- if (nord == NULL) {
- printk(KERN_ERR "no memory to store dma channel order\n");
- return -ENOMEM;
- }
-
- dma_order = nord;
- memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
- return 0;
-}
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
index b55da1d8cd8f..9e8117198e0c 100644
--- a/arch/arm/mach-s3c24xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c24xx/include/mach/dma.h
@@ -15,8 +15,6 @@
#include <linux/device.h>
-#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
-
/* We use `virtual` dma channels to hide the fact we have only a limited
* number of DMA channels, and not of all of them (dependent on the device)
* can be attached to any DMA source. We therefore let the DMA core handle
@@ -54,161 +52,4 @@ enum dma_ch {
DMACH_MAX, /* the end entry */
};
-static inline bool samsung_dma_has_circular(void)
-{
- return false;
-}
-
-static inline bool samsung_dma_is_dmadev(void)
-{
- return false;
-}
-
-#include <plat/dma.h>
-
-#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
-
-/* we have 4 dma channels */
-#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
-#define S3C_DMA_CHANNELS (4)
-#else
-#define S3C_DMA_CHANNELS (6)
-#endif
-
-/* types */
-
-enum s3c2410_dma_state {
- S3C2410_DMA_IDLE,
- S3C2410_DMA_RUNNING,
- S3C2410_DMA_PAUSED
-};
-
-/* enum s3c2410_dma_loadst
- *
- * This represents the state of the DMA engine, wrt to the loaded / running
- * transfers. Since we don't have any way of knowing exactly the state of
- * the DMA transfers, we need to know the state to make decisions on whether
- * we can
- *
- * S3C2410_DMA_NONE
- *
- * There are no buffers loaded (the channel should be inactive)
- *
- * S3C2410_DMA_1LOADED
- *
- * There is one buffer loaded, however it has not been confirmed to be
- * loaded by the DMA engine. This may be because the channel is not
- * yet running, or the DMA driver decided that it was too costly to
- * sit and wait for it to happen.
- *
- * S3C2410_DMA_1RUNNING
- *
- * The buffer has been confirmed running, and not finisged
- *
- * S3C2410_DMA_1LOADED_1RUNNING
- *
- * There is a buffer waiting to be loaded by the DMA engine, and one
- * currently running.
-*/
-
-enum s3c2410_dma_loadst {
- S3C2410_DMALOAD_NONE,
- S3C2410_DMALOAD_1LOADED,
- S3C2410_DMALOAD_1RUNNING,
- S3C2410_DMALOAD_1LOADED_1RUNNING,
-};
-
-
-/* flags */
-
-#define S3C2410_DMAF_SLOW (1<<0) /* slow, so don't worry about
- * waiting for reloads */
-#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */
-
-#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */
-
-/* dma buffer */
-
-struct s3c2410_dma_buf;
-
-/* s3c2410_dma_buf
- *
- * internally used buffer structure to describe a queued or running
- * buffer.
-*/
-
-struct s3c2410_dma_buf {
- struct s3c2410_dma_buf *next;
- int magic; /* magic */
- int size; /* buffer size in bytes */
- dma_addr_t data; /* start of DMA data */
- dma_addr_t ptr; /* where the DMA got to [1] */
- void *id; /* client's id */
-};
-
-/* [1] is this updated for both recv/send modes? */
-
-struct s3c2410_dma_stats {
- unsigned long loads;
- unsigned long timeout_longest;
- unsigned long timeout_shortest;
- unsigned long timeout_avg;
- unsigned long timeout_failed;
-};
-
-struct s3c2410_dma_map;
-
-/* struct s3c2410_dma_chan
- *
- * full state information for each DMA channel
-*/
-
-struct s3c2410_dma_chan {
- /* channel state flags and information */
- unsigned char number; /* number of this dma channel */
- unsigned char in_use; /* channel allocated */
- unsigned char irq_claimed; /* irq claimed for channel */
- unsigned char irq_enabled; /* irq enabled for channel */
- unsigned char xfer_unit; /* size of an transfer */
-
- /* channel state */
-
- enum s3c2410_dma_state state;
- enum s3c2410_dma_loadst load_state;
- struct s3c2410_dma_client *client;
-
- /* channel configuration */
- enum dma_data_direction source;
- enum dma_ch req_ch;
- unsigned long dev_addr;
- unsigned long load_timeout;
- unsigned int flags; /* channel flags */
-
- struct s3c24xx_dma_map *map; /* channel hw maps */
-
- /* channel's hardware position and configuration */
- void __iomem *regs; /* channels registers */
- void __iomem *addr_reg; /* data address register */
- unsigned int irq; /* channel irq */
- unsigned long dcon; /* default value of DCON */
-
- /* driver handles */
- s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
- s3c2410_dma_opfn_t op_fn; /* channel op callback */
-
- /* stats gathering */
- struct s3c2410_dma_stats *stats;
- struct s3c2410_dma_stats stats_store;
-
- /* buffer list and information */
- struct s3c2410_dma_buf *curr; /* current dma buffer */
- struct s3c2410_dma_buf *next; /* next buffer to load */
- struct s3c2410_dma_buf *end; /* end of queue */
-
- /* system device */
- struct device dev;
-};
-
-typedef unsigned long dma_device_t;
-
#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index 059b1fc85037..096e14073bd9 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -51,21 +51,6 @@ enum dma_ch {
DMACH_MAX = 32
};
-struct s3c2410_dma_client {
- char *name;
-};
-
-static inline bool samsung_dma_has_circular(void)
-{
- return true;
-}
-
-static inline bool samsung_dma_is_dmadev(void)
-{
- return true;
-}
-
#include <linux/amba/pl08x.h>
-#include <plat/dma-ops.h>
#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 1b4fafe524ff..2f36c85eec4b 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -7,6 +7,7 @@ config PM_RCAR
config PM_RMOBILE
bool
+ select PM_GENERIC_DOMAINS
config ARCH_RCAR_GEN1
bool
@@ -23,7 +24,7 @@ config ARCH_RCAR_GEN2
config ARCH_RMOBILE
bool
- select PM_RMOBILE if PM && !ARCH_SHMOBILE_MULTI
+ select PM_RMOBILE if PM
select SYS_SUPPORTS_SH_CMT
select SYS_SUPPORTS_SH_TMU
@@ -51,6 +52,11 @@ config ARCH_R7S72100
bool "RZ/A1H (R7S72100)"
select SYS_SUPPORTS_SH_MTU2
+config ARCH_R8A73A4
+ bool "R-Mobile APE6 (R8A73A40)"
+ select ARCH_RMOBILE
+ select RENESAS_IRQC
+
config ARCH_R8A7740
bool "R-Mobile A1 (R8A77400)"
select ARCH_RMOBILE
@@ -74,11 +80,6 @@ config ARCH_R8A7794
comment "Renesas ARM SoCs Board Type"
-config MACH_LAGER
- bool "Lager board"
- depends on ARCH_R8A7790
- select MICREL_PHY if SH_ETH
-
config MACH_MARZEN
bool "MARZEN board"
depends on ARCH_R8A7779
@@ -133,14 +134,6 @@ config ARCH_R8A7779
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
-config ARCH_R8A7790
- bool "R-Car H2 (R8A77900)"
- select ARCH_RCAR_GEN2
- select ARCH_WANT_OPTIONAL_GPIOLIB
- select ARM_GIC
- select MIGHT_HAVE_PCI
- select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
-
comment "Renesas ARM SoCs Board Type"
config MACH_APE6EVM
@@ -208,13 +201,6 @@ config MACH_MARZEN
select REGULATOR_FIXED_VOLTAGE if REGULATOR
select USE_OF
-config MACH_LAGER
- bool "Lager board"
- depends on ARCH_R8A7790
- select USE_OF
- select MICREL_PHY if SH_ETH
- select SND_SOC_AK4642 if SND_SIMPLE_CARD
-
config MACH_KZM9G
bool "KZM-A9-GT board"
depends on ARCH_SH73A0
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index b55cac0e5b2b..d53996e6da97 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_ARCH_R8A73A4) += clock-r8a73a4.o
obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o
obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o
obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o
-obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o
endif
# CPU reset vector handling objects
@@ -57,7 +56,6 @@ obj-$(CONFIG_ARCH_SH7372) += entry-intc.o sleep-sh7372.o
# Board objects
ifdef CONFIG_ARCH_SHMOBILE_MULTI
-obj-$(CONFIG_MACH_LAGER) += board-lager-reference.o
obj-$(CONFIG_MACH_MARZEN) += board-marzen-reference.o
else
obj-$(CONFIG_MACH_APE6EVM) += board-ape6evm.o
@@ -66,7 +64,6 @@ obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
obj-$(CONFIG_MACH_BOCKW) += board-bockw.o
obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o
obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
-obj-$(CONFIG_MACH_LAGER) += board-lager.o
obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o
obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o
diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot
index 57d00ed6ec0c..02532bea5300 100644
--- a/arch/arm/mach-shmobile/Makefile.boot
+++ b/arch/arm/mach-shmobile/Makefile.boot
@@ -7,7 +7,6 @@ loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000
loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000
-loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000
loadaddr-$(CONFIG_MACH_MACKEREL) += 0x40008000
loadaddr-$(CONFIG_MACH_MARZEN) += 0x60008000
diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
deleted file mode 100644
index fa06bdba61df..000000000000
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Lager board support - Reference DT implementation
- *
- * Copyright (C) 2013 Renesas Solutions Corp.
- * Copyright (C) 2013 Simon Horman
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "r8a7790.h"
-#include "rcar-gen2.h"
-
-static const char *lager_boards_compat_dt[] __initdata = {
- "renesas,lager",
- "renesas,lager-reference",
- NULL,
-};
-
-DT_MACHINE_START(LAGER_DT, "lager")
- .smp = smp_ops(r8a7790_smp_ops),
- .init_early = shmobile_init_delay,
- .init_time = rcar_gen2_timer_init,
- .init_late = shmobile_init_late,
- .reserve = rcar_gen2_reserve,
- .dt_compat = lager_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c
deleted file mode 100644
index 65b128dd4072..000000000000
--- a/arch/arm/mach-shmobile/board-lager.c
+++ /dev/null
@@ -1,840 +0,0 @@
-/*
- * Lager board support
- *
- * Copyright (C) 2013-2014 Renesas Solutions Corp.
- * Copyright (C) 2013 Magnus Damm
- * Copyright (C) 2014 Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqchip.h>
-#include <linux/irqchip/arm-gic.h>
-#include <linux/kernel.h>
-#include <linux/leds.h>
-#include <linux/mfd/tmio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sh_mmcif.h>
-#include <linux/mmc/sh_mobile_sdhi.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/mtd.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/platform_data/camera-rcar.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/usb-rcar-gen2-phy.h>
-#include <linux/platform_device.h>
-#include <linux/phy.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/gpio-regulator.h>
-#include <linux/regulator/machine.h>
-#include <linux/sh_eth.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/rspi.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/renesas_usbhs.h>
-
-#include <media/soc_camera.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <sound/rcar_snd.h>
-#include <sound/simple_card.h>
-
-#include "common.h"
-#include "irqs.h"
-#include "r8a7790.h"
-#include "rcar-gen2.h"
-
-/*
- * SSI-AK4643
- *
- * SW1: 1: AK4643
- * 2: CN22
- * 3: ADV7511
- *
- * this command is required when playback.
- *
- * # amixer set "LINEOUT Mixer DACL" on
- */
-
-/*
- * SDHI0 (CN8)
- *
- * JP3: pin1
- * SW20: pin1
-
- * GP5_24: 1: VDD 3.3V (defult)
- * 0: VDD 0.0V
- * GP5_29: 1: VccQ 3.3V (defult)
- * 0: VccQ 1.8V
- *
- */
-
-/* LEDS */
-static struct gpio_led lager_leds[] = {
- {
- .name = "led8",
- .gpio = RCAR_GP_PIN(5, 17),
- .default_state = LEDS_GPIO_DEFSTATE_ON,
- }, {
- .name = "led7",
- .gpio = RCAR_GP_PIN(4, 23),
- .default_state = LEDS_GPIO_DEFSTATE_ON,
- }, {
- .name = "led6",
- .gpio = RCAR_GP_PIN(4, 22),
- .default_state = LEDS_GPIO_DEFSTATE_ON,
- },
-};
-
-static const struct gpio_led_platform_data lager_leds_pdata __initconst = {
- .leds = lager_leds,
- .num_leds = ARRAY_SIZE(lager_leds),
-};
-
-/* GPIO KEY */
-#define GPIO_KEY(c, g, d, ...) \
- { .code = c, .gpio = g, .desc = d, .active_low = 1, \
- .wakeup = 1, .debounce_interval = 20 }
-
-static struct gpio_keys_button gpio_buttons[] = {
- GPIO_KEY(KEY_4, RCAR_GP_PIN(1, 28), "SW2-pin4"),
- GPIO_KEY(KEY_3, RCAR_GP_PIN(1, 26), "SW2-pin3"),
- GPIO_KEY(KEY_2, RCAR_GP_PIN(1, 24), "SW2-pin2"),
- GPIO_KEY(KEY_1, RCAR_GP_PIN(1, 14), "SW2-pin1"),
-};
-
-static const struct gpio_keys_platform_data lager_keys_pdata __initconst = {
- .buttons = gpio_buttons,
- .nbuttons = ARRAY_SIZE(gpio_buttons),
-};
-
-/* Fixed 3.3V regulator to be used by MMCIF */
-static struct regulator_consumer_supply fixed3v3_power_consumers[] =
-{
- REGULATOR_SUPPLY("vmmc", "sh_mmcif.1"),
-};
-
-/*
- * SDHI regulator macro
- *
- ** FIXME**
- * Lager board vqmmc is provided via DA9063 PMIC chip,
- * and we should use ${LINK}/drivers/mfd/da9063-* driver for it.
- * but, it doesn't have regulator support at this point.
- * It uses gpio-regulator for vqmmc as quick-hack.
- */
-#define SDHI_REGULATOR(idx, vdd_pin, vccq_pin) \
-static struct regulator_consumer_supply vcc_sdhi##idx##_consumer = \
- REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi." #idx); \
- \
-static struct regulator_init_data vcc_sdhi##idx##_init_data = { \
- .constraints = { \
- .valid_ops_mask = REGULATOR_CHANGE_STATUS, \
- }, \
- .consumer_supplies = &vcc_sdhi##idx##_consumer, \
- .num_consumer_supplies = 1, \
-}; \
- \
-static const struct fixed_voltage_config vcc_sdhi##idx##_info __initconst = {\
- .supply_name = "SDHI" #idx "Vcc", \
- .microvolts = 3300000, \
- .gpio = vdd_pin, \
- .enable_high = 1, \
- .init_data = &vcc_sdhi##idx##_init_data, \
-}; \
- \
-static struct regulator_consumer_supply vccq_sdhi##idx##_consumer = \
- REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi." #idx); \
- \
-static struct regulator_init_data vccq_sdhi##idx##_init_data = { \
- .constraints = { \
- .input_uV = 3300000, \
- .min_uV = 1800000, \
- .max_uV = 3300000, \
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \
- REGULATOR_CHANGE_STATUS, \
- }, \
- .consumer_supplies = &vccq_sdhi##idx##_consumer, \
- .num_consumer_supplies = 1, \
-}; \
- \
-static struct gpio vccq_sdhi##idx##_gpio = \
- { vccq_pin, GPIOF_OUT_INIT_HIGH, "vccq-sdhi" #idx }; \
- \
-static struct gpio_regulator_state vccq_sdhi##idx##_states[] = { \
- { .value = 1800000, .gpios = 0 }, \
- { .value = 3300000, .gpios = 1 }, \
-}; \
- \
-static const struct gpio_regulator_config vccq_sdhi##idx##_info __initconst = {\
- .supply_name = "vqmmc", \
- .gpios = &vccq_sdhi##idx##_gpio, \
- .nr_gpios = 1, \
- .states = vccq_sdhi##idx##_states, \
- .nr_states = ARRAY_SIZE(vccq_sdhi##idx##_states), \
- .type = REGULATOR_VOLTAGE, \
- .init_data = &vccq_sdhi##idx##_init_data, \
-};
-
-SDHI_REGULATOR(0, RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 29));
-SDHI_REGULATOR(2, RCAR_GP_PIN(5, 25), RCAR_GP_PIN(5, 30));
-
-/* MMCIF */
-static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = {
- .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
- .clk_ctrl2_present = true,
- .ccs_unsupported = true,
-};
-
-static const struct resource mmcif1_resources[] __initconst = {
- DEFINE_RES_MEM(0xee220000, 0x80),
- DEFINE_RES_IRQ(gic_spi(170)),
-};
-
-/* Ether */
-static const struct sh_eth_plat_data ether_pdata __initconst = {
- .phy = 0x1,
- .phy_irq = irq_pin(0),
- .edmac_endian = EDMAC_LITTLE_ENDIAN,
- .phy_interface = PHY_INTERFACE_MODE_RMII,
- .ether_link_active_low = 1,
-};
-
-static const struct resource ether_resources[] __initconst = {
- DEFINE_RES_MEM(0xee700000, 0x400),
- DEFINE_RES_IRQ(gic_spi(162)),
-};
-
-static const struct platform_device_info ether_info __initconst = {
- .name = "r8a7790-ether",
- .id = -1,
- .res = ether_resources,
- .num_res = ARRAY_SIZE(ether_resources),
- .data = &ether_pdata,
- .size_data = sizeof(ether_pdata),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-/* SPI Flash memory (Spansion S25FL512SAGMFIG11 64Mb) */
-static struct mtd_partition spi_flash_part[] = {
- /* Reserved for user loader program, read-only */
- {
- .name = "loader",
- .offset = 0,
- .size = SZ_256K,
- .mask_flags = MTD_WRITEABLE,
- },
- /* Reserved for user program, read-only */
- {
- .name = "user",
- .offset = MTDPART_OFS_APPEND,
- .size = SZ_4M,
- .mask_flags = MTD_WRITEABLE,
- },
- /* All else is writable (e.g. JFFS2) */
- {
- .name = "flash",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
- .mask_flags = 0,
- },
-};
-
-static const struct flash_platform_data spi_flash_data = {
- .name = "m25p80",
- .parts = spi_flash_part,
- .nr_parts = ARRAY_SIZE(spi_flash_part),
- .type = "s25fl512s",
-};
-
-static const struct rspi_plat_data qspi_pdata __initconst = {
- .num_chipselect = 1,
-};
-
-static const struct spi_board_info spi_info[] __initconst = {
- {
- .modalias = "m25p80",
- .platform_data = &spi_flash_data,
- .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD,
- .max_speed_hz = 30000000,
- .bus_num = 0,
- .chip_select = 0,
- },
-};
-
-/* QSPI resource */
-static const struct resource qspi_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6b10000, 0x1000),
- DEFINE_RES_IRQ_NAMED(gic_spi(184), "mux"),
-};
-
-/* VIN */
-static const struct resource vin_resources[] __initconst = {
- /* VIN0 */
- DEFINE_RES_MEM(0xe6ef0000, 0x1000),
- DEFINE_RES_IRQ(gic_spi(188)),
- /* VIN1 */
- DEFINE_RES_MEM(0xe6ef1000, 0x1000),
- DEFINE_RES_IRQ(gic_spi(189)),
-};
-
-static void __init lager_add_vin_device(unsigned idx,
- struct rcar_vin_platform_data *pdata)
-{
- struct platform_device_info vin_info = {
- .name = "r8a7790-vin",
- .id = idx,
- .res = &vin_resources[idx * 2],
- .num_res = 2,
- .dma_mask = DMA_BIT_MASK(32),
- .data = pdata,
- .size_data = sizeof(*pdata),
- };
-
- BUG_ON(idx > 1);
-
- platform_device_register_full(&vin_info);
-}
-
-#define LAGER_CAMERA(idx, name, addr, pdata, flag) \
-static struct i2c_board_info i2c_cam##idx##_device = { \
- I2C_BOARD_INFO(name, addr), \
-}; \
- \
-static struct rcar_vin_platform_data vin##idx##_pdata = { \
- .flags = flag, \
-}; \
- \
-static struct soc_camera_link cam##idx##_link = { \
- .bus_id = idx, \
- .board_info = &i2c_cam##idx##_device, \
- .i2c_adapter_id = 2, \
- .module_name = name, \
- .priv = pdata, \
-}
-
-/* Camera 0 is not currently supported due to adv7612 support missing */
-LAGER_CAMERA(1, "adv7180", 0x20, NULL, RCAR_VIN_BT656);
-
-static void __init lager_add_camera1_device(void)
-{
- platform_device_register_data(NULL, "soc-camera-pdrv", 1,
- &cam1_link, sizeof(cam1_link));
- lager_add_vin_device(1, &vin1_pdata);
-}
-
-/* SATA1 */
-static const struct resource sata1_resources[] __initconst = {
- DEFINE_RES_MEM(0xee500000, 0x2000),
- DEFINE_RES_IRQ(gic_spi(106)),
-};
-
-static const struct platform_device_info sata1_info __initconst = {
- .name = "sata-r8a7790",
- .id = 1,
- .res = sata1_resources,
- .num_res = ARRAY_SIZE(sata1_resources),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-/* USBHS */
-static const struct resource usbhs_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6590000, 0x100),
- DEFINE_RES_IRQ(gic_spi(107)),
-};
-
-struct usbhs_private {
- struct renesas_usbhs_platform_info info;
- struct usb_phy *phy;
-};
-
-#define usbhs_get_priv(pdev) \
- container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info)
-
-static int usbhs_power_ctrl(struct platform_device *pdev,
- void __iomem *base, int enable)
-{
- struct usbhs_private *priv = usbhs_get_priv(pdev);
-
- if (!priv->phy)
- return -ENODEV;
-
- if (enable) {
- int retval = usb_phy_init(priv->phy);
-
- if (!retval)
- retval = usb_phy_set_suspend(priv->phy, 0);
- return retval;
- }
-
- usb_phy_set_suspend(priv->phy, 1);
- usb_phy_shutdown(priv->phy);
- return 0;
-}
-
-static int usbhs_hardware_init(struct platform_device *pdev)
-{
- struct usbhs_private *priv = usbhs_get_priv(pdev);
- struct usb_phy *phy;
- int ret;
-
- /* USB0 Function - use PWEN as GPIO input to detect DIP Switch SW5
- * setting to avoid VBUS short circuit due to wrong cable.
- * PWEN should be pulled up high if USB Function is selected by SW5
- */
- gpio_request_one(RCAR_GP_PIN(5, 18), GPIOF_IN, NULL); /* USB0_PWEN */
- if (!gpio_get_value(RCAR_GP_PIN(5, 18))) {
- pr_warn("Error: USB Function not selected - check SW5 + SW6\n");
- ret = -ENOTSUPP;
- goto error;
- }
-
- phy = usb_get_phy_dev(&pdev->dev, 0);
- if (IS_ERR(phy)) {
- ret = PTR_ERR(phy);
- goto error;
- }
-
- priv->phy = phy;
- return 0;
- error:
- gpio_free(RCAR_GP_PIN(5, 18));
- return ret;
-}
-
-static int usbhs_hardware_exit(struct platform_device *pdev)
-{
- struct usbhs_private *priv = usbhs_get_priv(pdev);
-
- if (!priv->phy)
- return 0;
-
- usb_put_phy(priv->phy);
- priv->phy = NULL;
-
- gpio_free(RCAR_GP_PIN(5, 18));
- return 0;
-}
-
-static int usbhs_get_id(struct platform_device *pdev)
-{
- return USBHS_GADGET;
-}
-
-static u32 lager_usbhs_pipe_type[] = {
- USB_ENDPOINT_XFER_CONTROL,
- USB_ENDPOINT_XFER_ISOC,
- USB_ENDPOINT_XFER_ISOC,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_INT,
- USB_ENDPOINT_XFER_INT,
- USB_ENDPOINT_XFER_INT,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
- USB_ENDPOINT_XFER_BULK,
-};
-
-static struct usbhs_private usbhs_priv __initdata = {
- .info = {
- .platform_callback = {
- .power_ctrl = usbhs_power_ctrl,
- .hardware_init = usbhs_hardware_init,
- .hardware_exit = usbhs_hardware_exit,
- .get_id = usbhs_get_id,
- },
- .driver_param = {
- .buswait_bwait = 4,
- .pipe_type = lager_usbhs_pipe_type,
- .pipe_size = ARRAY_SIZE(lager_usbhs_pipe_type),
- },
- }
-};
-
-static void __init lager_register_usbhs(void)
-{
- usb_bind_phy("renesas_usbhs", 0, "usb_phy_rcar_gen2");
- platform_device_register_resndata(NULL,
- "renesas_usbhs", -1,
- usbhs_resources,
- ARRAY_SIZE(usbhs_resources),
- &usbhs_priv.info,
- sizeof(usbhs_priv.info));
-}
-
-/* USBHS PHY */
-static const struct rcar_gen2_phy_platform_data usbhs_phy_pdata __initconst = {
- .chan0_pci = 0, /* Channel 0 is USBHS */
- .chan2_pci = 1, /* Channel 2 is PCI USB */
-};
-
-static const struct resource usbhs_phy_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6590100, 0x100),
-};
-
-/* I2C */
-static struct i2c_board_info i2c2_devices[] = {
- {
- I2C_BOARD_INFO("ak4643", 0x12),
- }
-};
-
-/* Sound */
-static struct resource rsnd_resources[] __initdata = {
- [RSND_GEN2_SCU] = DEFINE_RES_MEM(0xec500000, 0x1000),
- [RSND_GEN2_ADG] = DEFINE_RES_MEM(0xec5a0000, 0x100),
- [RSND_GEN2_SSIU] = DEFINE_RES_MEM(0xec540000, 0x1000),
- [RSND_GEN2_SSI] = DEFINE_RES_MEM(0xec541000, 0x1280),
-};
-
-static struct rsnd_ssi_platform_info rsnd_ssi[] = {
- RSND_SSI(0, gic_spi(370), 0),
- RSND_SSI(0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE),
-};
-
-static struct rsnd_src_platform_info rsnd_src[2] = {
- /* no member at this point */
-};
-
-static struct rsnd_dai_platform_info rsnd_dai = {
- .playback = { .ssi = &rsnd_ssi[0], },
- .capture = { .ssi = &rsnd_ssi[1], },
-};
-
-static struct rcar_snd_info rsnd_info = {
- .flags = RSND_GEN2,
- .ssi_info = rsnd_ssi,
- .ssi_info_nr = ARRAY_SIZE(rsnd_ssi),
- .src_info = rsnd_src,
- .src_info_nr = ARRAY_SIZE(rsnd_src),
- .dai_info = &rsnd_dai,
- .dai_info_nr = 1,
-};
-
-static struct asoc_simple_card_info rsnd_card_info = {
- .name = "AK4643",
- .card = "SSI01-AK4643",
- .codec = "ak4642-codec.2-0012",
- .platform = "rcar_sound",
- .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
- .cpu_dai = {
- .name = "rcar_sound",
- },
- .codec_dai = {
- .name = "ak4642-hifi",
- .sysclk = 11289600,
- },
-};
-
-static void __init lager_add_rsnd_device(void)
-{
- struct platform_device_info cardinfo = {
- .name = "asoc-simple-card",
- .id = -1,
- .data = &rsnd_card_info,
- .size_data = sizeof(struct asoc_simple_card_info),
- .dma_mask = DMA_BIT_MASK(32),
- };
-
- i2c_register_board_info(2, i2c2_devices,
- ARRAY_SIZE(i2c2_devices));
-
- platform_device_register_resndata(
- NULL, "rcar_sound", -1,
- rsnd_resources, ARRAY_SIZE(rsnd_resources),
- &rsnd_info, sizeof(rsnd_info));
-
- platform_device_register_full(&cardinfo);
-}
-
-/* SDHI0 */
-static struct sh_mobile_sdhi_info sdhi0_info __initdata = {
- .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
- MMC_CAP_POWER_OFF_CARD,
- .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT |
- TMIO_MMC_WRPROTECT_DISABLE,
-};
-
-static struct resource sdhi0_resources[] __initdata = {
- DEFINE_RES_MEM(0xee100000, 0x200),
- DEFINE_RES_IRQ(gic_spi(165)),
-};
-
-/* SDHI2 */
-static struct sh_mobile_sdhi_info sdhi2_info __initdata = {
- .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
- MMC_CAP_POWER_OFF_CARD,
- .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT |
- TMIO_MMC_WRPROTECT_DISABLE,
-};
-
-static struct resource sdhi2_resources[] __initdata = {
- DEFINE_RES_MEM(0xee140000, 0x100),
- DEFINE_RES_IRQ(gic_spi(167)),
-};
-
-/* Internal PCI1 */
-static const struct resource pci1_resources[] __initconst = {
- DEFINE_RES_MEM(0xee0b0000, 0x10000), /* CFG */
- DEFINE_RES_MEM(0xee0a0000, 0x10000), /* MEM */
- DEFINE_RES_IRQ(gic_spi(112)),
-};
-
-static const struct platform_device_info pci1_info __initconst = {
- .name = "pci-rcar-gen2",
- .id = 1,
- .res = pci1_resources,
- .num_res = ARRAY_SIZE(pci1_resources),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-static void __init lager_add_usb1_device(void)
-{
- platform_device_register_full(&pci1_info);
-}
-
-/* Internal PCI2 */
-static const struct resource pci2_resources[] __initconst = {
- DEFINE_RES_MEM(0xee0d0000, 0x10000), /* CFG */
- DEFINE_RES_MEM(0xee0c0000, 0x10000), /* MEM */
- DEFINE_RES_IRQ(gic_spi(113)),
-};
-
-static const struct platform_device_info pci2_info __initconst = {
- .name = "pci-rcar-gen2",
- .id = 2,
- .res = pci2_resources,
- .num_res = ARRAY_SIZE(pci2_resources),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-static void __init lager_add_usb2_device(void)
-{
- platform_device_register_full(&pci2_info);
-}
-
-static const struct pinctrl_map lager_pinctrl_map[] = {
- /* DU (CN10: ARGB0, CN13: LVDS) */
- PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
- "du_rgb666", "du"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
- "du_sync_1", "du"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
- "du_clk_out_0", "du"),
- /* I2C2 */
- PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar.2", "pfc-r8a7790",
- "i2c2", "i2c2"),
- /* QSPI */
- PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790",
- "qspi_ctrl", "qspi"),
- PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790",
- "qspi_data4", "qspi"),
- /* SCIF0 (CN19: DEBUG SERIAL0) */
- PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790",
- "scif0_data", "scif0"),
- /* SCIF1 (CN20: DEBUG SERIAL1) */
- PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7790",
- "scif1_data", "scif1"),
- /* SDHI0 */
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
- "sdhi0_data4", "sdhi0"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
- "sdhi0_ctrl", "sdhi0"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
- "sdhi0_cd", "sdhi0"),
- /* SDHI2 */
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
- "sdhi2_data4", "sdhi2"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
- "sdhi2_ctrl", "sdhi2"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
- "sdhi2_cd", "sdhi2"),
- /* SSI (CN17: sound) */
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "ssi0129_ctrl", "ssi"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "ssi0_data", "ssi"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "ssi1_data", "ssi"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "audio_clk_a", "audio_clk"),
- /* MMCIF1 */
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.1", "pfc-r8a7790",
- "mmc1_data8", "mmc1"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.1", "pfc-r8a7790",
- "mmc1_ctrl", "mmc1"),
- /* Ether */
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "eth_link", "eth"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "eth_mdio", "eth"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "eth_rmii", "eth"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "intc_irq0", "intc"),
- /* VIN0 */
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_data24", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_sync", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_field", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_clkenb", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_clk", "vin0"),
- /* VIN1 */
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790",
- "vin1_data8", "vin1"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790",
- "vin1_clk", "vin1"),
- /* USB0 */
- PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7790",
- "usb0_ovc_vbus", "usb0"),
- /* USB1 */
- PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.1", "pfc-r8a7790",
- "usb1", "usb1"),
- /* USB2 */
- PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.2", "pfc-r8a7790",
- "usb2", "usb2"),
-};
-
-static void __init lager_add_standard_devices(void)
-{
- int fixed_regulator_idx = 0;
- int gpio_regulator_idx = 0;
-
- r8a7790_clock_init();
-
- pinctrl_register_mappings(lager_pinctrl_map,
- ARRAY_SIZE(lager_pinctrl_map));
- r8a7790_pinmux_init();
-
- r8a7790_add_standard_devices();
- platform_device_register_data(NULL, "leds-gpio", -1,
- &lager_leds_pdata,
- sizeof(lager_leds_pdata));
- platform_device_register_data(NULL, "gpio-keys", -1,
- &lager_keys_pdata,
- sizeof(lager_keys_pdata));
- regulator_register_always_on(fixed_regulator_idx++,
- "fixed-3.3V", fixed3v3_power_consumers,
- ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
- platform_device_register_resndata(NULL, "sh_mmcif", 1,
- mmcif1_resources, ARRAY_SIZE(mmcif1_resources),
- &mmcif1_pdata, sizeof(mmcif1_pdata));
-
- platform_device_register_full(&ether_info);
-
- platform_device_register_resndata(NULL, "qspi", 0,
- qspi_resources,
- ARRAY_SIZE(qspi_resources),
- &qspi_pdata, sizeof(qspi_pdata));
- spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
-
- platform_device_register_data(NULL, "reg-fixed-voltage", fixed_regulator_idx++,
- &vcc_sdhi0_info, sizeof(struct fixed_voltage_config));
- platform_device_register_data(NULL, "reg-fixed-voltage", fixed_regulator_idx++,
- &vcc_sdhi2_info, sizeof(struct fixed_voltage_config));
-
- platform_device_register_data(NULL, "gpio-regulator", gpio_regulator_idx++,
- &vccq_sdhi0_info, sizeof(struct gpio_regulator_config));
- platform_device_register_data(NULL, "gpio-regulator", gpio_regulator_idx++,
- &vccq_sdhi2_info, sizeof(struct gpio_regulator_config));
-
- lager_add_camera1_device();
-
- platform_device_register_full(&sata1_info);
-
- platform_device_register_resndata(NULL, "usb_phy_rcar_gen2",
- -1, usbhs_phy_resources,
- ARRAY_SIZE(usbhs_phy_resources),
- &usbhs_phy_pdata,
- sizeof(usbhs_phy_pdata));
- lager_register_usbhs();
- lager_add_usb1_device();
- lager_add_usb2_device();
-
- lager_add_rsnd_device();
-
- platform_device_register_resndata(NULL, "sh_mobile_sdhi", 0,
- sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
- &sdhi0_info, sizeof(struct sh_mobile_sdhi_info));
- platform_device_register_resndata(NULL, "sh_mobile_sdhi", 2,
- sdhi2_resources, ARRAY_SIZE(sdhi2_resources),
- &sdhi2_info, sizeof(struct sh_mobile_sdhi_info));
-}
-
-/*
- * Ether LEDs on the Lager board are named LINK and ACTIVE which corresponds
- * to non-default 01 setting of the Micrel KSZ8041 PHY control register 1 bits
- * 14-15. We have to set them back to 01 from the default 00 value each time
- * the PHY is reset. It's also important because the PHY's LED0 signal is
- * connected to SoC's ETH_LINK signal and in the PHY's default mode it will
- * bounce on and off after each packet, which we apparently want to avoid.
- */
-static int lager_ksz8041_fixup(struct phy_device *phydev)
-{
- u16 phyctrl1 = phy_read(phydev, 0x1e);
-
- phyctrl1 &= ~0xc000;
- phyctrl1 |= 0x4000;
- return phy_write(phydev, 0x1e, phyctrl1);
-}
-
-static void __init lager_init(void)
-{
- lager_add_standard_devices();
-
- irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW);
-
- if (IS_ENABLED(CONFIG_PHYLIB))
- phy_register_fixup_for_id("r8a7790-ether-ff:01",
- lager_ksz8041_fixup);
-}
-
-static void __init lager_legacy_init_irq(void)
-{
- void __iomem *gic_dist_base = ioremap_nocache(0xf1001000, 0x1000);
- void __iomem *gic_cpu_base = ioremap_nocache(0xf1002000, 0x1000);
-
- gic_init(0, 29, gic_dist_base, gic_cpu_base);
-
- /* Do not invoke DT-based interrupt code via irqchip_init() */
-}
-
-static const char * const lager_boards_compat_dt[] __initconst = {
- "renesas,lager",
- NULL,
-};
-
-DT_MACHINE_START(LAGER_DT, "lager")
- .smp = smp_ops(r8a7790_smp_ops),
- .init_early = shmobile_init_delay,
- .init_irq = lager_legacy_init_irq,
- .init_time = rcar_gen2_timer_init,
- .init_machine = lager_init,
- .init_late = shmobile_init_late,
- .reserve = rcar_gen2_reserve,
- .dt_compat = lager_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
deleted file mode 100644
index f9bbc5f0a9a1..000000000000
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * r8a7790 clock framework support
- *
- * Copyright (C) 2013 Renesas Solutions Corp.
- * Copyright (C) 2013 Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/sh_clk.h>
-#include <linux/clkdev.h>
-
-#include "clock.h"
-#include "common.h"
-#include "r8a7790.h"
-#include "rcar-gen2.h"
-
-/*
- * MD EXTAL PLL0 PLL1 PLL3
- * 14 13 19 (MHz) *1 *1
- *---------------------------------------------------
- * 0 0 0 15 x 1 x172/2 x208/2 x106
- * 0 0 1 15 x 1 x172/2 x208/2 x88
- * 0 1 0 20 x 1 x130/2 x156/2 x80
- * 0 1 1 20 x 1 x130/2 x156/2 x66
- * 1 0 0 26 / 2 x200/2 x240/2 x122
- * 1 0 1 26 / 2 x200/2 x240/2 x102
- * 1 1 0 30 / 2 x172/2 x208/2 x106
- * 1 1 1 30 / 2 x172/2 x208/2 x88
- *
- * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
- * see "p1 / 2" on R8A7790_CLOCK_ROOT() below
- */
-
-#define CPG_BASE 0xe6150000
-#define CPG_LEN 0x1000
-
-#define SMSTPCR1 0xe6150134
-#define SMSTPCR2 0xe6150138
-#define SMSTPCR3 0xe615013c
-#define SMSTPCR5 0xe6150144
-#define SMSTPCR7 0xe615014c
-#define SMSTPCR8 0xe6150990
-#define SMSTPCR9 0xe6150994
-#define SMSTPCR10 0xe6150998
-
-#define MSTPSR1 IOMEM(0xe6150038)
-#define MSTPSR2 IOMEM(0xe6150040)
-#define MSTPSR3 IOMEM(0xe6150048)
-#define MSTPSR5 IOMEM(0xe615003c)
-#define MSTPSR7 IOMEM(0xe61501c4)
-#define MSTPSR8 IOMEM(0xe61509a0)
-#define MSTPSR9 IOMEM(0xe61509a4)
-#define MSTPSR10 IOMEM(0xe61509a8)
-
-#define SDCKCR 0xE6150074
-#define SD2CKCR 0xE6150078
-#define SD3CKCR 0xE615026C
-#define MMC0CKCR 0xE6150240
-#define MMC1CKCR 0xE6150244
-#define SSPCKCR 0xE6150248
-#define SSPRSCKCR 0xE615024C
-
-static struct clk_mapping cpg_mapping = {
- .phys = CPG_BASE,
- .len = CPG_LEN,
-};
-
-static struct clk extal_clk = {
- /* .rate will be updated on r8a7790_clock_init() */
- .mapping = &cpg_mapping,
-};
-
-static struct sh_clk_ops followparent_clk_ops = {
- .recalc = followparent_recalc,
-};
-
-static struct clk main_clk = {
- /* .parent will be set r8a7790_clock_init */
- .ops = &followparent_clk_ops,
-};
-
-static struct clk audio_clk_a = {
-};
-
-static struct clk audio_clk_b = {
-};
-
-static struct clk audio_clk_c = {
-};
-
-/*
- * clock ratio of these clock will be updated
- * on r8a7790_clock_init()
- */
-SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(lb_clk, pll1_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(qspi_clk, pll1_clk, 1, 1);
-
-/* fixed ratio clock */
-SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2);
-SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2);
-
-SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2);
-SH_FIXED_RATIO_CLK_SET(zg_clk, pll1_clk, 1, 3);
-SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3);
-SH_FIXED_RATIO_CLK_SET(zs_clk, pll1_clk, 1, 6);
-SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12);
-SH_FIXED_RATIO_CLK_SET(i_clk, pll1_clk, 1, 2);
-SH_FIXED_RATIO_CLK_SET(b_clk, pll1_clk, 1, 12);
-SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24);
-SH_FIXED_RATIO_CLK_SET(cl_clk, pll1_clk, 1, 48);
-SH_FIXED_RATIO_CLK_SET(m2_clk, pll1_clk, 1, 8);
-SH_FIXED_RATIO_CLK_SET(imp_clk, pll1_clk, 1, 4);
-SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024));
-SH_FIXED_RATIO_CLK_SET(oscclk_clk, pll1_clk, 1, (12 * 1024));
-
-SH_FIXED_RATIO_CLK_SET(zb3_clk, pll3_clk, 1, 4);
-SH_FIXED_RATIO_CLK_SET(zb3d2_clk, pll3_clk, 1, 8);
-SH_FIXED_RATIO_CLK_SET(ddr_clk, pll3_clk, 1, 8);
-SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
-
-static struct clk *main_clks[] = {
- &audio_clk_a,
- &audio_clk_b,
- &audio_clk_c,
- &extal_clk,
- &extal_div2_clk,
- &main_clk,
- &pll1_clk,
- &pll1_div2_clk,
- &pll3_clk,
- &lb_clk,
- &qspi_clk,
- &zg_clk,
- &zx_clk,
- &zs_clk,
- &hp_clk,
- &i_clk,
- &b_clk,
- &p_clk,
- &cl_clk,
- &m2_clk,
- &imp_clk,
- &rclk_clk,
- &oscclk_clk,
- &zb3_clk,
- &zb3d2_clk,
- &ddr_clk,
- &mp_clk,
- &cp_clk,
-};
-
-/* SDHI (DIV4) clock */
-static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
-
-static struct clk_div_mult_table div4_div_mult_table = {
- .divisors = divisors,
- .nr_divisors = ARRAY_SIZE(divisors),
-};
-
-static struct clk_div4_table div4_table = {
- .div_mult_table = &div4_div_mult_table,
-};
-
-enum {
- DIV4_SDH, DIV4_SD0, DIV4_SD1, DIV4_NR
-};
-
-static struct clk div4_clks[DIV4_NR] = {
- [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
- [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1df0, CLK_ENABLE_ON_INIT),
- [DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1df0, CLK_ENABLE_ON_INIT),
-};
-
-/* DIV6 clocks */
-enum {
- DIV6_SD2, DIV6_SD3,
- DIV6_MMC0, DIV6_MMC1,
- DIV6_SSP, DIV6_SSPRS,
- DIV6_NR
-};
-
-static struct clk div6_clks[DIV6_NR] = {
- [DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
- [DIV6_SD3] = SH_CLK_DIV6(&pll1_div2_clk, SD3CKCR, 0),
- [DIV6_MMC0] = SH_CLK_DIV6(&pll1_div2_clk, MMC0CKCR, 0),
- [DIV6_MMC1] = SH_CLK_DIV6(&pll1_div2_clk, MMC1CKCR, 0),
- [DIV6_SSP] = SH_CLK_DIV6(&pll1_div2_clk, SSPCKCR, 0),
- [DIV6_SSPRS] = SH_CLK_DIV6(&pll1_div2_clk, SSPRSCKCR, 0),
-};
-
-/* MSTP */
-enum {
- MSTP1017, /* parent of SCU */
-
- MSTP1031, MSTP1030,
- MSTP1029, MSTP1028, MSTP1027, MSTP1026, MSTP1025, MSTP1024, MSTP1023, MSTP1022,
- MSTP1015, MSTP1014, MSTP1013, MSTP1012, MSTP1011, MSTP1010,
- MSTP1009, MSTP1008, MSTP1007, MSTP1006, MSTP1005,
- MSTP931, MSTP930, MSTP929, MSTP928,
- MSTP917,
- MSTP815, MSTP814,
- MSTP813,
- MSTP811, MSTP810, MSTP809, MSTP808,
- MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
- MSTP717, MSTP716,
- MSTP704, MSTP703,
- MSTP522,
- MSTP502, MSTP501,
- MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
- MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
- MSTP124,
- MSTP_NR
-};
-
-static struct clk mstp_clks[MSTP_NR] = {
- [MSTP1031] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 31, MSTPSR10, 0), /* SCU0 */
- [MSTP1030] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 30, MSTPSR10, 0), /* SCU1 */
- [MSTP1029] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 29, MSTPSR10, 0), /* SCU2 */
- [MSTP1028] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 28, MSTPSR10, 0), /* SCU3 */
- [MSTP1027] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 27, MSTPSR10, 0), /* SCU4 */
- [MSTP1026] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 26, MSTPSR10, 0), /* SCU5 */
- [MSTP1025] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 25, MSTPSR10, 0), /* SCU6 */
- [MSTP1024] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 24, MSTPSR10, 0), /* SCU7 */
- [MSTP1023] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 23, MSTPSR10, 0), /* SCU8 */
- [MSTP1022] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 22, MSTPSR10, 0), /* SCU9 */
- [MSTP1017] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 17, MSTPSR10, 0), /* SCU */
- [MSTP1015] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 15, MSTPSR10, 0), /* SSI0 */
- [MSTP1014] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 14, MSTPSR10, 0), /* SSI1 */
- [MSTP1013] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 13, MSTPSR10, 0), /* SSI2 */
- [MSTP1012] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 12, MSTPSR10, 0), /* SSI3 */
- [MSTP1011] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 11, MSTPSR10, 0), /* SSI4 */
- [MSTP1010] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 10, MSTPSR10, 0), /* SSI5 */
- [MSTP1009] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 9, MSTPSR10, 0), /* SSI6 */
- [MSTP1008] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 8, MSTPSR10, 0), /* SSI7 */
- [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */
- [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */
- [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */
- [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
- [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
- [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
- [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
- [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
- [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
- [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
- [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */
- [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */
- [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */
- [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */
- [MSTP808] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 8, MSTPSR8, 0), /* VIN3 */
- [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */
- [MSTP725] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 25, MSTPSR7, 0), /* LVDS1 */
- [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */
- [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */
- [MSTP722] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 22, MSTPSR7, 0), /* DU2 */
- [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */
- [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */
- [MSTP717] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 17, MSTPSR7, 0), /* HSCIF0 */
- [MSTP716] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 16, MSTPSR7, 0), /* HSCIF1 */
- [MSTP704] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 4, MSTPSR7, 0), /* HSUSB */
- [MSTP703] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 3, MSTPSR7, 0), /* EHCI */
- [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */
- [MSTP502] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 2, MSTPSR5, 0), /* Audio-DMAC low */
- [MSTP501] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 1, MSTPSR5, 0), /* Audio-DMAC hi */
- [MSTP315] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, MSTPSR3, 0), /* MMC0 */
- [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */
- [MSTP313] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD1], SMSTPCR3, 13, MSTPSR3, 0), /* SDHI1 */
- [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI2 */
- [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD3], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI3 */
- [MSTP305] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, MSTPSR3, 0), /* MMC1 */
- [MSTP304] = SH_CLK_MSTP32_STS(&cp_clk, SMSTPCR3, 4, MSTPSR3, 0), /* TPU0 */
- [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */
- [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */
- [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */
- [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */
- [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */
- [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */
- [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */
-};
-
-static struct clk_lookup lookups[] = {
-
- /* main clocks */
- CLKDEV_CON_ID("extal", &extal_clk),
- CLKDEV_CON_ID("extal_div2", &extal_div2_clk),
- CLKDEV_CON_ID("main", &main_clk),
- CLKDEV_CON_ID("pll1", &pll1_clk),
- CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk),
- CLKDEV_CON_ID("pll3", &pll3_clk),
- CLKDEV_CON_ID("zg", &zg_clk),
- CLKDEV_CON_ID("zx", &zx_clk),
- CLKDEV_CON_ID("zs", &zs_clk),
- CLKDEV_CON_ID("hp", &hp_clk),
- CLKDEV_CON_ID("i", &i_clk),
- CLKDEV_CON_ID("b", &b_clk),
- CLKDEV_CON_ID("lb", &lb_clk),
- CLKDEV_CON_ID("p", &p_clk),
- CLKDEV_CON_ID("cl", &cl_clk),
- CLKDEV_CON_ID("m2", &m2_clk),
- CLKDEV_CON_ID("imp", &imp_clk),
- CLKDEV_CON_ID("rclk", &rclk_clk),
- CLKDEV_CON_ID("oscclk", &oscclk_clk),
- CLKDEV_CON_ID("zb3", &zb3_clk),
- CLKDEV_CON_ID("zb3d2", &zb3d2_clk),
- CLKDEV_CON_ID("ddr", &ddr_clk),
- CLKDEV_CON_ID("mp", &mp_clk),
- CLKDEV_CON_ID("qspi", &qspi_clk),
- CLKDEV_CON_ID("cp", &cp_clk),
-
- /* DIV4 */
- CLKDEV_CON_ID("sdh", &div4_clks[DIV4_SDH]),
-
- /* DIV6 */
- CLKDEV_CON_ID("ssp", &div6_clks[DIV6_SSP]),
- CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]),
-
- /* MSTP */
- CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP1005]),
- CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
- CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
- CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
- CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]),
- CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
- CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]),
- CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]),
- CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
- CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
- CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]),
- CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
- CLKDEV_DEV_ID("r8a7790-vin.0", &mstp_clks[MSTP811]),
- CLKDEV_DEV_ID("r8a7790-vin.1", &mstp_clks[MSTP810]),
- CLKDEV_DEV_ID("r8a7790-vin.2", &mstp_clks[MSTP809]),
- CLKDEV_DEV_ID("r8a7790-vin.3", &mstp_clks[MSTP808]),
- CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
- CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP502]),
- CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP501]),
- CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
- CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
- CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
- CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
- CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]),
- CLKDEV_DEV_ID("pci-rcar-gen2.1", &mstp_clks[MSTP703]),
- CLKDEV_DEV_ID("pci-rcar-gen2.2", &mstp_clks[MSTP703]),
- CLKDEV_DEV_ID("sata-r8a7790.0", &mstp_clks[MSTP815]),
- CLKDEV_DEV_ID("sata-r8a7790.1", &mstp_clks[MSTP814]),
-
- /* ICK */
- CLKDEV_ICK_ID("fck", "sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
- CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]),
- CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]),
- CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]),
- CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
- CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
- CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
- CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
- CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
- CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
- CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk),
- CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP1031]),
- CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP1030]),
- CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP1029]),
- CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP1028]),
- CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP1027]),
- CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP1026]),
- CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP1025]),
- CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP1024]),
- CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP1023]),
- CLKDEV_ICK_ID("src.9", "rcar_sound", &mstp_clks[MSTP1022]),
- CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]),
- CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]),
- CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]),
- CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP1012]),
- CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP1011]),
- CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP1010]),
- CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP1009]),
- CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP1008]),
- CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP1007]),
- CLKDEV_ICK_ID("ssi.9", "rcar_sound", &mstp_clks[MSTP1006]),
-
-};
-
-#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
- extal_clk.rate = e * 1000 * 1000; \
- main_clk.parent = m; \
- SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
- if (mode & MD(19)) \
- SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
- else \
- SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
-
-
-void __init r8a7790_clock_init(void)
-{
- u32 mode = rcar_gen2_read_mode_pins();
- int k, ret = 0;
-
- switch (mode & (MD(14) | MD(13))) {
- case 0:
- R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
- break;
- case MD(13):
- R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
- break;
- case MD(14):
- R8A7790_CLOCK_ROOT(26 / 2, &extal_div2_clk, 200, 240, 122, 102);
- break;
- case MD(13) | MD(14):
- R8A7790_CLOCK_ROOT(30 / 2, &extal_div2_clk, 172, 208, 106, 88);
- break;
- }
-
- if (mode & (MD(18)))
- SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 36);
- else
- SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 24);
-
- if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
- SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
- else
- SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
-
- for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
- ret = clk_register(main_clks[k]);
-
- if (!ret)
- ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
-
- if (!ret)
- ret = sh_clk_div6_register(div6_clks, DIV6_NR);
-
- if (!ret)
- ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- if (!ret)
- shmobile_clk_init();
- else
- panic("failed to setup r8a7790 clocks\n");
-}
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 6b4c1f313cc9..3855fb024fdb 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -553,6 +553,7 @@ enum { MSTP001,
MSTP314, MSTP313, MSTP312, MSTP311,
MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
MSTP411, MSTP410, MSTP403,
+ MSTP508,
MSTP_NR };
#define MSTP(_parent, _reg, _bit, _flags) \
@@ -597,6 +598,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+ [MSTP508] = MSTP(&div4_clks[DIV4_HP], SMSTPCR5, 8, 0), /* INTCA0 */
};
/* The lookups structure below includes duplicate entries for some clocks
@@ -677,6 +679,14 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.0", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900000.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.1", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900004.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.2", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900008.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.3", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e690000c.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
/* ICK */
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
index ac2eecd6f5ea..34608fcf0648 100644
--- a/arch/arm/mach-shmobile/pm-r8a7740.c
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -9,10 +9,14 @@
* for more details.
*/
#include <linux/console.h>
+#include <linux/io.h>
#include <linux/suspend.h>
+
#include "common.h"
#include "pm-rmobile.h"
+#define SYSC_BASE IOMEM(0xe6180000)
+
#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM)
static int r8a7740_pd_a3sm_suspend(void)
{
@@ -45,41 +49,51 @@ static int r8a7740_pd_d4_suspend(void)
static struct rmobile_pm_domain r8a7740_pm_domains[] = {
{
.genpd.name = "A4LC",
+ .base = SYSC_BASE,
.bit_shift = 1,
}, {
.genpd.name = "A4MP",
+ .base = SYSC_BASE,
.bit_shift = 2,
}, {
.genpd.name = "D4",
+ .base = SYSC_BASE,
.bit_shift = 3,
.gov = &pm_domain_always_on_gov,
.suspend = r8a7740_pd_d4_suspend,
}, {
.genpd.name = "A4R",
+ .base = SYSC_BASE,
.bit_shift = 5,
}, {
.genpd.name = "A3RV",
+ .base = SYSC_BASE,
.bit_shift = 6,
}, {
.genpd.name = "A4S",
+ .base = SYSC_BASE,
.bit_shift = 10,
.no_debug = true,
}, {
.genpd.name = "A3SP",
+ .base = SYSC_BASE,
.bit_shift = 11,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
.suspend = r8a7740_pd_a3sp_suspend,
}, {
.genpd.name = "A3SM",
+ .base = SYSC_BASE,
.bit_shift = 12,
.gov = &pm_domain_always_on_gov,
.suspend = r8a7740_pd_a3sm_suspend,
}, {
.genpd.name = "A3SG",
+ .base = SYSC_BASE,
.bit_shift = 13,
}, {
.genpd.name = "A4SU",
+ .base = SYSC_BASE,
.bit_shift = 20,
},
};
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index 6f7d56ecf969..95018209ff0b 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2012 Renesas Solutions Corp.
* Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2014 Glider bvba
*
* based on pm-sh7372.c
* Copyright (C) 2011 Magnus Damm
@@ -13,16 +14,22 @@
*/
#include <linux/console.h>
#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_clock.h>
+#include <linux/slab.h>
+
#include <asm/io.h>
+
#include "pm-rmobile.h"
/* SYSC */
-#define SPDCR IOMEM(0xe6180008)
-#define SWUCR IOMEM(0xe6180014)
-#define PSTR IOMEM(0xe6180080)
+#define SPDCR 0x08 /* SYS Power Down Control Register */
+#define SWUCR 0x14 /* SYS Wakeup Control Register */
+#define PSTR 0x80 /* Power Status Register */
#define PSTR_RETRIES 100
#define PSTR_DELAY_US 10
@@ -30,8 +37,12 @@
static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
{
struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
- unsigned int mask = 1 << rmobile_pd->bit_shift;
+ unsigned int mask;
+
+ if (rmobile_pd->bit_shift == ~0)
+ return -EBUSY;
+ mask = 1 << rmobile_pd->bit_shift;
if (rmobile_pd->suspend) {
int ret = rmobile_pd->suspend();
@@ -39,12 +50,12 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
return ret;
}
- if (__raw_readl(PSTR) & mask) {
+ if (__raw_readl(rmobile_pd->base + PSTR) & mask) {
unsigned int retry_count;
- __raw_writel(mask, SPDCR);
+ __raw_writel(mask, rmobile_pd->base + SPDCR);
for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
- if (!(__raw_readl(SPDCR) & mask))
+ if (!(__raw_readl(rmobile_pd->base + SPDCR) & mask))
break;
cpu_relax();
}
@@ -52,7 +63,8 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
if (!rmobile_pd->no_debug)
pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
- genpd->name, mask, __raw_readl(PSTR));
+ genpd->name, mask,
+ __raw_readl(rmobile_pd->base + PSTR));
return 0;
}
@@ -60,17 +72,21 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
bool do_resume)
{
- unsigned int mask = 1 << rmobile_pd->bit_shift;
+ unsigned int mask;
unsigned int retry_count;
int ret = 0;
- if (__raw_readl(PSTR) & mask)
+ if (rmobile_pd->bit_shift == ~0)
+ return 0;
+
+ mask = 1 << rmobile_pd->bit_shift;
+ if (__raw_readl(rmobile_pd->base + PSTR) & mask)
goto out;
- __raw_writel(mask, SWUCR);
+ __raw_writel(mask, rmobile_pd->base + SWUCR);
for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
- if (!(__raw_readl(SWUCR) & mask))
+ if (!(__raw_readl(rmobile_pd->base + SWUCR) & mask))
break;
if (retry_count > PSTR_RETRIES)
udelay(PSTR_DELAY_US);
@@ -82,7 +98,8 @@ static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
if (!rmobile_pd->no_debug)
pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
- rmobile_pd->genpd.name, mask, __raw_readl(PSTR));
+ rmobile_pd->genpd.name, mask,
+ __raw_readl(rmobile_pd->base + PSTR));
out:
if (ret == 0 && rmobile_pd->resume && do_resume)
@@ -101,6 +118,36 @@ static bool rmobile_pd_active_wakeup(struct device *dev)
return true;
}
+static int rmobile_pd_attach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ int error;
+
+ error = pm_clk_create(dev);
+ if (error) {
+ dev_err(dev, "pm_clk_create failed %d\n", error);
+ return error;
+ }
+
+ error = pm_clk_add(dev, NULL);
+ if (error) {
+ dev_err(dev, "pm_clk_add failed %d\n", error);
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ pm_clk_destroy(dev);
+ return error;
+}
+
+static void rmobile_pd_detach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ pm_clk_destroy(dev);
+}
+
static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
{
struct generic_pm_domain *genpd = &rmobile_pd->genpd;
@@ -111,9 +158,13 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup;
genpd->power_off = rmobile_pd_power_down;
genpd->power_on = rmobile_pd_power_up;
+ genpd->attach_dev = rmobile_pd_attach_dev;
+ genpd->detach_dev = rmobile_pd_detach_dev;
__rmobile_pd_power_up(rmobile_pd, false);
}
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+
void rmobile_init_domains(struct rmobile_pm_domain domains[], int num)
{
int j;
@@ -129,8 +180,6 @@ void rmobile_add_device_to_domain_td(const char *domain_name,
struct device *dev = &pdev->dev;
__pm_genpd_name_add_device(domain_name, dev, td);
- if (pm_clk_no_clocks(dev))
- pm_clk_add(dev, NULL);
}
void rmobile_add_devices_to_domains(struct pm_domain_device data[],
@@ -148,3 +197,238 @@ void rmobile_add_devices_to_domains(struct pm_domain_device data[],
rmobile_add_device_to_domain_td(data[j].domain_name,
data[j].pdev, &latencies);
}
+
+#else /* !CONFIG_ARCH_SHMOBILE_LEGACY */
+
+static int rmobile_pd_suspend_busy(void)
+{
+ /*
+ * This domain should not be turned off.
+ */
+ return -EBUSY;
+}
+
+static int rmobile_pd_suspend_console(void)
+{
+ /*
+ * Serial consoles make use of SCIF hardware located in this domain,
+ * hence keep the power domain on if "no_console_suspend" is set.
+ */
+ return console_suspend_enabled ? 0 : -EBUSY;
+}
+
+enum pd_types {
+ PD_NORMAL,
+ PD_CPU,
+ PD_CONSOLE,
+ PD_DEBUG,
+ PD_MEMCTL,
+};
+
+#define MAX_NUM_SPECIAL_PDS 16
+
+static struct special_pd {
+ struct device_node *pd;
+ enum pd_types type;
+} special_pds[MAX_NUM_SPECIAL_PDS] __initdata;
+
+static unsigned int num_special_pds __initdata;
+
+static const struct of_device_id special_ids[] __initconst = {
+ { .compatible = "arm,coresight-etm3x", .data = (void *)PD_DEBUG },
+ { .compatible = "renesas,dbsc-r8a73a4", .data = (void *)PD_MEMCTL, },
+ { .compatible = "renesas,dbsc3-r8a7740", .data = (void *)PD_MEMCTL, },
+ { .compatible = "renesas,sbsc-sh73a0", .data = (void *)PD_MEMCTL, },
+ { /* sentinel */ },
+};
+
+static void __init add_special_pd(struct device_node *np, enum pd_types type)
+{
+ unsigned int i;
+ struct device_node *pd;
+
+ pd = of_parse_phandle(np, "power-domains", 0);
+ if (!pd)
+ return;
+
+ for (i = 0; i < num_special_pds; i++)
+ if (pd == special_pds[i].pd && type == special_pds[i].type) {
+ of_node_put(pd);
+ return;
+ }
+
+ if (num_special_pds == ARRAY_SIZE(special_pds)) {
+ pr_warn("Too many special PM domains\n");
+ of_node_put(pd);
+ return;
+ }
+
+ pr_debug("Special PM domain %s type %d for %s\n", pd->name, type,
+ np->full_name);
+
+ special_pds[num_special_pds].pd = pd;
+ special_pds[num_special_pds].type = type;
+ num_special_pds++;
+}
+
+static void __init get_special_pds(void)
+{
+ struct device_node *np;
+ const struct of_device_id *id;
+
+ /* PM domains containing CPUs */
+ for_each_node_by_type(np, "cpu")
+ add_special_pd(np, PD_CPU);
+
+ /* PM domain containing console */
+ if (of_stdout)
+ add_special_pd(of_stdout, PD_CONSOLE);
+
+ /* PM domains containing other special devices */
+ for_each_matching_node_and_match(np, special_ids, &id)
+ add_special_pd(np, (enum pd_types)id->data);
+}
+
+static void __init put_special_pds(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_special_pds; i++)
+ of_node_put(special_pds[i].pd);
+}
+
+static enum pd_types __init pd_type(const struct device_node *pd)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_special_pds; i++)
+ if (pd == special_pds[i].pd)
+ return special_pds[i].type;
+
+ return PD_NORMAL;
+}
+
+static void __init rmobile_setup_pm_domain(struct device_node *np,
+ struct rmobile_pm_domain *pd)
+{
+ const char *name = pd->genpd.name;
+
+ switch (pd_type(np)) {
+ case PD_CPU:
+ /*
+ * This domain contains the CPU core and therefore it should
+ * only be turned off if the CPU is not in use.
+ */
+ pr_debug("PM domain %s contains CPU\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_CONSOLE:
+ pr_debug("PM domain %s contains serial console\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_console;
+ break;
+
+ case PD_DEBUG:
+ /*
+ * This domain contains the Coresight-ETM hardware block and
+ * therefore it should only be turned off if the debug module
+ * is not in use.
+ */
+ pr_debug("PM domain %s contains Coresight-ETM\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_MEMCTL:
+ /*
+ * This domain contains a memory-controller and therefore it
+ * should only be turned off if memory is not in use.
+ */
+ pr_debug("PM domain %s contains MEMCTL\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_NORMAL:
+ break;
+ }
+
+ rmobile_init_pm_domain(pd);
+}
+
+static int __init rmobile_add_pm_domains(void __iomem *base,
+ struct device_node *parent,
+ struct generic_pm_domain *genpd_parent)
+{
+ struct device_node *np;
+
+ for_each_child_of_node(parent, np) {
+ struct rmobile_pm_domain *pd;
+ u32 idx = ~0;
+
+ if (of_property_read_u32(np, "reg", &idx)) {
+ /* always-on domain */
+ }
+
+ pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd)
+ return -ENOMEM;
+
+ pd->genpd.name = np->name;
+ pd->base = base;
+ pd->bit_shift = idx;
+
+ rmobile_setup_pm_domain(np, pd);
+ if (genpd_parent)
+ pm_genpd_add_subdomain(genpd_parent, &pd->genpd);
+ of_genpd_add_provider_simple(np, &pd->genpd);
+
+ rmobile_add_pm_domains(base, np, &pd->genpd);
+ }
+ return 0;
+}
+
+static int __init rmobile_init_pm_domains(void)
+{
+ struct device_node *np, *pmd;
+ bool scanned = false;
+ void __iomem *base;
+ int ret = 0;
+
+ for_each_compatible_node(np, NULL, "renesas,sysc-rmobile") {
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("%s cannot map reg 0\n", np->full_name);
+ continue;
+ }
+
+ pmd = of_get_child_by_name(np, "pm-domains");
+ if (!pmd) {
+ pr_warn("%s lacks pm-domains node\n", np->full_name);
+ continue;
+ }
+
+ if (!scanned) {
+ /* Find PM domains containing special blocks */
+ get_special_pds();
+ scanned = true;
+ }
+
+ ret = rmobile_add_pm_domains(base, pmd, NULL);
+ of_node_put(pmd);
+ if (ret) {
+ of_node_put(np);
+ break;
+ }
+ }
+
+ put_special_pds();
+
+ return ret;
+}
+
+core_initcall(rmobile_init_pm_domains);
+
+#endif /* !CONFIG_ARCH_SHMOBILE_LEGACY */
diff --git a/arch/arm/mach-shmobile/pm-rmobile.h b/arch/arm/mach-shmobile/pm-rmobile.h
index 8f66b343162b..53219786f539 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.h
+++ b/arch/arm/mach-shmobile/pm-rmobile.h
@@ -21,6 +21,7 @@ struct rmobile_pm_domain {
struct dev_power_governor *gov;
int (*suspend)(void);
void (*resume)(void);
+ void __iomem *base;
unsigned int bit_shift;
bool no_debug;
};
@@ -36,7 +37,7 @@ struct pm_domain_device {
struct platform_device *pdev;
};
-#ifdef CONFIG_PM_RMOBILE
+#if defined(CONFIG_PM_RMOBILE) && defined(CONFIG_ARCH_SHMOBILE_LEGACY)
extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num);
extern void rmobile_add_device_to_domain_td(const char *domain_name,
struct platform_device *pdev,
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 0e37da654ed5..c0293ae4b013 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -45,6 +45,8 @@
#define PLLC01STPCR IOMEM(0xe61500c8)
/* SYSC */
+#define SYSC_BASE IOMEM(0xe6180000)
+
#define SBAR IOMEM(0xe6180020)
#define WUPRMSK IOMEM(0xe6180028)
#define WUPSMSK IOMEM(0xe618002c)
@@ -118,24 +120,28 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A4LC",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 1,
},
{
.genpd.name = "A4MP",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 2,
},
{
.genpd.name = "D4",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 3,
},
{
.genpd.name = "A4R",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 5,
.suspend = sh7372_a4r_pd_suspend,
.resume = sh7372_intcs_resume,
@@ -144,18 +150,21 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A3RV",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 6,
},
{
.genpd.name = "A3RI",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 8,
},
{
.genpd.name = "A4S",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 10,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
@@ -166,6 +175,7 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A3SP",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 11,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
@@ -175,6 +185,7 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A3SG",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 13,
},
};
diff --git a/arch/arm/mach-shmobile/r8a7790.h b/arch/arm/mach-shmobile/r8a7790.h
index 388f0514d931..bf73a850aaed 100644
--- a/arch/arm/mach-shmobile/r8a7790.h
+++ b/arch/arm/mach-shmobile/r8a7790.h
@@ -1,34 +1,6 @@
#ifndef __ASM_R8A7790_H__
#define __ASM_R8A7790_H__
-/* DMA slave IDs */
-enum {
- RCAR_DMA_SLAVE_INVALID,
- AUDIO_DMAC_SLAVE_SSI0_TX,
- AUDIO_DMAC_SLAVE_SSI0_RX,
- AUDIO_DMAC_SLAVE_SSI1_TX,
- AUDIO_DMAC_SLAVE_SSI1_RX,
- AUDIO_DMAC_SLAVE_SSI2_TX,
- AUDIO_DMAC_SLAVE_SSI2_RX,
- AUDIO_DMAC_SLAVE_SSI3_TX,
- AUDIO_DMAC_SLAVE_SSI3_RX,
- AUDIO_DMAC_SLAVE_SSI4_TX,
- AUDIO_DMAC_SLAVE_SSI4_RX,
- AUDIO_DMAC_SLAVE_SSI5_TX,
- AUDIO_DMAC_SLAVE_SSI5_RX,
- AUDIO_DMAC_SLAVE_SSI6_TX,
- AUDIO_DMAC_SLAVE_SSI6_RX,
- AUDIO_DMAC_SLAVE_SSI7_TX,
- AUDIO_DMAC_SLAVE_SSI7_RX,
- AUDIO_DMAC_SLAVE_SSI8_TX,
- AUDIO_DMAC_SLAVE_SSI8_RX,
- AUDIO_DMAC_SLAVE_SSI9_TX,
- AUDIO_DMAC_SLAVE_SSI9_RX,
-};
-
-void r8a7790_add_standard_devices(void);
-void r8a7790_clock_init(void);
-void r8a7790_pinmux_init(void);
void r8a7790_pm_init(void);
extern struct smp_operations r8a7790_smp_ops;
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index d191cf419731..dd64caf79216 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -656,7 +656,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index ec7d97dca4de..3a18af4922b4 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -14,295 +14,14 @@
* GNU General Public License for more details.
*/
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/irq-renesas-irqc.h>
-#include <linux/serial_sci.h>
-#include <linux/sh_dma.h>
-#include <linux/sh_timer.h>
+#include <linux/init.h>
#include <asm/mach/arch.h>
#include "common.h"
-#include "dma-register.h"
-#include "irqs.h"
#include "r8a7790.h"
#include "rcar-gen2.h"
-/* Audio-DMAC */
-#define AUDIO_DMAC_SLAVE(_id, _addr, t, r) \
-{ \
- .slave_id = AUDIO_DMAC_SLAVE_## _id ##_TX, \
- .addr = _addr + 0x8, \
- .chcr = CHCR_TX(XMIT_SZ_32BIT), \
- .mid_rid = t, \
-}, { \
- .slave_id = AUDIO_DMAC_SLAVE_## _id ##_RX, \
- .addr = _addr + 0xc, \
- .chcr = CHCR_RX(XMIT_SZ_32BIT), \
- .mid_rid = r, \
-}
-
-static const struct sh_dmae_slave_config r8a7790_audio_dmac_slaves[] = {
- AUDIO_DMAC_SLAVE(SSI0, 0xec241000, 0x01, 0x02),
- AUDIO_DMAC_SLAVE(SSI1, 0xec241040, 0x03, 0x04),
- AUDIO_DMAC_SLAVE(SSI2, 0xec241080, 0x05, 0x06),
- AUDIO_DMAC_SLAVE(SSI3, 0xec2410c0, 0x07, 0x08),
- AUDIO_DMAC_SLAVE(SSI4, 0xec241100, 0x09, 0x0a),
- AUDIO_DMAC_SLAVE(SSI5, 0xec241140, 0x0b, 0x0c),
- AUDIO_DMAC_SLAVE(SSI6, 0xec241180, 0x0d, 0x0e),
- AUDIO_DMAC_SLAVE(SSI7, 0xec2411c0, 0x0f, 0x10),
- AUDIO_DMAC_SLAVE(SSI8, 0xec241200, 0x11, 0x12),
- AUDIO_DMAC_SLAVE(SSI9, 0xec241240, 0x13, 0x14),
-};
-
-#define DMAE_CHANNEL(a, b) \
-{ \
- .offset = (a) - 0x20, \
- .dmars = (a) - 0x20 + 0x40, \
- .chclr_bit = (b), \
- .chclr_offset = 0x80 - 0x20, \
-}
-
-static const struct sh_dmae_channel r8a7790_audio_dmac_channels[] = {
- DMAE_CHANNEL(0x8000, 0),
- DMAE_CHANNEL(0x8080, 1),
- DMAE_CHANNEL(0x8100, 2),
- DMAE_CHANNEL(0x8180, 3),
- DMAE_CHANNEL(0x8200, 4),
- DMAE_CHANNEL(0x8280, 5),
- DMAE_CHANNEL(0x8300, 6),
- DMAE_CHANNEL(0x8380, 7),
- DMAE_CHANNEL(0x8400, 8),
- DMAE_CHANNEL(0x8480, 9),
- DMAE_CHANNEL(0x8500, 10),
- DMAE_CHANNEL(0x8580, 11),
- DMAE_CHANNEL(0x8600, 12),
-};
-
-static struct sh_dmae_pdata r8a7790_audio_dmac_platform_data = {
- .slave = r8a7790_audio_dmac_slaves,
- .slave_num = ARRAY_SIZE(r8a7790_audio_dmac_slaves),
- .channel = r8a7790_audio_dmac_channels,
- .channel_num = ARRAY_SIZE(r8a7790_audio_dmac_channels),
- .ts_low_shift = TS_LOW_SHIFT,
- .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
- .ts_high_shift = TS_HI_SHIFT,
- .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
- .ts_shift = dma_ts_shift,
- .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
- .dmaor_init = DMAOR_DME,
- .chclr_present = 1,
- .chclr_bitwise = 1,
-};
-
-static struct resource r8a7790_audio_dmac_resources[] = {
- /* Channel registers and DMAOR for low */
- DEFINE_RES_MEM(0xec700020, 0x8663 - 0x20),
- DEFINE_RES_IRQ(gic_spi(346)),
- DEFINE_RES_NAMED(gic_spi(320), 13, NULL, IORESOURCE_IRQ),
-
- /* Channel registers and DMAOR for hi */
- DEFINE_RES_MEM(0xec720020, 0x8663 - 0x20), /* hi */
- DEFINE_RES_IRQ(gic_spi(347)),
- DEFINE_RES_NAMED(gic_spi(333), 13, NULL, IORESOURCE_IRQ),
-};
-
-#define r8a7790_register_audio_dmac(id) \
- platform_device_register_resndata( \
- NULL, "sh-dma-engine", id, \
- &r8a7790_audio_dmac_resources[id * 3], 3, \
- &r8a7790_audio_dmac_platform_data, \
- sizeof(r8a7790_audio_dmac_platform_data))
-
-static const struct resource pfc_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6060000, 0x250),
-};
-
-#define r8a7790_register_pfc() \
- platform_device_register_simple("pfc-r8a7790", -1, pfc_resources, \
- ARRAY_SIZE(pfc_resources))
-
-#define R8A7790_GPIO(idx) \
-static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \
- DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \
- DEFINE_RES_IRQ(gic_spi(4 + (idx))), \
-}; \
- \
-static const struct gpio_rcar_config \
-r8a7790_gpio##idx##_platform_data __initconst = { \
- .gpio_base = 32 * (idx), \
- .irq_base = 0, \
- .number_of_pins = 32, \
- .pctl_name = "pfc-r8a7790", \
- .has_both_edge_trigger = 1, \
-}; \
-
-R8A7790_GPIO(0);
-R8A7790_GPIO(1);
-R8A7790_GPIO(2);
-R8A7790_GPIO(3);
-R8A7790_GPIO(4);
-R8A7790_GPIO(5);
-
-#define r8a7790_register_gpio(idx) \
- platform_device_register_resndata(NULL, "gpio_rcar", idx, \
- r8a7790_gpio##idx##_resources, \
- ARRAY_SIZE(r8a7790_gpio##idx##_resources), \
- &r8a7790_gpio##idx##_platform_data, \
- sizeof(r8a7790_gpio##idx##_platform_data))
-
-static struct resource i2c_resources[] __initdata = {
- /* I2C0 */
- DEFINE_RES_MEM(0xE6508000, 0x40),
- DEFINE_RES_IRQ(gic_spi(287)),
- /* I2C1 */
- DEFINE_RES_MEM(0xE6518000, 0x40),
- DEFINE_RES_IRQ(gic_spi(288)),
- /* I2C2 */
- DEFINE_RES_MEM(0xE6530000, 0x40),
- DEFINE_RES_IRQ(gic_spi(286)),
- /* I2C3 */
- DEFINE_RES_MEM(0xE6540000, 0x40),
- DEFINE_RES_IRQ(gic_spi(290)),
-
-};
-
-#define r8a7790_register_i2c(idx) \
- platform_device_register_simple( \
- "i2c-rcar_gen2", idx, \
- i2c_resources + (2 * idx), 2); \
-
-void __init r8a7790_pinmux_init(void)
-{
- r8a7790_register_pfc();
- r8a7790_register_gpio(0);
- r8a7790_register_gpio(1);
- r8a7790_register_gpio(2);
- r8a7790_register_gpio(3);
- r8a7790_register_gpio(4);
- r8a7790_register_gpio(5);
-}
-
-#define __R8A7790_SCIF(scif_type, _scscr, index, baseaddr, irq) \
-static struct plat_sci_port scif##index##_platform_data = { \
- .type = scif_type, \
- .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \
- .scscr = _scscr, \
-}; \
- \
-static struct resource scif##index##_resources[] = { \
- DEFINE_RES_MEM(baseaddr, 0x100), \
- DEFINE_RES_IRQ(irq), \
-}
-
-#define R8A7790_SCIF(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_SCIF, SCSCR_RE | SCSCR_TE, \
- index, baseaddr, irq)
-
-#define R8A7790_SCIFA(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_SCIFA, SCSCR_RE | SCSCR_TE | SCSCR_CKE0, \
- index, baseaddr, irq)
-
-#define R8A7790_SCIFB(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_SCIFB, SCSCR_RE | SCSCR_TE, \
- index, baseaddr, irq)
-
-#define R8A7790_HSCIF(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_HSCIF, SCSCR_RE | SCSCR_TE, \
- index, baseaddr, irq)
-
-R8A7790_SCIFA(0, 0xe6c40000, gic_spi(144)); /* SCIFA0 */
-R8A7790_SCIFA(1, 0xe6c50000, gic_spi(145)); /* SCIFA1 */
-R8A7790_SCIFB(2, 0xe6c20000, gic_spi(148)); /* SCIFB0 */
-R8A7790_SCIFB(3, 0xe6c30000, gic_spi(149)); /* SCIFB1 */
-R8A7790_SCIFB(4, 0xe6ce0000, gic_spi(150)); /* SCIFB2 */
-R8A7790_SCIFA(5, 0xe6c60000, gic_spi(151)); /* SCIFA2 */
-R8A7790_SCIF(6, 0xe6e60000, gic_spi(152)); /* SCIF0 */
-R8A7790_SCIF(7, 0xe6e68000, gic_spi(153)); /* SCIF1 */
-R8A7790_HSCIF(8, 0xe62c0000, gic_spi(154)); /* HSCIF0 */
-R8A7790_HSCIF(9, 0xe62c8000, gic_spi(155)); /* HSCIF1 */
-
-#define r8a7790_register_scif(index) \
- platform_device_register_resndata(NULL, "sh-sci", index, \
- scif##index##_resources, \
- ARRAY_SIZE(scif##index##_resources), \
- &scif##index##_platform_data, \
- sizeof(scif##index##_platform_data))
-
-static const struct renesas_irqc_config irqc0_data __initconst = {
- .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
-};
-
-static const struct resource irqc0_resources[] __initconst = {
- DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
- DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
- DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
- DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */
- DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */
-};
-
-#define r8a7790_register_irqc(idx) \
- platform_device_register_resndata(NULL, "renesas_irqc", \
- idx, irqc##idx##_resources, \
- ARRAY_SIZE(irqc##idx##_resources), \
- &irqc##idx##_data, \
- sizeof(struct renesas_irqc_config))
-
-static const struct resource thermal_resources[] __initconst = {
- DEFINE_RES_MEM(0xe61f0000, 0x14),
- DEFINE_RES_MEM(0xe61f0100, 0x38),
- DEFINE_RES_IRQ(gic_spi(69)),
-};
-
-#define r8a7790_register_thermal() \
- platform_device_register_simple("rcar_thermal", -1, \
- thermal_resources, \
- ARRAY_SIZE(thermal_resources))
-
-static struct sh_timer_config cmt0_platform_data = {
- .channels_mask = 0x60,
-};
-
-static struct resource cmt0_resources[] = {
- DEFINE_RES_MEM(0xffca0000, 0x1004),
- DEFINE_RES_IRQ(gic_spi(142)),
-};
-
-#define r8a7790_register_cmt(idx) \
- platform_device_register_resndata(NULL, "sh-cmt-48-gen2", \
- idx, cmt##idx##_resources, \
- ARRAY_SIZE(cmt##idx##_resources), \
- &cmt##idx##_platform_data, \
- sizeof(struct sh_timer_config))
-
-void __init r8a7790_add_standard_devices(void)
-{
- r8a7790_register_scif(0);
- r8a7790_register_scif(1);
- r8a7790_register_scif(2);
- r8a7790_register_scif(3);
- r8a7790_register_scif(4);
- r8a7790_register_scif(5);
- r8a7790_register_scif(6);
- r8a7790_register_scif(7);
- r8a7790_register_scif(8);
- r8a7790_register_scif(9);
- r8a7790_register_cmt(0);
- r8a7790_register_irqc(0);
- r8a7790_register_thermal();
- r8a7790_register_i2c(0);
- r8a7790_register_i2c(1);
- r8a7790_register_i2c(2);
- r8a7790_register_i2c(3);
- r8a7790_register_audio_dmac(0);
- r8a7790_register_audio_dmac(1);
-}
-
-#ifdef CONFIG_USE_OF
-
static const char * const r8a7790_boards_compat_dt[] __initconst = {
"renesas,r8a7790",
NULL,
@@ -316,4 +35,3 @@ DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
.reserve = rcar_gen2_reserve,
.dt_compat = r8a7790_boards_compat_dt,
MACHINE_END
-#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index cc9470dfb1ce..d1fa625e61f5 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -52,15 +52,13 @@ void __init rcar_gen2_timer_init(void)
{
#if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK)
u32 mode = rcar_gen2_read_mode_pins();
- bool is_e2 = (bool)of_find_compatible_node(NULL, NULL,
- "renesas,r8a7794");
#endif
#ifdef CONFIG_ARM_ARCH_TIMER
void __iomem *base;
int extal_mhz = 0;
u32 freq;
- if (is_e2) {
+ if (of_machine_is_compatible("renesas,r8a7794")) {
freq = 260000000 / 8; /* ZS / 8 */
/* CNTVOFF has to be initialized either from non-secure
* Hypervisor mode or secure Monitor mode with SCR.NS==1.
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index fb5e1bb34be8..faea74a2151b 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -563,7 +563,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
@@ -766,7 +766,9 @@ void __init __weak sh73a0_register_twd(void) { }
void __init sh73a0_earlytimer_init(void)
{
shmobile_init_delay();
+#ifndef CONFIG_COMMON_CLK
sh73a0_clock_init();
+#endif
shmobile_earlytimer_init();
sh73a0_register_twd();
}
@@ -785,8 +787,9 @@ void __init sh73a0_add_early_devices(void)
void __init sh73a0_add_standard_devices_dt(void)
{
/* clocks are setup late during boot in the case of DT */
+#ifndef CONFIG_COMMON_CLK
sh73a0_clock_init();
-
+#endif
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 3f761f839043..9fc280e24ef4 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -56,7 +56,7 @@ static struct rcar_sysc_ch *r8a7779_ch_cpu[4] = {
[3] = &r8a7779_ch_cpu3,
};
-#ifdef CONFIG_HAVE_ARM_TWD
+#if defined(CONFIG_HAVE_ARM_TWD) && !defined(CONFIG_ARCH_MULTIPLATFORM)
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, R8A7779_SCU_BASE + 0x600, 29);
void __init r8a7779_register_twd(void)
{
diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c
index 3cf6ef8d4317..b067390cef4e 100644
--- a/arch/arm/mach-sti/board-dt.c
+++ b/arch/arm/mach-sti/board-dt.c
@@ -18,6 +18,7 @@ static const char *stih41x_dt_match[] __initdata = {
"st,stih415",
"st,stih416",
"st,stih407",
+ "st,stih418",
NULL
};
diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
index e44d028555a4..587b0468efcc 100644
--- a/arch/arm/mach-sunxi/platsmp.c
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -120,4 +120,4 @@ static struct smp_operations sun6i_smp_ops __initdata = {
.smp_prepare_cpus = sun6i_smp_prepare_cpus,
.smp_boot_secondary = sun6i_smp_boot_secondary,
};
-CPU_METHOD_OF_DECLARE(sun6i_smp, "allwinner,sun6i-a31", &sun6i_smp_ops);
+CPU_METHOD_OF_DECLARE(sun6i_a31_smp, "allwinner,sun6i-a31", &sun6i_smp_ops);
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 1f986758784a..1bc811a74a9f 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -13,9 +13,15 @@
#include <linux/clk-provider.h>
#include <linux/clocksource.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
+static void __init sunxi_dt_cpufreq_init(void)
+{
+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
static const char * const sunxi_board_dt_compat[] = {
"allwinner,sun4i-a10",
"allwinner,sun5i-a10s",
@@ -25,10 +31,12 @@ static const char * const sunxi_board_dt_compat[] = {
DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
.dt_compat = sunxi_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun6i_board_dt_compat[] = {
"allwinner,sun6i-a31",
+ "allwinner,sun6i-a31s",
NULL,
};
@@ -44,6 +52,7 @@ static void __init sun6i_timer_init(void)
DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
.init_time = sun6i_timer_init,
.dt_compat = sun6i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun7i_board_dt_compat[] = {
@@ -53,6 +62,7 @@ static const char * const sun7i_board_dt_compat[] = {
DT_MACHINE_START(SUN7I_DT, "Allwinner sun7i (A20) Family")
.dt_compat = sun7i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun8i_board_dt_compat[] = {
@@ -62,6 +72,7 @@ static const char * const sun8i_board_dt_compat[] = {
DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family")
.dt_compat = sun8i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun9i_board_dt_compat[] = {
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index d0be9a1ef6b8..5d1a318f1302 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -27,6 +27,7 @@ config ARCH_TEGRA_2x_SOC
select PINCTRL_TEGRA20
select PL310_ERRATA_727915 if CACHE_L2X0
select PL310_ERRATA_769419 if CACHE_L2X0
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra AP20 and T20 processors, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -37,6 +38,7 @@ config ARCH_TEGRA_3x_SOC
select ARM_ERRATA_764369 if SMP
select PINCTRL_TEGRA30
select PL310_ERRATA_769419 if CACHE_L2X0
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra T30 processor family, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -47,6 +49,7 @@ config ARCH_TEGRA_114_SOC
select ARM_L1_CACHE_SHIFT_6
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA114
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra T114 processor family, based on the
ARM CortexA15MP CPU
@@ -56,6 +59,7 @@ config ARCH_TEGRA_124_SOC
select ARM_L1_CACHE_SHIFT_6
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA124
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra T124 processor family, based on the
ARM CortexA15MP CPU
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 08fb8c89f414..6ea09fe53426 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -728,43 +728,6 @@ struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
};
#endif
-#ifdef CONFIG_LEDS
-#define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
-
-static void versatile_leds_event(led_event_t ledevt)
-{
- unsigned long flags;
- u32 val;
-
- local_irq_save(flags);
- val = readl(VA_LEDS_BASE);
-
- switch (ledevt) {
- case led_idle_start:
- val = val & ~VERSATILE_SYS_LED0;
- break;
-
- case led_idle_end:
- val = val | VERSATILE_SYS_LED0;
- break;
-
- case led_timer:
- val = val ^ VERSATILE_SYS_LED1;
- break;
-
- case led_halted:
- val = 0;
- break;
-
- default:
- break;
- }
-
- writel(val, VA_LEDS_BASE);
- local_irq_restore(flags);
-}
-#endif /* CONFIG_LEDS */
-
void versatile_restart(enum reboot_mode mode, const char *cmd)
{
void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index aaa5162c1509..78e5e007f52d 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -9,6 +9,8 @@ config ARCH_ZYNQ
select HAVE_ARM_TWD if SMP
select ICST
select MFD_SYSCON
+ select PINCTRL
+ select PINCTRL_ZYNQ
select SOC_BUS
help
Support for Xilinx Zynq ARM Cortex A9 Platform
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 26f92c28d22b..c887196cfdbe 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -146,8 +146,6 @@ out:
platform_device_register(&zynq_cpuidle_device);
platform_device_register_full(&devinfo);
-
- zynq_slcr_init();
}
static void __init zynq_timer_init(void)
diff --git a/arch/arm/mach-zynq/pm.c b/arch/arm/mach-zynq/pm.c
index 911fcf865be8..fa44fc1b6dd5 100644
--- a/arch/arm/mach-zynq/pm.c
+++ b/arch/arm/mach-zynq/pm.c
@@ -61,7 +61,7 @@ static void __iomem *zynq_pm_ioremap(const char *comp)
/**
* zynq_pm_late_init() - Power management init
*
- * Initialization of power management related featurs and infrastructure.
+ * Initialization of power management related features and infrastructure.
*/
void __init zynq_pm_late_init(void)
{
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index d4cb50cf97c0..c3c24fd8b306 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -47,11 +47,6 @@ static struct regmap *zynq_slcr_regmap;
*/
static int zynq_slcr_write(u32 val, u32 offset)
{
- if (!zynq_slcr_regmap) {
- writel(val, zynq_slcr_base + offset);
- return 0;
- }
-
return regmap_write(zynq_slcr_regmap, offset, val);
}
@@ -65,12 +60,7 @@ static int zynq_slcr_write(u32 val, u32 offset)
*/
static int zynq_slcr_read(u32 *val, u32 offset)
{
- if (zynq_slcr_regmap)
- return regmap_read(zynq_slcr_regmap, offset, val);
-
- *val = readl(zynq_slcr_base + offset);
-
- return 0;
+ return regmap_read(zynq_slcr_regmap, offset, val);
}
/**
@@ -196,23 +186,6 @@ void zynq_slcr_cpu_state_write(int cpu, bool die)
}
/**
- * zynq_slcr_init - Regular slcr driver init
- * Return: 0 on success, negative errno otherwise.
- *
- * Called early during boot from platform code to remap SLCR area.
- */
-int __init zynq_slcr_init(void)
-{
- zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
- if (IS_ERR(zynq_slcr_regmap)) {
- pr_err("%s: failed to find zynq-slcr\n", __func__);
- return -ENODEV;
- }
-
- return 0;
-}
-
-/**
* zynq_early_slcr_init - Early slcr init function
*
* Return: 0 on success, negative errno otherwise.
@@ -237,6 +210,12 @@ int __init zynq_early_slcr_init(void)
np->data = (__force void *)zynq_slcr_base;
+ zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
+ if (IS_ERR(zynq_slcr_regmap)) {
+ pr_err("%s: failed to find zynq-slcr\n", __func__);
+ return -ENODEV;
+ }
+
/* unlock the SLCR so that registers can be changed */
zynq_slcr_unlock();
diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/plat-iop/pmu.c
index ad9f9744a82d..c6d979ace524 100644
--- a/arch/arm/plat-iop/pmu.c
+++ b/arch/arm/plat-iop/pmu.c
@@ -24,7 +24,7 @@ static struct resource pmu_resource = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "xscale-pmu",
.id = -1,
.resource = &pmu_resource,
.num_resources = 1,
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 24770e5a5081..6416e03b4482 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -151,14 +151,6 @@ static int omap_dma_in_1510_mode(void)
#endif
#ifdef CONFIG_ARCH_OMAP1
-static inline int get_gdma_dev(int req)
-{
- u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
- int shift = ((req - 1) % 5) * 6;
-
- return ((omap_readl(reg) >> shift) & 0x3f) + 1;
-}
-
static inline void set_gdma_dev(int req, int dev)
{
u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 9bd2776e7d05..cb8e3d655d1a 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -236,13 +236,6 @@ config S3C_SETUP_CAMIF
help
Compile in common setup code for S3C CAMIF devices
-# DMA
-
-config S3C_DMA
- bool
- help
- Internal configuration for S3C DMA core
-
config SAMSUNG_PM_GPIO
bool
default y if GPIO_SAMSUNG && PM
@@ -250,14 +243,6 @@ config SAMSUNG_PM_GPIO
Include legacy GPIO power management code for platforms not using
pinctrl-samsung driver.
-config SAMSUNG_DMADEV
- bool "Use legacy Samsung DMA abstraction"
- depends on CPU_S5PV210 || ARCH_S3C64XX
- select DMADEVICES
- default y
- help
- Use DMA device engine for PL330 DMAC.
-
endif
config S5P_DEV_MFC
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 87746c37f030..1a29ab1f446d 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -26,12 +26,6 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o
-# DMA support
-
-obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o
-
-obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o
-
# PM support
obj-$(CONFIG_PM_SLEEP) += pm-common.o
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
index 360618ee39e5..71333bb61013 100644
--- a/arch/arm/plat-samsung/cpu.c
+++ b/arch/arm/plat-samsung/cpu.c
@@ -40,10 +40,14 @@ void __init s3c64xx_init_cpu(void)
}
samsung_cpu_rev = 0;
+
+ pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
}
void __init s5p_init_cpu(void __iomem *cpuid_addr)
{
samsung_cpu_id = __raw_readl(cpuid_addr);
samsung_cpu_rev = samsung_cpu_id & 0xFF;
+
+ pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
}
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
deleted file mode 100644
index 886326ee6f6c..000000000000
--- a/arch/arm/plat-samsung/dma-ops.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* linux/arch/arm/plat-samsung/dma-ops.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung DMA Operations
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/amba/pl330.h>
-#include <linux/scatterlist.h>
-#include <linux/export.h>
-
-#include <mach/dma.h>
-
-#if defined(CONFIG_PL330_DMA)
-#define dma_filter pl330_filter
-#elif defined(CONFIG_S3C64XX_PL080)
-#define dma_filter pl08x_filter_id
-#endif
-
-static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
- struct samsung_dma_req *param,
- struct device *dev, char *ch_name)
-{
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(param->cap, mask);
-
- if (dev->of_node)
- return (unsigned)dma_request_slave_channel(dev, ch_name);
- else
- return (unsigned)dma_request_channel(mask, dma_filter,
- (void *)dma_ch);
-}
-
-static int samsung_dmadev_release(unsigned ch, void *param)
-{
- dma_release_channel((struct dma_chan *)ch);
-
- return 0;
-}
-
-static int samsung_dmadev_config(unsigned ch,
- struct samsung_dma_config *param)
-{
- struct dma_chan *chan = (struct dma_chan *)ch;
- struct dma_slave_config slave_config;
-
- if (param->direction == DMA_DEV_TO_MEM) {
- memset(&slave_config, 0, sizeof(struct dma_slave_config));
- slave_config.direction = param->direction;
- slave_config.src_addr = param->fifo;
- slave_config.src_addr_width = param->width;
- slave_config.src_maxburst = 1;
- dmaengine_slave_config(chan, &slave_config);
- } else if (param->direction == DMA_MEM_TO_DEV) {
- memset(&slave_config, 0, sizeof(struct dma_slave_config));
- slave_config.direction = param->direction;
- slave_config.dst_addr = param->fifo;
- slave_config.dst_addr_width = param->width;
- slave_config.dst_maxburst = 1;
- dmaengine_slave_config(chan, &slave_config);
- } else {
- pr_warn("unsupported direction\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int samsung_dmadev_prepare(unsigned ch,
- struct samsung_dma_prep *param)
-{
- struct scatterlist sg;
- struct dma_chan *chan = (struct dma_chan *)ch;
- struct dma_async_tx_descriptor *desc;
-
- switch (param->cap) {
- case DMA_SLAVE:
- sg_init_table(&sg, 1);
- sg_dma_len(&sg) = param->len;
- sg_set_page(&sg, pfn_to_page(PFN_DOWN(param->buf)),
- param->len, offset_in_page(param->buf));
- sg_dma_address(&sg) = param->buf;
-
- desc = dmaengine_prep_slave_sg(chan,
- &sg, 1, param->direction, DMA_PREP_INTERRUPT);
- break;
- case DMA_CYCLIC:
- desc = dmaengine_prep_dma_cyclic(chan, param->buf,
- param->len, param->period, param->direction,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- break;
- default:
- dev_err(&chan->dev->device, "unsupported format\n");
- return -EFAULT;
- }
-
- if (!desc) {
- dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
- return -EFAULT;
- }
-
- desc->callback = param->fp;
- desc->callback_param = param->fp_param;
-
- dmaengine_submit((struct dma_async_tx_descriptor *)desc);
-
- return 0;
-}
-
-static inline int samsung_dmadev_trigger(unsigned ch)
-{
- dma_async_issue_pending((struct dma_chan *)ch);
-
- return 0;
-}
-
-static inline int samsung_dmadev_flush(unsigned ch)
-{
- return dmaengine_terminate_all((struct dma_chan *)ch);
-}
-
-static struct samsung_dma_ops dmadev_ops = {
- .request = samsung_dmadev_request,
- .release = samsung_dmadev_release,
- .config = samsung_dmadev_config,
- .prepare = samsung_dmadev_prepare,
- .trigger = samsung_dmadev_trigger,
- .started = NULL,
- .flush = samsung_dmadev_flush,
- .stop = samsung_dmadev_flush,
-};
-
-void *samsung_dmadev_get_ops(void)
-{
- return &dmadev_ops;
-}
-EXPORT_SYMBOL(samsung_dmadev_get_ops);
diff --git a/arch/arm/plat-samsung/dma.c b/arch/arm/plat-samsung/dma.c
deleted file mode 100644
index 6143aa147688..000000000000
--- a/arch/arm/plat-samsung/dma.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* linux/arch/arm/plat-samsung/dma.c
- *
- * Copyright (c) 2003-2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C DMA core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct s3c2410_dma_buf;
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-/* dma channel state information */
-struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
-
-/* s3c_dma_lookup_channel
- *
- * change the dma channel number given into a real dma channel id
-*/
-
-struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
-{
- if (channel & DMACH_LOW_LEVEL)
- return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
- else
- return s3c_dma_chan_map[channel];
-}
-
-/* do we need to protect the settings of the fields from
- * irq?
-*/
-
-int s3c2410_dma_set_opfn(enum dma_ch channel, s3c2410_dma_opfn_t rtn)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
-
- chan->op_fn = rtn;
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_opfn);
-
-int s3c2410_dma_set_buffdone_fn(enum dma_ch channel, s3c2410_dma_cbfn_t rtn)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
-
- chan->callback_fn = rtn;
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
-
-int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- chan->flags = flags;
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_setflags);
diff --git a/arch/arm/plat-samsung/include/plat/dma-core.h b/arch/arm/plat-samsung/include/plat/dma-core.h
deleted file mode 100644
index 32ff2a92cb3c..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-core.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/dma.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * Samsung S3C DMA core support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel);
-
-extern struct s3c2410_dma_chan *s3c_dma_chan_map[];
-
-/* the currently allocated channel information */
-extern struct s3c2410_dma_chan s3c2410_chans[];
-
-
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
deleted file mode 100644
index ce6d7634b6cb..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/dma-ops.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __SAMSUNG_DMA_OPS_H_
-#define __SAMSUNG_DMA_OPS_H_ __FILE__
-
-#include <linux/dmaengine.h>
-#include <mach/dma.h>
-
-struct samsung_dma_req {
- enum dma_transaction_type cap;
- struct s3c2410_dma_client *client;
-};
-
-struct samsung_dma_prep {
- enum dma_transaction_type cap;
- enum dma_transfer_direction direction;
- dma_addr_t buf;
- unsigned long period;
- unsigned long len;
- void (*fp)(void *data);
- void *fp_param;
-};
-
-struct samsung_dma_config {
- enum dma_transfer_direction direction;
- enum dma_slave_buswidth width;
- dma_addr_t fifo;
-};
-
-struct samsung_dma_ops {
- unsigned (*request)(enum dma_ch ch, struct samsung_dma_req *param,
- struct device *dev, char *ch_name);
- int (*release)(unsigned ch, void *param);
- int (*config)(unsigned ch, struct samsung_dma_config *param);
- int (*prepare)(unsigned ch, struct samsung_dma_prep *param);
- int (*trigger)(unsigned ch);
- int (*started)(unsigned ch);
- int (*flush)(unsigned ch);
- int (*stop)(unsigned ch);
-};
-
-extern void *samsung_dmadev_get_ops(void);
-extern void *s3c_dma_get_ops(void);
-
-static inline void *__samsung_dma_get_ops(void)
-{
- if (samsung_dma_is_dmadev())
- return samsung_dmadev_get_ops();
- else
- return s3c_dma_get_ops();
-}
-
-/*
- * samsung_dma_get_ops
- * get the set of samsung dma operations
- */
-#define samsung_dma_get_ops() __samsung_dma_get_ops()
-
-#endif /* __SAMSUNG_DMA_OPS_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
deleted file mode 100644
index abe07fae71db..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __DMA_PL330_H_
-#define __DMA_PL330_H_ __FILE__
-
-/*
- * PL330 can assign any channel to communicate with
- * any of the peripherals attched to the DMAC.
- * For the sake of consistency across client drivers,
- * We keep the channel names unchanged and only add
- * missing peripherals are added.
- * Order is not important since DMA PL330 API driver
- * use these just as IDs.
- */
-enum dma_ch {
- DMACH_UART0_RX = 0,
- DMACH_UART0_TX,
- DMACH_UART1_RX,
- DMACH_UART1_TX,
- DMACH_UART2_RX,
- DMACH_UART2_TX,
- DMACH_UART3_RX,
- DMACH_UART3_TX,
- DMACH_UART4_RX,
- DMACH_UART4_TX,
- DMACH_UART5_RX,
- DMACH_UART5_TX,
- DMACH_USI_RX,
- DMACH_USI_TX,
- DMACH_IRDA,
- DMACH_I2S0_RX,
- DMACH_I2S0_TX,
- DMACH_I2S0S_TX,
- DMACH_I2S1_RX,
- DMACH_I2S1_TX,
- DMACH_I2S2_RX,
- DMACH_I2S2_TX,
- DMACH_SPI0_RX,
- DMACH_SPI0_TX,
- DMACH_SPI1_RX,
- DMACH_SPI1_TX,
- DMACH_SPI2_RX,
- DMACH_SPI2_TX,
- DMACH_AC97_MICIN,
- DMACH_AC97_PCMIN,
- DMACH_AC97_PCMOUT,
- DMACH_EXTERNAL,
- DMACH_PWM,
- DMACH_SPDIF,
- DMACH_HSI_RX,
- DMACH_HSI_TX,
- DMACH_PCM0_TX,
- DMACH_PCM0_RX,
- DMACH_PCM1_TX,
- DMACH_PCM1_RX,
- DMACH_PCM2_TX,
- DMACH_PCM2_RX,
- DMACH_MSM_REQ3,
- DMACH_MSM_REQ2,
- DMACH_MSM_REQ1,
- DMACH_MSM_REQ0,
- DMACH_SLIMBUS0_RX,
- DMACH_SLIMBUS0_TX,
- DMACH_SLIMBUS0AUX_RX,
- DMACH_SLIMBUS0AUX_TX,
- DMACH_SLIMBUS1_RX,
- DMACH_SLIMBUS1_TX,
- DMACH_SLIMBUS2_RX,
- DMACH_SLIMBUS2_TX,
- DMACH_SLIMBUS3_RX,
- DMACH_SLIMBUS3_TX,
- DMACH_SLIMBUS4_RX,
- 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,
-};
-
-struct s3c2410_dma_client {
- char *name;
-};
-
-static inline bool samsung_dma_has_circular(void)
-{
- return true;
-}
-
-static inline bool samsung_dma_is_dmadev(void)
-{
- return true;
-}
-
-#include <plat/dma-ops.h>
-
-#endif /* __DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
deleted file mode 100644
index bd3a6db14cbb..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
- *
- * Copyright (C) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support - per SoC functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <plat/dma-core.h>
-
-extern struct bus_type dma_subsys;
-extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-
-#define DMA_CH_VALID (1<<31)
-#define DMA_CH_NEVER (1<<30)
-
-/* struct s3c24xx_dma_map
- *
- * this holds the mapping information for the channel selected
- * to be connected to the specified device
-*/
-
-struct s3c24xx_dma_map {
- const char *name;
-
- unsigned long channels[S3C_DMA_CHANNELS];
-};
-
-struct s3c24xx_dma_selection {
- struct s3c24xx_dma_map *map;
- unsigned long map_size;
- unsigned long dcon_mask;
-
- void (*select)(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map);
-};
-
-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
-
-/* struct s3c24xx_dma_order_ch
- *
- * channel map for one of the `enum dma_ch` dma channels. the list
- * entry contains a set of low-level channel numbers, orred with
- * DMA_CH_VALID, which are checked in the order in the array.
-*/
-
-struct s3c24xx_dma_order_ch {
- unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
- unsigned int flags; /* flags */
-};
-
-/* struct s3c24xx_dma_order
- *
- * information provided by either the core or the board to give the
- * dma system a hint on how to allocate channels
-*/
-
-struct s3c24xx_dma_order {
- struct s3c24xx_dma_order_ch channels[DMACH_MAX];
-};
-
-extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
-
-/* DMA init code, called from the cpu support code */
-
-extern int s3c2410_dma_init(void);
-
-extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
- unsigned int stride);
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
deleted file mode 100644
index 7b02143ccd9a..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_DMA_H
-#define __PLAT_DMA_H
-
-#include <linux/dma-mapping.h>
-
-enum s3c2410_dma_buffresult {
- S3C2410_RES_OK,
- S3C2410_RES_ERR,
- S3C2410_RES_ABORT
-};
-
-/* enum s3c2410_chan_op
- *
- * operation codes passed to the DMA code by the user, and also used
- * to inform the current channel owner of any changes to the system state
-*/
-
-enum s3c2410_chan_op {
- S3C2410_DMAOP_START,
- S3C2410_DMAOP_STOP,
- S3C2410_DMAOP_PAUSE,
- S3C2410_DMAOP_RESUME,
- S3C2410_DMAOP_FLUSH,
- S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */
- S3C2410_DMAOP_STARTED, /* indicate channel started */
-};
-
-struct s3c2410_dma_client {
- char *name;
-};
-
-struct s3c2410_dma_chan;
-enum dma_ch;
-
-/* s3c2410_dma_cbfn_t
- *
- * buffer callback routine type
-*/
-
-typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
- void *buf, int size,
- enum s3c2410_dma_buffresult result);
-
-typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
- enum s3c2410_chan_op );
-
-
-
-/* s3c2410_dma_request
- *
- * request a dma channel exclusivley
-*/
-
-extern int s3c2410_dma_request(enum dma_ch channel,
- struct s3c2410_dma_client *, void *dev);
-
-
-/* s3c2410_dma_ctrl
- *
- * change the state of the dma channel
-*/
-
-extern int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op);
-
-/* s3c2410_dma_setflags
- *
- * set the channel's flags to a given state
-*/
-
-extern int s3c2410_dma_setflags(enum dma_ch channel,
- unsigned int flags);
-
-/* s3c2410_dma_free
- *
- * free the dma channel (will also abort any outstanding operations)
-*/
-
-extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *);
-
-/* s3c2410_dma_enqueue
- *
- * 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(enum dma_ch channel, void *id,
- dma_addr_t data, int size);
-
-/* s3c2410_dma_config
- *
- * configure the dma channel
-*/
-
-extern int s3c2410_dma_config(enum dma_ch channel, int xferunit);
-
-/* s3c2410_dma_devconfig
- *
- * configure the device we're talking to
-*/
-
-extern int s3c2410_dma_devconfig(enum dma_ch channel,
- enum dma_data_direction source, unsigned long devaddr);
-
-/* s3c2410_dma_getposition
- *
- * get the position that the dma transfer is currently at
-*/
-
-extern int s3c2410_dma_getposition(enum dma_ch channel,
- dma_addr_t *src, dma_addr_t *dest);
-
-extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn);
-extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn);
-
-#include <plat/dma-ops.h>
-
-#endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-dma.h b/arch/arm/plat-samsung/include/plat/regs-dma.h
deleted file mode 100644
index a7d622ef16af..000000000000
--- a/arch/arm/plat-samsung/include/plat/regs-dma.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/regs-dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_REGS_DMA_H
-#define __ASM_PLAT_REGS_DMA_H __FILE__
-
-#define S3C2410_DMA_DISRC (0x00)
-#define S3C2410_DMA_DISRCC (0x04)
-#define S3C2410_DMA_DIDST (0x08)
-#define S3C2410_DMA_DIDSTC (0x0C)
-#define S3C2410_DMA_DCON (0x10)
-#define S3C2410_DMA_DSTAT (0x14)
-#define S3C2410_DMA_DCSRC (0x18)
-#define S3C2410_DMA_DCDST (0x1C)
-#define S3C2410_DMA_DMASKTRIG (0x20)
-#define S3C2412_DMA_DMAREQSEL (0x24)
-#define S3C2443_DMA_DMAREQSEL (0x24)
-
-#define S3C2410_DISRCC_INC (1 << 0)
-#define S3C2410_DISRCC_APB (1 << 1)
-
-#define S3C2410_DMASKTRIG_STOP (1 << 2)
-#define S3C2410_DMASKTRIG_ON (1 << 1)
-#define S3C2410_DMASKTRIG_SWTRIG (1 << 0)
-
-#define S3C2410_DCON_DEMAND (0 << 31)
-#define S3C2410_DCON_HANDSHAKE (1 << 31)
-#define S3C2410_DCON_SYNC_PCLK (0 << 30)
-#define S3C2410_DCON_SYNC_HCLK (1 << 30)
-
-#define S3C2410_DCON_INTREQ (1 << 29)
-
-#define S3C2410_DCON_CH0_XDREQ0 (0 << 24)
-#define S3C2410_DCON_CH0_UART0 (1 << 24)
-#define S3C2410_DCON_CH0_SDI (2 << 24)
-#define S3C2410_DCON_CH0_TIMER (3 << 24)
-#define S3C2410_DCON_CH0_USBEP1 (4 << 24)
-
-#define S3C2410_DCON_CH1_XDREQ1 (0 << 24)
-#define S3C2410_DCON_CH1_UART1 (1 << 24)
-#define S3C2410_DCON_CH1_I2SSDI (2 << 24)
-#define S3C2410_DCON_CH1_SPI (3 << 24)
-#define S3C2410_DCON_CH1_USBEP2 (4 << 24)
-
-#define S3C2410_DCON_CH2_I2SSDO (0 << 24)
-#define S3C2410_DCON_CH2_I2SSDI (1 << 24)
-#define S3C2410_DCON_CH2_SDI (2 << 24)
-#define S3C2410_DCON_CH2_TIMER (3 << 24)
-#define S3C2410_DCON_CH2_USBEP3 (4 << 24)
-
-#define S3C2410_DCON_CH3_UART2 (0 << 24)
-#define S3C2410_DCON_CH3_SDI (1 << 24)
-#define S3C2410_DCON_CH3_SPI (2 << 24)
-#define S3C2410_DCON_CH3_TIMER (3 << 24)
-#define S3C2410_DCON_CH3_USBEP4 (4 << 24)
-
-#define S3C2410_DCON_SRCSHIFT (24)
-#define S3C2410_DCON_SRCMASK (7 << 24)
-
-#define S3C2410_DCON_BYTE (0 << 20)
-#define S3C2410_DCON_HALFWORD (1 << 20)
-#define S3C2410_DCON_WORD (2 << 20)
-
-#define S3C2410_DCON_AUTORELOAD (0 << 22)
-#define S3C2410_DCON_NORELOAD (1 << 22)
-#define S3C2410_DCON_HWTRIG (1 << 23)
-
-#ifdef CONFIG_CPU_S3C2440
-
-#define S3C2440_DIDSTC_CHKINT (1 << 2)
-
-#define S3C2440_DCON_CH0_I2SSDO (5 << 24)
-#define S3C2440_DCON_CH0_PCMIN (6 << 24)
-
-#define S3C2440_DCON_CH1_PCMOUT (5 << 24)
-#define S3C2440_DCON_CH1_SDI (6 << 24)
-
-#define S3C2440_DCON_CH2_PCMIN (5 << 24)
-#define S3C2440_DCON_CH2_MICIN (6 << 24)
-
-#define S3C2440_DCON_CH3_MICIN (5 << 24)
-#define S3C2440_DCON_CH3_PCMOUT (6 << 24)
-#endif /* CONFIG_CPU_S3C2440 */
-
-#ifdef CONFIG_CPU_S3C2412
-
-#define S3C2412_DMAREQSEL_SRC(x) ((x) << 1)
-
-#define S3C2412_DMAREQSEL_HW (1)
-
-#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0)
-#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1)
-#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2)
-#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3)
-#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4)
-#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5)
-#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9)
-#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10)
-#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13)
-#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14)
-#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15)
-#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16)
-#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17)
-#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18)
-#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19)
-#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20)
-#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21)
-#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22)
-#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23)
-#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24)
-#endif /* CONFIG_CPU_S3C2412 */
-
-#if defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2443)
-
-#define S3C2443_DMAREQSEL_SRC(x) ((x) << 1)
-
-#define S3C2443_DMAREQSEL_HW (1)
-
-#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0)
-#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1)
-#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2)
-#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3)
-#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4)
-#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5)
-#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9)
-#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10)
-#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17)
-#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18)
-#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19)
-#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20)
-#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21)
-#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22)
-#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23)
-#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24)
-#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25)
-#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26)
-#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27)
-#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28)
-#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29)
-#endif /* CONFIG_CPU_S3C2443 */
-
-#endif /* __ASM_PLAT_REGS_DMA_H */
diff --git a/arch/arm/plat-samsung/s3c-dma-ops.c b/arch/arm/plat-samsung/s3c-dma-ops.c
deleted file mode 100644
index 98b10ba67dc7..000000000000
--- a/arch/arm/plat-samsung/s3c-dma-ops.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* linux/arch/arm/plat-samsung/s3c-dma-ops.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung S3C-DMA Operations
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/export.h>
-
-#include <mach/dma.h>
-
-struct cb_data {
- void (*fp) (void *);
- void *fp_param;
- unsigned ch;
- struct list_head node;
-};
-
-static LIST_HEAD(dma_list);
-
-static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param,
- int size, enum s3c2410_dma_buffresult res)
-{
- struct cb_data *data = param;
-
- data->fp(data->fp_param);
-}
-
-static unsigned s3c_dma_request(enum dma_ch dma_ch,
- struct samsung_dma_req *param,
- struct device *dev, char *ch_name)
-{
- struct cb_data *data;
-
- if (s3c2410_dma_request(dma_ch, param->client, NULL) < 0) {
- s3c2410_dma_free(dma_ch, param->client);
- return 0;
- }
-
- if (param->cap == DMA_CYCLIC)
- s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
-
- data = kzalloc(sizeof(struct cb_data), GFP_KERNEL);
- data->ch = dma_ch;
- list_add_tail(&data->node, &dma_list);
-
- return (unsigned)dma_ch;
-}
-
-static int s3c_dma_release(unsigned ch, void *param)
-{
- struct cb_data *data;
-
- list_for_each_entry(data, &dma_list, node)
- if (data->ch == ch)
- break;
- list_del(&data->node);
-
- s3c2410_dma_free(ch, param);
- kfree(data);
-
- return 0;
-}
-
-static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param)
-{
- s3c2410_dma_devconfig(ch, param->direction, param->fifo);
- s3c2410_dma_config(ch, param->width);
-
- return 0;
-}
-
-static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param)
-{
- struct cb_data *data;
- dma_addr_t pos = param->buf;
- dma_addr_t end = param->buf + param->len;
-
- list_for_each_entry(data, &dma_list, node)
- if (data->ch == ch)
- break;
-
- if (!data->fp) {
- s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb);
- data->fp = param->fp;
- data->fp_param = param->fp_param;
- }
-
- if (param->cap != DMA_CYCLIC) {
- s3c2410_dma_enqueue(ch, (void *)data, param->buf, param->len);
- return 0;
- }
-
- while (pos < end) {
- s3c2410_dma_enqueue(ch, (void *)data, pos, param->period);
- pos += param->period;
- }
-
- return 0;
-}
-
-static inline int s3c_dma_trigger(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START);
-}
-
-static inline int s3c_dma_started(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED);
-}
-
-static inline int s3c_dma_flush(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH);
-}
-
-static inline int s3c_dma_stop(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP);
-}
-
-static struct samsung_dma_ops s3c_dma_ops = {
- .request = s3c_dma_request,
- .release = s3c_dma_release,
- .config = s3c_dma_config,
- .prepare = s3c_dma_prepare,
- .trigger = s3c_dma_trigger,
- .started = s3c_dma_started,
- .flush = s3c_dma_flush,
- .stop = s3c_dma_stop,
-};
-
-void *s3c_dma_get_ops(void)
-{
- return &s3c_dma_ops;
-}
-EXPORT_SYMBOL(s3c_dma_get_ops);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 676454a65af8..1b8e97331ffb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -149,11 +149,65 @@ source "kernel/Kconfig.freezer"
menu "Platform selection"
+config ARCH_EXYNOS
+ bool
+ help
+ This enables support for Samsung Exynos SoC family
+
+config ARCH_EXYNOS7
+ bool "ARMv8 based Samsung Exynos7"
+ select ARCH_EXYNOS
+ select COMMON_CLK_SAMSUNG
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select HAVE_S3C_RTC if RTC_CLASS
+ select PINCTRL
+ select PINCTRL_EXYNOS
+
+ help
+ This enables support for Samsung Exynos7 SoC family
+
+config ARCH_FSL_LS2085A
+ bool "Freescale LS2085A SOC"
+ help
+ This enables support for Freescale LS2085A SOC.
+
+config ARCH_MEDIATEK
+ bool "Mediatek MT65xx & MT81xx ARMv8 SoC"
+ select ARM_GIC
+ help
+ Support for Mediatek MT65xx & MT81xx ARMv8 SoCs
+
config ARCH_SEATTLE
bool "AMD Seattle SoC Family"
help
This enables support for AMD Seattle SOC Family
+config ARCH_TEGRA
+ bool "NVIDIA Tegra SoC Family"
+ select ARCH_HAS_RESET_CONTROLLER
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select CLKSRC_OF
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ select PINCTRL
+ select RESET_CONTROLLER
+ help
+ This enables support for the NVIDIA Tegra SoC family.
+
+config ARCH_TEGRA_132_SOC
+ bool "NVIDIA Tegra132 SoC"
+ depends on ARCH_TEGRA
+ select PINCTRL_TEGRA124
+ select USB_ULPI if USB_PHY
+ select USB_ULPI_VIEWPORT if USB_PHY
+ help
+ Enable support for NVIDIA Tegra132 SoC, based on the Denver
+ ARMv8 CPU. The Tegra132 SoC is similar to the Tegra124 SoC,
+ but contains an NVIDIA Denver CPU complex in place of
+ Tegra124's "4+1" Cortex-A15 CPU complex.
+
config ARCH_THUNDER
bool "Cavium Inc. Thunder SoC Family"
help
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index c62b0f4d9ef6..e0350caf049e 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -2,5 +2,8 @@ dts-dirs += amd
dts-dirs += apm
dts-dirs += arm
dts-dirs += cavium
+dts-dirs += exynos
+dts-dirs += freescale
+dts-dirs += mediatek
subdir-y := $(dts-dirs)
diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile
new file mode 100644
index 000000000000..20310e5b6d6f
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_EXYNOS7) += exynos7-espresso.dtb
+
+always := $(dtb-y)
+subdir-y := $(dts-dirs)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
new file mode 100644
index 000000000000..5424cc450f72
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
@@ -0,0 +1,84 @@
+/*
+ * SAMSUNG Exynos7 Espresso board device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos7.dtsi"
+
+/ {
+ model = "Samsung Exynos7 Espresso board based on EXYNOS7";
+ compatible = "samsung,exynos7-espresso", "samsung,exynos7";
+
+ aliases {
+ serial0 = &serial_2;
+ mshc0 = &mmc_0;
+ mshc2 = &mmc_2;
+ };
+
+ chosen {
+ linux,stdout-path = &serial_2;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0x0 0xC0000000>;
+ };
+};
+
+&fin_pll {
+ clock-frequency = <24000000>;
+};
+
+&serial_2 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&adc {
+ status = "okay";
+};
+
+&mmc_0 {
+ status = "okay";
+ num-slots = <1>;
+ broken-cd;
+ cap-mmc-highspeed;
+ non-removable;
+ card-detect-delay = <200>;
+ clock-frequency = <800000000>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+ bus-width = <8>;
+};
+
+&mmc_2 {
+ status = "okay";
+ num-slots = <1>;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ clock-frequency = <400000000>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <2 3>;
+ samsung,dw-mshc-ddr-timing = <1 2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+ disable-wp;
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
new file mode 100644
index 000000000000..2eef4a279131
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
@@ -0,0 +1,588 @@
+/*
+ * Samsung's Exynos7 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos7 SoC pin-mux and pin-config options are listed as
+ * device tree nodes in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+&pinctrl_alive {
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+ <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+ interrupts = <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+ <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
+ };
+
+ gpa2: gpa2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa3: gpa3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
+&pinctrl_bus0 {
+ gpb0: gpb0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc2: gpc2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc3: gpc3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd2: gpd2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd4: gpd4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd5: gpd5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd6: gpd6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd7: gpd7 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd8: gpd8 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg3: gpg3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ hs_i2c10_bus: hs-i2c10-bus {
+ samsung,pins = "gpb0-1", "gpb0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c11_bus: hs-i2c11-bus {
+ samsung,pins = "gpb0-3", "gpb0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c2_bus: hs-i2c2-bus {
+ samsung,pins = "gpd0-3", "gpd0-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpd0-0", "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpd0-2", "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpd1-4", "gpd1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c3_bus: hs-i2c3-bus {
+ samsung,pins = "gpd1-3", "gpd1-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpd1-0", "gpd1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpd1-2", "gpd1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c0_bus: hs-i2c0-bus {
+ samsung,pins = "gpd2-1", "gpd2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c1_bus: hs-i2c1-bus {
+ samsung,pins = "gpd2-3", "gpd2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c9_bus: hs-i2c9-bus {
+ samsung,pins = "gpd2-7", "gpd2-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm0_out: pwm0-out {
+ samsung,pins = "gpd2-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm1_out: pwm1-out {
+ samsung,pins = "gpd2-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm2_out: pwm2-out {
+ samsung,pins = "gpd2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ pwm3_out: pwm3-out {
+ samsung,pins = "gpd2-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c8_bus: hs-i2c8-bus {
+ samsung,pins = "gpd5-3", "gpd5-2";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpd5-0", "gpd5-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpd5-0", "gpd5-1", "gpd5-2", "gpd5-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpd6-2", "gpd6-3", "gpd6-4", "gpd6-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpd8-0", "gpd8-1", "gpd6-0", "gpd6-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c4_bus: hs-i2c4-bus {
+ samsung,pins = "gpg3-1", "gpg3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ hs_i2c5_bus: hs-i2c5-bus {
+ samsung,pins = "gpg3-3", "gpg3-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_nfc {
+ gpj0: gpj0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ hs_i2c6_bus: hs-i2c6-bus {
+ samsung,pins = "gpj0-1", "gpj0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_touch {
+ gpj1: gpj1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ hs_i2c7_bus: hs-i2c7-bus {
+ samsung,pins = "gpj1-1", "gpj1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_ff {
+ gpg4: gpg4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ spi3_bus: spi3-bus {
+ samsung,pins = "gpg4-0", "gpg4-1", "gpg4-2", "gpg4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_ese {
+ gpv7: gpv7 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ spi4_bus: spi4-bus {
+ samsung,pins = "gpv7-0", "gpv7-1", "gpv7-2", "gpv7-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+};
+
+&pinctrl_fsys0 {
+ gpr4: gpr4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpr4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpr4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpr4-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpr4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+};
+
+&pinctrl_fsys1 {
+ gpr0: gpr0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr1: gpr1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr2: gpr2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpr3: gpr3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpr0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpr0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_ds: sd0-ds {
+ samsung,pins = "gpr0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_qrdy: sd0-qrdy {
+ samsung,pins = "gpr0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpr1-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpr2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpr2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_ds: sd1-ds {
+ samsung,pins = "gpr2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <6>;
+ };
+
+ sd1_qrdy: sd1-qrdy {
+ samsung,pins = "gpr2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <6>;
+ };
+
+ sd1_int: sd1-int {
+ samsung,pins = "gpr2-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <1>;
+ samsung,pin-drv = <6>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpr3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+
+ sd1_bus8: sd1-bus-width8 {
+ samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <2>;
+ };
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
new file mode 100644
index 000000000000..d7a37c3a6b52
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -0,0 +1,530 @@
+/*
+ * SAMSUNG EXYNOS7 SoC device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <dt-bindings/clock/exynos7-clk.h>
+
+/ {
+ compatible = "samsung,exynos7";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ pinctrl0 = &pinctrl_alive;
+ pinctrl1 = &pinctrl_bus0;
+ pinctrl2 = &pinctrl_nfc;
+ pinctrl3 = &pinctrl_touch;
+ pinctrl4 = &pinctrl_ff;
+ pinctrl5 = &pinctrl_ese;
+ pinctrl6 = &pinctrl_fsys0;
+ pinctrl7 = &pinctrl_fsys1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x0>;
+ enable-method = "psci";
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x1>;
+ enable-method = "psci";
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x2>;
+ enable-method = "psci";
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x3>;
+ enable-method = "psci";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0 0x18000000>;
+
+ chipid@10000000 {
+ compatible = "samsung,exynos4210-chipid";
+ reg = <0x10000000 0x100>;
+ };
+
+ fin_pll: xxti {
+ compatible = "fixed-clock";
+ clock-output-names = "fin_pll";
+ #clock-cells = <0>;
+ };
+
+ gic: interrupt-controller@11001000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x11001000 0x1000>,
+ <0x11002000 0x1000>,
+ <0x11004000 0x2000>,
+ <0x11006000 0x2000>;
+ };
+
+ clock_topc: clock-controller@10570000 {
+ compatible = "samsung,exynos7-clock-topc";
+ reg = <0x10570000 0x10000>;
+ #clock-cells = <1>;
+ };
+
+ clock_top0: clock-controller@105d0000 {
+ compatible = "samsung,exynos7-clock-top0";
+ reg = <0x105d0000 0xb000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_topc DOUT_SCLK_BUS0_PLL>,
+ <&clock_topc DOUT_SCLK_BUS1_PLL>,
+ <&clock_topc DOUT_SCLK_CC_PLL>,
+ <&clock_topc DOUT_SCLK_MFC_PLL>;
+ clock-names = "fin_pll", "dout_sclk_bus0_pll",
+ "dout_sclk_bus1_pll", "dout_sclk_cc_pll",
+ "dout_sclk_mfc_pll";
+ };
+
+ clock_top1: clock-controller@105e0000 {
+ compatible = "samsung,exynos7-clock-top1";
+ reg = <0x105e0000 0xb000>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_topc DOUT_SCLK_BUS0_PLL>,
+ <&clock_topc DOUT_SCLK_BUS1_PLL>,
+ <&clock_topc DOUT_SCLK_CC_PLL>,
+ <&clock_topc DOUT_SCLK_MFC_PLL>;
+ clock-names = "fin_pll", "dout_sclk_bus0_pll",
+ "dout_sclk_bus1_pll", "dout_sclk_cc_pll",
+ "dout_sclk_mfc_pll";
+ };
+
+ clock_ccore: clock-controller@105b0000 {
+ compatible = "samsung,exynos7-clock-ccore";
+ reg = <0x105b0000 0xd00>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_topc DOUT_ACLK_CCORE_133>;
+ clock-names = "fin_pll", "dout_aclk_ccore_133";
+ };
+
+ clock_peric0: clock-controller@13610000 {
+ compatible = "samsung,exynos7-clock-peric0";
+ reg = <0x13610000 0xd00>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_top0 DOUT_ACLK_PERIC0>,
+ <&clock_top0 CLK_SCLK_UART0>;
+ clock-names = "fin_pll", "dout_aclk_peric0_66",
+ "sclk_uart0";
+ };
+
+ clock_peric1: clock-controller@14c80000 {
+ compatible = "samsung,exynos7-clock-peric1";
+ reg = <0x14c80000 0xd00>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_top0 DOUT_ACLK_PERIC1>,
+ <&clock_top0 CLK_SCLK_UART1>,
+ <&clock_top0 CLK_SCLK_UART2>,
+ <&clock_top0 CLK_SCLK_UART3>;
+ clock-names = "fin_pll", "dout_aclk_peric1_66",
+ "sclk_uart1", "sclk_uart2", "sclk_uart3";
+ };
+
+ clock_peris: clock-controller@10040000 {
+ compatible = "samsung,exynos7-clock-peris";
+ reg = <0x10040000 0xd00>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_topc DOUT_ACLK_PERIS>;
+ clock-names = "fin_pll", "dout_aclk_peris_66";
+ };
+
+ clock_fsys0: clock-controller@10e90000 {
+ compatible = "samsung,exynos7-clock-fsys0";
+ reg = <0x10e90000 0xd00>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_top1 DOUT_ACLK_FSYS0_200>,
+ <&clock_top1 DOUT_SCLK_MMC2>;
+ clock-names = "fin_pll", "dout_aclk_fsys0_200",
+ "dout_sclk_mmc2";
+ };
+
+ clock_fsys1: clock-controller@156e0000 {
+ compatible = "samsung,exynos7-clock-fsys1";
+ reg = <0x156e0000 0xd00>;
+ #clock-cells = <1>;
+ clocks = <&fin_pll>, <&clock_top1 DOUT_ACLK_FSYS1_200>,
+ <&clock_top1 DOUT_SCLK_MMC0>,
+ <&clock_top1 DOUT_SCLK_MMC1>;
+ clock-names = "fin_pll", "dout_aclk_fsys1_200",
+ "dout_sclk_mmc0", "dout_sclk_mmc1";
+ };
+
+ serial_0: serial@13630000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x13630000 0x100>;
+ interrupts = <0 440 0>;
+ clocks = <&clock_peric0 PCLK_UART0>,
+ <&clock_peric0 SCLK_UART0>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_1: serial@14c20000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x14c20000 0x100>;
+ interrupts = <0 456 0>;
+ clocks = <&clock_peric1 PCLK_UART1>,
+ <&clock_peric1 SCLK_UART1>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_2: serial@14c30000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x14c30000 0x100>;
+ interrupts = <0 457 0>;
+ clocks = <&clock_peric1 PCLK_UART2>,
+ <&clock_peric1 SCLK_UART2>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ serial_3: serial@14c40000 {
+ compatible = "samsung,exynos4210-uart";
+ reg = <0x14c40000 0x100>;
+ interrupts = <0 458 0>;
+ clocks = <&clock_peric1 PCLK_UART3>,
+ <&clock_peric1 SCLK_UART3>;
+ clock-names = "uart", "clk_uart_baud0";
+ status = "disabled";
+ };
+
+ pinctrl_alive: pinctrl@10580000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x10580000 0x1000>;
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,exynos7-wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 16 0>;
+ };
+ };
+
+ pinctrl_bus0: pinctrl@13470000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x13470000 0x1000>;
+ interrupts = <0 383 0>;
+ };
+
+ pinctrl_nfc: pinctrl@14cd0000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x14cd0000 0x1000>;
+ interrupts = <0 473 0>;
+ };
+
+ pinctrl_touch: pinctrl@14ce0000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x14ce0000 0x1000>;
+ interrupts = <0 474 0>;
+ };
+
+ pinctrl_ff: pinctrl@14c90000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x14c90000 0x1000>;
+ interrupts = <0 475 0>;
+ };
+
+ pinctrl_ese: pinctrl@14ca0000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x14ca0000 0x1000>;
+ interrupts = <0 476 0>;
+ };
+
+ pinctrl_fsys0: pinctrl@10e60000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x10e60000 0x1000>;
+ interrupts = <0 221 0>;
+ };
+
+ pinctrl_fsys1: pinctrl@15690000 {
+ compatible = "samsung,exynos7-pinctrl";
+ reg = <0x15690000 0x1000>;
+ interrupts = <0 203 0>;
+ };
+
+ hsi2c_0: hsi2c@13640000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x13640000 0x1000>;
+ interrupts = <0 441 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c0_bus>;
+ clocks = <&clock_peric0 PCLK_HSI2C0>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_1: hsi2c@13650000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x13650000 0x1000>;
+ interrupts = <0 442 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c1_bus>;
+ clocks = <&clock_peric0 PCLK_HSI2C1>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_2: hsi2c@14e60000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e60000 0x1000>;
+ interrupts = <0 459 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c2_bus>;
+ clocks = <&clock_peric1 PCLK_HSI2C2>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_3: hsi2c@14e70000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e70000 0x1000>;
+ interrupts = <0 460 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c3_bus>;
+ clocks = <&clock_peric1 PCLK_HSI2C3>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_4: hsi2c@13660000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x13660000 0x1000>;
+ interrupts = <0 443 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c4_bus>;
+ clocks = <&clock_peric0 PCLK_HSI2C4>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_5: hsi2c@13670000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x13670000 0x1000>;
+ interrupts = <0 444 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c5_bus>;
+ clocks = <&clock_peric0 PCLK_HSI2C5>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_6: hsi2c@14e00000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e00000 0x1000>;
+ interrupts = <0 461 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c6_bus>;
+ clocks = <&clock_peric1 PCLK_HSI2C6>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_7: hsi2c@13e10000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x13e10000 0x1000>;
+ interrupts = <0 462 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c7_bus>;
+ clocks = <&clock_peric1 PCLK_HSI2C7>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_8: hsi2c@14e20000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x14e20000 0x1000>;
+ interrupts = <0 463 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c8_bus>;
+ clocks = <&clock_peric1 PCLK_HSI2C8>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_9: hsi2c@13680000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x13680000 0x1000>;
+ interrupts = <0 445 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c9_bus>;
+ clocks = <&clock_peric0 PCLK_HSI2C9>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_10: hsi2c@13690000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x13690000 0x1000>;
+ interrupts = <0 446 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c10_bus>;
+ clocks = <&clock_peric0 PCLK_HSI2C10>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ hsi2c_11: hsi2c@136a0000 {
+ compatible = "samsung,exynos7-hsi2c";
+ reg = <0x136a0000 0x1000>;
+ interrupts = <0 447 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hs_i2c11_bus>;
+ clocks = <&clock_peric0 PCLK_HSI2C11>;
+ clock-names = "hsi2c";
+ status = "disabled";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0xff01>,
+ <1 14 0xff01>,
+ <1 11 0xff01>,
+ <1 10 0xff01>;
+ };
+
+ pmu_system_controller: system-controller@105c0000 {
+ compatible = "samsung,exynos7-pmu", "syscon";
+ reg = <0x105c0000 0x5000>;
+ };
+
+ rtc: rtc@10590000 {
+ compatible = "samsung,s3c6410-rtc";
+ reg = <0x10590000 0x100>;
+ interrupts = <0 355 0>, <0 356 0>;
+ clocks = <&clock_ccore PCLK_RTC>;
+ clock-names = "rtc";
+ status = "disabled";
+ };
+
+ watchdog: watchdog@101d0000 {
+ compatible = "samsung,exynos7-wdt";
+ reg = <0x101d0000 0x100>;
+ interrupts = <0 110 0>;
+ clocks = <&clock_peris PCLK_WDT>;
+ clock-names = "watchdog";
+ samsung,syscon-phandle = <&pmu_system_controller>;
+ status = "disabled";
+ };
+
+ mmc_0: mmc@15740000 {
+ compatible = "samsung,exynos7-dw-mshc-smu";
+ interrupts = <0 201 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x15740000 0x2000>;
+ clocks = <&clock_fsys1 ACLK_MMC0>,
+ <&clock_top1 CLK_SCLK_MMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc_1: mmc@15750000 {
+ compatible = "samsung,exynos7-dw-mshc";
+ interrupts = <0 202 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x15750000 0x2000>;
+ clocks = <&clock_fsys1 ACLK_MMC1>,
+ <&clock_top1 CLK_SCLK_MMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ mmc_2: mmc@15560000 {
+ compatible = "samsung,exynos7-dw-mshc-smu";
+ interrupts = <0 216 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x15560000 0x2000>;
+ clocks = <&clock_fsys0 ACLK_MMC2>,
+ <&clock_top1 CLK_SCLK_MMC2>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x40>;
+ status = "disabled";
+ };
+
+ adc: adc@13620000 {
+ compatible = "samsung,exynos7-adc";
+ reg = <0x13620000 0x100>;
+ interrupts = <0 448 0>;
+ clocks = <&clock_peric0 PCLK_ADCIF>;
+ clock-names = "adc";
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+ status = "disabled";
+ };
+
+ pwm: pwm@136c0000 {
+ compatible = "samsung,exynos4210-pwm";
+ reg = <0x136c0000 0x100>;
+ samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+ #pwm-cells = <3>;
+ clocks = <&clock_peric0 PCLK_PWM>;
+ clock-names = "timers";
+ };
+ };
+};
+
+#include "exynos7-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
new file mode 100644
index 000000000000..4f2de3e789ee
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_FSL_LS2085A) += fsl-ls2085a-simu.dtb
+
+always := $(dtb-y)
+subdir-y := $(dts-dirs)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts b/arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts
new file mode 100644
index 000000000000..82e2a6fccc64
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2085a-simu.dts
@@ -0,0 +1,65 @@
+/*
+ * Device Tree file for Freescale LS2085a software Simulator model
+ *
+ * Copyright (C) 2014, Freescale Semiconductor
+ *
+ * Bhupesh Sharma <bhupesh.sharma@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+/include/ "fsl-ls2085a.dtsi"
+
+/ {
+ model = "Freescale Layerscape 2085a software Simulator model";
+ compatible = "fsl,ls2085a-simu", "fsl,ls2085a";
+
+ ethernet@2210000 {
+ compatible = "smsc,lan91c111";
+ reg = <0x0 0x2210000 0x0 0x100>;
+ interrupts = <0 58 0x1>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
new file mode 100644
index 000000000000..e281ceb338c3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls2085a.dtsi
@@ -0,0 +1,163 @@
+/*
+ * Device Tree Include file for Freescale Layerscape-2085A family SoC.
+ *
+ * Copyright (C) 2014, Freescale Semiconductor
+ *
+ * Bhupesh Sharma <bhupesh.sharma@freescale.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPLv2 or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+ compatible = "fsl,ls2085a";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ /*
+ * We expect the enable-method for cpu's to be "psci", but this
+ * is dependent on the SoC FW, which will fill this in.
+ *
+ * Currently supported enable-method is psci v0.2
+ */
+
+ /* We have 4 clusters having 2 Cortex-A57 cores each */
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x1>;
+ };
+
+ cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x100>;
+ };
+
+ cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x101>;
+ };
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x200>;
+ };
+
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x201>;
+ };
+
+ cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x300>;
+ };
+
+ cpu@301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x301>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000 0 0x80000000>;
+ /* DRAM space - 1, size : 2 GB DRAM */
+ };
+
+ gic: interrupt-controller@6000000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x06000000 0 0x10000>, /* GIC Dist */
+ <0x0 0x06100000 0 0x100000>; /* GICR (RD_base + SGI_base) */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <1 9 0x4>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
+ <1 14 0x8>, /* Physical Non-Secure PPI, active-low */
+ <1 11 0x8>, /* Virtual PPI, active-low */
+ <1 10 0x8>; /* Hypervisor PPI, active-low */
+ };
+
+ serial0: serial@21c0500 {
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21c0500 0x0 0x100>;
+ clock-frequency = <0>; /* Updated by bootloader */
+ interrupts = <0 32 0x1>; /* edge triggered */
+ };
+
+ serial1: serial@21c0600 {
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21c0600 0x0 0x100>;
+ clock-frequency = <0>; /* Updated by bootloader */
+ interrupts = <0 32 0x1>; /* edge triggered */
+ };
+
+ fsl_mc: fsl-mc@80c000000 {
+ compatible = "fsl,qoriq-mc";
+ reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
+ <0x00000000 0x08340000 0 0x40000>; /* MC control reg */
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
new file mode 100644
index 000000000000..3ce24622b231
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
+
+always := $(dtb-y)
+subdir-y := $(dts-dirs)
+clean-files := *.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
new file mode 100644
index 000000000000..43d54017b779
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Eddie Huang <eddie.huang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "mt8173.dtsi"
+
+/ {
+ model = "mediatek,mt8173-evb";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0 0x80000000>;
+ };
+
+ chosen { };
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
new file mode 100644
index 000000000000..8554ec31dd9e
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Eddie Huang <eddie.huang@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "mediatek,mt8173";
+ interrupt-parent = <&sysirq>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+ core1 {
+ cpu = <&cpu1>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&cpu2>;
+ };
+ core1 {
+ cpu = <&cpu3>;
+ };
+ };
+ };
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0x001>;
+ enable-method = "psci";
+ };
+
+ cpu2: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x100>;
+ enable-method = "psci";
+ };
+
+ cpu3: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x101>;
+ enable-method = "psci";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci";
+ method = "smc";
+ cpu_suspend = <0x84000001>;
+ cpu_off = <0x84000002>;
+ cpu_on = <0x84000003>;
+ };
+
+ uart_clk: dummy26m {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ #clock-cells = <0>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ sysirq: intpol-controller@10200620 {
+ compatible = "mediatek,mt8173-sysirq",
+ "mediatek,mt6577-sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0 0x10200620 0 0x20>;
+ };
+
+ gic: interrupt-controller@10220000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ interrupt-controller;
+ reg = <0 0x10221000 0 0x1000>,
+ <0 0x10222000 0 0x2000>,
+ <0 0x10224000 0 0x2000>,
+ <0 0x10226000 0 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ uart0: serial@11002000 {
+ compatible = "mediatek,mt8173-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11002000 0 0x400>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,mt8173-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11003000 0 0x400>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,mt8173-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11004000 0 0x400>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+
+ uart3: serial@11005000 {
+ compatible = "mediatek,mt8173-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11005000 0 0x400>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&uart_clk>;
+ status = "disabled";
+ };
+ };
+
+};
+
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 66b6cacc3251..be1f12a5a5f0 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -31,6 +31,8 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_FSL_LS2085A=y
+CONFIG_ARCH_MEDIATEK=y
CONFIG_ARCH_THUNDER=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_XGENE=y
@@ -88,6 +90,7 @@ CONFIG_SERIO_AMBAKMI=y
CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_MT6577=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 3bf8f4e99a51..07e1ba449bf1 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -63,7 +63,7 @@ static inline void set_fs(mm_segment_t fs)
current_thread_info()->addr_limit = fs;
}
-#define segment_eq(a,b) ((a) == (b))
+#define segment_eq(a, b) ((a) == (b))
/*
* Return 1 if addr < current->addr_limit, 0 otherwise.
@@ -147,7 +147,7 @@ do { \
default: \
BUILD_BUG(); \
} \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
} while (0)
#define __get_user(x, ptr) \
diff --git a/arch/avr32/include/asm/uaccess.h b/arch/avr32/include/asm/uaccess.h
index 245b2ee213c9..a46f7cf3e1ea 100644
--- a/arch/avr32/include/asm/uaccess.h
+++ b/arch/avr32/include/asm/uaccess.h
@@ -26,7 +26,7 @@ typedef struct {
* For historical reasons (Data Segment Register?), these macros are misnamed.
*/
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define segment_eq(a,b) ((a).is_user_space == (b).is_user_space)
+#define segment_eq(a, b) ((a).is_user_space == (b).is_user_space)
#define USER_ADDR_LIMIT 0x80000000
@@ -108,8 +108,8 @@ static inline __kernel_size_t __copy_from_user(void *to,
*
* Returns zero on success, or -EFAULT on error.
*/
-#define put_user(x,ptr) \
- __put_user_check((x),(ptr),sizeof(*(ptr)))
+#define put_user(x, ptr) \
+ __put_user_check((x), (ptr), sizeof(*(ptr)))
/*
* get_user: - Get a simple variable from user space.
@@ -128,8 +128,8 @@ static inline __kernel_size_t __copy_from_user(void *to,
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
-#define get_user(x,ptr) \
- __get_user_check((x),(ptr),sizeof(*(ptr)))
+#define get_user(x, ptr) \
+ __get_user_check((x), (ptr), sizeof(*(ptr)))
/*
* __put_user: - Write a simple value into user space, with less checking.
@@ -150,8 +150,8 @@ static inline __kernel_size_t __copy_from_user(void *to,
*
* Returns zero on success, or -EFAULT on error.
*/
-#define __put_user(x,ptr) \
- __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+ __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
/*
* __get_user: - Get a simple variable from user space, with less checking.
@@ -173,8 +173,8 @@ static inline __kernel_size_t __copy_from_user(void *to,
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
-#define __get_user(x,ptr) \
- __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user(x, ptr) \
+ __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
extern int __get_user_bad(void);
extern int __put_user_bad(void);
@@ -191,7 +191,7 @@ extern int __put_user_bad(void);
default: __gu_err = __get_user_bad(); break; \
} \
\
- x = (typeof(*(ptr)))__gu_val; \
+ x = (__force typeof(*(ptr)))__gu_val; \
__gu_err; \
})
@@ -222,7 +222,7 @@ extern int __put_user_bad(void);
} else { \
__gu_err = -EFAULT; \
} \
- x = (typeof(*(ptr)))__gu_val; \
+ x = (__force typeof(*(ptr)))__gu_val; \
__gu_err; \
})
@@ -278,7 +278,7 @@ extern int __put_user_bad(void);
__pu_err); \
break; \
case 8: \
- __put_user_asm("d", __pu_addr, __pu_val, \
+ __put_user_asm("d", __pu_addr, __pu_val, \
__pu_err); \
break; \
default: \
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index cc92cdb9994c..1d8b147282cf 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -607,7 +607,7 @@ static struct dw_dma_platform_data dw_dmac0_data = {
.nr_channels = 3,
.block_size = 4095U,
.nr_masters = 2,
- .data_width = { 2, 2, 0, 0 },
+ .data_width = { 2, 2 },
};
static struct resource dw_dmac0_resource[] = {
diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h
index 57701c3b8a59..90612a7f2cf3 100644
--- a/arch/blackfin/include/asm/uaccess.h
+++ b/arch/blackfin/include/asm/uaccess.h
@@ -27,7 +27,7 @@ static inline void set_fs(mm_segment_t fs)
current_thread_info()->addr_limit = fs;
}
-#define segment_eq(a,b) ((a) == (b))
+#define segment_eq(a, b) ((a) == (b))
#define VERIFY_READ 0
#define VERIFY_WRITE 1
@@ -68,11 +68,11 @@ struct exception_table_entry {
* use the right size if we just have the right pointer type.
*/
-#define put_user(x,p) \
+#define put_user(x, p) \
({ \
int _err = 0; \
typeof(*(p)) _x = (x); \
- typeof(*(p)) __user *_p = (p); \
+ typeof(*(p)) __user *_p = (p); \
if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\
_err = -EFAULT; \
} \
@@ -89,10 +89,10 @@ struct exception_table_entry {
break; \
case 8: { \
long _xl, _xh; \
- _xl = ((long *)&_x)[0]; \
- _xh = ((long *)&_x)[1]; \
- __put_user_asm(_xl, ((long __user *)_p)+0, ); \
- __put_user_asm(_xh, ((long __user *)_p)+1, ); \
+ _xl = ((__force long *)&_x)[0]; \
+ _xh = ((__force long *)&_x)[1]; \
+ __put_user_asm(_xl, ((__force long __user *)_p)+0, );\
+ __put_user_asm(_xh, ((__force long __user *)_p)+1, );\
} break; \
default: \
_err = __put_user_bad(); \
@@ -102,7 +102,7 @@ struct exception_table_entry {
_err; \
})
-#define __put_user(x,p) put_user(x,p)
+#define __put_user(x, p) put_user(x, p)
static inline int bad_user_access_length(void)
{
panic("bad_user_access_length");
@@ -121,10 +121,10 @@ static inline int bad_user_access_length(void)
#define __ptr(x) ((unsigned long __force *)(x))
-#define __put_user_asm(x,p,bhw) \
+#define __put_user_asm(x, p, bhw) \
__asm__ (#bhw"[%1] = %0;\n\t" \
: /* no outputs */ \
- :"d" (x),"a" (__ptr(p)) : "memory")
+ :"d" (x), "a" (__ptr(p)) : "memory")
#define get_user(x, ptr) \
({ \
@@ -136,10 +136,10 @@ static inline int bad_user_access_length(void)
BUILD_BUG_ON(ptr_size >= 8); \
switch (ptr_size) { \
case 1: \
- __get_user_asm(_val, _p, B,(Z)); \
+ __get_user_asm(_val, _p, B, (Z)); \
break; \
case 2: \
- __get_user_asm(_val, _p, W,(Z)); \
+ __get_user_asm(_val, _p, W, (Z)); \
break; \
case 4: \
__get_user_asm(_val, _p, , ); \
@@ -147,11 +147,11 @@ static inline int bad_user_access_length(void)
} \
} else \
_err = -EFAULT; \
- x = (typeof(*(ptr)))_val; \
+ x = (__force typeof(*(ptr)))_val; \
_err; \
})
-#define __get_user(x,p) get_user(x,p)
+#define __get_user(x, p) get_user(x, p)
#define __get_user_bad() (bad_user_access_length(), (-EFAULT))
@@ -168,10 +168,10 @@ static inline int bad_user_access_length(void)
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
-#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n))\
+#define copy_to_user_ret(to, from, n, retval) ({ if (copy_to_user(to, from, n))\
return retval; })
-#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n))\
+#define copy_from_user_ret(to, from, n, retval) ({ if (copy_from_user(to, from, n))\
return retval; })
static inline unsigned long __must_check
diff --git a/arch/frv/include/asm/segment.h b/arch/frv/include/asm/segment.h
index a2320a4a0042..4377c89a57f5 100644
--- a/arch/frv/include/asm/segment.h
+++ b/arch/frv/include/asm/segment.h
@@ -31,7 +31,7 @@ typedef struct {
#define get_ds() (KERNEL_DS)
#define get_fs() (__current_thread_info->addr_limit)
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
#define __kernel_ds_p() segment_eq(get_fs(), KERNEL_DS)
#define get_addr_limit() (get_fs().seg)
diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h
index 103bedc59644..4f3fb6ccbf21 100644
--- a/arch/ia64/include/asm/uaccess.h
+++ b/arch/ia64/include/asm/uaccess.h
@@ -169,10 +169,11 @@ do { \
(err) = ia64_getreg(_IA64_REG_R8); \
(val) = ia64_getreg(_IA64_REG_R9); \
} while (0)
-# define __put_user_size(val, addr, n, err) \
-do { \
- __st_user("__ex_table", (unsigned long) addr, n, RELOC_TYPE, (unsigned long) (val)); \
- (err) = ia64_getreg(_IA64_REG_R8); \
+# define __put_user_size(val, addr, n, err) \
+do { \
+ __st_user("__ex_table", (unsigned long) addr, n, RELOC_TYPE, \
+ (__force unsigned long) (val)); \
+ (err) = ia64_getreg(_IA64_REG_R8); \
} while (0)
#endif /* !ASM_SUPPORTED */
@@ -197,7 +198,7 @@ extern void __get_user_unknown (void);
case 8: __get_user_size(__gu_val, __gu_ptr, 8, __gu_err); break; \
default: __get_user_unknown(); break; \
} \
- (x) = (__typeof__(*(__gu_ptr))) __gu_val; \
+ (x) = (__force __typeof__(*(__gu_ptr))) __gu_val; \
__gu_err; \
})
diff --git a/arch/m32r/include/asm/uaccess.h b/arch/m32r/include/asm/uaccess.h
index 84fe7ba53035..71adff209405 100644
--- a/arch/m32r/include/asm/uaccess.h
+++ b/arch/m32r/include/asm/uaccess.h
@@ -54,7 +54,7 @@ static inline void set_fs(mm_segment_t s)
#endif /* not CONFIG_MMU */
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
#define __addr_ok(addr) \
((unsigned long)(addr) < (current_thread_info()->addr_limit.seg))
@@ -68,7 +68,7 @@ static inline void set_fs(mm_segment_t s)
*
* This needs 33-bit arithmetic. We have a carry...
*/
-#define __range_ok(addr,size) ({ \
+#define __range_ok(addr, size) ({ \
unsigned long flag, roksum; \
__chk_user_ptr(addr); \
asm ( \
@@ -103,7 +103,7 @@ static inline void set_fs(mm_segment_t s)
* this function, memory access functions may still return -EFAULT.
*/
#ifdef CONFIG_MMU
-#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
+#define access_ok(type, addr, size) (likely(__range_ok(addr, size) == 0))
#else
static inline int access_ok(int type, const void *addr, unsigned long size)
{
@@ -167,8 +167,8 @@ extern int fixup_exception(struct pt_regs *regs);
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
-#define get_user(x,ptr) \
- __get_user_check((x),(ptr),sizeof(*(ptr)))
+#define get_user(x, ptr) \
+ __get_user_check((x), (ptr), sizeof(*(ptr)))
/**
* put_user: - Write a simple value into user space.
@@ -186,8 +186,8 @@ extern int fixup_exception(struct pt_regs *regs);
*
* Returns zero on success, or -EFAULT on error.
*/
-#define put_user(x,ptr) \
- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define put_user(x, ptr) \
+ __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
/**
* __get_user: - Get a simple variable from user space, with less checking.
@@ -209,41 +209,41 @@ extern int fixup_exception(struct pt_regs *regs);
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
-#define __get_user(x,ptr) \
- __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user(x, ptr) \
+ __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
-#define __get_user_nocheck(x,ptr,size) \
+#define __get_user_nocheck(x, ptr, size) \
({ \
long __gu_err = 0; \
unsigned long __gu_val; \
might_fault(); \
- __get_user_size(__gu_val,(ptr),(size),__gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ __get_user_size(__gu_val, (ptr), (size), __gu_err); \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
-#define __get_user_check(x,ptr,size) \
+#define __get_user_check(x, ptr, size) \
({ \
long __gu_err = -EFAULT; \
unsigned long __gu_val = 0; \
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
might_fault(); \
- if (access_ok(VERIFY_READ,__gu_addr,size)) \
- __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ if (access_ok(VERIFY_READ, __gu_addr, size)) \
+ __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
extern long __get_user_bad(void);
-#define __get_user_size(x,ptr,size,retval) \
+#define __get_user_size(x, ptr, size, retval) \
do { \
retval = 0; \
__chk_user_ptr(ptr); \
switch (size) { \
- case 1: __get_user_asm(x,ptr,retval,"ub"); break; \
- case 2: __get_user_asm(x,ptr,retval,"uh"); break; \
- case 4: __get_user_asm(x,ptr,retval,""); break; \
+ case 1: __get_user_asm(x, ptr, retval, "ub"); break; \
+ case 2: __get_user_asm(x, ptr, retval, "uh"); break; \
+ case 4: __get_user_asm(x, ptr, retval, ""); break; \
default: (x) = __get_user_bad(); \
} \
} while (0)
@@ -288,26 +288,26 @@ do { \
*
* Returns zero on success, or -EFAULT on error.
*/
-#define __put_user(x,ptr) \
- __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+ __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
-#define __put_user_nocheck(x,ptr,size) \
+#define __put_user_nocheck(x, ptr, size) \
({ \
long __pu_err; \
might_fault(); \
- __put_user_size((x),(ptr),(size),__pu_err); \
+ __put_user_size((x), (ptr), (size), __pu_err); \
__pu_err; \
})
-#define __put_user_check(x,ptr,size) \
+#define __put_user_check(x, ptr, size) \
({ \
long __pu_err = -EFAULT; \
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
might_fault(); \
- if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
- __put_user_size((x),__pu_addr,(size),__pu_err); \
+ if (access_ok(VERIFY_WRITE, __pu_addr, size)) \
+ __put_user_size((x), __pu_addr, (size), __pu_err); \
__pu_err; \
})
@@ -366,15 +366,15 @@ do { \
extern void __put_user_bad(void);
-#define __put_user_size(x,ptr,size,retval) \
+#define __put_user_size(x, ptr, size, retval) \
do { \
retval = 0; \
__chk_user_ptr(ptr); \
switch (size) { \
- case 1: __put_user_asm(x,ptr,retval,"b"); break; \
- case 2: __put_user_asm(x,ptr,retval,"h"); break; \
- case 4: __put_user_asm(x,ptr,retval,""); break; \
- case 8: __put_user_u64((__typeof__(*ptr))(x),ptr,retval); break;\
+ case 1: __put_user_asm(x, ptr, retval, "b"); break; \
+ case 2: __put_user_asm(x, ptr, retval, "h"); break; \
+ case 4: __put_user_asm(x, ptr, retval, ""); break; \
+ case 8: __put_user_u64((__typeof__(*ptr))(x), ptr, retval); break;\
default: __put_user_bad(); \
} \
} while (0)
@@ -421,7 +421,7 @@ struct __large_struct { unsigned long buf[100]; };
/* Generic arbitrary sized copy. */
/* Return the number of bytes NOT copied. */
-#define __copy_user(to,from,size) \
+#define __copy_user(to, from, size) \
do { \
unsigned long __dst, __src, __c; \
__asm__ __volatile__ ( \
@@ -478,7 +478,7 @@ do { \
: "r14", "memory"); \
} while (0)
-#define __copy_user_zeroing(to,from,size) \
+#define __copy_user_zeroing(to, from, size) \
do { \
unsigned long __dst, __src, __c; \
__asm__ __volatile__ ( \
@@ -548,14 +548,14 @@ do { \
static inline unsigned long __generic_copy_from_user_nocheck(void *to,
const void __user *from, unsigned long n)
{
- __copy_user_zeroing(to,from,n);
+ __copy_user_zeroing(to, from, n);
return n;
}
static inline unsigned long __generic_copy_to_user_nocheck(void __user *to,
const void *from, unsigned long n)
{
- __copy_user(to,from,n);
+ __copy_user(to, from, n);
return n;
}
@@ -576,8 +576,8 @@ unsigned long __generic_copy_from_user(void *, const void __user *, unsigned lon
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*/
-#define __copy_to_user(to,from,n) \
- __generic_copy_to_user_nocheck((to),(from),(n))
+#define __copy_to_user(to, from, n) \
+ __generic_copy_to_user_nocheck((to), (from), (n))
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
@@ -595,10 +595,10 @@ unsigned long __generic_copy_from_user(void *, const void __user *, unsigned lon
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*/
-#define copy_to_user(to,from,n) \
+#define copy_to_user(to, from, n) \
({ \
might_fault(); \
- __generic_copy_to_user((to),(from),(n)); \
+ __generic_copy_to_user((to), (from), (n)); \
})
/**
@@ -617,8 +617,8 @@ unsigned long __generic_copy_from_user(void *, const void __user *, unsigned lon
* If some data could not be copied, this function will pad the copied
* data to the requested size using zero bytes.
*/
-#define __copy_from_user(to,from,n) \
- __generic_copy_from_user_nocheck((to),(from),(n))
+#define __copy_from_user(to, from, n) \
+ __generic_copy_from_user_nocheck((to), (from), (n))
/**
* copy_from_user: - Copy a block of data from user space.
@@ -636,10 +636,10 @@ unsigned long __generic_copy_from_user(void *, const void __user *, unsigned lon
* If some data could not be copied, this function will pad the copied
* data to the requested size using zero bytes.
*/
-#define copy_from_user(to,from,n) \
+#define copy_from_user(to, from, n) \
({ \
might_fault(); \
- __generic_copy_from_user((to),(from),(n)); \
+ __generic_copy_from_user((to), (from), (n)); \
})
long __must_check strncpy_from_user(char *dst, const char __user *src,
diff --git a/arch/m68k/68360/commproc.c b/arch/m68k/68360/commproc.c
index 315727b7ff40..14d7f35cd37b 100644
--- a/arch/m68k/68360/commproc.c
+++ b/arch/m68k/68360/commproc.c
@@ -64,15 +64,15 @@ QUICC *pquicc;
/* CPM interrupt vector functions. */
struct cpm_action {
- void (*handler)(void *);
- void *dev_id;
+ irq_handler_t handler;
+ void *dev_id;
};
static struct cpm_action cpm_vecs[CPMVEC_NR];
static void cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
static void cpm_error_interrupt(void *);
/* prototypes: */
-void cpm_install_handler(int vec, void (*handler)(), void *dev_id);
+void cpm_install_handler(int vec, irq_handler_t handler, void *dev_id);
void m360_cpm_reset(void);
@@ -208,7 +208,7 @@ cpm_error_interrupt(void *dev)
/* Install a CPM interrupt handler.
*/
void
-cpm_install_handler(int vec, void (*handler)(), void *dev_id)
+cpm_install_handler(int vec, irq_handler_t handler, void *dev_id)
{
request_irq(vec, handler, 0, "timer", dev_id);
diff --git a/arch/m68k/68360/config.c b/arch/m68k/68360/config.c
index 17ec416fed9d..fd1f948c7129 100644
--- a/arch/m68k/68360/config.c
+++ b/arch/m68k/68360/config.c
@@ -106,19 +106,6 @@ void hw_timer_init(irq_handler_t handler)
pquicc->timer_tgcr = tgcr_save;
}
-int BSP_set_clock_mmss(unsigned long nowtime)
-{
-#if 0
- short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
-
- tod->second1 = real_seconds / 10;
- tod->second2 = real_seconds % 10;
- tod->minute1 = real_minutes / 10;
- tod->minute2 = real_minutes % 10;
-#endif
- return 0;
-}
-
void BSP_reset (void)
{
local_irq_disable();
diff --git a/arch/m68k/include/asm/commproc.h b/arch/m68k/include/asm/commproc.h
index 66a36bd51aa1..f41c96863e98 100644
--- a/arch/m68k/include/asm/commproc.h
+++ b/arch/m68k/include/asm/commproc.h
@@ -480,28 +480,6 @@ typedef struct scc_enet {
#define SICR_ENET_CLKRT ((uint)0x0000003d)
#endif
-#ifdef CONFIG_BSEIP
-/* This ENET stuff is for the MPC823 with ethernet on SCC2.
- * This is unique to the BSE ip-Engine board.
- */
-#define PA_ENET_RXD ((ushort)0x0004)
-#define PA_ENET_TXD ((ushort)0x0008)
-#define PA_ENET_TCLK ((ushort)0x0100)
-#define PA_ENET_RCLK ((ushort)0x0200)
-#define PB_ENET_TENA ((uint)0x00002000)
-#define PC_ENET_CLSN ((ushort)0x0040)
-#define PC_ENET_RENA ((ushort)0x0080)
-
-/* BSE uses port B and C bits for PHY control also.
-*/
-#define PB_BSE_POWERUP ((uint)0x00000004)
-#define PB_BSE_FDXDIS ((uint)0x00008000)
-#define PC_BSE_LOOPBACK ((ushort)0x0800)
-
-#define SICR_ENET_MASK ((uint)0x0000ff00)
-#define SICR_ENET_CLKRT ((uint)0x00002c00)
-#endif
-
/* SCC Event register as used by Ethernet.
*/
#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */
@@ -671,7 +649,7 @@ typedef struct scc_trans {
/* #define CPMVEC_PIO_PC4 ((ushort)0x01) */
/* #define CPMVEC_ERROR ((ushort)0x00) */
-extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
+extern void cpm_install_handler(int vec, irq_handler_t handler, void *dev_id);
/* CPM interrupt configuration vector.
*/
diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h
index 0fa80e97ed2d..98216b8111f0 100644
--- a/arch/m68k/include/asm/segment.h
+++ b/arch/m68k/include/asm/segment.h
@@ -58,7 +58,7 @@ static inline mm_segment_t get_ds(void)
#define set_fs(x) (current_thread_info()->addr_limit = (x))
#endif
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
#endif /* __ASSEMBLY__ */
diff --git a/arch/m68k/include/asm/uaccess_mm.h b/arch/m68k/include/asm/uaccess_mm.h
index 15901db435b9..d228601b3afc 100644
--- a/arch/m68k/include/asm/uaccess_mm.h
+++ b/arch/m68k/include/asm/uaccess_mm.h
@@ -128,25 +128,25 @@ asm volatile ("\n" \
#define put_user(x, ptr) __put_user(x, ptr)
-#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \
- type __gu_val; \
- asm volatile ("\n" \
- "1: "MOVES"."#bwl" %2,%1\n" \
- "2:\n" \
- " .section .fixup,\"ax\"\n" \
- " .even\n" \
- "10: move.l %3,%0\n" \
- " sub.l %1,%1\n" \
- " jra 2b\n" \
- " .previous\n" \
- "\n" \
- " .section __ex_table,\"a\"\n" \
- " .align 4\n" \
- " .long 1b,10b\n" \
- " .previous" \
- : "+d" (res), "=&" #reg (__gu_val) \
- : "m" (*(ptr)), "i" (err)); \
- (x) = (typeof(*(ptr)))(unsigned long)__gu_val; \
+#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \
+ type __gu_val; \
+ asm volatile ("\n" \
+ "1: "MOVES"."#bwl" %2,%1\n" \
+ "2:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .even\n" \
+ "10: move.l %3,%0\n" \
+ " sub.l %1,%1\n" \
+ " jra 2b\n" \
+ " .previous\n" \
+ "\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 4\n" \
+ " .long 1b,10b\n" \
+ " .previous" \
+ : "+d" (res), "=&" #reg (__gu_val) \
+ : "m" (*(ptr)), "i" (err)); \
+ (x) = (__force typeof(*(ptr)))(__force unsigned long)__gu_val; \
})
#define __get_user(x, ptr) \
@@ -188,7 +188,7 @@ asm volatile ("\n" \
"+a" (__gu_ptr) \
: "i" (-EFAULT) \
: "memory"); \
- (x) = (typeof(*(ptr)))__gu_val; \
+ (x) = (__force typeof(*(ptr)))__gu_val; \
break; \
} */ \
default: \
diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h
index 0748b0a97986..8282cbce7e39 100644
--- a/arch/metag/include/asm/uaccess.h
+++ b/arch/metag/include/asm/uaccess.h
@@ -107,18 +107,23 @@ extern long __put_user_asm_w(unsigned int x, void __user *addr);
extern long __put_user_asm_d(unsigned int x, void __user *addr);
extern long __put_user_asm_l(unsigned long long x, void __user *addr);
-#define __put_user_size(x, ptr, size, retval) \
-do { \
- retval = 0; \
- switch (size) { \
+#define __put_user_size(x, ptr, size, retval) \
+do { \
+ retval = 0; \
+ switch (size) { \
case 1: \
- retval = __put_user_asm_b((unsigned int)x, ptr); break; \
+ retval = __put_user_asm_b((__force unsigned int)x, ptr);\
+ break; \
case 2: \
- retval = __put_user_asm_w((unsigned int)x, ptr); break; \
+ retval = __put_user_asm_w((__force unsigned int)x, ptr);\
+ break; \
case 4: \
- retval = __put_user_asm_d((unsigned int)x, ptr); break; \
+ retval = __put_user_asm_d((__force unsigned int)x, ptr);\
+ break; \
case 8: \
- retval = __put_user_asm_l((unsigned long long)x, ptr); break; \
+ retval = __put_user_asm_l((__force unsigned long long)x,\
+ ptr); \
+ break; \
default: \
__put_user_bad(); \
} \
@@ -135,7 +140,7 @@ extern long __get_user_bad(void);
({ \
long __gu_err, __gu_val; \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
@@ -145,7 +150,7 @@ extern long __get_user_bad(void);
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
if (access_ok(VERIFY_READ, __gu_addr, size)) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
index 986982db7c38..79cff26d8b36 100644
--- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
@@ -27,8 +27,6 @@ struct jz_nand_platform_data {
struct nand_ecclayout *ecc_layout;
- unsigned int busy_gpio;
-
unsigned char banks[JZ_NAND_NUM_BANKS];
void (*ident_callback)(struct platform_device *, struct nand_chip *,
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index c454525e7695..9dd051edb411 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -140,10 +140,18 @@ static void qi_lb60_nand_ident(struct platform_device *pdev,
static struct jz_nand_platform_data qi_lb60_nand_pdata = {
.ident_callback = qi_lb60_nand_ident,
- .busy_gpio = 94,
.banks = { 1 },
};
+static struct gpiod_lookup_table qi_lb60_nand_gpio_table = {
+ .dev_id = "jz4740-nand.0",
+ .table = {
+ GPIO_LOOKUP("Bank C", 30, "busy", 0),
+ { },
+ },
+};
+
+
/* Keyboard*/
#define KEY_QI_QI KEY_F13
@@ -472,6 +480,7 @@ static int __init qi_lb60_init_platform_devices(void)
jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata;
gpiod_add_lookup_table(&qi_lb60_audio_gpio_table);
+ gpiod_add_lookup_table(&qi_lb60_nand_gpio_table);
jz4740_serial_device_register();
diff --git a/arch/mn10300/unit-asb2305/pci-iomap.c b/arch/mn10300/unit-asb2305/pci-iomap.c
deleted file mode 100644
index bd65dae17f32..000000000000
--- a/arch/mn10300/unit-asb2305/pci-iomap.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ASB2305 PCI I/O mapping handler
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/pci.h>
-#include <linux/module.h>
-
-/*
- * Create a virtual mapping cookie for a PCI BAR (memory or IO)
- */
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
-{
- resource_size_t start = pci_resource_start(dev, bar);
- resource_size_t len = pci_resource_len(dev, bar);
- unsigned long flags = pci_resource_flags(dev, bar);
-
- if (!len || !start)
- return NULL;
-
- if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM)) {
- if (flags & IORESOURCE_CACHEABLE && !(flags & IORESOURCE_IO))
- return ioremap(start, len);
- else
- return ioremap_nocache(start, len);
- }
-
- return NULL;
-}
-EXPORT_SYMBOL(pci_iomap);
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 2361acf6d2b1..437555424bda 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -8,6 +8,7 @@ config NIOS2
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select HAVE_ARCH_TRACEHOOK
+ select HAVE_ARCH_KGDB
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select OF
@@ -134,6 +135,14 @@ config NIOS2_PASS_CMDLINE
will override "Default kernel command string".
Say N if you are unsure.
+config NIOS2_BOOT_LINK_OFFSET
+ hex "Link address offset for booting"
+ default "0x00500000"
+ help
+ This option allows you to set the link address offset of the zImage.
+ This can be useful if you are on a board which has a small amount of
+ memory.
+
endmenu
menu "Advanced setup"
diff --git a/arch/nios2/Kconfig.debug b/arch/nios2/Kconfig.debug
index 8d4e6bacd997..2fd08cbfdddb 100644
--- a/arch/nios2/Kconfig.debug
+++ b/arch/nios2/Kconfig.debug
@@ -14,4 +14,15 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat.
+config EARLY_PRINTK
+ bool "Activate early kernel debugging"
+ default y
+ select SERIAL_CORE_CONSOLE
+ depends on SERIAL_ALTERA_JTAGUART_CONSOLE || SERIAL_ALTERA_UART_CONSOLE
+ help
+ Enable early printk on console
+ This is useful for kernel debugging when your machine crashes very
+ early before the console code is initialized.
+ You should normally say N here, unless you want to debug such a crash.
+
endmenu
diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile
index 59392dc0bdcb..c899876320df 100644
--- a/arch/nios2/boot/Makefile
+++ b/arch/nios2/boot/Makefile
@@ -24,6 +24,13 @@ $(obj)/vmImage: $(obj)/vmlinux.gz
$(call if_changed,uimage)
@$(kecho) 'Kernel: $@ is ready'
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @$(kecho) 'Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
# Rule to build device tree blobs
DTB_SRC := $(patsubst "%",%,$(CONFIG_NIOS2_DTB_SOURCE))
diff --git a/arch/nios2/boot/compressed/Makefile b/arch/nios2/boot/compressed/Makefile
new file mode 100644
index 000000000000..5b0fb346d888
--- /dev/null
+++ b/arch/nios2/boot/compressed/Makefile
@@ -0,0 +1,19 @@
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets := vmlinux head.o misc.o piggy.o vmlinux.lds
+asflags-y :=
+
+OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+LDFLAGS_vmlinux := -T
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
+ $(call if_changed,ld)
+ @:
+
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/../vmlinux.gz FORCE
+ $(call if_changed,ld)
diff --git a/arch/nios2/boot/compressed/console.c b/arch/nios2/boot/compressed/console.c
new file mode 100644
index 000000000000..2675e879b85a
--- /dev/null
+++ b/arch/nios2/boot/compressed/console.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008-2010 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/io.h>
+
+#if (defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE))\
+ || (defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE))
+static void *my_ioremap(unsigned long physaddr)
+{
+ return (void *)(physaddr | CONFIG_NIOS2_IO_REGION_BASE);
+}
+#endif
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE)
+
+#define ALTERA_JTAGUART_SIZE 8
+#define ALTERA_JTAGUART_DATA_REG 0
+#define ALTERA_JTAGUART_CONTROL_REG 4
+#define ALTERA_JTAGUART_CONTROL_AC_MSK (0x00000400)
+#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK (0xFFFF0000)
+static void *uartbase;
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
+static void jtag_putc(int ch)
+{
+ if (readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
+ ALTERA_JTAGUART_CONTROL_WSPACE_MSK)
+ writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
+}
+#else
+static void jtag_putc(int ch)
+{
+ while ((readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
+ ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0)
+ ;
+ writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
+}
+#endif
+
+static int putchar(int ch)
+{
+ jtag_putc(ch);
+ return ch;
+}
+
+static void console_init(void)
+{
+ uartbase = my_ioremap((unsigned long) JTAG_UART_BASE);
+ writel(ALTERA_JTAGUART_CONTROL_AC_MSK,
+ uartbase + ALTERA_JTAGUART_CONTROL_REG);
+}
+
+#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE)
+
+#define ALTERA_UART_SIZE 32
+#define ALTERA_UART_TXDATA_REG 4
+#define ALTERA_UART_STATUS_REG 8
+#define ALTERA_UART_DIVISOR_REG 16
+#define ALTERA_UART_STATUS_TRDY_MSK (0x40)
+static unsigned uartbase;
+
+static void uart_putc(int ch)
+{
+ int i;
+
+ for (i = 0; (i < 0x10000); i++) {
+ if (readw(uartbase + ALTERA_UART_STATUS_REG) &
+ ALTERA_UART_STATUS_TRDY_MSK)
+ break;
+ }
+ writeb(ch, uartbase + ALTERA_UART_TXDATA_REG);
+}
+
+static int putchar(int ch)
+{
+ uart_putc(ch);
+ if (ch == '\n')
+ uart_putc('\r');
+ return ch;
+}
+
+static void console_init(void)
+{
+ unsigned int baud, baudclk;
+
+ uartbase = (unsigned long) my_ioremap((unsigned long) UART0_BASE);
+ baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
+ baudclk = UART0_FREQ / baud;
+ writew(baudclk, uartbase + ALTERA_UART_DIVISOR_REG);
+}
+
+#else
+
+static int putchar(int ch)
+{
+ return ch;
+}
+
+static void console_init(void)
+{
+}
+
+#endif
+
+static int puts(const char *s)
+{
+ while (*s)
+ putchar(*s++);
+ return 0;
+}
diff --git a/arch/nios2/boot/compressed/head.S b/arch/nios2/boot/compressed/head.S
new file mode 100644
index 000000000000..15c6c48dd909
--- /dev/null
+++ b/arch/nios2/boot/compressed/head.S
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * Based on arch/nios2/kernel/head.S
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+/*
+ * This code can be loaded anywhere, eg FLASH ROM as reset vector,
+ * as long as output does not overlap it.
+ */
+
+#include <linux/linkage.h>
+#include <asm/cache.h>
+
+ .text
+ .set noat
+ENTRY(_start)
+ wrctl status, r0 /* disable interrupt */
+ /* invalidate all instruction cache */
+ movia r1, NIOS2_ICACHE_SIZE
+ movui r2, NIOS2_ICACHE_LINE_SIZE
+1: initi r1
+ sub r1, r1, r2
+ bgt r1, r0, 1b
+ /* invalidate all data cache */
+ movia r1, NIOS2_DCACHE_SIZE
+ movui r2, NIOS2_DCACHE_LINE_SIZE
+1: initd 0(r1)
+ sub r1, r1, r2
+ bgt r1, r0, 1b
+
+ nextpc r1 /* Find out where we are */
+chkadr:
+ movia r2, chkadr
+ beq r1, r2, finish_move /* We are running in correct address,
+ done */
+ /* move code, r1: src, r2: dest, r3: last dest */
+ addi r1, r1, (_start - chkadr) /* Source */
+ movia r2, _start /* Destination */
+ movia r3, __bss_start /* End of copy */
+1: ldw r8, 0(r1) /* load a word from [r1] */
+ stw r8, 0(r2) /* stort a word to dest [r2] */
+ addi r1, r1, 4 /* inc the src addr */
+ addi r2, r2, 4 /* inc the dest addr */
+ blt r2, r3, 1b
+ /* flush the data cache after moving */
+ movia r1, NIOS2_DCACHE_SIZE
+ movui r2, NIOS2_DCACHE_LINE_SIZE
+1: flushd 0(r1)
+ sub r1, r1, r2
+ bgt r1, r0, 1b
+ movia r1, finish_move
+ jmp r1 /* jmp to linked address */
+
+finish_move:
+ /* zero out the .bss segment (uninitialized common data) */
+ movia r2, __bss_start /* presume nothing is between */
+ movia r1, _end /* the .bss and _end. */
+1: stb r0, 0(r2)
+ addi r2, r2, 1
+ bne r1, r2, 1b
+ /*
+ * set up the stack pointer, some where higher than _end.
+ * The stack space must be greater than 32K for decompress.
+ */
+ movia sp, 0x10000
+ add sp, sp, r1
+ /* save args passed from u-boot, maybe */
+ addi sp, sp, -16
+ stw r4, 0(sp)
+ stw r5, 4(sp)
+ stw r6, 8(sp)
+ stw r7, 12(sp)
+ /* decompress the kernel */
+ call decompress_kernel
+ /* pass saved args to kernel */
+ ldw r4, 0(sp)
+ ldw r5, 4(sp)
+ ldw r6, 8(sp)
+ ldw r7, 12(sp)
+
+ /* flush all data cache after decompressing */
+ movia r1, NIOS2_DCACHE_SIZE
+ movui r2, NIOS2_DCACHE_LINE_SIZE
+1: flushd 0(r1)
+ sub r1, r1, r2
+ bgt r1, r0, 1b
+ /* flush all instruction cache */
+ movia r1, NIOS2_ICACHE_SIZE
+ movui r2, NIOS2_ICACHE_LINE_SIZE
+1: flushi r1
+ sub r1, r1, r2
+ bgt r1, r0, 1b
+ flushp
+ /* jump to start real kernel */
+ movia r1, (CONFIG_NIOS2_MEM_BASE | CONFIG_NIOS2_KERNEL_REGION_BASE)
+ jmp r1
+
+ .balign 512
+fake_headers_as_bzImage:
+ .short 0
+ .ascii "HdrS"
+ .short 0x0202
+ .short 0
+ .short 0
+ .byte 0x00, 0x10
+ .short 0
+ .byte 0
+ .byte 1
+ .byte 0x00, 0x80
+ .long 0
+ .long 0
diff --git a/arch/nios2/boot/compressed/misc.c b/arch/nios2/boot/compressed/misc.c
new file mode 100644
index 000000000000..84377825ef1a
--- /dev/null
+++ b/arch/nios2/boot/compressed/misc.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ *
+ * Based on arch/sh/boot/compressed/misc.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/string.h>
+
+/*
+ * gzip declarations
+ */
+#define OF(args) args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+#define WSIZE 0x8000 /* Window size must be at least 32k, */
+ /* and a power of two */
+
+static uch *inbuf; /* input buffer */
+static uch window[WSIZE]; /* Sliding window buffer */
+
+static unsigned insize; /* valid bytes in inbuf */
+static unsigned inptr; /* index of next byte to be processed in inbuf */
+static unsigned outcnt; /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip
+ file */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
+#define RESERVED 0xC0 /* bit 6,7: reserved */
+
+#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+#ifdef DEBUG
+# define Assert(cond, msg) {if (!(cond)) error(msg); }
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ; }
+# define Tracevv(x) {if (verbose > 1) fprintf x ; }
+# define Tracec(c, x) {if (verbose && (c)) fprintf x ; }
+# define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; }
+#else
+# define Assert(cond, msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c, x)
+# define Tracecv(c, x)
+#endif
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out;
+static uch *output_data;
+static unsigned long output_ptr;
+
+#include "console.c"
+
+static void error(char *m);
+
+int puts(const char *);
+
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#define HEAP_SIZE 0x10000
+
+#include "../../../../lib/inflate.c"
+
+void *memset(void *s, int c, size_t n)
+{
+ int i;
+ char *ss = (char *)s;
+
+ for (i = 0; i < n; i++)
+ ss[i] = c;
+ return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+ int i;
+ char *d = (char *)__dest, *s = (char *)__src;
+
+ for (i = 0; i < __n; i++)
+ d[i] = s[i];
+ return __dest;
+}
+
+/*
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+ if (insize != 0)
+ error("ran out of input data");
+
+ inbuf = input_data;
+ insize = input_len;
+ inptr = 1;
+ return inbuf[0];
+}
+
+/*
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out++ = *in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
+}
+
+static void error(char *x)
+{
+ puts("\nERROR\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while (1) /* Halt */
+ ;
+}
+
+void decompress_kernel(void)
+{
+ output_data = (void *) (CONFIG_NIOS2_MEM_BASE |
+ CONFIG_NIOS2_KERNEL_REGION_BASE);
+ output_ptr = 0;
+ free_mem_ptr = (unsigned long)&_end;
+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+ console_init();
+ makecrc();
+ puts("Uncompressing Linux... ");
+ gunzip();
+ puts("Ok, booting the kernel.\n");
+}
diff --git a/arch/nios2/boot/compressed/vmlinux.lds.S b/arch/nios2/boot/compressed/vmlinux.lds.S
new file mode 100644
index 000000000000..e867b3756059
--- /dev/null
+++ b/arch/nios2/boot/compressed/vmlinux.lds.S
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+
+OUTPUT_FORMAT("elf32-littlenios2", "elf32-littlenios2", "elf32-littlenios2")
+
+OUTPUT_ARCH(nios)
+ENTRY(_start) /* Defined in head.S */
+
+SECTIONS
+{
+ . = (CONFIG_NIOS2_MEM_BASE + CONFIG_NIOS2_BOOT_LINK_OFFSET) | \
+ CONFIG_NIOS2_KERNEL_REGION_BASE;
+
+ _text = .;
+ .text : { *(.text) } = 0
+ .rodata : { *(.rodata) *(.rodata.*) }
+ _etext = .;
+
+ . = ALIGN(32 / 8);
+ .data : { *(.data) }
+ . = ALIGN(32 / 8);
+ _got = .;
+ .got : {
+ *(.got.plt)
+ *(.igot.plt)
+ *(.got)
+ *(.igot)
+ }
+ _egot = .;
+ _edata = .;
+
+ . = ALIGN(32 / 8);
+ __bss_start = .;
+ .bss : { *(.bss) *(.sbss) }
+ . = ALIGN(32 / 8);
+ _ebss = .;
+ end = . ;
+ _end = . ;
+
+ got_len = (_egot - _got);
+}
diff --git a/arch/arm/mach-at91/include/mach/memory.h b/arch/nios2/boot/compressed/vmlinux.scr
index 401c207f2f39..28c42f1d127e 100644
--- a/arch/arm/mach-at91/include/mach/memory.h
+++ b/arch/nios2/boot/compressed/vmlinux.scr
@@ -1,7 +1,5 @@
/*
- * arch/arm/mach-at91/include/mach/memory.h
- *
- * Copyright (C) 2004 SAN People
+ * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,13 +12,17 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
*/
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-#include <mach/hardware.h>
-
-#endif
+SECTIONS
+{
+ .data : {
+ input_len = .;
+ LONG(input_data_end - input_data) input_data = .;
+ *(.data)
+ . = ALIGN(4);
+ input_data_end = .;
+ }
+}
diff --git a/arch/nios2/configs/3c120_defconfig b/arch/nios2/configs/3c120_defconfig
index 87541f0a5d6e..9451940678a0 100644
--- a/arch/nios2/configs/3c120_defconfig
+++ b/arch/nios2/configs/3c120_defconfig
@@ -22,6 +22,7 @@ CONFIG_NIOS2_DCACHE_SIZE=0x8000
CONFIG_NIOS2_ICACHE_SIZE=0x8000
# CONFIG_NIOS2_CMDLINE_IGNORE_DTB is not set
CONFIG_NIOS2_PASS_CMDLINE=y
+CONFIG_NIOS2_BOOT_LINK_OFFSET=0x00800000
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
diff --git a/arch/nios2/include/asm/kgdb.h b/arch/nios2/include/asm/kgdb.h
new file mode 100644
index 000000000000..8fd5e3b66c57
--- /dev/null
+++ b/arch/nios2/include/asm/kgdb.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2015 Altera Corporation
+ * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
+ *
+ * Based on the code posted by Kazuyasu on the Altera Forum at:
+ * http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _ASM_NIOS2_KGDB_H
+#define _ASM_NIOS2_KGDB_H
+
+#define CACHE_FLUSH_IS_SAFE 1
+#define BUFMAX 2048
+
+enum regnames {
+ GDB_R0 = 0,
+ GDB_AT,
+ GDB_R2,
+ GDB_R3,
+ GDB_R4,
+ GDB_R5,
+ GDB_R6,
+ GDB_R7,
+ GDB_R8,
+ GDB_R9,
+ GDB_R10,
+ GDB_R11,
+ GDB_R12,
+ GDB_R13,
+ GDB_R14,
+ GDB_R15,
+ GDB_R16,
+ GDB_R17,
+ GDB_R18,
+ GDB_R19,
+ GDB_R20,
+ GDB_R21,
+ GDB_R22,
+ GDB_R23,
+ GDB_ET,
+ GDB_BT,
+ GDB_GP,
+ GDB_SP,
+ GDB_FP,
+ GDB_EA,
+ GDB_BA,
+ GDB_RA,
+ GDB_PC,
+ GDB_STATUS,
+ GDB_ESTATUS,
+ GDB_BSTATUS,
+ GDB_IENABLE,
+ GDB_IPENDING,
+ GDB_CPUID,
+ GDB_CTL6,
+ GDB_EXCEPTION,
+ GDB_PTEADDR,
+ GDB_TLBACC,
+ GDB_TLBMISC,
+ GDB_ECCINJ,
+ GDB_BADADDR,
+ GDB_CONFIG,
+ GDB_MPUBASE,
+ GDB_MPUACC,
+ /* do not change the last entry or anything below! */
+ GDB_NUMREGBYTES /* number of registers */
+};
+
+#define GDB_SIZEOF_REG sizeof(u32)
+#define DBG_MAX_REG_NUM (49)
+#define NUMREGBYTES (DBG_MAX_REG_NUM * sizeof(GDB_SIZEOF_REG))
+
+#define BREAK_INSTR_SIZE 4
+static inline void arch_kgdb_breakpoint(void)
+{
+ __asm__ __volatile__("trap 30\n");
+}
+
+#endif /* _ASM_NIOS2_KGDB_H */
diff --git a/arch/nios2/include/asm/processor.h b/arch/nios2/include/asm/processor.h
index 3bd349473b06..c2ba45c159c7 100644
--- a/arch/nios2/include/asm/processor.h
+++ b/arch/nios2/include/asm/processor.h
@@ -85,9 +85,6 @@ static inline void exit_thread(void)
extern unsigned long get_wchan(struct task_struct *p);
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
-
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
diff --git a/arch/nios2/include/asm/prom.h b/arch/nios2/include/asm/prom.h
new file mode 100644
index 000000000000..75fffb42cfa5
--- /dev/null
+++ b/arch/nios2/include/asm/prom.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright Altera Corporation (C) <2015>. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_NIOS2_PROM_H__
+#define __ASM_NIOS2_PROM_H__
+
+extern unsigned long __init of_early_console(void);
+
+#endif
diff --git a/arch/nios2/kernel/Makefile b/arch/nios2/kernel/Makefile
index 8ae76823ff93..1aae25703657 100644
--- a/arch/nios2/kernel/Makefile
+++ b/arch/nios2/kernel/Makefile
@@ -20,5 +20,7 @@ obj-y += syscall_table.o
obj-y += time.o
obj-y += traps.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o
diff --git a/arch/nios2/kernel/early_printk.c b/arch/nios2/kernel/early_printk.c
new file mode 100644
index 000000000000..c08e4c1486fc
--- /dev/null
+++ b/arch/nios2/kernel/early_printk.c
@@ -0,0 +1,118 @@
+/*
+ * Early printk for Nios2.
+ *
+ * Copyright (C) 2015, Altera Corporation
+ * Copyright (C) 2010, Tobias Klauser <tklauser@distanz.ch>
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include <asm/prom.h>
+
+static unsigned long base_addr;
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE)
+
+#define ALTERA_JTAGUART_DATA_REG 0
+#define ALTERA_JTAGUART_CONTROL_REG 4
+#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000
+#define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400
+
+#define JUART_GET_CR() \
+ __builtin_ldwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG))
+#define JUART_SET_CR(v) \
+ __builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG), v)
+#define JUART_SET_TX(v) \
+ __builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_DATA_REG), v)
+
+static void early_console_write(struct console *con, const char *s, unsigned n)
+{
+ unsigned long status;
+
+ while (n-- && *s) {
+ while (((status = JUART_GET_CR())
+ & ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) {
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
+ if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0)
+ return; /* no connection activity */
+#endif
+ }
+ JUART_SET_TX(*s);
+ s++;
+ }
+}
+
+#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
+
+#define ALTERA_UART_TXDATA_REG 4
+#define ALTERA_UART_STATUS_REG 8
+#define ALTERA_UART_STATUS_TRDY 0x0040
+
+#define UART_GET_SR() \
+ __builtin_ldwio((void *)(base_addr + ALTERA_UART_STATUS_REG))
+#define UART_SET_TX(v) \
+ __builtin_stwio((void *)(base_addr + ALTERA_UART_TXDATA_REG), v)
+
+static void early_console_putc(char c)
+{
+ while (!(UART_GET_SR() & ALTERA_UART_STATUS_TRDY))
+ ;
+
+ UART_SET_TX(c);
+}
+
+static void early_console_write(struct console *con, const char *s, unsigned n)
+{
+ while (n-- && *s) {
+ early_console_putc(*s);
+ if (*s == '\n')
+ early_console_putc('\r');
+ s++;
+ }
+}
+
+#else
+# error Neither SERIAL_ALTERA_JTAGUART_CONSOLE nor SERIAL_ALTERA_UART_CONSOLE \
+selected
+#endif
+
+static struct console early_console_prom = {
+ .name = "early",
+ .write = early_console_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1
+};
+
+void __init setup_early_printk(void)
+{
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) || \
+ defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
+ base_addr = of_early_console();
+#else
+ base_addr = 0;
+#endif
+
+ if (!base_addr)
+ return;
+
+#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
+ /* Clear activity bit so BYPASS doesn't stall if we've used JTAG for
+ * downloading the kernel. This might cause early data to be lost even
+ * if the JTAG terminal is running.
+ */
+ JUART_SET_CR(JUART_GET_CR() | ALTERA_JTAGUART_CONTROL_AC_MSK);
+#endif
+
+ early_console = &early_console_prom;
+ register_console(early_console);
+ pr_info("early_console initialized at 0x%08lx\n", base_addr);
+}
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S
index 0bdfd13ff98b..7729bd3f2e79 100644
--- a/arch/nios2/kernel/entry.S
+++ b/arch/nios2/kernel/entry.S
@@ -121,7 +121,11 @@ trap_table:
.word instruction_trap /* 27 */
.word instruction_trap /* 28 */
.word instruction_trap /* 29 */
- .word instruction_trap /* 30 */
+#ifdef CONFIG_KGDB
+ .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */
+#else
+ .word instruction_trap /* 30 */
+#endif
.word handle_breakpoint /* 31 */
.text
@@ -445,6 +449,12 @@ handle_diverror:
call handle_diverror_c
br ret_from_exception
+#ifdef CONFIG_KGDB
+handle_kgdb_breakpoint:
+ call kgdb_breakpoint_c
+ br ret_from_exception
+#endif
+
/*
* Beware - when entering resume, prev (the current task) is
* in r4, next (the new task) is in r5, don't change these
diff --git a/arch/nios2/kernel/kgdb.c b/arch/nios2/kernel/kgdb.c
new file mode 100644
index 000000000000..117859122d1c
--- /dev/null
+++ b/arch/nios2/kernel/kgdb.c
@@ -0,0 +1,171 @@
+/*
+ * Nios2 KGDB support
+ *
+ * Copyright (C) 2015 Altera Corporation
+ * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
+ *
+ * Based on the code posted by Kazuyasu on the Altera Forum at:
+ * http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <linux/ptrace.h>
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
+#include <linux/io.h>
+
+static int wait_for_remote_debugger;
+
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
+{
+ { "zero", GDB_SIZEOF_REG, -1 },
+ { "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, r1) },
+ { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, r2) },
+ { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, r3) },
+ { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, r4) },
+ { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, r5) },
+ { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, r6) },
+ { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, r7) },
+ { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, r8) },
+ { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, r9) },
+ { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, r10) },
+ { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, r11) },
+ { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, r12) },
+ { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, r13) },
+ { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, r14) },
+ { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, r15) },
+ { "r16", GDB_SIZEOF_REG, -1 },
+ { "r17", GDB_SIZEOF_REG, -1 },
+ { "r18", GDB_SIZEOF_REG, -1 },
+ { "r19", GDB_SIZEOF_REG, -1 },
+ { "r20", GDB_SIZEOF_REG, -1 },
+ { "r21", GDB_SIZEOF_REG, -1 },
+ { "r22", GDB_SIZEOF_REG, -1 },
+ { "r23", GDB_SIZEOF_REG, -1 },
+ { "et", GDB_SIZEOF_REG, -1 },
+ { "bt", GDB_SIZEOF_REG, -1 },
+ { "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp) },
+ { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
+ { "fp", GDB_SIZEOF_REG, offsetof(struct pt_regs, fp) },
+ { "ea", GDB_SIZEOF_REG, -1 },
+ { "ba", GDB_SIZEOF_REG, -1 },
+ { "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, ra) },
+ { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, ea) },
+ { "status", GDB_SIZEOF_REG, -1 },
+ { "estatus", GDB_SIZEOF_REG, offsetof(struct pt_regs, estatus) },
+ { "bstatus", GDB_SIZEOF_REG, -1 },
+ { "ienable", GDB_SIZEOF_REG, -1 },
+ { "ipending", GDB_SIZEOF_REG, -1},
+ { "cpuid", GDB_SIZEOF_REG, -1 },
+ { "ctl6", GDB_SIZEOF_REG, -1 },
+ { "exception", GDB_SIZEOF_REG, -1 },
+ { "pteaddr", GDB_SIZEOF_REG, -1 },
+ { "tlbacc", GDB_SIZEOF_REG, -1 },
+ { "tlbmisc", GDB_SIZEOF_REG, -1 },
+ { "eccinj", GDB_SIZEOF_REG, -1 },
+ { "badaddr", GDB_SIZEOF_REG, -1 },
+ { "config", GDB_SIZEOF_REG, -1 },
+ { "mpubase", GDB_SIZEOF_REG, -1 },
+ { "mpuacc", GDB_SIZEOF_REG, -1 },
+};
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+ else
+ memset(mem, 0, dbg_reg_def[regno].size);
+
+ return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return -EINVAL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+
+ return 0;
+}
+
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+ memset((char *)gdb_regs, 0, NUMREGBYTES);
+ gdb_regs[GDB_SP] = p->thread.kregs->sp;
+ gdb_regs[GDB_PC] = p->thread.kregs->ea;
+}
+
+void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+{
+ regs->ea = pc;
+}
+
+int kgdb_arch_handle_exception(int vector, int signo, int err_code,
+ char *remcom_in_buffer, char *remcom_out_buffer,
+ struct pt_regs *regs)
+{
+ char *ptr;
+ unsigned long addr;
+
+ switch (remcom_in_buffer[0]) {
+ case 's':
+ case 'c':
+ /* handle the optional parameters */
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &addr))
+ regs->ea = addr;
+
+ return 0;
+ }
+
+ return -1; /* this means that we do not want to exit from the handler */
+}
+
+asmlinkage void kgdb_breakpoint_c(struct pt_regs *regs)
+{
+ /*
+ * The breakpoint entry code has moved the PC on by 4 bytes, so we must
+ * move it back. This could be done on the host but we do it here
+ */
+ if (!wait_for_remote_debugger)
+ regs->ea -= 4;
+ else /* pass the first trap 30 code */
+ wait_for_remote_debugger = 0;
+
+ kgdb_handle_exception(30, SIGTRAP, 0, regs);
+}
+
+int kgdb_arch_init(void)
+{
+ wait_for_remote_debugger = 1;
+ return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+ /* Nothing to do */
+}
+
+struct kgdb_arch arch_kgdb_ops = {
+ /* Breakpoint instruction: trap 30 */
+ .gdb_bpt_instr = { 0xba, 0x6f, 0x3b, 0x00 },
+};
diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c
index 0522d3378e3f..718dd197909f 100644
--- a/arch/nios2/kernel/prom.c
+++ b/arch/nios2/kernel/prom.c
@@ -1,7 +1,7 @@
/*
* Device tree support
*
- * Copyright (C) 2013 Altera Corporation
+ * Copyright (C) 2013, 2015 Altera Corporation
* Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
*
* Based on MIPS support for CONFIG_OF device tree support
@@ -30,6 +30,7 @@
#include <linux/of_fdt.h>
#include <linux/io.h>
+#include <asm/prom.h>
#include <asm/sections.h>
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
@@ -63,3 +64,52 @@ void __init early_init_devtree(void *params)
early_init_dt_scan(params);
}
+
+#ifdef CONFIG_EARLY_PRINTK
+static int __init early_init_dt_scan_serial(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ u64 *addr64 = (u64 *) data;
+ const char *p;
+
+ /* only consider serial nodes */
+ if (strncmp(uname, "serial", 6) != 0)
+ return 0;
+
+ p = of_get_flat_dt_prop(node, "compatible", NULL);
+ if (!p)
+ return 0;
+
+ /*
+ * We found an altera_jtaguart but it wasn't configured for console, so
+ * skip it.
+ */
+#ifndef CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE
+ if (strncmp(p, "altr,juart", 10) == 0)
+ return 0;
+#endif
+
+ /*
+ * Same for altera_uart.
+ */
+#ifndef CONFIG_SERIAL_ALTERA_UART_CONSOLE
+ if (strncmp(p, "altr,uart", 9) == 0)
+ return 0;
+#endif
+
+ *addr64 = fdt_translate_address((const void *)initial_boot_params,
+ node);
+
+ return *addr64 == OF_BAD_ADDR ? 0 : 1;
+}
+
+unsigned long __init of_early_console(void)
+{
+ u64 base = 0;
+
+ if (of_scan_flat_dt(early_init_dt_scan_serial, &base))
+ return (u32)ioremap(base, 32);
+ else
+ return 0;
+}
+#endif /* CONFIG_EARLY_PRINTK */
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index cb3121f975d4..b101a43d3c5a 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -139,6 +139,10 @@ void __init setup_arch(char **cmdline_p)
console_verbose();
+#ifdef CONFIG_EARLY_PRINTK
+ setup_early_printk();
+#endif
+
memory_start = PAGE_ALIGN((unsigned long)__pa(_end));
memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size;
diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c
index d194c0427b26..0d231adfe576 100644
--- a/arch/nios2/mm/fault.c
+++ b/arch/nios2/mm/fault.c
@@ -47,7 +47,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
struct mm_struct *mm = tsk->mm;
int code = SEGV_MAPERR;
int fault;
- unsigned int flags = 0;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
cause >>= 2;
@@ -86,6 +86,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
if (!down_read_trylock(&mm->mmap_sem)) {
if (!user_mode(regs) && !search_exception_tables(regs->ea))
goto bad_area_nosemaphore;
+retry:
down_read(&mm->mmap_sem);
}
@@ -132,6 +133,10 @@ survive:
* the fault.
*/
fault = handle_mm_fault(mm, vma, address, flags);
+
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return;
+
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -141,10 +146,32 @@ survive:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
- tsk->maj_flt++;
- else
- tsk->min_flt++;
+
+ /*
+ * Major/minor page fault accounting is only done on the
+ * initial attempt. If we go through a retry, it is extremely
+ * likely that the page will be found in page cache at that point.
+ */
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR)
+ current->maj_flt++;
+ else
+ current->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+ * of starvation. */
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
+
+ /*
+ * No need to up_read(&mm->mmap_sem) as we would
+ * have already released it in __lock_page_or_retry
+ * in mm/filemap.c.
+ */
+
+ goto retry;
+ }
+ }
up_read(&mm->mmap_sem);
return;
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index ab2e7a198a4c..a6bd07ca3d6c 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -192,7 +192,7 @@ struct __large_struct {
({ \
long __gu_err, __gu_val; \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
@@ -202,7 +202,7 @@ struct __large_struct {
const __typeof__(*(ptr)) * __gu_addr = (ptr); \
if (access_ok(VERIFY_READ, __gu_addr, size)) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 1554a6f2a5bb..8014727a2743 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -291,10 +291,6 @@ config SYSVIPC_COMPAT
config AUDIT_ARCH
def_bool y
-config HPUX
- bool "Support for HP-UX binaries"
- depends on !64BIT
-
config NR_CPUS
int "Maximum number of CPUs (2-32)"
range 2 32
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 5db8882f732c..91fbb6ee702c 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -84,7 +84,6 @@ head-y := arch/parisc/kernel/head.o
KBUILD_CFLAGS += $(cflags-y)
kernel-y := mm/ kernel/ math-emu/
-kernel-$(CONFIG_HPUX) += hpux/
core-y += $(addprefix arch/parisc/, $(kernel-y))
libs-y += arch/parisc/lib/ $(LIBGCC)
diff --git a/arch/parisc/hpux/Makefile b/arch/parisc/hpux/Makefile
deleted file mode 100644
index 1048fb69f06d..000000000000
--- a/arch/parisc/hpux/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for HPUX emulation
-#
-
-obj-y := entry_hpux.o gate.o wrappers.o fs.o ioctl.o sys_hpux.o
diff --git a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S
deleted file mode 100644
index d15a413572f0..000000000000
--- a/arch/parisc/hpux/entry_hpux.S
+++ /dev/null
@@ -1,546 +0,0 @@
-/* syscall table for HPUX specific syscalls
- *
- * Linux/PA-RISC Project (http://www.parisc-linux.org/)
- * Copyright (C) 1999 Matthew Wilcox <willy at debian . org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <asm/unistd.h>
-#include <asm/assembly.h>
-#include <linux/sys.h>
-#include <linux/linkage.h>
-
-#define ENTRY_NAME(_name_) ASM_ULONG_INSN _name_
-
- .section .rodata,"a"
- .import hpux_unimplemented_wrapper
-ENTRY(hpux_call_table)
- ENTRY_NAME(sys_ni_syscall) /* 0 */
- ENTRY_NAME(sys_exit)
- ENTRY_NAME(hpux_fork_wrapper)
- ENTRY_NAME(sys_read)
- ENTRY_NAME(sys_write)
- ENTRY_NAME(sys_open) /* 5 */
- ENTRY_NAME(sys_close)
- ENTRY_NAME(hpux_wait)
- ENTRY_NAME(sys_creat)
- ENTRY_NAME(sys_link)
- ENTRY_NAME(sys_unlink) /* 10 */
- ENTRY_NAME(hpux_execv_wrapper)
- ENTRY_NAME(sys_chdir)
- ENTRY_NAME(sys_time)
- ENTRY_NAME(sys_mknod)
- ENTRY_NAME(sys_chmod) /* 15 */
- ENTRY_NAME(sys_chown)
- ENTRY_NAME(hpux_brk)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_lseek)
- ENTRY_NAME(sys_getpid) /* 20 */
- ENTRY_NAME(hpux_mount)
- ENTRY_NAME(sys_oldumount)
- ENTRY_NAME(sys_setuid)
- ENTRY_NAME(sys_getuid)
- ENTRY_NAME(sys_stime) /* 25 */
- ENTRY_NAME(hpux_ptrace)
- ENTRY_NAME(sys_alarm)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_pause)
- ENTRY_NAME(sys_utime) /* 30 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_access)
- ENTRY_NAME(hpux_nice)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 35 */
- ENTRY_NAME(sys_sync)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_newstat)
- ENTRY_NAME(hpux_setpgrp3)
- ENTRY_NAME(sys_newlstat) /* 40 */
- ENTRY_NAME(sys_dup)
- ENTRY_NAME(hpux_pipe_wrapper)
- ENTRY_NAME(sys_times)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 45 */
- ENTRY_NAME(sys_setgid)
- ENTRY_NAME(sys_getgid)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 50 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_ioctl)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 55 */
- ENTRY_NAME(sys_symlink)
- ENTRY_NAME(hpux_utssys)
- ENTRY_NAME(sys_readlink)
- ENTRY_NAME(hpux_execve_wrapper)
- ENTRY_NAME(sys_umask) /* 60 */
- ENTRY_NAME(sys_chroot)
- ENTRY_NAME(sys_fcntl)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 65 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_sbrk)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 70 */
- ENTRY_NAME(sys_mmap)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 75 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 80 */
- ENTRY_NAME(sys_getpgid)
- ENTRY_NAME(sys_setpgid)
- ENTRY_NAME(sys_setitimer)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 85 */
- ENTRY_NAME(sys_getitimer)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_dup2) /* 90 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_newfstat)
- ENTRY_NAME(sys_select)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 95 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 100 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 105 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 110 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 115 */
- ENTRY_NAME(sys_gettimeofday)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 120 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_fchown)
- ENTRY_NAME(sys_fchmod)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 125 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_rename)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 130 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_sysconf)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 135 */
- ENTRY_NAME(sys_mkdir)
- ENTRY_NAME(sys_rmdir)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 140 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_getrlimit)
- ENTRY_NAME(sys_setrlimit) /* 145 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 150 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_lockf) /* 155 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 160 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 165 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 170 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 175 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 180 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_sigprocmask) /* 185 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 190 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_getdomainname)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 195 */
- ENTRY_NAME(hpux_statfs)
- ENTRY_NAME(hpux_fstatfs)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_waitpid) /* 200 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 205 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 210 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 215 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 220 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 225 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 230 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 235 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 240 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 245 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 250 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 255 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 260 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 265 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 270 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_fchdir)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_accept) /* 275 */
- ENTRY_NAME(sys_bind)
- ENTRY_NAME(sys_connect)
- ENTRY_NAME(sys_getpeername)
- ENTRY_NAME(sys_getsockname)
- ENTRY_NAME(sys_getsockopt) /* 280 */
- ENTRY_NAME(sys_listen)
- ENTRY_NAME(sys_recv)
- ENTRY_NAME(sys_recvfrom)
- ENTRY_NAME(sys_recvmsg)
- ENTRY_NAME(sys_send) /* 285 */
- ENTRY_NAME(sys_sendmsg)
- ENTRY_NAME(sys_sendto)
- ENTRY_NAME(sys_setsockopt)
- ENTRY_NAME(sys_shutdown)
- ENTRY_NAME(sys_socket) /* 290 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 295 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 300 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 305 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 310 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 315 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 320 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 325 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 330 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_lchown)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_sysfs)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 335 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 340 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 345 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 350 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(sys_nanosleep)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 355 */
- ENTRY_NAME(hpux_getdents)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 360 */
- ENTRY_NAME(hpux_fstat64)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 365 */
- ENTRY_NAME(hpux_lstat64)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_stat64)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 370 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 375 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 380 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_setpgrp)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 385 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 390 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 395 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 400 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 405 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 410 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 415 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 420 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 425 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 430 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 435 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 440 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 445 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 450 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 455 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 460 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 465 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 470 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 475 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 480 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 485 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 490 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 495 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 500 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 505 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper) /* 510 */
- ENTRY_NAME(hpux_unimplemented_wrapper)
- ENTRY_NAME(hpux_unimplemented_wrapper)
-END(hpux_call_table)
-.end
-
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
deleted file mode 100644
index 97a7bf8df348..000000000000
--- a/arch/parisc/hpux/fs.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Implements HPUX syscalls.
- *
- * Copyright (C) 1999 Matthew Wilcox <willy with parisc-linux.org>
- * Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
- * Copyright (C) 2000 John Marvin <jsm with parisc-linux.org>
- * Copyright (C) 2000 Philipp Rumpf
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/file.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-int hpux_execve(struct pt_regs *regs)
-{
- return do_execve(getname((const char __user *) regs->gr[26]),
- (const char __user *const __user *) regs->gr[25],
- (const char __user *const __user *) regs->gr[24]);
-}
-
-struct hpux_dirent {
- loff_t d_off;
- ino_t d_ino;
- short d_reclen;
- short d_namlen;
- char d_name[1];
-};
-
-struct getdents_callback {
- struct dir_context ctx;
- struct hpux_dirent __user *current_dir;
- struct hpux_dirent __user *previous;
- int count;
- int error;
-};
-
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-
-static int filldir(struct dir_context *ctx, const char *name, int namlen,
- loff_t offset, u64 ino, unsigned d_type)
-{
- struct hpux_dirent __user * dirent;
- struct getdents_callback *buf =
- container_of(ctx, struct getdents_callback, ctx);
- ino_t d_ino;
- int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(long));
-
- buf->error = -EINVAL; /* only used if we fail.. */
- if (reclen > buf->count)
- return -EINVAL;
- d_ino = ino;
- if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
- buf->error = -EOVERFLOW;
- return -EOVERFLOW;
- }
- dirent = buf->previous;
- if (dirent)
- if (put_user(offset, &dirent->d_off))
- goto Efault;
- dirent = buf->current_dir;
- if (put_user(d_ino, &dirent->d_ino) ||
- put_user(reclen, &dirent->d_reclen) ||
- put_user(namlen, &dirent->d_namlen) ||
- copy_to_user(dirent->d_name, name, namlen) ||
- put_user(0, dirent->d_name + namlen))
- goto Efault;
- buf->previous = dirent;
- buf->current_dir = (void __user *)dirent + reclen;
- buf->count -= reclen;
- return 0;
-Efault:
- buf->error = -EFAULT;
- return -EFAULT;
-}
-
-#undef NAME_OFFSET
-
-int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
-{
- struct fd arg;
- struct hpux_dirent __user * lastdirent;
- struct getdents_callback buf = {
- .ctx.actor = filldir,
- .current_dir = dirent,
- .count = count
- };
- int error;
-
- arg = fdget(fd);
- if (!arg.file)
- return -EBADF;
-
- error = iterate_dir(arg.file, &buf.ctx);
- if (error >= 0)
- error = buf.error;
- lastdirent = buf.previous;
- if (lastdirent) {
- if (put_user(buf.ctx.pos, &lastdirent->d_off))
- error = -EFAULT;
- else
- error = count - buf.count;
- }
-
- fdput(arg);
- return error;
-}
-
-int hpux_mount(const char *fs, const char *path, int mflag,
- const char *fstype, const char *dataptr, int datalen)
-{
- return -ENOSYS;
-}
-
-static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 __user *statbuf)
-{
- struct hpux_stat64 tmp;
-
- /* we probably want a different split here - is hpux 12:20? */
-
- if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.st_dev = new_encode_dev(stat->dev);
- tmp.st_ino = stat->ino;
- tmp.st_mode = stat->mode;
- tmp.st_nlink = stat->nlink;
- tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
- tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
- tmp.st_rdev = new_encode_dev(stat->rdev);
- tmp.st_size = stat->size;
- tmp.st_atime = stat->atime.tv_sec;
- tmp.st_mtime = stat->mtime.tv_sec;
- tmp.st_ctime = stat->ctime.tv_sec;
- tmp.st_blocks = stat->blocks;
- tmp.st_blksize = stat->blksize;
- return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
-}
-
-long hpux_stat64(const char __user *filename, struct hpux_stat64 __user *statbuf)
-{
- struct kstat stat;
- int error = vfs_stat(filename, &stat);
-
- if (!error)
- error = cp_hpux_stat(&stat, statbuf);
-
- return error;
-}
-
-long hpux_fstat64(unsigned int fd, struct hpux_stat64 __user *statbuf)
-{
- struct kstat stat;
- int error = vfs_fstat(fd, &stat);
-
- if (!error)
- error = cp_hpux_stat(&stat, statbuf);
-
- return error;
-}
-
-long hpux_lstat64(const char __user *filename,
- struct hpux_stat64 __user *statbuf)
-{
- struct kstat stat;
- int error = vfs_lstat(filename, &stat);
-
- if (!error)
- error = cp_hpux_stat(&stat, statbuf);
-
- return error;
-}
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
deleted file mode 100644
index 011468857e98..000000000000
--- a/arch/parisc/hpux/gate.S
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *
- * Linux/PARISC Project (http://www.parisc-linux.org/)
- *
- * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
- * Licensed under the GNU GPL.
- * thanks to Philipp Rumpf, Mike Shaver and various others
- * sorry about the wall, puffin..
- */
-
-#include <asm/assembly.h>
-#include <asm/asm-offsets.h>
-#include <asm/unistd.h>
-#include <asm/errno.h>
-#include <linux/linkage.h>
-
- .level LEVEL
- .text
-
- .import hpux_call_table
- .import hpux_syscall_exit,code
-
- .align PAGE_SIZE
-ENTRY(hpux_gateway_page)
- nop
-#ifdef CONFIG_64BIT
-#warning NEEDS WORK for 64-bit
-#endif
- ldw -64(%r30), %r29 ;! 8th argument
- ldw -60(%r30), %r19 ;! 7th argument
- ldw -56(%r30), %r20 ;! 6th argument
- ldw -52(%r30), %r21 ;! 5th argument
- gate .+8, %r0 /* become privileged */
- mtsp %r0,%sr4 /* get kernel space into sr4 */
- mtsp %r0,%sr5 /* get kernel space into sr5 */
- mtsp %r0,%sr6 /* get kernel space into sr6 */
- mfsp %sr7,%r1 /* save user sr7 */
- mtsp %r1,%sr3 /* and store it in sr3 */
-
- mtctl %r30,%cr28
- mfctl %cr30,%r1
- xor %r1,%r30,%r30 /* ye olde xor trick */
- xor %r1,%r30,%r1
- xor %r1,%r30,%r30
- ldo TASK_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */
-
- /* N.B.: It is critical that we don't set sr7 to 0 until r30
- * contains a valid kernel stack pointer. It is also
- * critical that we don't start using the kernel stack
- * until after sr7 has been set to 0.
- */
-
- mtsp %r0,%sr7 /* get kernel space into sr7 */
- STREG %r1,TASK_PT_GR30-TASK_SZ_ALGN-FRAME_SIZE(%r30) /* save usp */
- ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr in %r1 */
-
- /* Save some registers for sigcontext and potential task
- switch (see entry.S for the details of which ones are
- saved/restored). TASK_PT_PSW is zeroed so we can see whether
- a process is on a syscall or not. For an interrupt the real
- PSW value is stored. This is needed for gdb and sys_ptrace. */
- STREG %r0, TASK_PT_PSW(%r1)
- STREG %r2, TASK_PT_GR2(%r1) /* preserve rp */
- STREG %r19, TASK_PT_GR19(%r1) /* 7th argument */
- STREG %r20, TASK_PT_GR20(%r1) /* 6th argument */
- STREG %r21, TASK_PT_GR21(%r1) /* 5th argument */
- STREG %r22, TASK_PT_GR22(%r1) /* syscall # */
- STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */
- STREG %r24, TASK_PT_GR24(%r1) /* 3rd argument */
- STREG %r25, TASK_PT_GR25(%r1) /* 2nd argument */
- STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */
- STREG %r27, TASK_PT_GR27(%r1) /* user dp */
- STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */
- STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */
- STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */
- STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */
-
- ldo TASK_PT_FR0(%r1), %r27 /* save fpregs from the kernel */
- save_fp %r27 /* or potential task switch */
-
- mfctl %cr11, %r27 /* i.e. SAR */
- STREG %r27, TASK_PT_SAR(%r1)
-
- loadgp
-
- stw %r21, -52(%r30) ;! 5th argument
- stw %r20, -56(%r30) ;! 6th argument
- stw %r19, -60(%r30) ;! 7th argument
- stw %r29, -64(%r30) ;! 8th argument
-
- ldil L%hpux_call_table, %r21
- ldo R%hpux_call_table(%r21), %r21
- comiclr,>>= __NR_HPUX_syscalls, %r22, %r0
- b,n syscall_nosys
- LDREGX %r22(%r21), %r21
- ldil L%hpux_syscall_exit,%r2
- be 0(%sr7,%r21)
- ldo R%hpux_syscall_exit(%r2),%r2
-
-syscall_nosys:
- ldil L%hpux_syscall_exit,%r1
- be R%hpux_syscall_exit(%sr7,%r1)
- ldo -ENOSYS(%r0),%r28
-ENDPROC(hpux_gateway_page)
-
- .align PAGE_SIZE
-ENTRY(end_hpux_gateway_page)
diff --git a/arch/parisc/hpux/ioctl.c b/arch/parisc/hpux/ioctl.c
deleted file mode 100644
index dede4765852e..000000000000
--- a/arch/parisc/hpux/ioctl.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Implements some necessary HPUX ioctls.
- *
- * Copyright (C) 1999-2002 Matthew Wilcox <willy with parisc-linux.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Supported ioctls:
- * TCGETA
- * TCSETA
- * TCSETAW
- * TCSETAF
- * TCSBRK
- * TCXONC
- * TCFLSH
- * TIOCGWINSZ
- * TIOCSWINSZ
- * TIOCGPGRP
- * TIOCSPGRP
- */
-
-#include <linux/sched.h>
-#include <linux/syscalls.h>
-#include <asm/errno.h>
-#include <asm/ioctl.h>
-#include <asm/termios.h>
-#include <asm/uaccess.h>
-
-static int hpux_ioctl_t(int fd, unsigned long cmd, unsigned long arg)
-{
- int result = -EOPNOTSUPP;
- int nr = _IOC_NR(cmd);
- switch (nr) {
- case 106:
- result = sys_ioctl(fd, TIOCSWINSZ, arg);
- break;
- case 107:
- result = sys_ioctl(fd, TIOCGWINSZ, arg);
- break;
- }
- return result;
-}
-
-int hpux_ioctl(int fd, unsigned long cmd, unsigned long arg)
-{
- int result = -EOPNOTSUPP;
- int type = _IOC_TYPE(cmd);
- switch (type) {
- case 'T':
- /* Our structures are now compatible with HPUX's */
- result = sys_ioctl(fd, cmd, arg);
- break;
- case 't':
- result = hpux_ioctl_t(fd, cmd, arg);
- break;
- }
- return result;
-}
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
deleted file mode 100644
index e5c4da035810..000000000000
--- a/arch/parisc/hpux/sys_hpux.c
+++ /dev/null
@@ -1,963 +0,0 @@
-/*
- * Implements HPUX syscalls.
- *
- * Copyright (C) 1999 Matthew Wilcox <willy with parisc-linux.org>
- * Copyright (C) 2000 Philipp Rumpf
- * Copyright (C) 2000 John Marvin <jsm with parisc-linux.org>
- * Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
- * Copyright (C) 2001 Nathan Neulinger <nneul at umr.edu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/capability.h>
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/namei.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/syscalls.h>
-#include <linux/utsname.h>
-#include <linux/vfs.h>
-#include <linux/vmalloc.h>
-
-#include <asm/errno.h>
-#include <asm/pgalloc.h>
-#include <asm/uaccess.h>
-
-unsigned long hpux_brk(unsigned long addr)
-{
- /* Sigh. Looks like HP/UX libc relies on kernel bugs. */
- return sys_brk(addr + PAGE_SIZE);
-}
-
-int hpux_sbrk(void)
-{
- return -ENOSYS;
-}
-
-/* Random other syscalls */
-
-int hpux_nice(int priority_change)
-{
- return -ENOSYS;
-}
-
-int hpux_ptrace(void)
-{
- return -ENOSYS;
-}
-
-int hpux_wait(int __user *stat_loc)
-{
- return sys_waitpid(-1, stat_loc, 0);
-}
-
-int hpux_setpgrp(void)
-{
- return sys_setpgid(0,0);
-}
-
-int hpux_setpgrp3(void)
-{
- return hpux_setpgrp();
-}
-
-#define _SC_CPU_VERSION 10001
-#define _SC_OPEN_MAX 4
-#define CPU_PA_RISC1_1 0x210
-
-int hpux_sysconf(int which)
-{
- switch (which) {
- case _SC_CPU_VERSION:
- return CPU_PA_RISC1_1;
- case _SC_OPEN_MAX:
- return INT_MAX;
- default:
- return -EINVAL;
- }
-}
-
-/*****************************************************************************/
-
-#define HPUX_UTSLEN 9
-#define HPUX_SNLEN 15
-
-struct hpux_utsname {
- char sysname[HPUX_UTSLEN];
- char nodename[HPUX_UTSLEN];
- char release[HPUX_UTSLEN];
- char version[HPUX_UTSLEN];
- char machine[HPUX_UTSLEN];
- char idnumber[HPUX_SNLEN];
-} ;
-
-struct hpux_ustat {
- int32_t f_tfree; /* total free (daddr_t) */
- u_int32_t f_tinode; /* total inodes free (ino_t) */
- char f_fname[6]; /* filsys name */
- char f_fpack[6]; /* filsys pack name */
- u_int32_t f_blksize; /* filsys block size (int) */
-};
-
-/*
- * HPUX's utssys() call. It's a collection of miscellaneous functions,
- * alas, so there's no nice way of splitting them up.
- */
-
-/* This function is called from hpux_utssys(); HP-UX implements
- * ustat() as an option to utssys().
- *
- * Now, struct ustat on HP-UX is exactly the same as on Linux, except
- * that it contains one addition field on the end, int32_t f_blksize.
- * So, we could have written this function to just call the Linux
- * sys_ustat(), (defined in linux/fs/super.c), and then just
- * added this additional field to the user's structure. But I figure
- * if we're gonna be digging through filesystem structures to get
- * this, we might as well just do the whole enchilada all in one go.
- *
- * So, most of this function is almost identical to sys_ustat().
- * I have placed comments at the few lines changed or added, to
- * aid in porting forward if and when sys_ustat() is changed from
- * its form in kernel 2.2.5.
- */
-static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
-{
- struct hpux_ustat tmp; /* Changed to hpux_ustat */
- struct kstatfs sbuf;
- int err = vfs_ustat(dev, &sbuf);
- if (err)
- goto out;
-
- memset(&tmp,0,sizeof(tmp));
-
- tmp.f_tfree = (int32_t)sbuf.f_bfree;
- tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
- tmp.f_blksize = (u_int32_t)sbuf.f_bsize; /* Added this line */
-
- err = copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
-out:
- return err;
-}
-
-/*
- * Wrapper for hpux statfs call. At the moment, just calls the linux native one
- * and ignores the extra fields at the end of the hpux statfs struct.
- *
- */
-
-typedef int32_t hpux_fsid_t[2]; /* file system ID type */
-typedef uint16_t hpux_site_t;
-
-struct hpux_statfs {
- int32_t f_type; /* type of info, zero for now */
- int32_t f_bsize; /* fundamental file system block size */
- int32_t f_blocks; /* total blocks in file system */
- int32_t f_bfree; /* free block in fs */
- int32_t f_bavail; /* free blocks avail to non-superuser */
- int32_t f_files; /* total file nodes in file system */
- int32_t f_ffree; /* free file nodes in fs */
- hpux_fsid_t f_fsid; /* file system ID */
- int32_t f_magic; /* file system magic number */
- int32_t f_featurebits; /* file system features */
- int32_t f_spare[4]; /* spare for later */
- hpux_site_t f_cnode; /* cluster node where mounted */
- int16_t f_pad;
-};
-
-static int do_statfs_hpux(struct kstatfs *st, struct hpux_statfs __user *p)
-{
- struct hpux_statfs buf;
- memset(&buf, 0, sizeof(buf));
- buf.f_type = st->f_type;
- buf.f_bsize = st->f_bsize;
- buf.f_blocks = st->f_blocks;
- buf.f_bfree = st->f_bfree;
- buf.f_bavail = st->f_bavail;
- buf.f_files = st->f_files;
- buf.f_ffree = st->f_ffree;
- buf.f_fsid[0] = st->f_fsid.val[0];
- buf.f_fsid[1] = st->f_fsid.val[1];
- if (copy_to_user(p, &buf, sizeof(buf)))
- return -EFAULT;
- return 0;
-}
-
-/* hpux statfs */
-asmlinkage long hpux_statfs(const char __user *pathname,
- struct hpux_statfs __user *buf)
-{
- struct kstatfs st;
- int error = user_statfs(pathname, &st);
- if (!error)
- error = do_statfs_hpux(&st, buf);
- return error;
-}
-
-asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
-{
- struct kstatfs st;
- int error = fd_statfs(fd, &st);
- if (!error)
- error = do_statfs_hpux(&st, buf);
- return error;
-}
-
-
-/* This function is called from hpux_utssys(); HP-UX implements
- * uname() as an option to utssys().
- *
- * The form of this function is pretty much copied from sys_olduname(),
- * defined in linux/arch/i386/kernel/sys_i386.c.
- */
-/* TODO: Are these put_user calls OK? Should they pass an int?
- * (I copied it from sys_i386.c like this.)
- */
-static int hpux_uname(struct hpux_utsname __user *name)
-{
- int error;
-
- if (!name)
- return -EFAULT;
- if (!access_ok(VERIFY_WRITE,name,sizeof(struct hpux_utsname)))
- return -EFAULT;
-
- down_read(&uts_sem);
-
- error = __copy_to_user(&name->sysname, &utsname()->sysname,
- HPUX_UTSLEN - 1);
- error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1);
- error |= __copy_to_user(&name->nodename, &utsname()->nodename,
- HPUX_UTSLEN - 1);
- error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1);
- error |= __copy_to_user(&name->release, &utsname()->release,
- HPUX_UTSLEN - 1);
- error |= __put_user(0, name->release + HPUX_UTSLEN - 1);
- error |= __copy_to_user(&name->version, &utsname()->version,
- HPUX_UTSLEN - 1);
- error |= __put_user(0, name->version + HPUX_UTSLEN - 1);
- error |= __copy_to_user(&name->machine, &utsname()->machine,
- HPUX_UTSLEN - 1);
- error |= __put_user(0, name->machine + HPUX_UTSLEN - 1);
-
- up_read(&uts_sem);
-
- /* HP-UX utsname has no domainname field. */
-
- /* TODO: Implement idnumber!!! */
-#if 0
- error |= __put_user(0,name->idnumber);
- error |= __put_user(0,name->idnumber+HPUX_SNLEN-1);
-#endif
-
- error = error ? -EFAULT : 0;
-
- return error;
-}
-
-/* Note: HP-UX just uses the old suser() function to check perms
- * in this system call. We'll use capable(CAP_SYS_ADMIN).
- */
-int hpux_utssys(char __user *ubuf, int n, int type)
-{
- int len;
- int error;
- switch( type ) {
- case 0:
- /* uname(): */
- return hpux_uname((struct hpux_utsname __user *)ubuf);
- break ;
- case 1:
- /* Obsolete (used to be umask().) */
- return -EFAULT ;
- break ;
- case 2:
- /* ustat(): */
- return hpux_ustat(new_decode_dev(n),
- (struct hpux_ustat __user *)ubuf);
- break;
- case 3:
- /* setuname():
- *
- * On linux (unlike HP-UX), utsname.nodename
- * is the same as the hostname.
- *
- * sys_sethostname() is defined in linux/kernel/sys.c.
- */
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- /* Unlike Linux, HP-UX returns an error if n==0: */
- if ( n <= 0 )
- return -EINVAL ;
- /* Unlike Linux, HP-UX truncates it if n is too big: */
- len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
- return sys_sethostname(ubuf, len);
- break ;
- case 4:
- /* sethostname():
- *
- * sys_sethostname() is defined in linux/kernel/sys.c.
- */
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- /* Unlike Linux, HP-UX returns an error if n==0: */
- if ( n <= 0 )
- return -EINVAL ;
- /* Unlike Linux, HP-UX truncates it if n is too big: */
- len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
- return sys_sethostname(ubuf, len);
- break ;
- case 5:
- /* gethostname():
- *
- * sys_gethostname() is defined in linux/kernel/sys.c.
- */
- /* Unlike Linux, HP-UX returns an error if n==0: */
- if ( n <= 0 )
- return -EINVAL ;
- return sys_gethostname(ubuf, n);
- break ;
- case 6:
- /* Supposedly called from setuname() in libc.
- * TODO: When and why is this called?
- * Is it ever even called?
- *
- * This code should look a lot like sys_sethostname(),
- * defined in linux/kernel/sys.c. If that gets updated,
- * update this code similarly.
- */
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- /* Unlike Linux, HP-UX returns an error if n==0: */
- if ( n <= 0 )
- return -EINVAL ;
- /* Unlike Linux, HP-UX truncates it if n is too big: */
- len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
- /**/
- /* TODO: print a warning about using this? */
- down_write(&uts_sem);
- error = -EFAULT;
- if (!copy_from_user(utsname()->sysname, ubuf, len)) {
- utsname()->sysname[len] = 0;
- error = 0;
- }
- up_write(&uts_sem);
- return error;
- break ;
- case 7:
- /* Sets utsname.release, if you're allowed.
- * Undocumented. Used by swinstall to change the
- * OS version, during OS updates. Yuck!!!
- *
- * This code should look a lot like sys_sethostname()
- * in linux/kernel/sys.c. If that gets updated, update
- * this code similarly.
- */
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- /* Unlike Linux, HP-UX returns an error if n==0: */
- if ( n <= 0 )
- return -EINVAL ;
- /* Unlike Linux, HP-UX truncates it if n is too big: */
- len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
- /**/
- /* TODO: print a warning about this? */
- down_write(&uts_sem);
- error = -EFAULT;
- if (!copy_from_user(utsname()->release, ubuf, len)) {
- utsname()->release[len] = 0;
- error = 0;
- }
- up_write(&uts_sem);
- return error;
- break ;
- default:
- /* This system call returns -EFAULT if given an unknown type.
- * Why not -EINVAL? I don't know, it's just not what they did.
- */
- return -EFAULT ;
- }
-}
-
-int hpux_getdomainname(char __user *name, int len)
-{
- int nlen;
- int err = -EFAULT;
-
- down_read(&uts_sem);
-
- nlen = strlen(utsname()->domainname) + 1;
-
- if (nlen < len)
- len = nlen;
- if(len > __NEW_UTS_LEN)
- goto done;
- if(copy_to_user(name, utsname()->domainname, len))
- goto done;
- err = 0;
-done:
- up_read(&uts_sem);
- return err;
-
-}
-
-int hpux_pipe(int *kstack_fildes)
-{
- return do_pipe_flags(kstack_fildes, 0);
-}
-
-/* lies - says it works, but it really didn't lock anything */
-int hpux_lockf(int fildes, int function, off_t size)
-{
- return 0;
-}
-
-int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
-{
- char *fsname = NULL;
- int len = 0;
- int fstype;
-
-/*Unimplemented HP-UX syscall emulation. Syscall #334 (sysfs)
- Args: 1 80057bf4 0 400179f0 0 0 0 */
- printk(KERN_DEBUG "in hpux_sysfs\n");
- printk(KERN_DEBUG "hpux_sysfs called with opcode = %d\n", opcode);
- printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);
-
- if ( opcode == 1 ) { /* GETFSIND */
- char __user *user_fsname = (char __user *)arg1;
- len = strlen_user(user_fsname);
- printk(KERN_DEBUG "len of arg1 = %d\n", len);
- if (len == 0)
- return 0;
- fsname = kmalloc(len, GFP_KERNEL);
- if (!fsname) {
- printk(KERN_DEBUG "failed to kmalloc fsname\n");
- return 0;
- }
-
- if (copy_from_user(fsname, user_fsname, len)) {
- printk(KERN_DEBUG "failed to copy_from_user fsname\n");
- kfree(fsname);
- return 0;
- }
-
- /* String could be altered by userspace after strlen_user() */
- fsname[len - 1] = '\0';
-
- printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
- if ( !strcmp(fsname, "hfs") ) {
- fstype = 0;
- } else {
- fstype = 0;
- }
-
- kfree(fsname);
-
- printk(KERN_DEBUG "returning fstype=%d\n", fstype);
- return fstype; /* something other than default */
- }
-
-
- return 0;
-}
-
-
-/* Table of syscall names and handle for unimplemented routines */
-static const char * const syscall_names[] = {
- "nosys", /* 0 */
- "exit",
- "fork",
- "read",
- "write",
- "open", /* 5 */
- "close",
- "wait",
- "creat",
- "link",
- "unlink", /* 10 */
- "execv",
- "chdir",
- "time",
- "mknod",
- "chmod", /* 15 */
- "chown",
- "brk",
- "lchmod",
- "lseek",
- "getpid", /* 20 */
- "mount",
- "umount",
- "setuid",
- "getuid",
- "stime", /* 25 */
- "ptrace",
- "alarm",
- NULL,
- "pause",
- "utime", /* 30 */
- "stty",
- "gtty",
- "access",
- "nice",
- "ftime", /* 35 */
- "sync",
- "kill",
- "stat",
- "setpgrp3",
- "lstat", /* 40 */
- "dup",
- "pipe",
- "times",
- "profil",
- "ki_call", /* 45 */
- "setgid",
- "getgid",
- NULL,
- NULL,
- NULL, /* 50 */
- "acct",
- "set_userthreadid",
- NULL,
- "ioctl",
- "reboot", /* 55 */
- "symlink",
- "utssys",
- "readlink",
- "execve",
- "umask", /* 60 */
- "chroot",
- "fcntl",
- "ulimit",
- NULL,
- NULL, /* 65 */
- "vfork",
- NULL,
- NULL,
- NULL,
- NULL, /* 70 */
- "mmap",
- NULL,
- "munmap",
- "mprotect",
- "madvise", /* 75 */
- "vhangup",
- "swapoff",
- NULL,
- "getgroups",
- "setgroups", /* 80 */
- "getpgrp2",
- "setpgid/setpgrp2",
- "setitimer",
- "wait3",
- "swapon", /* 85 */
- "getitimer",
- NULL,
- NULL,
- NULL,
- "dup2", /* 90 */
- NULL,
- "fstat",
- "select",
- NULL,
- "fsync", /* 95 */
- "setpriority",
- NULL,
- NULL,
- NULL,
- "getpriority", /* 100 */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /* 105 */
- NULL,
- NULL,
- "sigvector",
- "sigblock",
- "sigsetmask", /* 110 */
- "sigpause",
- "sigstack",
- NULL,
- NULL,
- NULL, /* 115 */
- "gettimeofday",
- "getrusage",
- NULL,
- NULL,
- "readv", /* 120 */
- "writev",
- "settimeofday",
- "fchown",
- "fchmod",
- NULL, /* 125 */
- "setresuid",
- "setresgid",
- "rename",
- "truncate",
- "ftruncate", /* 130 */
- NULL,
- "sysconf",
- NULL,
- NULL,
- NULL, /* 135 */
- "mkdir",
- "rmdir",
- NULL,
- "sigcleanup",
- "setcore", /* 140 */
- NULL,
- "gethostid",
- "sethostid",
- "getrlimit",
- "setrlimit", /* 145 */
- NULL,
- NULL,
- "quotactl",
- "get_sysinfo",
- NULL, /* 150 */
- "privgrp",
- "rtprio",
- "plock",
- NULL,
- "lockf", /* 155 */
- "semget",
- NULL,
- "semop",
- "msgget",
- NULL, /* 160 */
- "msgsnd",
- "msgrcv",
- "shmget",
- NULL,
- "shmat", /* 165 */
- "shmdt",
- NULL,
- "csp/nsp_init",
- "cluster",
- "mkrnod", /* 170 */
- "test",
- "unsp_open",
- NULL,
- "getcontext",
- "osetcontext", /* 175 */
- "bigio",
- "pipenode",
- "lsync",
- "getmachineid",
- "cnodeid/mysite", /* 180 */
- "cnodes/sitels",
- "swapclients",
- "rmtprocess",
- "dskless_stats",
- "sigprocmask", /* 185 */
- "sigpending",
- "sigsuspend",
- "sigaction",
- NULL,
- "nfssvc", /* 190 */
- "getfh",
- "getdomainname",
- "setdomainname",
- "async_daemon",
- "getdirentries", /* 195 */
- NULL,
- NULL,
- "vfsmount",
- NULL,
- "waitpid", /* 200 */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /* 205 */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /* 210 */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /* 215 */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /* 220 */
- NULL,
- NULL,
- NULL,
- "sigsetreturn",
- "sigsetstatemask", /* 225 */
- "bfactl",
- "cs",
- "cds",
- NULL,
- "pathconf", /* 230 */
- "fpathconf",
- NULL,
- NULL,
- "nfs_fcntl",
- "ogetacl", /* 235 */
- "ofgetacl",
- "osetacl",
- "ofsetacl",
- "pstat",
- "getaudid", /* 240 */
- "setaudid",
- "getaudproc",
- "setaudproc",
- "getevent",
- "setevent", /* 245 */
- "audwrite",
- "audswitch",
- "audctl",
- "ogetaccess",
- "fsctl", /* 250 */
- "ulconnect",
- "ulcontrol",
- "ulcreate",
- "uldest",
- "ulrecv", /* 255 */
- "ulrecvcn",
- "ulsend",
- "ulshutdown",
- "swapfs",
- "fss", /* 260 */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL, /* 265 */
- NULL,
- "tsync",
- "getnumfds",
- "poll",
- "getmsg", /* 270 */
- "putmsg",
- "fchdir",
- "getmount_cnt",
- "getmount_entry",
- "accept", /* 275 */
- "bind",
- "connect",
- "getpeername",
- "getsockname",
- "getsockopt", /* 280 */
- "listen",
- "recv",
- "recvfrom",
- "recvmsg",
- "send", /* 285 */
- "sendmsg",
- "sendto",
- "setsockopt",
- "shutdown",
- "socket", /* 290 */
- "socketpair",
- "proc_open",
- "proc_close",
- "proc_send",
- "proc_recv", /* 295 */
- "proc_sendrecv",
- "proc_syscall",
- "ipccreate",
- "ipcname",
- "ipcnamerase", /* 300 */
- "ipclookup",
- "ipcselect",
- "ipcconnect",
- "ipcrecvcn",
- "ipcsend", /* 305 */
- "ipcrecv",
- "ipcgetnodename",
- "ipcsetnodename",
- "ipccontrol",
- "ipcshutdown", /* 310 */
- "ipcdest",
- "semctl",
- "msgctl",
- "shmctl",
- "mpctl", /* 315 */
- "exportfs",
- "getpmsg",
- "putpmsg",
- "strioctl",
- "msync", /* 320 */
- "msleep",
- "mwakeup",
- "msem_init",
- "msem_remove",
- "adjtime", /* 325 */
- "kload",
- "fattach",
- "fdetach",
- "serialize",
- "statvfs", /* 330 */
- "fstatvfs",
- "lchown",
- "getsid",
- "sysfs",
- NULL, /* 335 */
- NULL,
- "sched_setparam",
- "sched_getparam",
- "sched_setscheduler",
- "sched_getscheduler", /* 340 */
- "sched_yield",
- "sched_get_priority_max",
- "sched_get_priority_min",
- "sched_rr_get_interval",
- "clock_settime", /* 345 */
- "clock_gettime",
- "clock_getres",
- "timer_create",
- "timer_delete",
- "timer_settime", /* 350 */
- "timer_gettime",
- "timer_getoverrun",
- "nanosleep",
- "toolbox",
- NULL, /* 355 */
- "getdents",
- "getcontext",
- "sysinfo",
- "fcntl64",
- "ftruncate64", /* 360 */
- "fstat64",
- "getdirentries64",
- "getrlimit64",
- "lockf64",
- "lseek64", /* 365 */
- "lstat64",
- "mmap64",
- "setrlimit64",
- "stat64",
- "truncate64", /* 370 */
- "ulimit64",
- NULL,
- NULL,
- NULL,
- NULL, /* 375 */
- NULL,
- NULL,
- NULL,
- NULL,
- "setcontext", /* 380 */
- "sigaltstack",
- "waitid",
- "setpgrp",
- "recvmsg2",
- "sendmsg2", /* 385 */
- "socket2",
- "socketpair2",
- "setregid",
- "lwp_create",
- "lwp_terminate", /* 390 */
- "lwp_wait",
- "lwp_suspend",
- "lwp_resume",
- "lwp_self",
- "lwp_abort_syscall", /* 395 */
- "lwp_info",
- "lwp_kill",
- "ksleep",
- "kwakeup",
- "ksleep_abort", /* 400 */
- "lwp_proc_info",
- "lwp_exit",
- "lwp_continue",
- "getacl",
- "fgetacl", /* 405 */
- "setacl",
- "fsetacl",
- "getaccess",
- "lwp_mutex_init",
- "lwp_mutex_lock_sys", /* 410 */
- "lwp_mutex_unlock",
- "lwp_cond_init",
- "lwp_cond_signal",
- "lwp_cond_broadcast",
- "lwp_cond_wait_sys", /* 415 */
- "lwp_getscheduler",
- "lwp_setscheduler",
- "lwp_getprivate",
- "lwp_setprivate",
- "lwp_detach", /* 420 */
- "mlock",
- "munlock",
- "mlockall",
- "munlockall",
- "shm_open", /* 425 */
- "shm_unlink",
- "sigqueue",
- "sigwaitinfo",
- "sigtimedwait",
- "sigwait", /* 430 */
- "aio_read",
- "aio_write",
- "lio_listio",
- "aio_error",
- "aio_return", /* 435 */
- "aio_cancel",
- "aio_suspend",
- "aio_fsync",
- "mq_open",
- "mq_unlink", /* 440 */
- "mq_send",
- "mq_receive",
- "mq_notify",
- "mq_setattr",
- "mq_getattr", /* 445 */
- "ksem_open",
- "ksem_unlink",
- "ksem_close",
- "ksem_destroy",
- "lw_sem_incr", /* 450 */
- "lw_sem_decr",
- "lw_sem_read",
- "mq_close",
-};
-static const int syscall_names_max = 453;
-
-int
-hpux_unimplemented(unsigned long arg1,unsigned long arg2,unsigned long arg3,
- unsigned long arg4,unsigned long arg5,unsigned long arg6,
- unsigned long arg7,unsigned long sc_num)
-{
- /* NOTE: sc_num trashes arg8 for the few syscalls that actually
- * have a valid 8th argument.
- */
- const char *name = NULL;
- if ( sc_num <= syscall_names_max && sc_num >= 0 ) {
- name = syscall_names[sc_num];
- }
-
- if ( name ) {
- printk(KERN_DEBUG "Unimplemented HP-UX syscall emulation. Syscall #%lu (%s)\n",
- sc_num, name);
- } else {
- printk(KERN_DEBUG "Unimplemented unknown HP-UX syscall emulation. Syscall #%lu\n",
- sc_num);
- }
-
- printk(KERN_DEBUG " Args: %lx %lx %lx %lx %lx %lx %lx\n",
- arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-
- return -ENOSYS;
-}
diff --git a/arch/parisc/hpux/wrappers.S b/arch/parisc/hpux/wrappers.S
deleted file mode 100644
index 58c53c879c02..000000000000
--- a/arch/parisc/hpux/wrappers.S
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Linux/PARISC Project (http://www.parisc-linux.org/)
- *
- * HP-UX System Call Wrapper routines and System Call Return Path
- *
- * Copyright (C) 2000 Hewlett-Packard (John Marvin)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifdef CONFIG_64BIT
-#warning PA64 support needs more work...did first cut
-#endif
-
-#include <asm/asm-offsets.h>
-#include <asm/assembly.h>
-#include <asm/signal.h>
-#include <linux/linkage.h>
-
- .level LEVEL
- .text
-
- /* These should probably go in a header file somewhere.
- * They are duplicated in kernel/wrappers.S
- * Possibly we should consider consolidating these
- * register save/restore macros.
- */
- .macro reg_save regs
-#ifdef CONFIG_64BIT
-#warning NEEDS WORK for 64-bit
-#endif
- STREG %r3, PT_GR3(\regs)
- STREG %r4, PT_GR4(\regs)
- STREG %r5, PT_GR5(\regs)
- STREG %r6, PT_GR6(\regs)
- STREG %r7, PT_GR7(\regs)
- STREG %r8, PT_GR8(\regs)
- STREG %r9, PT_GR9(\regs)
- STREG %r10,PT_GR10(\regs)
- STREG %r11,PT_GR11(\regs)
- STREG %r12,PT_GR12(\regs)
- STREG %r13,PT_GR13(\regs)
- STREG %r14,PT_GR14(\regs)
- STREG %r15,PT_GR15(\regs)
- STREG %r16,PT_GR16(\regs)
- STREG %r17,PT_GR17(\regs)
- STREG %r18,PT_GR18(\regs)
- .endm
-
- .macro reg_restore regs
- LDREG PT_GR3(\regs), %r3
- LDREG PT_GR4(\regs), %r4
- LDREG PT_GR5(\regs), %r5
- LDREG PT_GR6(\regs), %r6
- LDREG PT_GR7(\regs), %r7
- LDREG PT_GR8(\regs), %r8
- LDREG PT_GR9(\regs), %r9
- LDREG PT_GR10(\regs),%r10
- LDREG PT_GR11(\regs),%r11
- LDREG PT_GR12(\regs),%r12
- LDREG PT_GR13(\regs),%r13
- LDREG PT_GR14(\regs),%r14
- LDREG PT_GR15(\regs),%r15
- LDREG PT_GR16(\regs),%r16
- LDREG PT_GR17(\regs),%r17
- LDREG PT_GR18(\regs),%r18
- .endm
-
-
- .import sys_fork
-
-ENTRY(hpux_fork_wrapper)
- ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
- ;! pointer in task
- reg_save %r1
-
- STREG %r2,-20(%r30)
- ldo 64(%r30),%r30
- STREG %r2,PT_GR19(%r1) ;! save for child
- STREG %r30,PT_GR21(%r1) ;! save for child
-
- LDREG PT_GR30(%r1),%r25
- mtctl %r25,%cr29
- copy %r1,%r24
- bl sys_clone,%r2
- ldi SIGCHLD,%r26
-
- LDREG -84(%r30),%r2
-fork_return:
- ldo -64(%r30),%r30
- ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
-
- reg_restore %r1
-
- /*
- * HP-UX wants pid (child gets parent pid, parent gets child pid)
- * in r28 and a flag in r29 (r29 == 1 for child, 0 for parent).
- * Linux fork returns 0 for child, pid for parent. Since HP-UX
- * libc stub throws away parent pid and returns 0 for child,
- * we'll just return 0 for parent pid now. Only applications
- * that jump directly to the gateway page (not supported) will
- * know the difference. We can fix this later if necessary.
- */
-
- ldo -1024(%r0),%r1
- comb,>>=,n %r28,%r1,fork_exit /* just let the syscall exit handle it */
- or,= %r28,%r0,%r0
- or,tr %r0,%r0,%r29 /* r28 <> 0, we are parent, set r29 to 0 */
- ldo 1(%r0),%r29 /* r28 == 0, we are child, set r29 to 1 */
-
-fork_exit:
- bv %r0(%r2)
- nop
-ENDPROC(hpux_fork_wrapper)
-
- /* Set the return value for the child */
-
-ENTRY(hpux_child_return)
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
- bl,n schedule_tail, %r2
-#endif
-
- LDREG TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
- b fork_return
- copy %r0,%r28
-ENDPROC(hpux_child_return)
-
- .import hpux_execve
-
-ENTRY(hpux_execv_wrapper)
- copy %r0,%r24 /* NULL environment */
-
-ENTRY(hpux_execve_wrapper)
-
- ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
-
- /*
- * Do we need to save/restore r3-r18 here?
- * I don't think so. why would new thread need old
- * threads registers?
- */
-
- /* Store arg0, arg1 and arg2 so that hpux_execve will find them */
-
- STREG %r26,PT_GR26(%r1)
- STREG %r25,PT_GR25(%r1)
- STREG %r24,PT_GR24(%r1)
-
- STREG %r2,-20(%r30)
- ldo 64(%r30),%r30
- bl hpux_execve,%r2
- copy %r1,%arg0
-
- ldo -64(%r30),%r30
- LDREG -20(%r30),%r2
-
- /* If exec succeeded we need to load the args */
-
- ldo -1024(%r0),%r1
- comb,>>= %r28,%r1,exec_error
- copy %r2,%r19
- ldo -TASK_SZ_ALGN-64(%r30),%r1 ;! get task ptr
- LDREG TASK_PT_GR26(%r1),%r26
- LDREG TASK_PT_GR25(%r1),%r25
- LDREG TASK_PT_GR24(%r1),%r24
- LDREG TASK_PT_GR23(%r1),%r23
- copy %r0,%r2 /* Flag to syscall_exit not to clear args */
-
-exec_error:
- bv %r0(%r19)
- nop
-ENDPROC(hpux_execv_wrapper)
-
- .import hpux_pipe
-
- /* HP-UX expects pipefd's returned in r28 & r29 */
-
-ENTRY(hpux_pipe_wrapper)
- STREG %r2,-20(%r30)
- ldo 64(%r30),%r30
- bl hpux_pipe,%r2
- ldo -56(%r30),%r26 /* pass local array to hpux_pipe */
-
-
- ldo -1024(%r0),%r1
- comb,>>= %r28,%r1,pipe_exit /* let syscall exit handle it */
- LDREG -84(%r30),%r2
-
- /* if success, load fd's from stack array */
-
- LDREG -56(%r30),%r28
- LDREG -52(%r30),%r29
-
-pipe_exit:
- bv %r0(%r2)
- ldo -64(%r30),%r30
-ENDPROC(hpux_pipe_wrapper)
-
- .import syscall_exit
-
-ENTRY(hpux_syscall_exit)
- /*
- *
- * HP-UX call return conventions:
- *
- * if error:
- * r22 = 1
- * r28 = errno value
- * r29 = secondary return value
- * else
- * r22 = 0
- * r28 = return value
- * r29 = secondary return value
- *
- * For now, we'll just check to see if r28 is < (unsigned long)-1024
- * (to handle addresses > 2 Gb) and if so set r22 to zero. If not,
- * we'll complement r28 and set r22 to 1. Wrappers will be
- * needed for syscalls that care about the secondary return value.
- * The wrapper may also need a way of avoiding the following code,
- * but we'll deal with that when it becomes necessary.
- */
-
- ldo -1024(%r0),%r1
- comb,<< %r28,%r1,no_error
- copy %r0,%r22
- subi 0,%r28,%r28
- ldo 1(%r0),%r22
-
-no_error:
- b,n syscall_exit
-ENDPROC(hpux_syscall_exit)
-
- .import hpux_unimplemented
-
-ENTRY(hpux_unimplemented_wrapper)
- b hpux_unimplemented
- STREG %r22,-64(%r30) /* overwrite arg8 with syscall number */
-ENDPROC(hpux_unimplemented_wrapper)
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index 689a8ade3606..54adb60c0a42 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -330,8 +330,6 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
-extern void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm);
-
extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
index a5cb070b54bf..0abdd4c607ed 100644
--- a/arch/parisc/include/asm/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
@@ -17,7 +17,7 @@
#define KERNEL_DS ((mm_segment_t){0})
#define USER_DS ((mm_segment_t){1})
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
#define get_ds() (KERNEL_DS)
#define get_fs() (current_thread_info()->addr_limit)
@@ -42,14 +42,14 @@ static inline long access_ok(int type, const void __user * addr,
#if !defined(CONFIG_64BIT)
#define LDD_KERNEL(ptr) BUILD_BUG()
#define LDD_USER(ptr) BUILD_BUG()
-#define STD_KERNEL(x, ptr) __put_kernel_asm64(x,ptr)
-#define STD_USER(x, ptr) __put_user_asm64(x,ptr)
+#define STD_KERNEL(x, ptr) __put_kernel_asm64(x, ptr)
+#define STD_USER(x, ptr) __put_user_asm64(x, ptr)
#define ASM_WORD_INSN ".word\t"
#else
-#define LDD_KERNEL(ptr) __get_kernel_asm("ldd",ptr)
-#define LDD_USER(ptr) __get_user_asm("ldd",ptr)
-#define STD_KERNEL(x, ptr) __put_kernel_asm("std",x,ptr)
-#define STD_USER(x, ptr) __put_user_asm("std",x,ptr)
+#define LDD_KERNEL(ptr) __get_kernel_asm("ldd", ptr)
+#define LDD_USER(ptr) __get_user_asm("ldd", ptr)
+#define STD_KERNEL(x, ptr) __put_kernel_asm("std", x, ptr)
+#define STD_USER(x, ptr) __put_user_asm("std", x, ptr)
#define ASM_WORD_INSN ".dword\t"
#endif
@@ -80,68 +80,68 @@ struct exception_data {
unsigned long fault_addr;
};
-#define __get_user(x,ptr) \
-({ \
- register long __gu_err __asm__ ("r8") = 0; \
- register long __gu_val __asm__ ("r9") = 0; \
- \
- if (segment_eq(get_fs(),KERNEL_DS)) { \
- switch (sizeof(*(ptr))) { \
- case 1: __get_kernel_asm("ldb",ptr); break; \
- case 2: __get_kernel_asm("ldh",ptr); break; \
- case 4: __get_kernel_asm("ldw",ptr); break; \
- case 8: LDD_KERNEL(ptr); break; \
- default: BUILD_BUG(); break; \
- } \
- } \
- else { \
- switch (sizeof(*(ptr))) { \
- case 1: __get_user_asm("ldb",ptr); break; \
- case 2: __get_user_asm("ldh",ptr); break; \
- case 4: __get_user_asm("ldw",ptr); break; \
- case 8: LDD_USER(ptr); break; \
- default: BUILD_BUG(); break; \
- } \
- } \
- \
- (x) = (__typeof__(*(ptr))) __gu_val; \
- __gu_err; \
+#define __get_user(x, ptr) \
+({ \
+ register long __gu_err __asm__ ("r8") = 0; \
+ register long __gu_val __asm__ ("r9") = 0; \
+ \
+ if (segment_eq(get_fs(), KERNEL_DS)) { \
+ switch (sizeof(*(ptr))) { \
+ case 1: __get_kernel_asm("ldb", ptr); break; \
+ case 2: __get_kernel_asm("ldh", ptr); break; \
+ case 4: __get_kernel_asm("ldw", ptr); break; \
+ case 8: LDD_KERNEL(ptr); break; \
+ default: BUILD_BUG(); break; \
+ } \
+ } \
+ else { \
+ switch (sizeof(*(ptr))) { \
+ case 1: __get_user_asm("ldb", ptr); break; \
+ case 2: __get_user_asm("ldh", ptr); break; \
+ case 4: __get_user_asm("ldw", ptr); break; \
+ case 8: LDD_USER(ptr); break; \
+ default: BUILD_BUG(); break; \
+ } \
+ } \
+ \
+ (x) = (__force __typeof__(*(ptr))) __gu_val; \
+ __gu_err; \
})
-#define __get_kernel_asm(ldx,ptr) \
+#define __get_kernel_asm(ldx, ptr) \
__asm__("\n1:\t" ldx "\t0(%2),%0\n\t" \
ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_1)\
: "=r"(__gu_val), "=r"(__gu_err) \
: "r"(ptr), "1"(__gu_err) \
: "r1");
-#define __get_user_asm(ldx,ptr) \
+#define __get_user_asm(ldx, ptr) \
__asm__("\n1:\t" ldx "\t0(%%sr3,%2),%0\n\t" \
- ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_get_user_skip_1)\
+ ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_1)\
: "=r"(__gu_val), "=r"(__gu_err) \
: "r"(ptr), "1"(__gu_err) \
: "r1");
-#define __put_user(x,ptr) \
+#define __put_user(x, ptr) \
({ \
register long __pu_err __asm__ ("r8") = 0; \
__typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \
\
- if (segment_eq(get_fs(),KERNEL_DS)) { \
+ if (segment_eq(get_fs(), KERNEL_DS)) { \
switch (sizeof(*(ptr))) { \
- case 1: __put_kernel_asm("stb",__x,ptr); break; \
- case 2: __put_kernel_asm("sth",__x,ptr); break; \
- case 4: __put_kernel_asm("stw",__x,ptr); break; \
- case 8: STD_KERNEL(__x,ptr); break; \
+ case 1: __put_kernel_asm("stb", __x, ptr); break; \
+ case 2: __put_kernel_asm("sth", __x, ptr); break; \
+ case 4: __put_kernel_asm("stw", __x, ptr); break; \
+ case 8: STD_KERNEL(__x, ptr); break; \
default: BUILD_BUG(); break; \
} \
} \
else { \
switch (sizeof(*(ptr))) { \
- case 1: __put_user_asm("stb",__x,ptr); break; \
- case 2: __put_user_asm("sth",__x,ptr); break; \
- case 4: __put_user_asm("stw",__x,ptr); break; \
- case 8: STD_USER(__x,ptr); break; \
+ case 1: __put_user_asm("stb", __x, ptr); break; \
+ case 2: __put_user_asm("sth", __x, ptr); break; \
+ case 4: __put_user_asm("stw", __x, ptr); break; \
+ case 8: STD_USER(__x, ptr); break; \
default: BUILD_BUG(); break; \
} \
} \
@@ -159,18 +159,18 @@ struct exception_data {
* r8/r9 are already listed as err/val.
*/
-#define __put_kernel_asm(stx,x,ptr) \
+#define __put_kernel_asm(stx, x, ptr) \
__asm__ __volatile__ ( \
"\n1:\t" stx "\t%2,0(%1)\n\t" \
- ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_1)\
+ ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_1)\
: "=r"(__pu_err) \
: "r"(ptr), "r"(x), "0"(__pu_err) \
: "r1")
-#define __put_user_asm(stx,x,ptr) \
+#define __put_user_asm(stx, x, ptr) \
__asm__ __volatile__ ( \
"\n1:\t" stx "\t%2,0(%%sr3,%1)\n\t" \
- ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_1)\
+ ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_1)\
: "=r"(__pu_err) \
: "r"(ptr), "r"(x), "0"(__pu_err) \
: "r1")
@@ -178,23 +178,23 @@ struct exception_data {
#if !defined(CONFIG_64BIT)
-#define __put_kernel_asm64(__val,ptr) do { \
+#define __put_kernel_asm64(__val, ptr) do { \
__asm__ __volatile__ ( \
"\n1:\tstw %2,0(%1)" \
"\n2:\tstw %R2,4(%1)\n\t" \
- ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\
- ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\
+ ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_2)\
+ ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_put_user_skip_1)\
: "=r"(__pu_err) \
: "r"(ptr), "r"(__val), "0"(__pu_err) \
: "r1"); \
} while (0)
-#define __put_user_asm64(__val,ptr) do { \
+#define __put_user_asm64(__val, ptr) do { \
__asm__ __volatile__ ( \
"\n1:\tstw %2,0(%%sr3,%1)" \
"\n2:\tstw %R2,4(%%sr3,%1)\n\t" \
- ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\
- ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\
+ ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_2)\
+ ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_put_user_skip_1)\
: "=r"(__pu_err) \
: "r"(ptr), "r"(__val), "0"(__pu_err) \
: "r1"); \
@@ -211,8 +211,8 @@ extern unsigned long lcopy_to_user(void __user *, const void *, unsigned long);
extern unsigned long lcopy_from_user(void *, const void __user *, unsigned long);
extern unsigned long lcopy_in_user(void __user *, const void __user *, unsigned long);
extern long strncpy_from_user(char *, const char __user *, long);
-extern unsigned lclear_user(void __user *,unsigned long);
-extern long lstrnlen_user(const char __user *,long);
+extern unsigned lclear_user(void __user *, unsigned long);
+extern long lstrnlen_user(const char __user *, long);
/*
* Complex access routines -- macros
*/
diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h
index 5f5c0373de63..2e639d7604f6 100644
--- a/arch/parisc/include/uapi/asm/unistd.h
+++ b/arch/parisc/include/uapi/asm/unistd.h
@@ -2,480 +2,6 @@
#define _UAPI_ASM_PARISC_UNISTD_H_
/*
- * This file contains the system call numbers.
- */
-
-/*
- * HP-UX system calls get their native numbers for binary compatibility.
- */
-
-#define __NR_HPUX_exit 1
-#define __NR_HPUX_fork 2
-#define __NR_HPUX_read 3
-#define __NR_HPUX_write 4
-#define __NR_HPUX_open 5
-#define __NR_HPUX_close 6
-#define __NR_HPUX_wait 7
-#define __NR_HPUX_creat 8
-#define __NR_HPUX_link 9
-#define __NR_HPUX_unlink 10
-#define __NR_HPUX_execv 11
-#define __NR_HPUX_chdir 12
-#define __NR_HPUX_time 13
-#define __NR_HPUX_mknod 14
-#define __NR_HPUX_chmod 15
-#define __NR_HPUX_chown 16
-#define __NR_HPUX_break 17
-#define __NR_HPUX_lchmod 18
-#define __NR_HPUX_lseek 19
-#define __NR_HPUX_getpid 20
-#define __NR_HPUX_mount 21
-#define __NR_HPUX_umount 22
-#define __NR_HPUX_setuid 23
-#define __NR_HPUX_getuid 24
-#define __NR_HPUX_stime 25
-#define __NR_HPUX_ptrace 26
-#define __NR_HPUX_alarm 27
-#define __NR_HPUX_oldfstat 28
-#define __NR_HPUX_pause 29
-#define __NR_HPUX_utime 30
-#define __NR_HPUX_stty 31
-#define __NR_HPUX_gtty 32
-#define __NR_HPUX_access 33
-#define __NR_HPUX_nice 34
-#define __NR_HPUX_ftime 35
-#define __NR_HPUX_sync 36
-#define __NR_HPUX_kill 37
-#define __NR_HPUX_stat 38
-#define __NR_HPUX_setpgrp3 39
-#define __NR_HPUX_lstat 40
-#define __NR_HPUX_dup 41
-#define __NR_HPUX_pipe 42
-#define __NR_HPUX_times 43
-#define __NR_HPUX_profil 44
-#define __NR_HPUX_ki_call 45
-#define __NR_HPUX_setgid 46
-#define __NR_HPUX_getgid 47
-#define __NR_HPUX_sigsys 48
-#define __NR_HPUX_reserved1 49
-#define __NR_HPUX_reserved2 50
-#define __NR_HPUX_acct 51
-#define __NR_HPUX_set_userthreadid 52
-#define __NR_HPUX_oldlock 53
-#define __NR_HPUX_ioctl 54
-#define __NR_HPUX_reboot 55
-#define __NR_HPUX_symlink 56
-#define __NR_HPUX_utssys 57
-#define __NR_HPUX_readlink 58
-#define __NR_HPUX_execve 59
-#define __NR_HPUX_umask 60
-#define __NR_HPUX_chroot 61
-#define __NR_HPUX_fcntl 62
-#define __NR_HPUX_ulimit 63
-#define __NR_HPUX_getpagesize 64
-#define __NR_HPUX_mremap 65
-#define __NR_HPUX_vfork 66
-#define __NR_HPUX_vread 67
-#define __NR_HPUX_vwrite 68
-#define __NR_HPUX_sbrk 69
-#define __NR_HPUX_sstk 70
-#define __NR_HPUX_mmap 71
-#define __NR_HPUX_vadvise 72
-#define __NR_HPUX_munmap 73
-#define __NR_HPUX_mprotect 74
-#define __NR_HPUX_madvise 75
-#define __NR_HPUX_vhangup 76
-#define __NR_HPUX_swapoff 77
-#define __NR_HPUX_mincore 78
-#define __NR_HPUX_getgroups 79
-#define __NR_HPUX_setgroups 80
-#define __NR_HPUX_getpgrp2 81
-#define __NR_HPUX_setpgrp2 82
-#define __NR_HPUX_setitimer 83
-#define __NR_HPUX_wait3 84
-#define __NR_HPUX_swapon 85
-#define __NR_HPUX_getitimer 86
-#define __NR_HPUX_gethostname42 87
-#define __NR_HPUX_sethostname42 88
-#define __NR_HPUX_getdtablesize 89
-#define __NR_HPUX_dup2 90
-#define __NR_HPUX_getdopt 91
-#define __NR_HPUX_fstat 92
-#define __NR_HPUX_select 93
-#define __NR_HPUX_setdopt 94
-#define __NR_HPUX_fsync 95
-#define __NR_HPUX_setpriority 96
-#define __NR_HPUX_socket_old 97
-#define __NR_HPUX_connect_old 98
-#define __NR_HPUX_accept_old 99
-#define __NR_HPUX_getpriority 100
-#define __NR_HPUX_send_old 101
-#define __NR_HPUX_recv_old 102
-#define __NR_HPUX_socketaddr_old 103
-#define __NR_HPUX_bind_old 104
-#define __NR_HPUX_setsockopt_old 105
-#define __NR_HPUX_listen_old 106
-#define __NR_HPUX_vtimes_old 107
-#define __NR_HPUX_sigvector 108
-#define __NR_HPUX_sigblock 109
-#define __NR_HPUX_siggetmask 110
-#define __NR_HPUX_sigpause 111
-#define __NR_HPUX_sigstack 112
-#define __NR_HPUX_recvmsg_old 113
-#define __NR_HPUX_sendmsg_old 114
-#define __NR_HPUX_vtrace_old 115
-#define __NR_HPUX_gettimeofday 116
-#define __NR_HPUX_getrusage 117
-#define __NR_HPUX_getsockopt_old 118
-#define __NR_HPUX_resuba_old 119
-#define __NR_HPUX_readv 120
-#define __NR_HPUX_writev 121
-#define __NR_HPUX_settimeofday 122
-#define __NR_HPUX_fchown 123
-#define __NR_HPUX_fchmod 124
-#define __NR_HPUX_recvfrom_old 125
-#define __NR_HPUX_setresuid 126
-#define __NR_HPUX_setresgid 127
-#define __NR_HPUX_rename 128
-#define __NR_HPUX_truncate 129
-#define __NR_HPUX_ftruncate 130
-#define __NR_HPUX_flock_old 131
-#define __NR_HPUX_sysconf 132
-#define __NR_HPUX_sendto_old 133
-#define __NR_HPUX_shutdown_old 134
-#define __NR_HPUX_socketpair_old 135
-#define __NR_HPUX_mkdir 136
-#define __NR_HPUX_rmdir 137
-#define __NR_HPUX_utimes_old 138
-#define __NR_HPUX_sigcleanup_old 139
-#define __NR_HPUX_setcore 140
-#define __NR_HPUX_getpeername_old 141
-#define __NR_HPUX_gethostid 142
-#define __NR_HPUX_sethostid 143
-#define __NR_HPUX_getrlimit 144
-#define __NR_HPUX_setrlimit 145
-#define __NR_HPUX_killpg_old 146
-#define __NR_HPUX_cachectl 147
-#define __NR_HPUX_quotactl 148
-#define __NR_HPUX_get_sysinfo 149
-#define __NR_HPUX_getsockname_old 150
-#define __NR_HPUX_privgrp 151
-#define __NR_HPUX_rtprio 152
-#define __NR_HPUX_plock 153
-#define __NR_HPUX_reserved3 154
-#define __NR_HPUX_lockf 155
-#define __NR_HPUX_semget 156
-#define __NR_HPUX_osemctl 157
-#define __NR_HPUX_semop 158
-#define __NR_HPUX_msgget 159
-#define __NR_HPUX_omsgctl 160
-#define __NR_HPUX_msgsnd 161
-#define __NR_HPUX_msgrecv 162
-#define __NR_HPUX_shmget 163
-#define __NR_HPUX_oshmctl 164
-#define __NR_HPUX_shmat 165
-#define __NR_HPUX_shmdt 166
-#define __NR_HPUX_m68020_advise 167
-/* [168,189] are for Discless/DUX */
-#define __NR_HPUX_csp 168
-#define __NR_HPUX_cluster 169
-#define __NR_HPUX_mkrnod 170
-#define __NR_HPUX_test 171
-#define __NR_HPUX_unsp_open 172
-#define __NR_HPUX_reserved4 173
-#define __NR_HPUX_getcontext_old 174
-#define __NR_HPUX_osetcontext 175
-#define __NR_HPUX_bigio 176
-#define __NR_HPUX_pipenode 177
-#define __NR_HPUX_lsync 178
-#define __NR_HPUX_getmachineid 179
-#define __NR_HPUX_cnodeid 180
-#define __NR_HPUX_cnodes 181
-#define __NR_HPUX_swapclients 182
-#define __NR_HPUX_rmt_process 183
-#define __NR_HPUX_dskless_stats 184
-#define __NR_HPUX_sigprocmask 185
-#define __NR_HPUX_sigpending 186
-#define __NR_HPUX_sigsuspend 187
-#define __NR_HPUX_sigaction 188
-#define __NR_HPUX_reserved5 189
-#define __NR_HPUX_nfssvc 190
-#define __NR_HPUX_getfh 191
-#define __NR_HPUX_getdomainname 192
-#define __NR_HPUX_setdomainname 193
-#define __NR_HPUX_async_daemon 194
-#define __NR_HPUX_getdirentries 195
-#define __NR_HPUX_statfs 196
-#define __NR_HPUX_fstatfs 197
-#define __NR_HPUX_vfsmount 198
-#define __NR_HPUX_reserved6 199
-#define __NR_HPUX_waitpid 200
-/* 201 - 223 missing */
-#define __NR_HPUX_sigsetreturn 224
-#define __NR_HPUX_sigsetstatemask 225
-/* 226 missing */
-#define __NR_HPUX_cs 227
-#define __NR_HPUX_cds 228
-#define __NR_HPUX_set_no_trunc 229
-#define __NR_HPUX_pathconf 230
-#define __NR_HPUX_fpathconf 231
-/* 232, 233 missing */
-#define __NR_HPUX_nfs_fcntl 234
-#define __NR_HPUX_ogetacl 235
-#define __NR_HPUX_ofgetacl 236
-#define __NR_HPUX_osetacl 237
-#define __NR_HPUX_ofsetacl 238
-#define __NR_HPUX_pstat 239
-#define __NR_HPUX_getaudid 240
-#define __NR_HPUX_setaudid 241
-#define __NR_HPUX_getaudproc 242
-#define __NR_HPUX_setaudproc 243
-#define __NR_HPUX_getevent 244
-#define __NR_HPUX_setevent 245
-#define __NR_HPUX_audwrite 246
-#define __NR_HPUX_audswitch 247
-#define __NR_HPUX_audctl 248
-#define __NR_HPUX_ogetaccess 249
-#define __NR_HPUX_fsctl 250
-/* 251 - 258 missing */
-#define __NR_HPUX_swapfs 259
-#define __NR_HPUX_fss 260
-/* 261 - 266 missing */
-#define __NR_HPUX_tsync 267
-#define __NR_HPUX_getnumfds 268
-#define __NR_HPUX_poll 269
-#define __NR_HPUX_getmsg 270
-#define __NR_HPUX_putmsg 271
-#define __NR_HPUX_fchdir 272
-#define __NR_HPUX_getmount_cnt 273
-#define __NR_HPUX_getmount_entry 274
-#define __NR_HPUX_accept 275
-#define __NR_HPUX_bind 276
-#define __NR_HPUX_connect 277
-#define __NR_HPUX_getpeername 278
-#define __NR_HPUX_getsockname 279
-#define __NR_HPUX_getsockopt 280
-#define __NR_HPUX_listen 281
-#define __NR_HPUX_recv 282
-#define __NR_HPUX_recvfrom 283
-#define __NR_HPUX_recvmsg 284
-#define __NR_HPUX_send 285
-#define __NR_HPUX_sendmsg 286
-#define __NR_HPUX_sendto 287
-#define __NR_HPUX_setsockopt 288
-#define __NR_HPUX_shutdown 289
-#define __NR_HPUX_socket 290
-#define __NR_HPUX_socketpair 291
-#define __NR_HPUX_proc_open 292
-#define __NR_HPUX_proc_close 293
-#define __NR_HPUX_proc_send 294
-#define __NR_HPUX_proc_recv 295
-#define __NR_HPUX_proc_sendrecv 296
-#define __NR_HPUX_proc_syscall 297
-/* 298 - 311 missing */
-#define __NR_HPUX_semctl 312
-#define __NR_HPUX_msgctl 313
-#define __NR_HPUX_shmctl 314
-#define __NR_HPUX_mpctl 315
-#define __NR_HPUX_exportfs 316
-#define __NR_HPUX_getpmsg 317
-#define __NR_HPUX_putpmsg 318
-/* 319 missing */
-#define __NR_HPUX_msync 320
-#define __NR_HPUX_msleep 321
-#define __NR_HPUX_mwakeup 322
-#define __NR_HPUX_msem_init 323
-#define __NR_HPUX_msem_remove 324
-#define __NR_HPUX_adjtime 325
-#define __NR_HPUX_kload 326
-#define __NR_HPUX_fattach 327
-#define __NR_HPUX_fdetach 328
-#define __NR_HPUX_serialize 329
-#define __NR_HPUX_statvfs 330
-#define __NR_HPUX_fstatvfs 331
-#define __NR_HPUX_lchown 332
-#define __NR_HPUX_getsid 333
-#define __NR_HPUX_sysfs 334
-/* 335, 336 missing */
-#define __NR_HPUX_sched_setparam 337
-#define __NR_HPUX_sched_getparam 338
-#define __NR_HPUX_sched_setscheduler 339
-#define __NR_HPUX_sched_getscheduler 340
-#define __NR_HPUX_sched_yield 341
-#define __NR_HPUX_sched_get_priority_max 342
-#define __NR_HPUX_sched_get_priority_min 343
-#define __NR_HPUX_sched_rr_get_interval 344
-#define __NR_HPUX_clock_settime 345
-#define __NR_HPUX_clock_gettime 346
-#define __NR_HPUX_clock_getres 347
-#define __NR_HPUX_timer_create 348
-#define __NR_HPUX_timer_delete 349
-#define __NR_HPUX_timer_settime 350
-#define __NR_HPUX_timer_gettime 351
-#define __NR_HPUX_timer_getoverrun 352
-#define __NR_HPUX_nanosleep 353
-#define __NR_HPUX_toolbox 354
-/* 355 missing */
-#define __NR_HPUX_getdents 356
-#define __NR_HPUX_getcontext 357
-#define __NR_HPUX_sysinfo 358
-#define __NR_HPUX_fcntl64 359
-#define __NR_HPUX_ftruncate64 360
-#define __NR_HPUX_fstat64 361
-#define __NR_HPUX_getdirentries64 362
-#define __NR_HPUX_getrlimit64 363
-#define __NR_HPUX_lockf64 364
-#define __NR_HPUX_lseek64 365
-#define __NR_HPUX_lstat64 366
-#define __NR_HPUX_mmap64 367
-#define __NR_HPUX_setrlimit64 368
-#define __NR_HPUX_stat64 369
-#define __NR_HPUX_truncate64 370
-#define __NR_HPUX_ulimit64 371
-#define __NR_HPUX_pread 372
-#define __NR_HPUX_preadv 373
-#define __NR_HPUX_pwrite 374
-#define __NR_HPUX_pwritev 375
-#define __NR_HPUX_pread64 376
-#define __NR_HPUX_preadv64 377
-#define __NR_HPUX_pwrite64 378
-#define __NR_HPUX_pwritev64 379
-#define __NR_HPUX_setcontext 380
-#define __NR_HPUX_sigaltstack 381
-#define __NR_HPUX_waitid 382
-#define __NR_HPUX_setpgrp 383
-#define __NR_HPUX_recvmsg2 384
-#define __NR_HPUX_sendmsg2 385
-#define __NR_HPUX_socket2 386
-#define __NR_HPUX_socketpair2 387
-#define __NR_HPUX_setregid 388
-#define __NR_HPUX_lwp_create 389
-#define __NR_HPUX_lwp_terminate 390
-#define __NR_HPUX_lwp_wait 391
-#define __NR_HPUX_lwp_suspend 392
-#define __NR_HPUX_lwp_resume 393
-/* 394 missing */
-#define __NR_HPUX_lwp_abort_syscall 395
-#define __NR_HPUX_lwp_info 396
-#define __NR_HPUX_lwp_kill 397
-#define __NR_HPUX_ksleep 398
-#define __NR_HPUX_kwakeup 399
-/* 400 missing */
-#define __NR_HPUX_pstat_getlwp 401
-#define __NR_HPUX_lwp_exit 402
-#define __NR_HPUX_lwp_continue 403
-#define __NR_HPUX_getacl 404
-#define __NR_HPUX_fgetacl 405
-#define __NR_HPUX_setacl 406
-#define __NR_HPUX_fsetacl 407
-#define __NR_HPUX_getaccess 408
-#define __NR_HPUX_lwp_mutex_init 409
-#define __NR_HPUX_lwp_mutex_lock_sys 410
-#define __NR_HPUX_lwp_mutex_unlock 411
-#define __NR_HPUX_lwp_cond_init 412
-#define __NR_HPUX_lwp_cond_signal 413
-#define __NR_HPUX_lwp_cond_broadcast 414
-#define __NR_HPUX_lwp_cond_wait_sys 415
-#define __NR_HPUX_lwp_getscheduler 416
-#define __NR_HPUX_lwp_setscheduler 417
-#define __NR_HPUX_lwp_getstate 418
-#define __NR_HPUX_lwp_setstate 419
-#define __NR_HPUX_lwp_detach 420
-#define __NR_HPUX_mlock 421
-#define __NR_HPUX_munlock 422
-#define __NR_HPUX_mlockall 423
-#define __NR_HPUX_munlockall 424
-#define __NR_HPUX_shm_open 425
-#define __NR_HPUX_shm_unlink 426
-#define __NR_HPUX_sigqueue 427
-#define __NR_HPUX_sigwaitinfo 428
-#define __NR_HPUX_sigtimedwait 429
-#define __NR_HPUX_sigwait 430
-#define __NR_HPUX_aio_read 431
-#define __NR_HPUX_aio_write 432
-#define __NR_HPUX_lio_listio 433
-#define __NR_HPUX_aio_error 434
-#define __NR_HPUX_aio_return 435
-#define __NR_HPUX_aio_cancel 436
-#define __NR_HPUX_aio_suspend 437
-#define __NR_HPUX_aio_fsync 438
-#define __NR_HPUX_mq_open 439
-#define __NR_HPUX_mq_close 440
-#define __NR_HPUX_mq_unlink 441
-#define __NR_HPUX_mq_send 442
-#define __NR_HPUX_mq_receive 443
-#define __NR_HPUX_mq_notify 444
-#define __NR_HPUX_mq_setattr 445
-#define __NR_HPUX_mq_getattr 446
-#define __NR_HPUX_ksem_open 447
-#define __NR_HPUX_ksem_unlink 448
-#define __NR_HPUX_ksem_close 449
-#define __NR_HPUX_ksem_post 450
-#define __NR_HPUX_ksem_wait 451
-#define __NR_HPUX_ksem_read 452
-#define __NR_HPUX_ksem_trywait 453
-#define __NR_HPUX_lwp_rwlock_init 454
-#define __NR_HPUX_lwp_rwlock_destroy 455
-#define __NR_HPUX_lwp_rwlock_rdlock_sys 456
-#define __NR_HPUX_lwp_rwlock_wrlock_sys 457
-#define __NR_HPUX_lwp_rwlock_tryrdlock 458
-#define __NR_HPUX_lwp_rwlock_trywrlock 459
-#define __NR_HPUX_lwp_rwlock_unlock 460
-#define __NR_HPUX_ttrace 461
-#define __NR_HPUX_ttrace_wait 462
-#define __NR_HPUX_lf_wire_mem 463
-#define __NR_HPUX_lf_unwire_mem 464
-#define __NR_HPUX_lf_send_pin_map 465
-#define __NR_HPUX_lf_free_buf 466
-#define __NR_HPUX_lf_wait_nq 467
-#define __NR_HPUX_lf_wakeup_conn_q 468
-#define __NR_HPUX_lf_unused 469
-#define __NR_HPUX_lwp_sema_init 470
-#define __NR_HPUX_lwp_sema_post 471
-#define __NR_HPUX_lwp_sema_wait 472
-#define __NR_HPUX_lwp_sema_trywait 473
-#define __NR_HPUX_lwp_sema_destroy 474
-#define __NR_HPUX_statvfs64 475
-#define __NR_HPUX_fstatvfs64 476
-#define __NR_HPUX_msh_register 477
-#define __NR_HPUX_ptrace64 478
-#define __NR_HPUX_sendfile 479
-#define __NR_HPUX_sendpath 480
-#define __NR_HPUX_sendfile64 481
-#define __NR_HPUX_sendpath64 482
-#define __NR_HPUX_modload 483
-#define __NR_HPUX_moduload 484
-#define __NR_HPUX_modpath 485
-#define __NR_HPUX_getksym 486
-#define __NR_HPUX_modadm 487
-#define __NR_HPUX_modstat 488
-#define __NR_HPUX_lwp_detached_exit 489
-#define __NR_HPUX_crashconf 490
-#define __NR_HPUX_siginhibit 491
-#define __NR_HPUX_sigenable 492
-#define __NR_HPUX_spuctl 493
-#define __NR_HPUX_zerokernelsum 494
-#define __NR_HPUX_nfs_kstat 495
-#define __NR_HPUX_aio_read64 496
-#define __NR_HPUX_aio_write64 497
-#define __NR_HPUX_aio_error64 498
-#define __NR_HPUX_aio_return64 499
-#define __NR_HPUX_aio_cancel64 500
-#define __NR_HPUX_aio_suspend64 501
-#define __NR_HPUX_aio_fsync64 502
-#define __NR_HPUX_lio_listio64 503
-#define __NR_HPUX_recv2 504
-#define __NR_HPUX_recvfrom2 505
-#define __NR_HPUX_send2 506
-#define __NR_HPUX_sendto2 507
-#define __NR_HPUX_acl 508
-#define __NR_HPUX___cnx_p2p_ctl 509
-#define __NR_HPUX___cnx_gsched_ctl 510
-#define __NR_HPUX___cnx_pmon_ctl 511
-
-#define __NR_HPUX_syscalls 512
-
-/*
* Linux system call numbers.
*
* Cary Coutant says that we should just use another syscall gateway
@@ -484,9 +10,6 @@
* very least. If we decide to change it later, we can ``just'' tweak
* the LINUX_GATEWAY_ADDR define at the bottom and make __NR_Linux be
* 1024 or something. Oh, and recompile libc. =)
- *
- * 64-bit HPUX binaries get the syscall gateway address passed in a register
- * from the kernel at startup, which seems a sane strategy.
*/
#define __NR_Linux 0
@@ -834,15 +357,15 @@
#define __NR_getrandom (__NR_Linux + 339)
#define __NR_memfd_create (__NR_Linux + 340)
#define __NR_bpf (__NR_Linux + 341)
+#define __NR_execveat (__NR_Linux + 342)
-#define __NR_Linux_syscalls (__NR_bpf + 1)
+#define __NR_Linux_syscalls (__NR_execveat + 1)
#define __IGNORE_select /* newselect */
#define __IGNORE_fadvise64 /* fadvise64_64 */
-#define HPUX_GATEWAY_ADDR 0xC0000004
#define LINUX_GATEWAY_ADDR 0x100
#endif /* _UAPI_ASM_PARISC_UNISTD_H_ */
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index e8f07dd28401..2ab16bb160a8 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -1774,10 +1774,6 @@ ENTRY(sys_rt_sigreturn_wrapper)
ENDPROC(sys_rt_sigreturn_wrapper)
ENTRY(syscall_exit)
- /* NOTE: HP-UX syscalls also come through here
- * after hpux_syscall_exit fixes up return
- * values. */
-
/* NOTE: Not all syscalls exit this way. rt_sigreturn will exit
* via syscall_exit_rfi if the signal was received while the process
* was running.
@@ -1789,22 +1785,6 @@ ENTRY(syscall_exit)
LDREG TI_TASK(%r1),%r1
STREG %r28,TASK_PT_GR28(%r1)
-#ifdef CONFIG_HPUX
-/* <linux/personality.h> cannot be easily included */
-#define PER_HPUX 0x10
- ldw TASK_PERSONALITY(%r1),%r19
-
- /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
- ldo -PER_HPUX(%r19), %r19
- cmpib,COND(<>),n 0,%r19,1f
-
- /* Save other hpux returns if personality is PER_HPUX */
- STREG %r22,TASK_PT_GR22(%r1)
- STREG %r29,TASK_PT_GR29(%r1)
-1:
-
-#endif /* CONFIG_HPUX */
-
/* Seems to me that dp could be wrong here, if the syscall involved
* calling a module, and nothing got round to restoring dp on return.
*/
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 0bbbf0d3f608..8a488c22a99f 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -193,9 +193,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
* Make them const so the compiler knows they live in .text */
extern void * const ret_from_kernel_thread;
extern void * const child_return;
-#ifdef CONFIG_HPUX
- extern void * const hpux_child_return;
-#endif
+
if (unlikely(p->flags & PF_KTHREAD)) {
memset(cregs, 0, sizeof(struct pt_regs));
if (!usp) /* idle thread */
@@ -229,15 +227,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
cregs->gr[30] = usp;
}
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
- if (personality(p->personality) == PER_HPUX) {
-#ifdef CONFIG_HPUX
- cregs->kpc = (unsigned long) &hpux_child_return;
-#else
- BUG();
-#endif
- } else {
- cregs->kpc = (unsigned long) &child_return;
- }
+ cregs->kpc = (unsigned long) &child_return;
+
/* Setup thread TLS area from the 4th parameter in clone */
if (clone_flags & CLONE_SETTLS)
cregs->cr27 = cregs->gr[23];
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 9b910a0251b8..dc1ea796fd60 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -9,8 +9,7 @@
*
* Like the IA-64, we are a recent enough port (we are *starting*
* with glibc2.2) that we do not need to support the old non-realtime
- * Linux signals. Therefore we don't. HP/UX signals will go in
- * arch/parisc/hpux/signal.c when we figure out how to do them.
+ * Linux signals. Therefore we don't.
*/
#include <linux/sched.h>
@@ -476,6 +475,9 @@ insert_restart_trampoline(struct pt_regs *regs)
case -ERESTART_RESTARTBLOCK: {
/* Restart the system call - no handlers present */
unsigned int *usp = (unsigned int *)regs->gr[30];
+ unsigned long start = (unsigned long) &usp[2];
+ unsigned long end = (unsigned long) &usp[5];
+ long err = 0;
/* Setup a trampoline to restart the syscall
* with __NR_restart_syscall
@@ -487,23 +489,21 @@ insert_restart_trampoline(struct pt_regs *regs)
* 16: ldi __NR_restart_syscall, %r20
*/
#ifdef CONFIG_64BIT
- put_user(regs->gr[31] >> 32, &usp[0]);
- put_user(regs->gr[31] & 0xffffffff, &usp[1]);
- put_user(0x0fc010df, &usp[2]);
+ err |= put_user(regs->gr[31] >> 32, &usp[0]);
+ err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
+ err |= put_user(0x0fc010df, &usp[2]);
#else
- put_user(regs->gr[31], &usp[0]);
- put_user(0x0fc0109f, &usp[2]);
+ err |= put_user(regs->gr[31], &usp[0]);
+ err |= put_user(0x0fc0109f, &usp[2]);
#endif
- put_user(0xe0008200, &usp[3]);
- put_user(0x34140000, &usp[4]);
+ err |= put_user(0xe0008200, &usp[3]);
+ err |= put_user(0x34140000, &usp[4]);
- /* Stack is 64-byte aligned, and we only need
- * to flush 1 cache line.
- * Flushing one cacheline is cheap.
- * "sync" on bigger (> 4 way) boxes is not.
- */
- flush_user_dcache_range(regs->gr[30], regs->gr[30] + 4);
- flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
+ WARN_ON(err);
+
+ /* flush data/instruction cache for new insns */
+ flush_user_dcache_range(start, end);
+ flush_user_icache_range(start, end);
regs->gr[31] = regs->gr[30] + 8;
return;
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index ceda229ea6c2..52e85973a283 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -230,9 +230,6 @@ send_IPI_allbutself(enum ipi_message_type op)
inline void
smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); }
-static inline void
-smp_send_start(void) { send_IPI_allbutself(IPI_CPU_START); }
-
void
smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index fe4f0b89bf8f..5a8997d63899 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -437,6 +437,7 @@
ENTRY_SAME(getrandom)
ENTRY_SAME(memfd_create) /* 340 */
ENTRY_SAME(bpf)
+ ENTRY_COMP(execveat)
/* Nothing yet */
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 0bef864264c0..15dbe81cf5f3 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -750,78 +750,6 @@ static void __init gateway_init(void)
PAGE_SIZE, PAGE_GATEWAY, 1);
}
-#ifdef CONFIG_HPUX
-void
-map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm)
-{
- pgd_t *pg_dir;
- pmd_t *pmd;
- pte_t *pg_table;
- unsigned long start_pmd;
- unsigned long start_pte;
- unsigned long address;
- unsigned long hpux_gw_page_addr;
- /* FIXME: This is 'const' in order to trick the compiler
- into not treating it as DP-relative data. */
- extern void * const hpux_gateway_page;
-
- hpux_gw_page_addr = HPUX_GATEWAY_ADDR & PAGE_MASK;
-
- /*
- * Setup HP-UX Gateway page.
- *
- * The HP-UX gateway page resides in the user address space,
- * so it needs to be aliased into each process.
- */
-
- pg_dir = pgd_offset(mm,hpux_gw_page_addr);
-
-#if PTRS_PER_PMD == 1
- start_pmd = 0;
-#else
- start_pmd = ((hpux_gw_page_addr >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
-#endif
- start_pte = ((hpux_gw_page_addr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
-
- address = __pa(&hpux_gateway_page);
-#if PTRS_PER_PMD == 1
- pmd = (pmd_t *)__pa(pg_dir);
-#else
- pmd = (pmd_t *) pgd_address(*pg_dir);
-
- /*
- * pmd is physical at this point
- */
-
- if (!pmd) {
- pmd = (pmd_t *) get_zeroed_page(GFP_KERNEL);
- pmd = (pmd_t *) __pa(pmd);
- }
-
- __pgd_val_set(*pg_dir, PxD_FLAG_PRESENT | PxD_FLAG_VALID | (unsigned long) pmd);
-#endif
- /* now change pmd to kernel virtual addresses */
-
- pmd = (pmd_t *)__va(pmd) + start_pmd;
-
- /*
- * pg_table is physical at this point
- */
-
- pg_table = (pte_t *) pmd_address(*pmd);
- if (!pg_table)
- pg_table = (pte_t *) __pa(get_zeroed_page(GFP_KERNEL));
-
- __pmd_val_set(*pmd, PxD_FLAG_PRESENT | PxD_FLAG_VALID | (unsigned long) pg_table);
-
- /* now change pg_table to kernel virtual addresses */
-
- pg_table = (pte_t *) __va(pg_table) + start_pte;
- set_pte(pg_table, __mk_pte(address, PAGE_GATEWAY));
-}
-EXPORT_SYMBOL(map_hpux_gateway_page);
-#endif
-
void __init paging_init(void)
{
int i;
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index 14bdcbd31670..64b52b1cf542 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -333,8 +333,8 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
/*
* Encode and decode a swap entry.
* Note that the bits we use in a PTE for representing a swap entry
- * must not include the _PAGE_PRESENT bit, the _PAGE_FILE bit, or the
- *_PAGE_HASHPTE bit (if used). -- paulus
+ * must not include the _PAGE_PRESENT bit or the _PAGE_HASHPTE bit (if used).
+ * -- paulus
*/
#define __swp_type(entry) ((entry).val & 0x1f)
#define __swp_offset(entry) ((entry).val >> 5)
@@ -342,11 +342,6 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 })
-/* Encode and decode a nonlinear file mapping entry */
-#define PTE_FILE_MAX_BITS 29
-#define pte_to_pgoff(pte) (pte_val(pte) >> 3)
-#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE })
-
#ifndef CONFIG_PPC_4K_PAGES
void pgtable_cache_init(void);
#else
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index d46532ccc386..43e6ad424c7f 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -352,9 +352,6 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
#define __swp_entry(type, offset) ((swp_entry_t){((type)<< 1)|((offset)<<8)})
#define __pte_to_swp_entry(pte) ((swp_entry_t){pte_val(pte) >> PTE_RPN_SHIFT})
#define __swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_RPN_SHIFT })
-#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_RPN_SHIFT)
-#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
-#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_RPN_SHIFT)
void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
void pgtable_cache_init(void);
@@ -389,7 +386,7 @@ void pgtable_cache_init(void);
* The last three bits are intentionally left to zero. This memory location
* are also used as normal page PTE pointers. So if we have any pointers
* left around while we collapse a hugepage, we need to make sure
- * _PAGE_PRESENT and _PAGE_FILE bits of that are zero when we look at them
+ * _PAGE_PRESENT bit of that is zero when we look at them
*/
static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index)
{
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 79fee2eb8d56..9835ac4173b7 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -34,7 +34,6 @@ static inline int pte_write(pte_t pte)
{ return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; }
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
-static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/pte-40x.h
index ec0b0b0d1df9..486b1ef81338 100644
--- a/arch/powerpc/include/asm/pte-40x.h
+++ b/arch/powerpc/include/asm/pte-40x.h
@@ -38,7 +38,6 @@
*/
#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
-#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
diff --git a/arch/powerpc/include/asm/pte-44x.h b/arch/powerpc/include/asm/pte-44x.h
index 4192b9bad901..36f75fab23f5 100644
--- a/arch/powerpc/include/asm/pte-44x.h
+++ b/arch/powerpc/include/asm/pte-44x.h
@@ -44,9 +44,6 @@
* - PRESENT *must* be in the bottom three bits because swap cache
* entries use the top 29 bits for TLB2.
*
- * - FILE *must* be in the bottom three bits because swap cache
- * entries use the top 29 bits for TLB2.
- *
* - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
* because it doesn't support SMP. However, some later 460 variants
* have -some- form of SMP support and so I keep the bit there for
@@ -68,7 +65,6 @@
*
* There are three protection bits available for SWAP entry:
* _PAGE_PRESENT
- * _PAGE_FILE
* _PAGE_HASHPTE (if HW has)
*
* So those three bits have to be inside of 0-2nd LSB of PTE.
@@ -77,7 +73,6 @@
#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
#define _PAGE_RW 0x00000002 /* S: Write permission */
-#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */
#define _PAGE_EXEC 0x00000004 /* H: Execute permission */
#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h
index eb6edb44f140..97bae64afdaa 100644
--- a/arch/powerpc/include/asm/pte-8xx.h
+++ b/arch/powerpc/include/asm/pte-8xx.h
@@ -29,7 +29,6 @@
/* Definitions for 8xx embedded chips. */
#define _PAGE_PRESENT 0x0001 /* Page is valid */
-#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */
#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
#define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */
diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h
index 576ad88104cb..91a704952ca1 100644
--- a/arch/powerpc/include/asm/pte-book3e.h
+++ b/arch/powerpc/include/asm/pte-book3e.h
@@ -10,7 +10,6 @@
/* Architected bits */
#define _PAGE_PRESENT 0x000001 /* software: pte contains a translation */
-#define _PAGE_FILE 0x000002 /* (!present only) software: pte holds file offset */
#define _PAGE_SW1 0x000002
#define _PAGE_BAP_SR 0x000004
#define _PAGE_BAP_UR 0x000008
diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
index e84dd7ed505e..9f5c3d04a1a3 100644
--- a/arch/powerpc/include/asm/pte-fsl-booke.h
+++ b/arch/powerpc/include/asm/pte-fsl-booke.h
@@ -13,14 +13,11 @@
- PRESENT *must* be in the bottom three bits because swap cache
entries use the top 29 bits.
- - FILE *must* be in the bottom three bits because swap cache
- entries use the top 29 bits.
*/
/* Definitions for FSL Book-E Cores */
#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
-#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
#define _PAGE_EXEC 0x00010 /* H: SX permission */
diff --git a/arch/powerpc/include/asm/pte-hash32.h b/arch/powerpc/include/asm/pte-hash32.h
index 4aad4132d0a8..62cfb0c663bb 100644
--- a/arch/powerpc/include/asm/pte-hash32.h
+++ b/arch/powerpc/include/asm/pte-hash32.h
@@ -18,7 +18,6 @@
#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
-#define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
#define _PAGE_USER 0x004 /* usermode access allowed */
#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
diff --git a/arch/powerpc/include/asm/pte-hash64.h b/arch/powerpc/include/asm/pte-hash64.h
index 55aea0caf95e..fc852f7e7b3a 100644
--- a/arch/powerpc/include/asm/pte-hash64.h
+++ b/arch/powerpc/include/asm/pte-hash64.h
@@ -16,7 +16,6 @@
*/
#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
#define _PAGE_USER 0x0002 /* matches one of the PP bits */
-#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */
#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
#define _PAGE_GUARDED 0x0008
/* We can derive Memory coherence from _PAGE_NO_CACHE */
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index f96d1ec24189..1a74446fd9e5 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -96,8 +96,6 @@ int default_machine_kexec_prepare(struct kimage *image)
return 0;
}
-#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
-
static void copy_segments(unsigned long ind)
{
unsigned long entry;
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 91bb8836825a..6957cc1ca0a7 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -782,7 +782,7 @@ pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
{
pmd_t pmd;
/*
- * For a valid pte, we would have _PAGE_PRESENT or _PAGE_FILE always
+ * For a valid pte, we would have _PAGE_PRESENT always
* set. We use this to check THP page at pmd level.
* leaf pte for huge page, bottom two bits != 00
*/
diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h
index f664e96f48c7..1a9a98de5bde 100644
--- a/arch/s390/include/asm/pci_io.h
+++ b/arch/s390/include/asm/pci_io.h
@@ -16,6 +16,7 @@
struct zpci_iomap_entry {
u32 fh;
u8 bar;
+ u16 count;
};
extern struct zpci_iomap_entry *zpci_iomap_start;
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 3290f11ae1d9..753a56731951 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -259,7 +259,10 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
}
/* Create a virtual mapping cookie for a PCI BAR */
-void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max)
+void __iomem *pci_iomap_range(struct pci_dev *pdev,
+ int bar,
+ unsigned long offset,
+ unsigned long max)
{
struct zpci_dev *zdev = get_zdev(pdev);
u64 addr;
@@ -270,14 +273,27 @@ void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max)
idx = zdev->bars[bar].map_idx;
spin_lock(&zpci_iomap_lock);
- zpci_iomap_start[idx].fh = zdev->fh;
- zpci_iomap_start[idx].bar = bar;
+ if (zpci_iomap_start[idx].count++) {
+ BUG_ON(zpci_iomap_start[idx].fh != zdev->fh ||
+ zpci_iomap_start[idx].bar != bar);
+ } else {
+ zpci_iomap_start[idx].fh = zdev->fh;
+ zpci_iomap_start[idx].bar = bar;
+ }
+ /* Detect overrun */
+ BUG_ON(!zpci_iomap_start[idx].count);
spin_unlock(&zpci_iomap_lock);
addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
- return (void __iomem *) addr;
+ return (void __iomem *) addr + offset;
}
-EXPORT_SYMBOL_GPL(pci_iomap);
+EXPORT_SYMBOL_GPL(pci_iomap_range);
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+ return pci_iomap_range(dev, bar, 0, maxlen);
+}
+EXPORT_SYMBOL(pci_iomap);
void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
{
@@ -285,8 +301,12 @@ void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
spin_lock(&zpci_iomap_lock);
- zpci_iomap_start[idx].fh = 0;
- zpci_iomap_start[idx].bar = 0;
+ /* Detect underrun */
+ BUG_ON(!zpci_iomap_start[idx].count);
+ if (!--zpci_iomap_start[idx].count) {
+ zpci_iomap_start[idx].fh = 0;
+ zpci_iomap_start[idx].bar = 0;
+ }
spin_unlock(&zpci_iomap_lock);
}
EXPORT_SYMBOL_GPL(pci_iounmap);
diff --git a/arch/sh/include/asm/segment.h b/arch/sh/include/asm/segment.h
index 5e2725f4ac49..ff795d3a6909 100644
--- a/arch/sh/include/asm/segment.h
+++ b/arch/sh/include/asm/segment.h
@@ -23,7 +23,7 @@ typedef struct {
#define USER_DS KERNEL_DS
#endif
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
#define get_ds() (KERNEL_DS)
diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h
index 9486376605f4..a49635c51266 100644
--- a/arch/sh/include/asm/uaccess.h
+++ b/arch/sh/include/asm/uaccess.h
@@ -60,7 +60,7 @@ struct __large_struct { unsigned long buf[100]; };
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
@@ -71,7 +71,7 @@ struct __large_struct { unsigned long buf[100]; };
const __typeof__(*(ptr)) *__gu_addr = (ptr); \
if (likely(access_ok(VERIFY_READ, __gu_addr, (size)))) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
- (x) = (__typeof__(*(ptr)))__gu_val; \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
diff --git a/arch/sh/include/asm/uaccess_64.h b/arch/sh/include/asm/uaccess_64.h
index 2e07e0f40c6a..c01376c76b86 100644
--- a/arch/sh/include/asm/uaccess_64.h
+++ b/arch/sh/include/asm/uaccess_64.h
@@ -59,19 +59,19 @@ do { \
switch (size) { \
case 1: \
retval = __put_user_asm_b((void *)&x, \
- (long)ptr); \
+ (__force long)ptr); \
break; \
case 2: \
retval = __put_user_asm_w((void *)&x, \
- (long)ptr); \
+ (__force long)ptr); \
break; \
case 4: \
retval = __put_user_asm_l((void *)&x, \
- (long)ptr); \
+ (__force long)ptr); \
break; \
case 8: \
retval = __put_user_asm_q((void *)&x, \
- (long)ptr); \
+ (__force long)ptr); \
break; \
default: \
__put_user_unknown(); \
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 9634d086fc56..64ee103dc29d 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -37,7 +37,7 @@
#define get_fs() (current->thread.current_ds)
#define set_fs(val) ((current->thread.current_ds) = (val))
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
/* We have there a nice not-mapped page at PAGE_OFFSET - PAGE_SIZE, so that this test
* can be fairly lightweight.
@@ -46,8 +46,8 @@
*/
#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
-#define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
-#define access_ok(type, addr, size) \
+#define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size)))
+#define access_ok(type, addr, size) \
({ (void)(type); __access_ok((unsigned long)(addr), size); })
/*
@@ -91,158 +91,221 @@ void __ret_efault(void);
* of a performance impact. Thus we have a few rather ugly macros here,
* and hide all the ugliness from the user.
*/
-#define put_user(x,ptr) ({ \
-unsigned long __pu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
-
-#define get_user(x,ptr) ({ \
-unsigned long __gu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+#define put_user(x, ptr) ({ \
+ unsigned long __pu_addr = (unsigned long)(ptr); \
+ __chk_user_ptr(ptr); \
+ __put_user_check((__typeof__(*(ptr)))(x), __pu_addr, sizeof(*(ptr))); \
+})
+
+#define get_user(x, ptr) ({ \
+ unsigned long __gu_addr = (unsigned long)(ptr); \
+ __chk_user_ptr(ptr); \
+ __get_user_check((x), __gu_addr, sizeof(*(ptr)), __typeof__(*(ptr))); \
+})
/*
* The "__xxx" versions do not do address space checking, useful when
* doing multiple accesses to the same area (the user has to do the
* checks by hand with "access_ok()")
*/
-#define __put_user(x,ptr) __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
+#define __put_user(x, ptr) \
+ __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+#define __get_user(x, ptr) \
+ __get_user_nocheck((x), (ptr), sizeof(*(ptr)), __typeof__(*(ptr)))
struct __large_struct { unsigned long buf[100]; };
#define __m(x) ((struct __large_struct __user *)(x))
-#define __put_user_check(x,addr,size) ({ \
-register int __pu_ret; \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
-case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
-case 4: __put_user_asm(x,,addr,__pu_ret); break; \
-case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} } else { __pu_ret = -EFAULT; } __pu_ret; })
-
-#define __put_user_nocheck(x,addr,size) ({ \
-register int __pu_ret; \
-switch (size) { \
-case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
-case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
-case 4: __put_user_asm(x,,addr,__pu_ret); break; \
-case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} __pu_ret; })
-
-#define __put_user_asm(x,size,addr,ret) \
+#define __put_user_check(x, addr, size) ({ \
+ register int __pu_ret; \
+ if (__access_ok(addr, size)) { \
+ switch (size) { \
+ case 1: \
+ __put_user_asm(x, b, addr, __pu_ret); \
+ break; \
+ case 2: \
+ __put_user_asm(x, h, addr, __pu_ret); \
+ break; \
+ case 4: \
+ __put_user_asm(x, , addr, __pu_ret); \
+ break; \
+ case 8: \
+ __put_user_asm(x, d, addr, __pu_ret); \
+ break; \
+ default: \
+ __pu_ret = __put_user_bad(); \
+ break; \
+ } \
+ } else { \
+ __pu_ret = -EFAULT; \
+ } \
+ __pu_ret; \
+})
+
+#define __put_user_nocheck(x, addr, size) ({ \
+ register int __pu_ret; \
+ switch (size) { \
+ case 1: __put_user_asm(x, b, addr, __pu_ret); break; \
+ case 2: __put_user_asm(x, h, addr, __pu_ret); break; \
+ case 4: __put_user_asm(x, , addr, __pu_ret); break; \
+ case 8: __put_user_asm(x, d, addr, __pu_ret); break; \
+ default: __pu_ret = __put_user_bad(); break; \
+ } \
+ __pu_ret; \
+})
+
+#define __put_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
- "/* Put user asm, inline. */\n" \
-"1:\t" "st"#size " %1, %2\n\t" \
- "clr %0\n" \
-"2:\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
-"3:\n\t" \
- "b 2b\n\t" \
- " mov %3, %0\n\t" \
- ".previous\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\t" \
- ".previous\n\n\t" \
- : "=&r" (ret) : "r" (x), "m" (*__m(addr)), \
- "i" (-EFAULT))
+ "/* Put user asm, inline. */\n" \
+ "1:\t" "st"#size " %1, %2\n\t" \
+ "clr %0\n" \
+ "2:\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "b 2b\n\t" \
+ " mov %3, %0\n\t" \
+ ".previous\n\n\t" \
+ ".section __ex_table,#alloc\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\t" \
+ ".previous\n\n\t" \
+ : "=&r" (ret) : "r" (x), "m" (*__m(addr)), \
+ "i" (-EFAULT))
int __put_user_bad(void);
-#define __get_user_check(x,addr,size,type) ({ \
-register int __gu_ret; \
-register unsigned long __gu_val; \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
-case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
-case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
-case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
-default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
-} } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; })
-
-#define __get_user_check_ret(x,addr,size,type,retval) ({ \
-register unsigned long __gu_val __asm__ ("l1"); \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
-case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
-case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
-case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
-default: if (__get_user_bad()) return retval; \
-} x = (type) __gu_val; } else return retval; })
-
-#define __get_user_nocheck(x,addr,size,type) ({ \
-register int __gu_ret; \
-register unsigned long __gu_val; \
-switch (size) { \
-case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
-case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
-case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
-case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
-default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
-} x = (type) __gu_val; __gu_ret; })
-
-#define __get_user_nocheck_ret(x,addr,size,type,retval) ({ \
-register unsigned long __gu_val __asm__ ("l1"); \
-switch (size) { \
-case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
-case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
-case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
-case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
-default: if (__get_user_bad()) return retval; \
-} x = (type) __gu_val; })
-
-#define __get_user_asm(x,size,addr,ret) \
+#define __get_user_check(x, addr, size, type) ({ \
+ register int __gu_ret; \
+ register unsigned long __gu_val; \
+ if (__access_ok(addr, size)) { \
+ switch (size) { \
+ case 1: \
+ __get_user_asm(__gu_val, ub, addr, __gu_ret); \
+ break; \
+ case 2: \
+ __get_user_asm(__gu_val, uh, addr, __gu_ret); \
+ break; \
+ case 4: \
+ __get_user_asm(__gu_val, , addr, __gu_ret); \
+ break; \
+ case 8: \
+ __get_user_asm(__gu_val, d, addr, __gu_ret); \
+ break; \
+ default: \
+ __gu_val = 0; \
+ __gu_ret = __get_user_bad(); \
+ break; \
+ } \
+ } else { \
+ __gu_val = 0; \
+ __gu_ret = -EFAULT; \
+ } \
+ x = (__force type) __gu_val; \
+ __gu_ret; \
+})
+
+#define __get_user_check_ret(x, addr, size, type, retval) ({ \
+ register unsigned long __gu_val __asm__ ("l1"); \
+ if (__access_ok(addr, size)) { \
+ switch (size) { \
+ case 1: \
+ __get_user_asm_ret(__gu_val, ub, addr, retval); \
+ break; \
+ case 2: \
+ __get_user_asm_ret(__gu_val, uh, addr, retval); \
+ break; \
+ case 4: \
+ __get_user_asm_ret(__gu_val, , addr, retval); \
+ break; \
+ case 8: \
+ __get_user_asm_ret(__gu_val, d, addr, retval); \
+ break; \
+ default: \
+ if (__get_user_bad()) \
+ return retval; \
+ } \
+ x = (__force type) __gu_val; \
+ } else \
+ return retval; \
+})
+
+#define __get_user_nocheck(x, addr, size, type) ({ \
+ register int __gu_ret; \
+ register unsigned long __gu_val; \
+ switch (size) { \
+ case 1: __get_user_asm(__gu_val, ub, addr, __gu_ret); break; \
+ case 2: __get_user_asm(__gu_val, uh, addr, __gu_ret); break; \
+ case 4: __get_user_asm(__gu_val, , addr, __gu_ret); break; \
+ case 8: __get_user_asm(__gu_val, d, addr, __gu_ret); break; \
+ default: \
+ __gu_val = 0; \
+ __gu_ret = __get_user_bad(); \
+ break; \
+ } \
+ x = (__force type) __gu_val; \
+ __gu_ret; \
+})
+
+#define __get_user_nocheck_ret(x, addr, size, type, retval) ({ \
+ register unsigned long __gu_val __asm__ ("l1"); \
+ switch (size) { \
+ case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \
+ case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \
+ case 4: __get_user_asm_ret(__gu_val, , addr, retval); break; \
+ case 8: __get_user_asm_ret(__gu_val, d, addr, retval); break; \
+ default: \
+ if (__get_user_bad()) \
+ return retval; \
+ } \
+ x = (__force type) __gu_val; \
+})
+
+#define __get_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
- "/* Get user asm, inline. */\n" \
-"1:\t" "ld"#size " %2, %1\n\t" \
- "clr %0\n" \
-"2:\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
-"3:\n\t" \
- "clr %1\n\t" \
- "b 2b\n\t" \
- " mov %3, %0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=&r" (ret), "=&r" (x) : "m" (*__m(addr)), \
- "i" (-EFAULT))
-
-#define __get_user_asm_ret(x,size,addr,retval) \
+ "/* Get user asm, inline. */\n" \
+ "1:\t" "ld"#size " %2, %1\n\t" \
+ "clr %0\n" \
+ "2:\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "clr %1\n\t" \
+ "b 2b\n\t" \
+ " mov %3, %0\n\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,#alloc\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\n\t" \
+ ".previous\n\t" \
+ : "=&r" (ret), "=&r" (x) : "m" (*__m(addr)), \
+ "i" (-EFAULT))
+
+#define __get_user_asm_ret(x, size, addr, retval) \
if (__builtin_constant_p(retval) && retval == -EFAULT) \
-__asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
-"1:\t" "ld"#size " %1, %0\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b,__ret_efault\n\n\t" \
- ".previous\n\t" \
- : "=&r" (x) : "m" (*__m(addr))); \
+ __asm__ __volatile__( \
+ "/* Get user asm ret, inline. */\n" \
+ "1:\t" "ld"#size " %1, %0\n\n\t" \
+ ".section __ex_table,#alloc\n\t" \
+ ".align 4\n\t" \
+ ".word 1b,__ret_efault\n\n\t" \
+ ".previous\n\t" \
+ : "=&r" (x) : "m" (*__m(addr))); \
else \
-__asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
-"1:\t" "ld"#size " %1, %0\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
-"3:\n\t" \
- "ret\n\t" \
- " restore %%g0, %2, %%o0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
+ __asm__ __volatile__( \
+ "/* Get user asm ret, inline. */\n" \
+ "1:\t" "ld"#size " %1, %0\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "ret\n\t" \
+ " restore %%g0, %2, %%o0\n\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,#alloc\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\n\t" \
+ ".previous\n\t" \
+ : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
int __get_user_bad(void);
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index c990a5e577f0..a35194b7dba0 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -41,11 +41,11 @@
#define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)})
#define get_ds() (KERNEL_DS)
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
#define set_fs(val) \
do { \
- current_thread_info()->current_ds =(val).seg; \
+ current_thread_info()->current_ds = (val).seg; \
__asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \
} while(0)
@@ -88,121 +88,135 @@ void __retl_efault(void);
* of a performance impact. Thus we have a few rather ugly macros here,
* and hide all the ugliness from the user.
*/
-#define put_user(x,ptr) ({ \
-unsigned long __pu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
+#define put_user(x, ptr) ({ \
+ unsigned long __pu_addr = (unsigned long)(ptr); \
+ __chk_user_ptr(ptr); \
+ __put_user_nocheck((__typeof__(*(ptr)))(x), __pu_addr, sizeof(*(ptr)));\
+})
-#define get_user(x,ptr) ({ \
-unsigned long __gu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+#define get_user(x, ptr) ({ \
+ unsigned long __gu_addr = (unsigned long)(ptr); \
+ __chk_user_ptr(ptr); \
+ __get_user_nocheck((x), __gu_addr, sizeof(*(ptr)), __typeof__(*(ptr)));\
+})
-#define __put_user(x,ptr) put_user(x,ptr)
-#define __get_user(x,ptr) get_user(x,ptr)
+#define __put_user(x, ptr) put_user(x, ptr)
+#define __get_user(x, ptr) get_user(x, ptr)
struct __large_struct { unsigned long buf[100]; };
#define __m(x) ((struct __large_struct *)(x))
-#define __put_user_nocheck(data,addr,size) ({ \
-register int __pu_ret; \
-switch (size) { \
-case 1: __put_user_asm(data,b,addr,__pu_ret); break; \
-case 2: __put_user_asm(data,h,addr,__pu_ret); break; \
-case 4: __put_user_asm(data,w,addr,__pu_ret); break; \
-case 8: __put_user_asm(data,x,addr,__pu_ret); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} __pu_ret; })
-
-#define __put_user_asm(x,size,addr,ret) \
+#define __put_user_nocheck(data, addr, size) ({ \
+ register int __pu_ret; \
+ switch (size) { \
+ case 1: __put_user_asm(data, b, addr, __pu_ret); break; \
+ case 2: __put_user_asm(data, h, addr, __pu_ret); break; \
+ case 4: __put_user_asm(data, w, addr, __pu_ret); break; \
+ case 8: __put_user_asm(data, x, addr, __pu_ret); break; \
+ default: __pu_ret = __put_user_bad(); break; \
+ } \
+ __pu_ret; \
+})
+
+#define __put_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
- "/* Put user asm, inline. */\n" \
-"1:\t" "st"#size "a %1, [%2] %%asi\n\t" \
- "clr %0\n" \
-"2:\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
-"3:\n\t" \
- "sethi %%hi(2b), %0\n\t" \
- "jmpl %0 + %%lo(2b), %%g0\n\t" \
- " mov %3, %0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\t" \
- ".previous\n\n\t" \
- : "=r" (ret) : "r" (x), "r" (__m(addr)), \
- "i" (-EFAULT))
+ "/* Put user asm, inline. */\n" \
+ "1:\t" "st"#size "a %1, [%2] %%asi\n\t" \
+ "clr %0\n" \
+ "2:\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "sethi %%hi(2b), %0\n\t" \
+ "jmpl %0 + %%lo(2b), %%g0\n\t" \
+ " mov %3, %0\n\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\t" \
+ ".previous\n\n\t" \
+ : "=r" (ret) : "r" (x), "r" (__m(addr)), \
+ "i" (-EFAULT))
int __put_user_bad(void);
-#define __get_user_nocheck(data,addr,size,type) ({ \
-register int __gu_ret; \
-register unsigned long __gu_val; \
-switch (size) { \
-case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
-case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
-case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
-case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
-default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
-} data = (type) __gu_val; __gu_ret; })
-
-#define __get_user_nocheck_ret(data,addr,size,type,retval) ({ \
-register unsigned long __gu_val __asm__ ("l1"); \
-switch (size) { \
-case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
-case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
-case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
-case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
-default: if (__get_user_bad()) return retval; \
-} data = (type) __gu_val; })
-
-#define __get_user_asm(x,size,addr,ret) \
+#define __get_user_nocheck(data, addr, size, type) ({ \
+ register int __gu_ret; \
+ register unsigned long __gu_val; \
+ switch (size) { \
+ case 1: __get_user_asm(__gu_val, ub, addr, __gu_ret); break; \
+ case 2: __get_user_asm(__gu_val, uh, addr, __gu_ret); break; \
+ case 4: __get_user_asm(__gu_val, uw, addr, __gu_ret); break; \
+ case 8: __get_user_asm(__gu_val, x, addr, __gu_ret); break; \
+ default: \
+ __gu_val = 0; \
+ __gu_ret = __get_user_bad(); \
+ break; \
+ } \
+ data = (__force type) __gu_val; \
+ __gu_ret; \
+})
+
+#define __get_user_nocheck_ret(data, addr, size, type, retval) ({ \
+ register unsigned long __gu_val __asm__ ("l1"); \
+ switch (size) { \
+ case 1: __get_user_asm_ret(__gu_val, ub, addr, retval); break; \
+ case 2: __get_user_asm_ret(__gu_val, uh, addr, retval); break; \
+ case 4: __get_user_asm_ret(__gu_val, uw, addr, retval); break; \
+ case 8: __get_user_asm_ret(__gu_val, x, addr, retval); break; \
+ default: \
+ if (__get_user_bad()) \
+ return retval; \
+ } \
+ data = (__force type) __gu_val; \
+})
+
+#define __get_user_asm(x, size, addr, ret) \
__asm__ __volatile__( \
- "/* Get user asm, inline. */\n" \
-"1:\t" "ld"#size "a [%2] %%asi, %1\n\t" \
- "clr %0\n" \
-"2:\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
-"3:\n\t" \
- "sethi %%hi(2b), %0\n\t" \
- "clr %1\n\t" \
- "jmpl %0 + %%lo(2b), %%g0\n\t" \
- " mov %3, %0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=r" (ret), "=r" (x) : "r" (__m(addr)), \
- "i" (-EFAULT))
-
-#define __get_user_asm_ret(x,size,addr,retval) \
+ "/* Get user asm, inline. */\n" \
+ "1:\t" "ld"#size "a [%2] %%asi, %1\n\t" \
+ "clr %0\n" \
+ "2:\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "sethi %%hi(2b), %0\n\t" \
+ "clr %1\n\t" \
+ "jmpl %0 + %%lo(2b), %%g0\n\t" \
+ " mov %3, %0\n\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\n\t" \
+ ".previous\n\t" \
+ : "=r" (ret), "=r" (x) : "r" (__m(addr)), \
+ "i" (-EFAULT))
+
+#define __get_user_asm_ret(x, size, addr, retval) \
if (__builtin_constant_p(retval) && retval == -EFAULT) \
-__asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
-"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b,__ret_efault\n\n\t" \
- ".previous\n\t" \
- : "=r" (x) : "r" (__m(addr))); \
+ __asm__ __volatile__( \
+ "/* Get user asm ret, inline. */\n" \
+ "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".align 4\n\t" \
+ ".word 1b,__ret_efault\n\n\t" \
+ ".previous\n\t" \
+ : "=r" (x) : "r" (__m(addr))); \
else \
-__asm__ __volatile__( \
- "/* Get user asm ret, inline. */\n" \
-"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
- ".section .fixup,#alloc,#execinstr\n\t" \
- ".align 4\n" \
-"3:\n\t" \
- "ret\n\t" \
- " restore %%g0, %2, %%o0\n\n\t" \
- ".previous\n\t" \
- ".section __ex_table,\"a\"\n\t" \
- ".align 4\n\t" \
- ".word 1b, 3b\n\n\t" \
- ".previous\n\t" \
- : "=r" (x) : "r" (__m(addr)), "i" (retval))
+ __asm__ __volatile__( \
+ "/* Get user asm ret, inline. */\n" \
+ "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \
+ ".section .fixup,#alloc,#execinstr\n\t" \
+ ".align 4\n" \
+ "3:\n\t" \
+ "ret\n\t" \
+ " restore %%g0, %2, %%o0\n\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,\"a\"\n\t" \
+ ".align 4\n\t" \
+ ".word 1b, 3b\n\n\t" \
+ ".previous\n\t" \
+ : "=r" (x) : "r" (__m(addr)), "i" (retval))
int __get_user_bad(void);
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h
index 879fd7d33877..ef01fef3eebc 100644
--- a/arch/x86/include/asm/lguest_hcall.h
+++ b/arch/x86/include/asm/lguest_hcall.h
@@ -16,7 +16,6 @@
#define LHCALL_SET_PTE 14
#define LHCALL_SET_PGD 15
#define LHCALL_LOAD_TLS 16
-#define LHCALL_NOTIFY 17
#define LHCALL_LOAD_GDT_ENTRY 18
#define LHCALL_SEND_INTERRUPTS 19
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h
index 876e74e8eec7..09b9620a73b4 100644
--- a/arch/x86/include/asm/mmu.h
+++ b/arch/x86/include/asm/mmu.h
@@ -19,6 +19,8 @@ typedef struct {
struct mutex lock;
void __user *vdso;
+
+ atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */
} mm_context_t;
#ifdef CONFIG_SMP
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 4b75d591eb5e..883f6b933fa4 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -18,6 +18,21 @@ static inline void paravirt_activate_mm(struct mm_struct *prev,
}
#endif /* !CONFIG_PARAVIRT */
+#ifdef CONFIG_PERF_EVENTS
+extern struct static_key rdpmc_always_available;
+
+static inline void load_mm_cr4(struct mm_struct *mm)
+{
+ if (static_key_true(&rdpmc_always_available) ||
+ atomic_read(&mm->context.perf_rdpmc_allowed))
+ cr4_set_bits(X86_CR4_PCE);
+ else
+ cr4_clear_bits(X86_CR4_PCE);
+}
+#else
+static inline void load_mm_cr4(struct mm_struct *mm) {}
+#endif
+
/*
* Used for LDT copy/destruction.
*/
@@ -52,15 +67,20 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
/* Stop flush ipis for the previous mm */
cpumask_clear_cpu(cpu, mm_cpumask(prev));
+ /* Load per-mm CR4 state */
+ load_mm_cr4(next);
+
/*
* Load the LDT, if the LDT is different.
*
- * It's possible leave_mm(prev) has been called. If so,
- * then prev->context.ldt could be out of sync with the
- * LDT descriptor or the LDT register. This can only happen
- * if prev->context.ldt is non-null, since we never free
- * an LDT. But LDTs can't be shared across mms, so
- * prev->context.ldt won't be equal to next->context.ldt.
+ * It's possible that prev->context.ldt doesn't match
+ * the LDT register. This can happen if leave_mm(prev)
+ * was called and then modify_ldt changed
+ * prev->context.ldt but suppressed an IPI to this CPU.
+ * In this case, prev->context.ldt != NULL, because we
+ * never free an LDT while the mm still exists. That
+ * means that next->context.ldt != prev->context.ldt,
+ * because mms never share an LDT.
*/
if (unlikely(prev->context.ldt != next->context.ldt))
load_LDT_nolock(&next->context);
@@ -85,6 +105,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
*/
load_cr3(next->pgd);
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
+ load_mm_cr4(next);
load_LDT_nolock(&next->context);
}
}
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 32444ae939ca..965c47d254aa 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -80,16 +80,16 @@ static inline void write_cr3(unsigned long x)
PVOP_VCALL1(pv_mmu_ops.write_cr3, x);
}
-static inline unsigned long read_cr4(void)
+static inline unsigned long __read_cr4(void)
{
return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4);
}
-static inline unsigned long read_cr4_safe(void)
+static inline unsigned long __read_cr4_safe(void)
{
return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4_safe);
}
-static inline void write_cr4(unsigned long x)
+static inline void __write_cr4(unsigned long x)
{
PVOP_VCALL1(pv_cpu_ops.write_cr4, x);
}
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index a092a0cce0b7..ec1c93588cef 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -579,39 +579,6 @@ static inline void load_sp0(struct tss_struct *tss,
#define set_iopl_mask native_set_iopl_mask
#endif /* CONFIG_PARAVIRT */
-/*
- * Save the cr4 feature set we're using (ie
- * Pentium 4MB enable and PPro Global page
- * enable), so that any CPU's that boot up
- * after us can get the correct flags.
- */
-extern unsigned long mmu_cr4_features;
-extern u32 *trampoline_cr4_features;
-
-static inline void set_in_cr4(unsigned long mask)
-{
- unsigned long cr4;
-
- mmu_cr4_features |= mask;
- if (trampoline_cr4_features)
- *trampoline_cr4_features = mmu_cr4_features;
- cr4 = read_cr4();
- cr4 |= mask;
- write_cr4(cr4);
-}
-
-static inline void clear_in_cr4(unsigned long mask)
-{
- unsigned long cr4;
-
- mmu_cr4_features &= ~mask;
- if (trampoline_cr4_features)
- *trampoline_cr4_features = mmu_cr4_features;
- cr4 = read_cr4();
- cr4 &= ~mask;
- write_cr4(cr4);
-}
-
typedef struct {
unsigned long seg;
} mm_segment_t;
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
index e820c080a4e9..6a4b00fafb00 100644
--- a/arch/x86/include/asm/special_insns.h
+++ b/arch/x86/include/asm/special_insns.h
@@ -137,17 +137,17 @@ static inline void write_cr3(unsigned long x)
native_write_cr3(x);
}
-static inline unsigned long read_cr4(void)
+static inline unsigned long __read_cr4(void)
{
return native_read_cr4();
}
-static inline unsigned long read_cr4_safe(void)
+static inline unsigned long __read_cr4_safe(void)
{
return native_read_cr4_safe();
}
-static inline void write_cr4(unsigned long x)
+static inline void __write_cr4(unsigned long x)
{
native_write_cr4(x);
}
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 04905bfc508b..cd791948b286 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -15,6 +15,75 @@
#define __flush_tlb_single(addr) __native_flush_tlb_single(addr)
#endif
+struct tlb_state {
+#ifdef CONFIG_SMP
+ struct mm_struct *active_mm;
+ int state;
+#endif
+
+ /*
+ * Access to this CR4 shadow and to H/W CR4 is protected by
+ * disabling interrupts when modifying either one.
+ */
+ unsigned long cr4;
+};
+DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
+
+/* Initialize cr4 shadow for this CPU. */
+static inline void cr4_init_shadow(void)
+{
+ this_cpu_write(cpu_tlbstate.cr4, __read_cr4());
+}
+
+/* Set in this cpu's CR4. */
+static inline void cr4_set_bits(unsigned long mask)
+{
+ unsigned long cr4;
+
+ cr4 = this_cpu_read(cpu_tlbstate.cr4);
+ if ((cr4 | mask) != cr4) {
+ cr4 |= mask;
+ this_cpu_write(cpu_tlbstate.cr4, cr4);
+ __write_cr4(cr4);
+ }
+}
+
+/* Clear in this cpu's CR4. */
+static inline void cr4_clear_bits(unsigned long mask)
+{
+ unsigned long cr4;
+
+ cr4 = this_cpu_read(cpu_tlbstate.cr4);
+ if ((cr4 & ~mask) != cr4) {
+ cr4 &= ~mask;
+ this_cpu_write(cpu_tlbstate.cr4, cr4);
+ __write_cr4(cr4);
+ }
+}
+
+/* Read the CR4 shadow. */
+static inline unsigned long cr4_read_shadow(void)
+{
+ return this_cpu_read(cpu_tlbstate.cr4);
+}
+
+/*
+ * Save some of cr4 feature set we're using (e.g. Pentium 4MB
+ * enable and PPro Global page enable), so that any CPU's that boot
+ * up after us can get the correct flags. This should only be used
+ * during boot on the boot cpu.
+ */
+extern unsigned long mmu_cr4_features;
+extern u32 *trampoline_cr4_features;
+
+static inline void cr4_set_bits_and_update_boot(unsigned long mask)
+{
+ mmu_cr4_features |= mask;
+ if (trampoline_cr4_features)
+ *trampoline_cr4_features = mmu_cr4_features;
+ cr4_set_bits(mask);
+}
+
static inline void __native_flush_tlb(void)
{
native_write_cr3(native_read_cr3());
@@ -24,7 +93,7 @@ static inline void __native_flush_tlb_global_irq_disabled(void)
{
unsigned long cr4;
- cr4 = native_read_cr4();
+ cr4 = this_cpu_read(cpu_tlbstate.cr4);
/* clear PGE */
native_write_cr4(cr4 & ~X86_CR4_PGE);
/* write old PGE again and flush TLBs */
@@ -184,12 +253,6 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
#define TLBSTATE_OK 1
#define TLBSTATE_LAZY 2
-struct tlb_state {
- struct mm_struct *active_mm;
- int state;
-};
-DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
-
static inline void reset_lazy_tlbstate(void)
{
this_cpu_write(cpu_tlbstate.state, 0);
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 0d592e0a5b84..ace9dec050b1 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -179,7 +179,7 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
asm volatile("call __get_user_%P3" \
: "=a" (__ret_gu), "=r" (__val_gu) \
: "0" (ptr), "i" (sizeof(*(ptr)))); \
- (x) = (__typeof__(*(ptr))) __val_gu; \
+ (x) = (__force __typeof__(*(ptr))) __val_gu; \
__ret_gu; \
})
diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h
index 5da71c27cc59..cce9ee68e335 100644
--- a/arch/x86/include/asm/virtext.h
+++ b/arch/x86/include/asm/virtext.h
@@ -19,6 +19,7 @@
#include <asm/vmx.h>
#include <asm/svm.h>
+#include <asm/tlbflush.h>
/*
* VMX functions:
@@ -40,12 +41,12 @@ static inline int cpu_has_vmx(void)
static inline void cpu_vmxoff(void)
{
asm volatile (ASM_VMX_VMXOFF : : : "cc");
- write_cr4(read_cr4() & ~X86_CR4_VMXE);
+ cr4_clear_bits(X86_CR4_VMXE);
}
static inline int cpu_vmx_enabled(void)
{
- return read_cr4() & X86_CR4_VMXE;
+ return __read_cr4() & X86_CR4_VMXE;
}
/** Disable VMX if it is enabled on the current CPU
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 31368207837c..d1daead5fcdd 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -78,7 +78,7 @@ int x86_acpi_suspend_lowlevel(void)
header->pmode_cr0 = read_cr0();
if (__this_cpu_read(cpu_info.cpuid_level) >= 0) {
- header->pmode_cr4 = read_cr4();
+ header->pmode_cr4 = __read_cr4();
header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_CR4);
}
if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index b15bffcaba6d..b5c8ff5e9dfc 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -19,6 +19,7 @@
#include <asm/archrandom.h>
#include <asm/hypervisor.h>
#include <asm/processor.h>
+#include <asm/tlbflush.h>
#include <asm/debugreg.h>
#include <asm/sections.h>
#include <asm/vsyscall.h>
@@ -278,7 +279,7 @@ __setup("nosmep", setup_disable_smep);
static __always_inline void setup_smep(struct cpuinfo_x86 *c)
{
if (cpu_has(c, X86_FEATURE_SMEP))
- set_in_cr4(X86_CR4_SMEP);
+ cr4_set_bits(X86_CR4_SMEP);
}
static __init int setup_disable_smap(char *arg)
@@ -298,9 +299,9 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_SMAP)) {
#ifdef CONFIG_X86_SMAP
- set_in_cr4(X86_CR4_SMAP);
+ cr4_set_bits(X86_CR4_SMAP);
#else
- clear_in_cr4(X86_CR4_SMAP);
+ cr4_clear_bits(X86_CR4_SMAP);
#endif
}
}
@@ -1295,6 +1296,12 @@ void cpu_init(void)
wait_for_master_cpu(cpu);
/*
+ * Initialize the CR4 shadow before doing anything that could
+ * try to read it.
+ */
+ cr4_init_shadow();
+
+ /*
* Load microcode on this cpu if a valid microcode is available.
* This is early microcode loading procedure.
*/
@@ -1313,7 +1320,7 @@ void cpu_init(void)
pr_debug("Initializing CPU#%d\n", cpu);
- clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
+ cr4_clear_bits(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
/*
* Initialize the per-CPU GDT with the boot GDT,
@@ -1394,7 +1401,7 @@ void cpu_init(void)
printk(KERN_INFO "Initializing CPU#%d\n", cpu);
if (cpu_feature_enabled(X86_FEATURE_VME) || cpu_has_tsc || cpu_has_de)
- clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
+ cr4_clear_bits(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
load_current_idt();
switch_to_new_gdt(cpu);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index cdfed7953963..3c036cb4a370 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -44,6 +44,7 @@
#include <asm/processor.h>
#include <asm/traps.h>
+#include <asm/tlbflush.h>
#include <asm/mce.h>
#include <asm/msr.h>
@@ -151,14 +152,11 @@ static struct mce_log mcelog = {
void mce_log(struct mce *mce)
{
unsigned next, entry;
- int ret = 0;
/* Emit the trace record: */
trace_mce_record(mce);
- ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
- if (ret == NOTIFY_STOP)
- return;
+ atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
mce->finished = 0;
wmb();
@@ -1452,7 +1450,7 @@ static void __mcheck_cpu_init_generic(void)
bitmap_fill(all_banks, MAX_NR_BANKS);
machine_check_poll(MCP_UC | m_fl, &all_banks);
- set_in_cr4(X86_CR4_MCE);
+ cr4_set_bits(X86_CR4_MCE);
rdmsrl(MSR_IA32_MCG_CAP, cap);
if (cap & MCG_CTL_P)
diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c
index ec2663a708e4..737b0ad4e61a 100644
--- a/arch/x86/kernel/cpu/mcheck/p5.c
+++ b/arch/x86/kernel/cpu/mcheck/p5.c
@@ -9,6 +9,7 @@
#include <asm/processor.h>
#include <asm/traps.h>
+#include <asm/tlbflush.h>
#include <asm/mce.h>
#include <asm/msr.h>
@@ -65,7 +66,7 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
"Intel old style machine check architecture supported.\n");
/* Enable MCE: */
- set_in_cr4(X86_CR4_MCE);
+ cr4_set_bits(X86_CR4_MCE);
printk(KERN_INFO
"Intel old style machine check reporting enabled on CPU#%d.\n",
smp_processor_id());
diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c
index bd5d46a32210..44f138296fbe 100644
--- a/arch/x86/kernel/cpu/mcheck/winchip.c
+++ b/arch/x86/kernel/cpu/mcheck/winchip.c
@@ -8,6 +8,7 @@
#include <asm/processor.h>
#include <asm/traps.h>
+#include <asm/tlbflush.h>
#include <asm/mce.h>
#include <asm/msr.h>
@@ -36,7 +37,7 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c)
lo &= ~(1<<4); /* Enable MCE */
wrmsr(MSR_IDT_FCR1, lo, hi);
- set_in_cr4(X86_CR4_MCE);
+ cr4_set_bits(X86_CR4_MCE);
printk(KERN_INFO
"Winchip machine check reporting enabled on CPU#0.\n");
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
index 9e451b0876b5..f8c81ba0b465 100644
--- a/arch/x86/kernel/cpu/mtrr/cyrix.c
+++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
@@ -138,8 +138,8 @@ static void prepare_set(void)
/* Save value of CR4 and clear Page Global Enable (bit 7) */
if (cpu_has_pge) {
- cr4 = read_cr4();
- write_cr4(cr4 & ~X86_CR4_PGE);
+ cr4 = __read_cr4();
+ __write_cr4(cr4 & ~X86_CR4_PGE);
}
/*
@@ -171,7 +171,7 @@ static void post_set(void)
/* Restore value of CR4 */
if (cpu_has_pge)
- write_cr4(cr4);
+ __write_cr4(cr4);
}
static void cyrix_set_arr(unsigned int reg, unsigned long base,
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 0e25a1bc5ab5..7d74f7b3c6ba 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -678,8 +678,8 @@ static void prepare_set(void) __acquires(set_atomicity_lock)
/* Save value of CR4 and clear Page Global Enable (bit 7) */
if (cpu_has_pge) {
- cr4 = read_cr4();
- write_cr4(cr4 & ~X86_CR4_PGE);
+ cr4 = __read_cr4();
+ __write_cr4(cr4 & ~X86_CR4_PGE);
}
/* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
@@ -708,7 +708,7 @@ static void post_set(void) __releases(set_atomicity_lock)
/* Restore value of CR4 */
if (cpu_has_pge)
- write_cr4(cr4);
+ __write_cr4(cr4);
raw_spin_unlock(&set_atomicity_lock);
}
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 143e5f5dc855..b71a7f86d68a 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -31,6 +31,8 @@
#include <asm/nmi.h>
#include <asm/smp.h>
#include <asm/alternative.h>
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
#include <asm/timer.h>
#include <asm/desc.h>
#include <asm/ldt.h>
@@ -43,6 +45,8 @@ DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
.enabled = 1,
};
+struct static_key rdpmc_always_available = STATIC_KEY_INIT_FALSE;
+
u64 __read_mostly hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
@@ -1327,8 +1331,6 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
break;
case CPU_STARTING:
- if (x86_pmu.attr_rdpmc)
- set_in_cr4(X86_CR4_PCE);
if (x86_pmu.cpu_starting)
x86_pmu.cpu_starting(cpu);
break;
@@ -1804,14 +1806,44 @@ static int x86_pmu_event_init(struct perf_event *event)
event->destroy(event);
}
+ if (ACCESS_ONCE(x86_pmu.attr_rdpmc))
+ event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
+
return err;
}
+static void refresh_pce(void *ignored)
+{
+ if (current->mm)
+ load_mm_cr4(current->mm);
+}
+
+static void x86_pmu_event_mapped(struct perf_event *event)
+{
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+ return;
+
+ if (atomic_inc_return(&current->mm->context.perf_rdpmc_allowed) == 1)
+ on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+}
+
+static void x86_pmu_event_unmapped(struct perf_event *event)
+{
+ if (!current->mm)
+ return;
+
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
+ return;
+
+ if (atomic_dec_and_test(&current->mm->context.perf_rdpmc_allowed))
+ on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1);
+}
+
static int x86_pmu_event_idx(struct perf_event *event)
{
int idx = event->hw.idx;
- if (!x86_pmu.attr_rdpmc)
+ if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED))
return 0;
if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) {
@@ -1829,16 +1861,6 @@ static ssize_t get_attr_rdpmc(struct device *cdev,
return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
}
-static void change_rdpmc(void *info)
-{
- bool enable = !!(unsigned long)info;
-
- if (enable)
- set_in_cr4(X86_CR4_PCE);
- else
- clear_in_cr4(X86_CR4_PCE);
-}
-
static ssize_t set_attr_rdpmc(struct device *cdev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1850,14 +1872,27 @@ static ssize_t set_attr_rdpmc(struct device *cdev,
if (ret)
return ret;
+ if (val > 2)
+ return -EINVAL;
+
if (x86_pmu.attr_rdpmc_broken)
return -ENOTSUPP;
- if (!!val != !!x86_pmu.attr_rdpmc) {
- x86_pmu.attr_rdpmc = !!val;
- on_each_cpu(change_rdpmc, (void *)val, 1);
+ if ((val == 2) != (x86_pmu.attr_rdpmc == 2)) {
+ /*
+ * Changing into or out of always available, aka
+ * perf-event-bypassing mode. This path is extremely slow,
+ * but only root can trigger it, so it's okay.
+ */
+ if (val == 2)
+ static_key_slow_inc(&rdpmc_always_available);
+ else
+ static_key_slow_dec(&rdpmc_always_available);
+ on_each_cpu(refresh_pce, NULL, 1);
}
+ x86_pmu.attr_rdpmc = val;
+
return count;
}
@@ -1900,6 +1935,9 @@ static struct pmu pmu = {
.event_init = x86_pmu_event_init,
+ .event_mapped = x86_pmu_event_mapped,
+ .event_unmapped = x86_pmu_event_unmapped,
+
.add = x86_pmu_add,
.del = x86_pmu_del,
.start = x86_pmu_start,
@@ -1914,13 +1952,15 @@ static struct pmu pmu = {
.flush_branch_stack = x86_pmu_flush_branch_stack,
};
-void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
+void arch_perf_update_userpage(struct perf_event *event,
+ struct perf_event_mmap_page *userpg, u64 now)
{
struct cyc2ns_data *data;
userpg->cap_user_time = 0;
userpg->cap_user_time_zero = 0;
- userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc;
+ userpg->cap_user_rdpmc =
+ !!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED);
userpg->pmc_width = x86_pmu.cntval_bits;
if (!sched_clock_stable())
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 4e6cdb0ddc70..df525d2be1e8 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -71,6 +71,8 @@ struct event_constraint {
#define PERF_X86_EVENT_COMMITTED 0x8 /* event passed commit_txn */
#define PERF_X86_EVENT_PEBS_LD_HSW 0x10 /* haswell style datala, load */
#define PERF_X86_EVENT_PEBS_NA_HSW 0x20 /* haswell style datala, unknown */
+#define PERF_X86_EVENT_RDPMC_ALLOWED 0x40 /* grant rdpmc permission */
+
struct amd_nb {
int nb_id; /* NorthBridge id */
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index d6c1b9836995..2911ef3a9f1c 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -31,6 +31,7 @@ static void __init i386_default_early_setup(void)
asmlinkage __visible void __init i386_start_kernel(void)
{
+ cr4_init_shadow();
sanitize_boot_params(&boot_params);
/* Call the subarch specific early setup function */
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index efcddfaf05f9..c4f8d4659070 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -156,6 +156,8 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
(__START_KERNEL & PGDIR_MASK)));
BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) <= MODULES_END);
+ cr4_init_shadow();
+
/* Kill off the identity-map trampoline */
reset_early_page_tables();
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index 81049ffab2d6..d5651fce0b71 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -13,6 +13,7 @@
#include <asm/sigcontext.h>
#include <asm/processor.h>
#include <asm/math_emu.h>
+#include <asm/tlbflush.h>
#include <asm/uaccess.h>
#include <asm/ptrace.h>
#include <asm/i387.h>
@@ -193,7 +194,7 @@ void fpu_init(void)
if (cpu_has_xmm)
cr4_mask |= X86_CR4_OSXMMEXCPT;
if (cr4_mask)
- set_in_cr4(cr4_mask);
+ cr4_set_bits(cr4_mask);
cr0 = read_cr0();
cr0 &= ~(X86_CR0_TS|X86_CR0_EM); /* clear TS and EM */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index e127ddaa2d5a..046e2d620bbe 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -28,6 +28,7 @@
#include <asm/fpu-internal.h>
#include <asm/debugreg.h>
#include <asm/nmi.h>
+#include <asm/tlbflush.h>
/*
* per-CPU TSS segments. Threads are completely 'soft' on Linux,
@@ -141,7 +142,7 @@ void flush_thread(void)
static void hard_disable_TSC(void)
{
- write_cr4(read_cr4() | X86_CR4_TSD);
+ cr4_set_bits(X86_CR4_TSD);
}
void disable_TSC(void)
@@ -158,7 +159,7 @@ void disable_TSC(void)
static void hard_enable_TSC(void)
{
- write_cr4(read_cr4() & ~X86_CR4_TSD);
+ cr4_clear_bits(X86_CR4_TSD);
}
static void enable_TSC(void)
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 8f3ebfe710d0..603c4f99cb5a 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -101,7 +101,7 @@ void __show_regs(struct pt_regs *regs, int all)
cr0 = read_cr0();
cr2 = read_cr2();
cr3 = read_cr3();
- cr4 = read_cr4_safe();
+ cr4 = __read_cr4_safe();
printk(KERN_DEFAULT "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
cr0, cr2, cr3, cr4);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 5a2c02913af3..67fcc43577d2 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -93,7 +93,7 @@ void __show_regs(struct pt_regs *regs, int all)
cr0 = read_cr0();
cr2 = read_cr2();
cr3 = read_cr3();
- cr4 = read_cr4();
+ cr4 = __read_cr4();
printk(KERN_DEFAULT "FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
fs, fsindex, gs, gsindex, shadowgs);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 27d200929864..0a2421cca01f 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1179,7 +1179,7 @@ void __init setup_arch(char **cmdline_p)
if (boot_cpu_data.cpuid_level >= 0) {
/* A CPU has %cr4 if and only if it has CPUID */
- mmu_cr4_features = read_cr4();
+ mmu_cr4_features = __read_cr4();
if (trampoline_cr4_features)
*trampoline_cr4_features = mmu_cr4_features;
}
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 0de1fae2bdf0..34f66e58a896 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -12,6 +12,7 @@
#include <asm/i387.h>
#include <asm/fpu-internal.h>
#include <asm/sigframe.h>
+#include <asm/tlbflush.h>
#include <asm/xcr.h>
/*
@@ -453,7 +454,7 @@ static void prepare_fx_sw_frame(void)
*/
static inline void xstate_enable(void)
{
- set_in_cr4(X86_CR4_OSXSAVE);
+ cr4_set_bits(X86_CR4_OSXSAVE);
xsetbv(XCR_XFEATURE_ENABLED_MASK, pcntxt_mask);
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index a17d848c6d42..d319e0c24758 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1583,7 +1583,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
static int svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
{
- unsigned long host_cr4_mce = read_cr4() & X86_CR4_MCE;
+ unsigned long host_cr4_mce = cr4_read_shadow() & X86_CR4_MCE;
unsigned long old_cr4 = to_svm(vcpu)->vmcb->save.cr4;
if (cr4 & X86_CR4_VMXE)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 3f73bfad0349..14c1a18d206a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2871,7 +2871,7 @@ static int hardware_enable(void)
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
u64 old, test_bits;
- if (read_cr4() & X86_CR4_VMXE)
+ if (cr4_read_shadow() & X86_CR4_VMXE)
return -EBUSY;
INIT_LIST_HEAD(&per_cpu(loaded_vmcss_on_cpu, cpu));
@@ -2898,7 +2898,7 @@ static int hardware_enable(void)
/* enable and lock */
wrmsrl(MSR_IA32_FEATURE_CONTROL, old | test_bits);
}
- write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */
+ cr4_set_bits(X86_CR4_VMXE);
if (vmm_exclusive) {
kvm_cpu_vmxon(phys_addr);
@@ -2935,7 +2935,7 @@ static void hardware_disable(void)
vmclear_local_loaded_vmcss();
kvm_cpu_vmxoff();
}
- write_cr4(read_cr4() & ~X86_CR4_VMXE);
+ cr4_clear_bits(X86_CR4_VMXE);
}
static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
@@ -4450,7 +4450,7 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */
/* Save the most likely value for this task's CR4 in the VMCS. */
- cr4 = read_cr4();
+ cr4 = cr4_read_shadow();
vmcs_writel(HOST_CR4, cr4); /* 22.2.3, 22.2.5 */
vmx->host_state.vmcs_host_cr4 = cr4;
@@ -8146,7 +8146,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
- cr4 = read_cr4();
+ cr4 = cr4_read_shadow();
if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) {
vmcs_writel(HOST_CR4, cr4);
vmx->host_state.vmcs_host_cr4 = cr4;
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index c1c1544b8485..ac4453d8520e 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -56,6 +56,9 @@
#include <linux/virtio_console.h>
#include <linux/pm.h>
#include <linux/export.h>
+#include <linux/pci.h>
+#include <linux/virtio_pci.h>
+#include <asm/acpi.h>
#include <asm/apic.h>
#include <asm/lguest.h>
#include <asm/paravirt.h>
@@ -71,6 +74,8 @@
#include <asm/stackprotector.h>
#include <asm/reboot.h> /* for struct machine_ops */
#include <asm/kvm_para.h>
+#include <asm/pci_x86.h>
+#include <asm/pci-direct.h>
/*G:010
* Welcome to the Guest!
@@ -831,6 +836,24 @@ static struct irq_chip lguest_irq_controller = {
.irq_unmask = enable_lguest_irq,
};
+static int lguest_enable_irq(struct pci_dev *dev)
+{
+ u8 line = 0;
+
+ /* We literally use the PCI interrupt line as the irq number. */
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
+ irq_set_chip_and_handler_name(line, &lguest_irq_controller,
+ handle_level_irq, "level");
+ dev->irq = line;
+ return 0;
+}
+
+/* We don't do hotplug PCI, so this shouldn't be called. */
+static void lguest_disable_irq(struct pci_dev *dev)
+{
+ WARN_ON(1);
+}
+
/*
* This sets up the Interrupt Descriptor Table (IDT) entry for each hardware
* interrupt (except 128, which is used for system calls), and then tells the
@@ -1181,25 +1204,136 @@ static __init char *lguest_memory_setup(void)
return "LGUEST";
}
+/* Offset within PCI config space of BAR access capability. */
+static int console_cfg_offset = 0;
+static int console_access_cap;
+
+/* Set up so that we access off in bar0 (on bus 0, device 1, function 0) */
+static void set_cfg_window(u32 cfg_offset, u32 off)
+{
+ write_pci_config_byte(0, 1, 0,
+ cfg_offset + offsetof(struct virtio_pci_cap, bar),
+ 0);
+ write_pci_config(0, 1, 0,
+ cfg_offset + offsetof(struct virtio_pci_cap, length),
+ 4);
+ write_pci_config(0, 1, 0,
+ cfg_offset + offsetof(struct virtio_pci_cap, offset),
+ off);
+}
+
+static void write_bar_via_cfg(u32 cfg_offset, u32 off, u32 val)
+{
+ /*
+ * We could set this up once, then leave it; nothing else in the *
+ * kernel should touch these registers. But if it went wrong, that
+ * would be a horrible bug to find.
+ */
+ set_cfg_window(cfg_offset, off);
+ write_pci_config(0, 1, 0,
+ cfg_offset + sizeof(struct virtio_pci_cap), val);
+}
+
+static void probe_pci_console(void)
+{
+ u8 cap, common_cap = 0, device_cap = 0;
+ /* Offset within BAR0 */
+ u32 device_offset;
+ u32 device_len;
+
+ /* Avoid recursive printk into here. */
+ console_cfg_offset = -1;
+
+ if (!early_pci_allowed()) {
+ printk(KERN_ERR "lguest: early PCI access not allowed!\n");
+ return;
+ }
+
+ /* We expect a console PCI device at BUS0, slot 1. */
+ if (read_pci_config(0, 1, 0, 0) != 0x10431AF4) {
+ printk(KERN_ERR "lguest: PCI device is %#x!\n",
+ read_pci_config(0, 1, 0, 0));
+ return;
+ }
+
+ /* Find the capabilities we need (must be in bar0) */
+ cap = read_pci_config_byte(0, 1, 0, PCI_CAPABILITY_LIST);
+ while (cap) {
+ u8 vndr = read_pci_config_byte(0, 1, 0, cap);
+ if (vndr == PCI_CAP_ID_VNDR) {
+ u8 type, bar;
+ u32 offset, length;
+
+ type = read_pci_config_byte(0, 1, 0,
+ cap + offsetof(struct virtio_pci_cap, cfg_type));
+ bar = read_pci_config_byte(0, 1, 0,
+ cap + offsetof(struct virtio_pci_cap, bar));
+ offset = read_pci_config(0, 1, 0,
+ cap + offsetof(struct virtio_pci_cap, offset));
+ length = read_pci_config(0, 1, 0,
+ cap + offsetof(struct virtio_pci_cap, length));
+
+ switch (type) {
+ case VIRTIO_PCI_CAP_DEVICE_CFG:
+ if (bar == 0) {
+ device_cap = cap;
+ device_offset = offset;
+ device_len = length;
+ }
+ break;
+ case VIRTIO_PCI_CAP_PCI_CFG:
+ console_access_cap = cap;
+ break;
+ }
+ }
+ cap = read_pci_config_byte(0, 1, 0, cap + PCI_CAP_LIST_NEXT);
+ }
+ if (!device_cap || !console_access_cap) {
+ printk(KERN_ERR "lguest: No caps (%u/%u/%u) in console!\n",
+ common_cap, device_cap, console_access_cap);
+ return;
+ }
+
+ /*
+ * Note that we can't check features, until we've set the DRIVER
+ * status bit. We don't want to do that until we have a real driver,
+ * so we just check that the device-specific config has room for
+ * emerg_wr. If it doesn't support VIRTIO_CONSOLE_F_EMERG_WRITE
+ * it should ignore the access.
+ */
+ if (device_len < (offsetof(struct virtio_console_config, emerg_wr)
+ + sizeof(u32))) {
+ printk(KERN_ERR "lguest: console missing emerg_wr field\n");
+ return;
+ }
+
+ console_cfg_offset = device_offset;
+ printk(KERN_INFO "lguest: Console via virtio-pci emerg_wr\n");
+}
+
/*
* We will eventually use the virtio console device to produce console output,
- * but before that is set up we use LHCALL_NOTIFY on normal memory to produce
- * console output.
+ * but before that is set up we use the virtio PCI console's backdoor mmio
+ * access and the "emergency" write facility (which is legal even before the
+ * device is configured).
*/
static __init int early_put_chars(u32 vtermno, const char *buf, int count)
{
- char scratch[17];
- unsigned int len = count;
+ /* If we couldn't find PCI console, forget it. */
+ if (console_cfg_offset < 0)
+ return count;
- /* We use a nul-terminated string, so we make a copy. Icky, huh? */
- if (len > sizeof(scratch) - 1)
- len = sizeof(scratch) - 1;
- scratch[len] = '\0';
- memcpy(scratch, buf, len);
- hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0);
+ if (unlikely(!console_cfg_offset)) {
+ probe_pci_console();
+ if (console_cfg_offset < 0)
+ return count;
+ }
- /* This routine returns the number of bytes actually written. */
- return len;
+ write_bar_via_cfg(console_access_cap,
+ console_cfg_offset
+ + offsetof(struct virtio_console_config, emerg_wr),
+ buf[0]);
+ return 1;
}
/*
@@ -1400,14 +1534,6 @@ __init void lguest_init(void)
atomic_notifier_chain_register(&panic_notifier_list, &paniced);
/*
- * The IDE code spends about 3 seconds probing for disks: if we reserve
- * all the I/O ports up front it can't get them and so doesn't probe.
- * Other device drivers are similar (but less severe). This cuts the
- * kernel boot time on my machine from 4.1 seconds to 0.45 seconds.
- */
- paravirt_disable_iospace();
-
- /*
* This is messy CPU setup stuff which the native boot code does before
* start_kernel, so we have to do, too:
*/
@@ -1436,6 +1562,13 @@ __init void lguest_init(void)
/* Register our very early console. */
virtio_cons_early_init(early_put_chars);
+ /* Don't let ACPI try to control our PCI interrupts. */
+ disable_acpi();
+
+ /* We control them ourselves, by overriding these two hooks. */
+ pcibios_enable_irq = lguest_enable_irq;
+ pcibios_disable_irq = lguest_disable_irq;
+
/*
* Last of all, we set the power management poweroff hook to point to
* the Guest routine to power off, and the reboot hook to our restart
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index e3ff27a5b634..ede025fb46f1 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -600,7 +600,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,
printk(nx_warning, from_kuid(&init_user_ns, current_uid()));
if (pte && pte_present(*pte) && pte_exec(*pte) &&
(pgd_flags(*pgd) & _PAGE_USER) &&
- (read_cr4() & X86_CR4_SMEP))
+ (__read_cr4() & X86_CR4_SMEP))
printk(smep_warning, from_kuid(&init_user_ns, current_uid()));
}
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 649da47d3827..553c094b9cd7 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -173,11 +173,11 @@ static void __init probe_page_size_mask(void)
/* Enable PSE if available */
if (cpu_has_pse)
- set_in_cr4(X86_CR4_PSE);
+ cr4_set_bits_and_update_boot(X86_CR4_PSE);
/* Enable PGE if available */
if (cpu_has_pge) {
- set_in_cr4(X86_CR4_PGE);
+ cr4_set_bits_and_update_boot(X86_CR4_PGE);
__supported_pte_mask |= _PAGE_GLOBAL;
}
}
@@ -713,6 +713,15 @@ void __init zone_sizes_init(void)
free_area_init_nodes(max_zone_pfns);
}
+DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = {
+#ifdef CONFIG_SMP
+ .active_mm = &init_mm,
+ .state = 0,
+#endif
+ .cr4 = ~0UL, /* fail hard if we screw up cr4 shadow initialization */
+};
+EXPORT_SYMBOL_GPL(cpu_tlbstate);
+
void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache)
{
/* entry 0 MUST be WB (hardwired to speed up translations) */
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index ee61c36d64f8..3250f2371aea 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -14,9 +14,6 @@
#include <asm/uv/uv.h>
#include <linux/debugfs.h>
-DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
- = { &init_mm, 0, };
-
/*
* Smarter SMP flushing macros.
* c/o Linus Torvalds.
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 6ec7910f59bf..3e32ed5648a0 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -105,11 +105,8 @@ static void __save_processor_state(struct saved_context *ctxt)
ctxt->cr0 = read_cr0();
ctxt->cr2 = read_cr2();
ctxt->cr3 = read_cr3();
-#ifdef CONFIG_X86_32
- ctxt->cr4 = read_cr4_safe();
-#else
-/* CONFIG_X86_64 */
- ctxt->cr4 = read_cr4();
+ ctxt->cr4 = __read_cr4_safe();
+#ifdef CONFIG_X86_64
ctxt->cr8 = read_cr8();
#endif
ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE,
@@ -175,12 +172,12 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
/* cr4 was introduced in the Pentium CPU */
#ifdef CONFIG_X86_32
if (ctxt->cr4)
- write_cr4(ctxt->cr4);
+ __write_cr4(ctxt->cr4);
#else
/* CONFIG X86_64 */
wrmsrl(MSR_EFER, ctxt->efer);
write_cr8(ctxt->cr8);
- write_cr4(ctxt->cr4);
+ __write_cr4(ctxt->cr4);
#endif
write_cr3(ctxt->cr3);
write_cr2(ctxt->cr2);
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index bad628a620c4..0b7a63d98440 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -81,7 +81,7 @@ void __init setup_real_mode(void)
trampoline_header->start = (u64) secondary_startup_64;
trampoline_cr4_features = &trampoline_header->cr4;
- *trampoline_cr4_features = read_cr4();
+ *trampoline_cr4_features = __read_cr4();
trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
trampoline_pgd[0] = init_level4_pgt[pgd_index(__PAGE_OFFSET)].pgd;
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 78a881b7fc41..bd8b8459c3d0 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1494,10 +1494,10 @@ static void xen_pvh_set_cr_flags(int cpu)
* set them here. For all, OSFXSR OSXMMEXCPT are set in fpu_init.
*/
if (cpu_has_pse)
- set_in_cr4(X86_CR4_PSE);
+ cr4_set_bits_and_update_boot(X86_CR4_PSE);
if (cpu_has_pge)
- set_in_cr4(X86_CR4_PGE);
+ cr4_set_bits_and_update_boot(X86_CR4_PGE);
}
/*
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index 876eb380aa26..147b26ed9c91 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -182,13 +182,13 @@
#define get_fs() (current->thread.current_ds)
#define set_fs(val) (current->thread.current_ds = (val))
-#define segment_eq(a,b) ((a).seg == (b).seg)
+#define segment_eq(a, b) ((a).seg == (b).seg)
#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
-#define __user_ok(addr,size) \
+#define __user_ok(addr, size) \
(((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
-#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
-#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))
+#define access_ok(type, addr, size) __access_ok((unsigned long)(addr), (size))
/*
* These are the main single-value transfer routines. They
@@ -204,8 +204,8 @@
* (a) re-use the arguments for side effects (sizeof is ok)
* (b) require any knowledge of processes at this stage
*/
-#define put_user(x,ptr) __put_user_check((x),(ptr),sizeof(*(ptr)))
-#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr)))
+#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr)))
+#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
/*
* The "__xxx" versions of the user access functions are versions that
@@ -213,39 +213,39 @@
* with a separate "access_ok()" call (this is used when we do multiple
* accesses to the same area of user memory).
*/
-#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
-#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
extern long __put_user_bad(void);
-#define __put_user_nocheck(x,ptr,size) \
+#define __put_user_nocheck(x, ptr, size) \
({ \
long __pu_err; \
- __put_user_size((x),(ptr),(size),__pu_err); \
+ __put_user_size((x), (ptr), (size), __pu_err); \
__pu_err; \
})
-#define __put_user_check(x,ptr,size) \
-({ \
- long __pu_err = -EFAULT; \
- __typeof__(*(ptr)) *__pu_addr = (ptr); \
- if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
- __put_user_size((x),__pu_addr,(size),__pu_err); \
- __pu_err; \
+#define __put_user_check(x, ptr, size) \
+({ \
+ long __pu_err = -EFAULT; \
+ __typeof__(*(ptr)) *__pu_addr = (ptr); \
+ if (access_ok(VERIFY_WRITE, __pu_addr, size)) \
+ __put_user_size((x), __pu_addr, (size), __pu_err); \
+ __pu_err; \
})
-#define __put_user_size(x,ptr,size,retval) \
+#define __put_user_size(x, ptr, size, retval) \
do { \
int __cb; \
retval = 0; \
switch (size) { \
- case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \
- case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \
- case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \
+ case 1: __put_user_asm(x, ptr, retval, 1, "s8i", __cb); break; \
+ case 2: __put_user_asm(x, ptr, retval, 2, "s16i", __cb); break; \
+ case 4: __put_user_asm(x, ptr, retval, 4, "s32i", __cb); break; \
case 8: { \
__typeof__(*ptr) __v64 = x; \
- retval = __copy_to_user(ptr,&__v64,8); \
+ retval = __copy_to_user(ptr, &__v64, 8); \
break; \
} \
default: __put_user_bad(); \
@@ -316,35 +316,35 @@ __asm__ __volatile__( \
:"=r" (err), "=r" (cb) \
:"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err))
-#define __get_user_nocheck(x,ptr,size) \
+#define __get_user_nocheck(x, ptr, size) \
({ \
long __gu_err, __gu_val; \
- __get_user_size(__gu_val,(ptr),(size),__gu_err); \
- (x) = (__force __typeof__(*(ptr)))__gu_val; \
+ __get_user_size(__gu_val, (ptr), (size), __gu_err); \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
-#define __get_user_check(x,ptr,size) \
+#define __get_user_check(x, ptr, size) \
({ \
long __gu_err = -EFAULT, __gu_val = 0; \
const __typeof__(*(ptr)) *__gu_addr = (ptr); \
- if (access_ok(VERIFY_READ,__gu_addr,size)) \
- __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \
- (x) = (__force __typeof__(*(ptr)))__gu_val; \
+ if (access_ok(VERIFY_READ, __gu_addr, size)) \
+ __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
+ (x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \
})
extern long __get_user_bad(void);
-#define __get_user_size(x,ptr,size,retval) \
+#define __get_user_size(x, ptr, size, retval) \
do { \
int __cb; \
retval = 0; \
switch (size) { \
- case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \
- case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \
- case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \
- case 8: retval = __copy_from_user(&x,ptr,8); break; \
+ case 1: __get_user_asm(x, ptr, retval, 1, "l8ui", __cb); break;\
+ case 2: __get_user_asm(x, ptr, retval, 2, "l16ui", __cb); break;\
+ case 4: __get_user_asm(x, ptr, retval, 4, "l32i", __cb); break;\
+ case 8: retval = __copy_from_user(&x, ptr, 8); break; \
default: (x) = __get_user_bad(); \
} \
} while (0)
@@ -390,19 +390,19 @@ __asm__ __volatile__( \
*/
extern unsigned __xtensa_copy_user(void *to, const void *from, unsigned n);
-#define __copy_user(to,from,size) __xtensa_copy_user(to,from,size)
+#define __copy_user(to, from, size) __xtensa_copy_user(to, from, size)
static inline unsigned long
__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
{
- return __copy_user(to,from,n);
+ return __copy_user(to, from, n);
}
static inline unsigned long
__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
{
- return __copy_user(to,from,n);
+ return __copy_user(to, from, n);
}
static inline unsigned long
@@ -410,7 +410,7 @@ __generic_copy_to_user(void *to, const void *from, unsigned long n)
{
prefetch(from);
if (access_ok(VERIFY_WRITE, to, n))
- return __copy_user(to,from,n);
+ return __copy_user(to, from, n);
return n;
}
@@ -419,18 +419,18 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n)
{
prefetchw(to);
if (access_ok(VERIFY_READ, from, n))
- return __copy_user(to,from,n);
+ return __copy_user(to, from, n);
else
memset(to, 0, n);
return n;
}
-#define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n))
-#define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n))
-#define __copy_to_user(to,from,n) \
- __generic_copy_to_user_nocheck((to),(from),(n))
-#define __copy_from_user(to,from,n) \
- __generic_copy_from_user_nocheck((to),(from),(n))
+#define copy_to_user(to, from, n) __generic_copy_to_user((to), (from), (n))
+#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
+#define __copy_to_user(to, from, n) \
+ __generic_copy_to_user_nocheck((to), (from), (n))
+#define __copy_from_user(to, from, n) \
+ __generic_copy_from_user_nocheck((to), (from), (n))
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index c256bd7fbd78..c6bb9f1257c9 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -732,9 +732,8 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
static bool acpi_idle_fallback_to_c1(struct acpi_processor *pr)
{
- return IS_ENABLED(CONFIG_HOTPLUG_CPU) && num_online_cpus() > 1 &&
- !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED) &&
- !pr->flags.has_cst;
+ return IS_ENABLED(CONFIG_HOTPLUG_CPU) && !pr->flags.has_cst &&
+ !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED);
}
static int c3_cpu_count;
@@ -744,9 +743,10 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
* acpi_idle_enter_bm - enters C3 with proper BM handling
* @pr: Target processor
* @cx: Target state context
+ * @timer_bc: Whether or not to change timer mode to broadcast
*/
static void acpi_idle_enter_bm(struct acpi_processor *pr,
- struct acpi_processor_cx *cx)
+ struct acpi_processor_cx *cx, bool timer_bc)
{
acpi_unlazy_tlb(smp_processor_id());
@@ -754,7 +754,8 @@ static void acpi_idle_enter_bm(struct acpi_processor *pr,
* Must be done before busmaster disable as we might need to
* access HPET !
*/
- lapic_timer_state_broadcast(pr, cx, 1);
+ if (timer_bc)
+ lapic_timer_state_broadcast(pr, cx, 1);
/*
* disable bus master
@@ -784,7 +785,8 @@ static void acpi_idle_enter_bm(struct acpi_processor *pr,
raw_spin_unlock(&c3_lock);
}
- lapic_timer_state_broadcast(pr, cx, 0);
+ if (timer_bc)
+ lapic_timer_state_broadcast(pr, cx, 0);
}
static int acpi_idle_enter(struct cpuidle_device *dev,
@@ -798,12 +800,12 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
return -EINVAL;
if (cx->type != ACPI_STATE_C1) {
- if (acpi_idle_fallback_to_c1(pr)) {
+ if (acpi_idle_fallback_to_c1(pr) && num_online_cpus() > 1) {
index = CPUIDLE_DRIVER_STATE_START;
cx = per_cpu(acpi_cstate[index], dev->cpu);
} else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) {
if (cx->bm_sts_skip || !acpi_idle_bm_check()) {
- acpi_idle_enter_bm(pr, cx);
+ acpi_idle_enter_bm(pr, cx, true);
return index;
} else if (drv->safe_state_index >= 0) {
index = drv->safe_state_index;
@@ -827,6 +829,27 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
return index;
}
+static void acpi_idle_enter_freeze(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
+
+ if (cx->type == ACPI_STATE_C3) {
+ struct acpi_processor *pr = __this_cpu_read(processors);
+
+ if (unlikely(!pr))
+ return;
+
+ if (pr->flags.bm_check) {
+ acpi_idle_enter_bm(pr, cx, false);
+ return;
+ } else {
+ ACPI_FLUSH_CPU_CACHE();
+ }
+ }
+ acpi_idle_do_entry(cx);
+}
+
struct cpuidle_driver acpi_idle_driver = {
.name = "acpi_idle",
.owner = THIS_MODULE,
@@ -925,6 +948,15 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
state->enter_dead = acpi_idle_play_dead;
drv->safe_state_index = count;
}
+ /*
+ * Halt-induced C1 is not good for ->enter_freeze, because it
+ * re-enables interrupts on exit. Moreover, C1 is generally not
+ * particularly interesting from the suspend-to-idle angle, so
+ * avoid C1 and the situations in which we may need to fall back
+ * to it altogether.
+ */
+ if (cx->type != ACPI_STATE_C1 && !acpi_idle_fallback_to_c1(pr))
+ state->enter_freeze = acpi_idle_enter_freeze;
count++;
if (count == CPUIDLE_STATE_MAX)
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 014a1cfc41c5..1b8094d4d7af 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -393,14 +393,15 @@ config BLK_DEV_RAM_SIZE
The default value is 4096 kilobytes. Only change this if you know
what you are doing.
-config BLK_DEV_XIP
- bool "Support XIP filesystems on RAM block device"
- depends on BLK_DEV_RAM
+config BLK_DEV_RAM_DAX
+ bool "Support Direct Access (DAX) to RAM block devices"
+ depends on BLK_DEV_RAM && FS_DAX
default n
help
- Support XIP filesystems (such as ext2 with XIP support on) on
- top of block ram device. This will slightly enlarge the kernel, and
- will prevent RAM block device backing store memory from being
+ Support filesystems using DAX to access RAM block devices. This
+ avoids double-buffering data in the page cache before copying it
+ to the block device. Answering Y will slightly enlarge the kernel,
+ and will prevent RAM block device backing store memory from being
allocated from highmem (only a problem for highmem systems).
config CDROM_PKTCDVD
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index c01b921b1b4a..64ab4951e9d6 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -97,13 +97,13 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
* Must use NOIO because we don't want to recurse back into the
* block or filesystem layers from page reclaim.
*
- * Cannot support XIP and highmem, because our ->direct_access
- * routine for XIP must return memory that is always addressable.
- * If XIP was reworked to use pfns and kmap throughout, this
+ * Cannot support DAX and highmem, because our ->direct_access
+ * routine for DAX must return memory that is always addressable.
+ * If DAX was reworked to use pfns and kmap throughout, this
* restriction might be able to be lifted.
*/
gfp_flags = GFP_NOIO | __GFP_ZERO;
-#ifndef CONFIG_BLK_DEV_XIP
+#ifndef CONFIG_BLK_DEV_RAM_DAX
gfp_flags |= __GFP_HIGHMEM;
#endif
page = alloc_page(gfp_flags);
@@ -369,7 +369,7 @@ static int brd_rw_page(struct block_device *bdev, sector_t sector,
return err;
}
-#ifdef CONFIG_BLK_DEV_XIP
+#ifdef CONFIG_BLK_DEV_RAM_DAX
static long brd_direct_access(struct block_device *bdev, sector_t sector,
void **kaddr, unsigned long *pfn, long size)
{
@@ -390,6 +390,8 @@ static long brd_direct_access(struct block_device *bdev, sector_t sector,
*/
return PAGE_SIZE;
}
+#else
+#define brd_direct_access NULL
#endif
static int brd_ioctl(struct block_device *bdev, fmode_t mode,
@@ -430,9 +432,7 @@ static const struct block_device_operations brd_fops = {
.owner = THIS_MODULE,
.rw_page = brd_rw_page,
.ioctl = brd_ioctl,
-#ifdef CONFIG_BLK_DEV_XIP
.direct_access = brd_direct_access,
-#endif
};
/*
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index cdfbd21e3597..655e570b9b31 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -28,8 +28,7 @@ struct virtio_blk_vq {
char name[VQ_NAME_LEN];
} ____cacheline_aligned_in_smp;
-struct virtio_blk
-{
+struct virtio_blk {
struct virtio_device *vdev;
/* The disk structure for the kernel. */
@@ -52,8 +51,7 @@ struct virtio_blk
struct virtio_blk_vq *vqs;
};
-struct virtblk_req
-{
+struct virtblk_req {
struct request *req;
struct virtio_blk_outhdr out_hdr;
struct virtio_scsi_inhdr in_hdr;
@@ -575,6 +573,12 @@ static int virtblk_probe(struct virtio_device *vdev)
u16 min_io_size;
u8 physical_block_exp, alignment_offset;
+ if (!vdev->config->get) {
+ dev_err(&vdev->dev, "%s failure: config access disabled\n",
+ __func__);
+ return -EINVAL;
+ }
+
err = ida_simple_get(&vd_index_ida, 0, minor_to_index(1 << MINORBITS),
GFP_KERNEL);
if (err < 0)
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
index 81bf297f1034..fb9ec6221730 100644
--- a/drivers/bus/mvebu-mbus.c
+++ b/drivers/bus/mvebu-mbus.c
@@ -58,6 +58,7 @@
#include <linux/debugfs.h>
#include <linux/log2.h>
#include <linux/syscore_ops.h>
+#include <linux/memblock.h>
/*
* DDR target is the same on all platforms.
@@ -69,6 +70,7 @@
*/
#define WIN_CTRL_OFF 0x0000
#define WIN_CTRL_ENABLE BIT(0)
+#define WIN_CTRL_SYNCBARRIER BIT(1)
#define WIN_CTRL_TGT_MASK 0xf0
#define WIN_CTRL_TGT_SHIFT 4
#define WIN_CTRL_ATTR_MASK 0xff00
@@ -82,6 +84,9 @@
#define WIN_REMAP_LOW 0xffff0000
#define WIN_REMAP_HI_OFF 0x000c
+#define UNIT_SYNC_BARRIER_OFF 0x84
+#define UNIT_SYNC_BARRIER_ALL 0xFFFF
+
#define ATTR_HW_COHERENCY (0x1 << 4)
#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
@@ -97,7 +102,9 @@
/* Relative to mbusbridge_base */
#define MBUS_BRIDGE_CTRL_OFF 0x0
+#define MBUS_BRIDGE_SIZE_MASK 0xffff0000
#define MBUS_BRIDGE_BASE_OFF 0x4
+#define MBUS_BRIDGE_BASE_MASK 0xffff0000
/* Maximum number of windows, for all known platforms */
#define MBUS_WINS_MAX 20
@@ -106,9 +113,9 @@ struct mvebu_mbus_state;
struct mvebu_mbus_soc_data {
unsigned int num_wins;
- unsigned int num_remappable_wins;
bool has_mbus_bridge;
unsigned int (*win_cfg_offset)(const int win);
+ unsigned int (*win_remap_offset)(const int win);
void (*setup_cpu_target)(struct mvebu_mbus_state *s);
int (*save_cpu_target)(struct mvebu_mbus_state *s,
u32 *store_addr);
@@ -154,6 +161,13 @@ const struct mbus_dram_target_info *mv_mbus_dram_info(void)
}
EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
+/* Checks whether the given window has remap capability */
+static bool mvebu_mbus_window_is_remappable(struct mvebu_mbus_state *mbus,
+ const int win)
+{
+ return mbus->soc->win_remap_offset(win) != MVEBU_MBUS_NO_REMAP;
+}
+
/*
* Functions to manipulate the address decoding windows
*/
@@ -185,9 +199,12 @@ static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus,
*attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT;
if (remap) {
- if (win < mbus->soc->num_remappable_wins) {
- u32 remap_low = readl(addr + WIN_REMAP_LO_OFF);
- u32 remap_hi = readl(addr + WIN_REMAP_HI_OFF);
+ if (mvebu_mbus_window_is_remappable(mbus, win)) {
+ u32 remap_low, remap_hi;
+ void __iomem *addr_rmp = mbus->mbuswins_base +
+ mbus->soc->win_remap_offset(win);
+ remap_low = readl(addr_rmp + WIN_REMAP_LO_OFF);
+ remap_hi = readl(addr_rmp + WIN_REMAP_HI_OFF);
*remap = ((u64)remap_hi << 32) | remap_low;
} else
*remap = 0;
@@ -200,10 +217,11 @@ static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus,
void __iomem *addr;
addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win);
-
writel(0, addr + WIN_BASE_OFF);
writel(0, addr + WIN_CTRL_OFF);
- if (win < mbus->soc->num_remappable_wins) {
+
+ if (mvebu_mbus_window_is_remappable(mbus, win)) {
+ addr = mbus->mbuswins_base + mbus->soc->win_remap_offset(win);
writel(0, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
@@ -211,14 +229,6 @@ static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus,
/* Checks whether the given window number is available */
-/* On Armada XP, 375 and 38x the MBus window 13 has the remap
- * capability, like windows 0 to 7. However, the mvebu-mbus driver
- * isn't currently taking into account this special case, which means
- * that when window 13 is actually used, the remap registers are left
- * to 0, making the device using this MBus window unavailable. The
- * quick fix for stable is to not use window 13. A follow up patch
- * will correctly handle this window.
-*/
static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus,
const int win)
{
@@ -226,9 +236,6 @@ static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus,
mbus->soc->win_cfg_offset(win);
u32 ctrl = readl(addr + WIN_CTRL_OFF);
- if (win == 13)
- return false;
-
return !(ctrl & WIN_CTRL_ENABLE);
}
@@ -316,17 +323,22 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) |
(attr << WIN_CTRL_ATTR_SHIFT) |
(target << WIN_CTRL_TGT_SHIFT) |
+ WIN_CTRL_SYNCBARRIER |
WIN_CTRL_ENABLE;
writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF);
writel(ctrl, addr + WIN_CTRL_OFF);
- if (win < mbus->soc->num_remappable_wins) {
+
+ if (mvebu_mbus_window_is_remappable(mbus, win)) {
+ void __iomem *addr_rmp = mbus->mbuswins_base +
+ mbus->soc->win_remap_offset(win);
+
if (remap == MVEBU_MBUS_NO_REMAP)
remap_addr = base;
else
remap_addr = remap;
- writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF);
- writel(0, addr + WIN_REMAP_HI_OFF);
+ writel(remap_addr & WIN_REMAP_LOW, addr_rmp + WIN_REMAP_LO_OFF);
+ writel(0, addr_rmp + WIN_REMAP_HI_OFF);
}
return 0;
@@ -340,19 +352,27 @@ static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus,
int win;
if (remap == MVEBU_MBUS_NO_REMAP) {
- for (win = mbus->soc->num_remappable_wins;
- win < mbus->soc->num_wins; win++)
+ for (win = 0; win < mbus->soc->num_wins; win++) {
+ if (mvebu_mbus_window_is_remappable(mbus, win))
+ continue;
+
if (mvebu_mbus_window_is_free(mbus, win))
return mvebu_mbus_setup_window(mbus, win, base,
size, remap,
target, attr);
+ }
}
+ for (win = 0; win < mbus->soc->num_wins; win++) {
+ /* Skip window if need remap but is not supported */
+ if ((remap != MVEBU_MBUS_NO_REMAP) &&
+ !mvebu_mbus_window_is_remappable(mbus, win))
+ continue;
- for (win = 0; win < mbus->soc->num_wins; win++)
if (mvebu_mbus_window_is_free(mbus, win))
return mvebu_mbus_setup_window(mbus, win, base, size,
remap, target, attr);
+ }
return -ENOMEM;
}
@@ -464,7 +484,7 @@ static int mvebu_devs_debug_show(struct seq_file *seq, void *v)
((wbase & (u64)(wsize - 1)) != 0))
seq_puts(seq, " (Invalid base/size!!)");
- if (win < mbus->soc->num_remappable_wins) {
+ if (mvebu_mbus_window_is_remappable(mbus, win)) {
seq_printf(seq, " (remap %016llx)\n",
(unsigned long long)wremap);
} else
@@ -490,12 +510,12 @@ static const struct file_operations mvebu_devs_debug_fops = {
* SoC-specific functions and definitions
*/
-static unsigned int orion_mbus_win_offset(int win)
+static unsigned int generic_mbus_win_cfg_offset(int win)
{
return win << 4;
}
-static unsigned int armada_370_xp_mbus_win_offset(int win)
+static unsigned int armada_370_xp_mbus_win_cfg_offset(int win)
{
/* The register layout is a bit annoying and the below code
* tries to cope with it.
@@ -515,7 +535,7 @@ static unsigned int armada_370_xp_mbus_win_offset(int win)
return 0x90 + ((win - 8) << 3);
}
-static unsigned int mv78xx0_mbus_win_offset(int win)
+static unsigned int mv78xx0_mbus_win_cfg_offset(int win)
{
if (win < 8)
return win << 4;
@@ -523,36 +543,140 @@ static unsigned int mv78xx0_mbus_win_offset(int win)
return 0x900 + ((win - 8) << 4);
}
+static unsigned int generic_mbus_win_remap_2_offset(int win)
+{
+ if (win < 2)
+ return generic_mbus_win_cfg_offset(win);
+ else
+ return MVEBU_MBUS_NO_REMAP;
+}
+
+static unsigned int generic_mbus_win_remap_4_offset(int win)
+{
+ if (win < 4)
+ return generic_mbus_win_cfg_offset(win);
+ else
+ return MVEBU_MBUS_NO_REMAP;
+}
+
+static unsigned int generic_mbus_win_remap_8_offset(int win)
+{
+ if (win < 8)
+ return generic_mbus_win_cfg_offset(win);
+ else
+ return MVEBU_MBUS_NO_REMAP;
+}
+
+static unsigned int armada_xp_mbus_win_remap_offset(int win)
+{
+ if (win < 8)
+ return generic_mbus_win_cfg_offset(win);
+ else if (win == 13)
+ return 0xF0 - WIN_REMAP_LO_OFF;
+ else
+ return MVEBU_MBUS_NO_REMAP;
+}
+
+/*
+ * Use the memblock information to find the MBus bridge hole in the
+ * physical address space.
+ */
+static void __init
+mvebu_mbus_find_bridge_hole(uint64_t *start, uint64_t *end)
+{
+ struct memblock_region *r;
+ uint64_t s = 0;
+
+ for_each_memblock(memory, r) {
+ /*
+ * This part of the memory is above 4 GB, so we don't
+ * care for the MBus bridge hole.
+ */
+ if (r->base >= 0x100000000)
+ continue;
+
+ /*
+ * The MBus bridge hole is at the end of the RAM under
+ * the 4 GB limit.
+ */
+ if (r->base + r->size > s)
+ s = r->base + r->size;
+ }
+
+ *start = s;
+ *end = 0x100000000;
+}
+
static void __init
mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
{
int i;
int cs;
+ uint64_t mbus_bridge_base, mbus_bridge_end;
mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+ mvebu_mbus_find_bridge_hole(&mbus_bridge_base, &mbus_bridge_end);
+
for (i = 0, cs = 0; i < 4; i++) {
- u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
- u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
+ u64 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
+ u64 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
+ u64 end;
+ struct mbus_dram_window *w;
+
+ /* Ignore entries that are not enabled */
+ if (!(size & DDR_SIZE_ENABLED))
+ continue;
/*
- * We only take care of entries for which the chip
- * select is enabled, and that don't have high base
- * address bits set (devices can only access the first
- * 32 bits of the memory).
+ * Ignore entries whose base address is above 2^32,
+ * since devices cannot DMA to such high addresses
*/
- if ((size & DDR_SIZE_ENABLED) &&
- !(base & DDR_BASE_CS_HIGH_MASK)) {
- struct mbus_dram_window *w;
+ if (base & DDR_BASE_CS_HIGH_MASK)
+ continue;
- w = &mvebu_mbus_dram_info.cs[cs++];
- w->cs_index = i;
- w->mbus_attr = 0xf & ~(1 << i);
- if (mbus->hw_io_coherency)
- w->mbus_attr |= ATTR_HW_COHERENCY;
- w->base = base & DDR_BASE_CS_LOW_MASK;
- w->size = (size | ~DDR_SIZE_MASK) + 1;
+ base = base & DDR_BASE_CS_LOW_MASK;
+ size = (size | ~DDR_SIZE_MASK) + 1;
+ end = base + size;
+
+ /*
+ * Adjust base/size of the current CS to make sure it
+ * doesn't overlap with the MBus bridge hole. This is
+ * particularly important for devices that do DMA from
+ * DRAM to a SRAM mapped in a MBus window, such as the
+ * CESA cryptographic engine.
+ */
+
+ /*
+ * The CS is fully enclosed inside the MBus bridge
+ * area, so ignore it.
+ */
+ if (base >= mbus_bridge_base && end <= mbus_bridge_end)
+ continue;
+
+ /*
+ * Beginning of CS overlaps with end of MBus, raise CS
+ * base address, and shrink its size.
+ */
+ if (base >= mbus_bridge_base && end > mbus_bridge_end) {
+ size -= mbus_bridge_end - base;
+ base = mbus_bridge_end;
}
+
+ /*
+ * End of CS overlaps with beginning of MBus, shrink
+ * CS size.
+ */
+ if (base < mbus_bridge_base && end > mbus_bridge_base)
+ size -= end - mbus_bridge_base;
+
+ w = &mvebu_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0xf & ~(1 << i);
+ if (mbus->hw_io_coherency)
+ w->mbus_attr |= ATTR_HW_COHERENCY;
+ w->base = base;
+ w->size = size;
}
mvebu_mbus_dram_info.num_cs = cs;
}
@@ -632,30 +756,40 @@ int mvebu_mbus_save_cpu_target(u32 *store_addr)
return mbus_state.soc->save_cpu_target(&mbus_state, store_addr);
}
-static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = {
+static const struct mvebu_mbus_soc_data armada_370_mbus_data = {
.num_wins = 20,
- .num_remappable_wins = 8,
.has_mbus_bridge = true,
- .win_cfg_offset = armada_370_xp_mbus_win_offset,
+ .win_cfg_offset = armada_370_xp_mbus_win_cfg_offset,
+ .win_remap_offset = generic_mbus_win_remap_8_offset,
+ .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
+ .show_cpu_target = mvebu_sdram_debug_show_orion,
.save_cpu_target = mvebu_mbus_default_save_cpu_target,
+};
+
+static const struct mvebu_mbus_soc_data armada_xp_mbus_data = {
+ .num_wins = 20,
+ .has_mbus_bridge = true,
+ .win_cfg_offset = armada_370_xp_mbus_win_cfg_offset,
+ .win_remap_offset = armada_xp_mbus_win_remap_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
+ .save_cpu_target = mvebu_mbus_default_save_cpu_target,
};
static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
.num_wins = 8,
- .num_remappable_wins = 4,
- .win_cfg_offset = orion_mbus_win_offset,
+ .win_cfg_offset = generic_mbus_win_cfg_offset,
.save_cpu_target = mvebu_mbus_default_save_cpu_target,
+ .win_remap_offset = generic_mbus_win_remap_4_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
};
static const struct mvebu_mbus_soc_data dove_mbus_data = {
.num_wins = 8,
- .num_remappable_wins = 4,
- .win_cfg_offset = orion_mbus_win_offset,
+ .win_cfg_offset = generic_mbus_win_cfg_offset,
.save_cpu_target = mvebu_mbus_dove_save_cpu_target,
+ .win_remap_offset = generic_mbus_win_remap_4_offset,
.setup_cpu_target = mvebu_mbus_dove_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_dove,
};
@@ -666,36 +800,40 @@ static const struct mvebu_mbus_soc_data dove_mbus_data = {
*/
static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = {
.num_wins = 8,
- .num_remappable_wins = 4,
- .win_cfg_offset = orion_mbus_win_offset,
+ .win_cfg_offset = generic_mbus_win_cfg_offset,
.save_cpu_target = mvebu_mbus_default_save_cpu_target,
+ .win_remap_offset = generic_mbus_win_remap_4_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
};
static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
.num_wins = 8,
- .num_remappable_wins = 2,
- .win_cfg_offset = orion_mbus_win_offset,
+ .win_cfg_offset = generic_mbus_win_cfg_offset,
.save_cpu_target = mvebu_mbus_default_save_cpu_target,
+ .win_remap_offset = generic_mbus_win_remap_2_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
};
static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
.num_wins = 14,
- .num_remappable_wins = 8,
- .win_cfg_offset = mv78xx0_mbus_win_offset,
+ .win_cfg_offset = mv78xx0_mbus_win_cfg_offset,
.save_cpu_target = mvebu_mbus_default_save_cpu_target,
+ .win_remap_offset = generic_mbus_win_remap_8_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
};
static const struct of_device_id of_mvebu_mbus_ids[] = {
{ .compatible = "marvell,armada370-mbus",
- .data = &armada_370_xp_mbus_data, },
+ .data = &armada_370_mbus_data, },
+ { .compatible = "marvell,armada375-mbus",
+ .data = &armada_xp_mbus_data, },
+ { .compatible = "marvell,armada380-mbus",
+ .data = &armada_xp_mbus_data, },
{ .compatible = "marvell,armadaxp-mbus",
- .data = &armada_370_xp_mbus_data, },
+ .data = &armada_xp_mbus_data, },
{ .compatible = "marvell,kirkwood-mbus",
.data = &kirkwood_mbus_data, },
{ .compatible = "marvell,dove-mbus",
@@ -802,15 +940,19 @@ static int mvebu_mbus_suspend(void)
for (win = 0; win < s->soc->num_wins; win++) {
void __iomem *addr = s->mbuswins_base +
s->soc->win_cfg_offset(win);
+ void __iomem *addr_rmp;
s->wins[win].base = readl(addr + WIN_BASE_OFF);
s->wins[win].ctrl = readl(addr + WIN_CTRL_OFF);
- if (win >= s->soc->num_remappable_wins)
+ if (!mvebu_mbus_window_is_remappable(s, win))
continue;
- s->wins[win].remap_lo = readl(addr + WIN_REMAP_LO_OFF);
- s->wins[win].remap_hi = readl(addr + WIN_REMAP_HI_OFF);
+ addr_rmp = s->mbuswins_base +
+ s->soc->win_remap_offset(win);
+
+ s->wins[win].remap_lo = readl(addr_rmp + WIN_REMAP_LO_OFF);
+ s->wins[win].remap_hi = readl(addr_rmp + WIN_REMAP_HI_OFF);
}
s->mbus_bridge_ctrl = readl(s->mbusbridge_base +
@@ -834,15 +976,19 @@ static void mvebu_mbus_resume(void)
for (win = 0; win < s->soc->num_wins; win++) {
void __iomem *addr = s->mbuswins_base +
s->soc->win_cfg_offset(win);
+ void __iomem *addr_rmp;
writel(s->wins[win].base, addr + WIN_BASE_OFF);
writel(s->wins[win].ctrl, addr + WIN_CTRL_OFF);
- if (win >= s->soc->num_remappable_wins)
+ if (!mvebu_mbus_window_is_remappable(s, win))
continue;
- writel(s->wins[win].remap_lo, addr + WIN_REMAP_LO_OFF);
- writel(s->wins[win].remap_hi, addr + WIN_REMAP_HI_OFF);
+ addr_rmp = s->mbuswins_base +
+ s->soc->win_remap_offset(win);
+
+ writel(s->wins[win].remap_lo, addr_rmp + WIN_REMAP_LO_OFF);
+ writel(s->wins[win].remap_hi, addr_rmp + WIN_REMAP_HI_OFF);
}
}
@@ -857,7 +1003,8 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
phys_addr_t sdramwins_phys_base,
size_t sdramwins_size,
phys_addr_t mbusbridge_phys_base,
- size_t mbusbridge_size)
+ size_t mbusbridge_size,
+ bool is_coherent)
{
int win;
@@ -889,6 +1036,10 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
mbus->soc->setup_cpu_target(mbus);
+ if (is_coherent)
+ writel(UNIT_SYNC_BARRIER_ALL,
+ mbus->mbuswins_base + UNIT_SYNC_BARRIER_OFF);
+
register_syscore_ops(&mvebu_mbus_syscore_ops);
return 0;
@@ -916,7 +1067,7 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
mbuswins_phys_base,
mbuswins_size,
sdramwins_phys_base,
- sdramwins_size, 0, 0);
+ sdramwins_size, 0, 0, false);
}
#ifdef CONFIG_OF
@@ -1118,7 +1269,8 @@ int __init mvebu_mbus_dt_init(bool is_coherent)
sdramwins_res.start,
resource_size(&sdramwins_res),
mbusbridge_res.start,
- resource_size(&mbusbridge_res));
+ resource_size(&mbusbridge_res),
+ is_coherent);
if (ret)
return ret;
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index b709749c8639..4eb1c772ded7 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -219,7 +219,10 @@ struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev);
/* generic functions for user-populated AGP memory types */
struct agp_memory *agp_generic_alloc_user(size_t page_count, int type);
void agp_alloc_page_array(size_t size, struct agp_memory *mem);
-void agp_free_page_array(struct agp_memory *mem);
+static inline void agp_free_page_array(struct agp_memory *mem)
+{
+ kvfree(mem->pages);
+}
/* generic routines for agp>=3 */
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 0fbccce1cee9..f002fa5d1887 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -98,17 +98,6 @@ void agp_alloc_page_array(size_t size, struct agp_memory *mem)
}
EXPORT_SYMBOL(agp_alloc_page_array);
-void agp_free_page_array(struct agp_memory *mem)
-{
- if (is_vmalloc_addr(mem->pages)) {
- vfree(mem->pages);
- } else {
- kfree(mem->pages);
- }
-}
-EXPORT_SYMBOL(agp_free_page_array);
-
-
static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages)
{
struct agp_memory *new;
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 92aa43fa8d70..0b4188b9af7c 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -225,7 +225,7 @@ static int i810_insert_dcache_entries(struct agp_memory *mem, off_t pg_start,
intel_private.driver->write_entry(addr,
i, type);
}
- readl(intel_private.gtt+i-1);
+ wmb();
return 0;
}
@@ -329,7 +329,7 @@ static void i810_write_entry(dma_addr_t addr, unsigned int entry,
break;
}
- writel(addr | pte_flags, intel_private.gtt + entry);
+ writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
}
static const struct aper_size_info_fixed intel_fake_agp_sizes[] = {
@@ -735,7 +735,7 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry,
if (flags == AGP_USER_CACHED_MEMORY)
pte_flags |= I830_PTE_SYSTEM_CACHED;
- writel(addr | pte_flags, intel_private.gtt + entry);
+ writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
}
bool intel_enable_gtt(void)
@@ -858,7 +858,7 @@ void intel_gtt_insert_sg_entries(struct sg_table *st,
j++;
}
}
- readl(intel_private.gtt+j-1);
+ wmb();
}
EXPORT_SYMBOL(intel_gtt_insert_sg_entries);
@@ -875,7 +875,7 @@ static void intel_gtt_insert_pages(unsigned int first_entry,
intel_private.driver->write_entry(addr,
j, flags);
}
- readl(intel_private.gtt+j-1);
+ wmb();
}
static int intel_fake_agp_insert_entries(struct agp_memory *mem,
@@ -938,7 +938,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
intel_private.driver->write_entry(intel_private.scratch_page_dma,
i, 0);
}
- readl(intel_private.gtt+i-1);
+ wmb();
}
EXPORT_SYMBOL(intel_gtt_clear_range);
@@ -1106,7 +1106,7 @@ static void i965_write_entry(dma_addr_t addr,
/* Shift high bits down */
addr |= (addr >> 28) & 0xf0;
- writel(addr | pte_flags, intel_private.gtt + entry);
+ writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
}
static int i9xx_setup(void)
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index bf53a3771da5..e85d3416d899 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -901,8 +901,10 @@ int tpm_pm_suspend(struct device *dev)
if (chip == NULL)
return -ENODEV;
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- return tpm2_shutdown(chip, TPM2_SU_CLEAR);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+ tpm2_shutdown(chip, TPM2_SU_STATE);
+ return 0;
+ }
/* for buggy tpm, flush pcrs with extend to selected dummy */
if (tpm_suspend_pcr) {
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 7b0727c5e803..f8319a0860fd 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -432,7 +432,8 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
u32 *value, const char *desc);
extern int tpm2_startup(struct tpm_chip *chip, u16 startup_type);
-extern int tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
+extern void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
extern unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *, u32);
extern int tpm2_do_selftest(struct tpm_chip *chip);
-extern int tpm2_gen_interrupt(struct tpm_chip *chip, bool quiet);
+extern int tpm2_gen_interrupt(struct tpm_chip *chip);
+extern int tpm2_probe(struct tpm_chip *chip);
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 1abe6502219f..011909a9be96 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -456,20 +456,23 @@ static const struct tpm_input_header tpm2_shutdown_header = {
* @chip: TPM chip to use.
* @shutdown_type shutdown type. The value is either
* TPM_SU_CLEAR or TPM_SU_STATE.
- *
- * 0 is returned when the operation is successful. If a negative number is
- * returned it remarks a POSIX error code. If a positive number is returned
- * it remarks a TPM error.
*/
-int tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
+void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
{
struct tpm2_cmd cmd;
+ int rc;
cmd.header.in = tpm2_shutdown_header;
-
cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type);
- return tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
- "stopping the TPM");
+
+ rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), "stopping the TPM");
+
+ /* In places where shutdown command is sent there's no much we can do
+ * except print the error code on a system failure.
+ */
+ if (rc < 0)
+ dev_warn(chip->pdev, "transmit returned %d while stopping the TPM",
+ rc);
}
EXPORT_SYMBOL_GPL(tpm2_shutdown);
@@ -598,20 +601,46 @@ EXPORT_SYMBOL_GPL(tpm2_do_selftest);
/**
* tpm2_gen_interrupt() - generate an interrupt
* @chip: TPM chip to use
- * @quiet: surpress the error message
*
* 0 is returned when the operation is successful. If a negative number is
* returned it remarks a POSIX error code. If a positive number is returned
* it remarks a TPM error.
*/
-int tpm2_gen_interrupt(struct tpm_chip *chip, bool quiet)
+int tpm2_gen_interrupt(struct tpm_chip *chip)
{
- const char *desc = NULL;
u32 dummy;
- if (!quiet)
- desc = "attempting to generate an interrupt";
-
- return tpm2_get_tpm_pt(chip, TPM2_CAP_TPM_PROPERTIES, &dummy, desc);
+ return tpm2_get_tpm_pt(chip, 0x100, &dummy,
+ "attempting to generate an interrupt");
}
EXPORT_SYMBOL_GPL(tpm2_gen_interrupt);
+
+/**
+ * tpm2_probe() - probe TPM 2.0
+ * @chip: TPM chip to use
+ *
+ * Send idempotent TPM 2.0 command and see whether TPM 2.0 chip replied based on
+ * the reply tag.
+ */
+int tpm2_probe(struct tpm_chip *chip)
+{
+ struct tpm2_cmd cmd;
+ int rc;
+
+ cmd.header.in = tpm2_get_tpm_pt_header;
+ cmd.params.get_tpm_pt_in.cap_id = cpu_to_be32(TPM2_CAP_TPM_PROPERTIES);
+ cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100);
+ cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
+
+ rc = tpm_transmit(chip, (const char *) &cmd, sizeof(cmd));
+ if (rc < 0)
+ return rc;
+ else if (rc < TPM_HEADER_SIZE)
+ return -EFAULT;
+
+ if (be16_to_cpu(cmd.header.out.tag) == TPM2_ST_NO_SESSIONS)
+ chip->flags |= TPM_CHIP_FLAG_TPM2;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(tpm2_probe);
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 3dd23cfae4fe..b26ceee3585e 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -95,21 +95,7 @@ struct crb_priv {
u8 __iomem *rsp;
};
-#ifdef CONFIG_PM_SLEEP
-static int crb_resume(struct device *dev)
-{
- int rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
-
- rc = tpm2_shutdown(chip, TPM2_SU_STATE);
- if (!rc)
- rc = tpm2_do_selftest(chip);
-
- return rc;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, crb_resume);
+static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume);
static u8 crb_status(struct tpm_chip *chip)
{
@@ -326,6 +312,10 @@ static int crb_acpi_remove(struct acpi_device *device)
struct tpm_chip *chip = dev_get_drvdata(dev);
tpm_chip_unregister(chip);
+
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ tpm2_shutdown(chip, TPM2_SU_CLEAR);
+
return 0;
}
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index 0840347e251c..b1e53e3aece5 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -148,7 +148,8 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
crq.len = (u16)count;
crq.data = ibmvtpm->rtce_dma_handle;
- rc = ibmvtpm_send_crq(ibmvtpm->vdev, word[0], word[1]);
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(word[0]),
+ cpu_to_be64(word[1]));
if (rc != H_SUCCESS) {
dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
rc = 0;
@@ -186,7 +187,8 @@ static int ibmvtpm_crq_get_rtce_size(struct ibmvtpm_dev *ibmvtpm)
crq.valid = (u8)IBMVTPM_VALID_CMD;
crq.msg = (u8)VTPM_GET_RTCE_BUFFER_SIZE;
- rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]),
+ cpu_to_be64(buf[1]));
if (rc != H_SUCCESS)
dev_err(ibmvtpm->dev,
"ibmvtpm_crq_get_rtce_size failed rc=%d\n", rc);
@@ -212,7 +214,8 @@ static int ibmvtpm_crq_get_version(struct ibmvtpm_dev *ibmvtpm)
crq.valid = (u8)IBMVTPM_VALID_CMD;
crq.msg = (u8)VTPM_GET_VERSION;
- rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]),
+ cpu_to_be64(buf[1]));
if (rc != H_SUCCESS)
dev_err(ibmvtpm->dev,
"ibmvtpm_crq_get_version failed rc=%d\n", rc);
@@ -336,7 +339,8 @@ static int tpm_ibmvtpm_suspend(struct device *dev)
crq.valid = (u8)IBMVTPM_VALID_CMD;
crq.msg = (u8)VTPM_PREPARE_TO_SUSPEND;
- rc = ibmvtpm_send_crq(ibmvtpm->vdev, buf[0], buf[1]);
+ rc = ibmvtpm_send_crq(ibmvtpm->vdev, cpu_to_be64(buf[0]),
+ cpu_to_be64(buf[1]));
if (rc != H_SUCCESS)
dev_err(ibmvtpm->dev,
"tpm_ibmvtpm_suspend failed rc=%d\n", rc);
@@ -481,11 +485,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
case IBMVTPM_VALID_CMD:
switch (crq->msg) {
case VTPM_GET_RTCE_BUFFER_SIZE_RES:
- if (crq->len <= 0) {
+ if (be16_to_cpu(crq->len) <= 0) {
dev_err(ibmvtpm->dev, "Invalid rtce size\n");
return;
}
- ibmvtpm->rtce_size = crq->len;
+ ibmvtpm->rtce_size = be16_to_cpu(crq->len);
ibmvtpm->rtce_buf = kmalloc(ibmvtpm->rtce_size,
GFP_KERNEL);
if (!ibmvtpm->rtce_buf) {
@@ -506,11 +510,11 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
return;
case VTPM_GET_VERSION_RES:
- ibmvtpm->vtpm_version = crq->data;
+ ibmvtpm->vtpm_version = be32_to_cpu(crq->data);
return;
case VTPM_TPM_COMMAND_RES:
/* len of the data in rtce buffer */
- ibmvtpm->res_len = crq->len;
+ ibmvtpm->res_len = be16_to_cpu(crq->len);
wake_up_interruptible(&ibmvtpm->wq);
return;
default:
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 6725bef7cb96..f2dffa770b8e 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -588,6 +588,9 @@ MODULE_PARM_DESC(interrupts, "Enable interrupts");
static void tpm_tis_remove(struct tpm_chip *chip)
{
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ tpm2_shutdown(chip, TPM2_SU_CLEAR);
+
iowrite32(~TPM_GLOBAL_INT_ENABLE &
ioread32(chip->vendor.iobase +
TPM_INT_ENABLE(chip->vendor.
@@ -639,12 +642,9 @@ static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
goto out_err;
}
- /* Every TPM 2.x command has a higher ordinal than TPM 1.x commands.
- * Therefore, we can use an idempotent TPM 2.x command to probe TPM 2.x.
- */
- rc = tpm2_gen_interrupt(chip, true);
- if (rc == 0 || rc == TPM2_RC_INITIALIZE)
- chip->flags |= TPM_CHIP_FLAG_TPM2;
+ rc = tpm2_probe(chip);
+ if (rc)
+ goto out_err;
vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
chip->vendor.manufacturer_id = vendor;
@@ -747,7 +747,7 @@ static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
/* Generate Interrupts */
if (chip->flags & TPM_CHIP_FLAG_TPM2)
- tpm2_gen_interrupt(chip, false);
+ tpm2_gen_interrupt(chip);
else
tpm_gen_interrupt(chip);
@@ -865,25 +865,22 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
static int tpm_tis_resume(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
- int ret = 0;
+ int ret;
if (chip->vendor.irq)
tpm_tis_reenable_interrupts(chip);
- if (chip->flags & TPM_CHIP_FLAG_TPM2) {
- /* NOP if firmware properly does this. */
- tpm2_startup(chip, TPM2_SU_STATE);
+ ret = tpm_pm_resume(dev);
+ if (ret)
+ return ret;
- ret = tpm2_shutdown(chip, TPM2_SU_STATE);
- if (!ret)
- ret = tpm2_do_selftest(chip);
- } else {
- ret = tpm_pm_resume(dev);
- if (!ret)
- tpm_do_selftest(chip);
- }
+ /* TPM 1.2 requires self-test on resume. This function actually returns
+ * an error code but for unknown reason it isn't handled.
+ */
+ if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
+ tpm_do_selftest(chip);
- return ret;
+ return 0;
}
#endif
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 26afb56a8073..fae2dbbf5745 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1986,7 +1986,10 @@ static int virtcons_probe(struct virtio_device *vdev)
bool multiport;
bool early = early_put_chars != NULL;
- if (!vdev->config->get) {
+ /* We only need a config space if features are offered */
+ if (!vdev->config->get &&
+ (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)
+ || virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT))) {
dev_err(&vdev->dev, "%s failure: config access disabled\n",
__func__);
return -EINVAL;
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 386999b4f8eb..f07c8152e5cc 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -27,6 +27,15 @@
void __iomem *at91_pmc_base;
EXPORT_SYMBOL_GPL(at91_pmc_base);
+void at91rm9200_idle(void)
+{
+ /*
+ * Disable the processor clock. The processor will be automatically
+ * re-enabled by an interrupt or by a reset.
+ */
+ at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+}
+
void at91sam9_idle(void)
{
at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 848d602efc06..07d666cc6a29 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -635,8 +635,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
SRC_TOP3, 0, 1),
MUX(0, "mout_user_aclk400_mscl", mout_user_aclk400_mscl_p,
SRC_TOP3, 4, 1),
- MUX(0, "mout_user_aclk200_disp1", mout_user_aclk200_disp1_p,
- SRC_TOP3, 8, 1),
+ MUX(CLK_MOUT_USER_ACLK200_DISP1, "mout_user_aclk200_disp1",
+ mout_user_aclk200_disp1_p, SRC_TOP3, 8, 1),
MUX(0, "mout_user_aclk200_fsys2", mout_user_aclk200_fsys2_p,
SRC_TOP3, 12, 1),
MUX(0, "mout_user_aclk400_wcore", mout_user_aclk400_wcore_p,
@@ -663,8 +663,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
MUX(CLK_MOUT_USER_ACLK333, "mout_user_aclk333", mout_user_aclk333_p,
SRC_TOP4, 28, 1),
- MUX(0, "mout_user_aclk400_disp1", mout_user_aclk400_disp1_p,
- SRC_TOP5, 0, 1),
+ MUX(CLK_MOUT_USER_ACLK400_DISP1, "mout_user_aclk400_disp1",
+ mout_user_aclk400_disp1_p, SRC_TOP5, 0, 1),
MUX(0, "mout_user_aclk66_psgen", mout_user_aclk66_peric_p,
SRC_TOP5, 4, 1),
MUX(0, "mout_user_aclk333_g2d", mout_user_aclk333_g2d_p,
@@ -675,8 +675,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
SRC_TOP5, 16, 1),
MUX(0, "mout_user_aclk300_jpeg", mout_user_aclk300_jpeg_p,
SRC_TOP5, 20, 1),
- MUX(0, "mout_user_aclk300_disp1", mout_user_aclk300_disp1_p,
- SRC_TOP5, 24, 1),
+ MUX(CLK_MOUT_USER_ACLK300_DISP1, "mout_user_aclk300_disp1",
+ mout_user_aclk300_disp1_p, SRC_TOP5, 24, 1),
MUX(0, "mout_user_aclk300_gscl", mout_user_aclk300_gscl_p,
SRC_TOP5, 28, 1),
@@ -693,7 +693,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
SRC_TOP10, 0, 1),
MUX(0, "mout_sw_aclk400_mscl", mout_sw_aclk400_mscl_p,
SRC_TOP10, 4, 1),
- MUX(0, "mout_sw_aclk200", mout_sw_aclk200_p, SRC_TOP10, 8, 1),
+ MUX(CLK_MOUT_SW_ACLK200, "mout_sw_aclk200", mout_sw_aclk200_p,
+ SRC_TOP10, 8, 1),
MUX(0, "mout_sw_aclk200_fsys2", mout_sw_aclk200_fsys2_p,
SRC_TOP10, 12, 1),
MUX(0, "mout_sw_aclk400_wcore", mout_sw_aclk400_wcore_p,
@@ -717,8 +718,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
MUX(CLK_MOUT_SW_ACLK333, "mout_sw_aclk333", mout_sw_aclk333_p,
SRC_TOP11, 28, 1),
- MUX(0, "mout_sw_aclk400_disp1", mout_sw_aclk400_disp1_p,
- SRC_TOP12, 4, 1),
+ MUX(CLK_MOUT_SW_ACLK400, "mout_sw_aclk400_disp1",
+ mout_sw_aclk400_disp1_p, SRC_TOP12, 4, 1),
MUX(0, "mout_sw_aclk333_g2d", mout_sw_aclk333_g2d_p,
SRC_TOP12, 8, 1),
MUX(0, "mout_sw_aclk266_g2d", mout_sw_aclk266_g2d_p,
@@ -726,8 +727,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
MUX(0, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p, SRC_TOP12, 16, 1),
MUX(0, "mout_sw_aclk300_jpeg", mout_sw_aclk300_jpeg_p,
SRC_TOP12, 20, 1),
- MUX(0, "mout_sw_aclk300_disp1", mout_sw_aclk300_disp1_p,
- SRC_TOP12, 24, 1),
+ MUX(CLK_MOUT_SW_ACLK300, "mout_sw_aclk300_disp1",
+ mout_sw_aclk300_disp1_p, SRC_TOP12, 24, 1),
MUX(0, "mout_sw_aclk300_gscl", mout_sw_aclk300_gscl_p,
SRC_TOP12, 28, 1),
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index 960bf22d42ae..f83980f2b956 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -5,5 +5,6 @@ obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o
diff --git a/drivers/clk/shmobile/clk-sh73a0.c b/drivers/clk/shmobile/clk-sh73a0.c
new file mode 100644
index 000000000000..cd529cfe412f
--- /dev/null
+++ b/drivers/clk/shmobile/clk-sh73a0.c
@@ -0,0 +1,218 @@
+/*
+ * sh73a0 Core CPG Clocks
+ *
+ * Copyright (C) 2014 Ulrich Hecht
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+struct sh73a0_cpg {
+ struct clk_onecell_data data;
+ spinlock_t lock;
+ void __iomem *reg;
+};
+
+#define CPG_FRQCRA 0x00
+#define CPG_FRQCRB 0x04
+#define CPG_SD0CKCR 0x74
+#define CPG_SD1CKCR 0x78
+#define CPG_SD2CKCR 0x7c
+#define CPG_PLLECR 0xd0
+#define CPG_PLL0CR 0xd8
+#define CPG_PLL1CR 0x28
+#define CPG_PLL2CR 0x2c
+#define CPG_PLL3CR 0xdc
+#define CPG_CKSCR 0xc0
+#define CPG_DSI0PHYCR 0x6c
+#define CPG_DSI1PHYCR 0x70
+
+#define CLK_ENABLE_ON_INIT BIT(0)
+
+struct div4_clk {
+ const char *name;
+ const char *parent;
+ unsigned int reg;
+ unsigned int shift;
+};
+
+static struct div4_clk div4_clks[] = {
+ { "zg", "pll0", CPG_FRQCRA, 16 },
+ { "m3", "pll1", CPG_FRQCRA, 12 },
+ { "b", "pll1", CPG_FRQCRA, 8 },
+ { "m1", "pll1", CPG_FRQCRA, 4 },
+ { "m2", "pll1", CPG_FRQCRA, 0 },
+ { "zx", "pll1", CPG_FRQCRB, 12 },
+ { "hp", "pll1", CPG_FRQCRB, 4 },
+ { NULL, NULL, 0, 0 },
+};
+
+static const struct clk_div_table div4_div_table[] = {
+ { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 },
+ { 6, 16 }, { 7, 18 }, { 8, 24 }, { 10, 36 }, { 11, 48 },
+ { 12, 7 }, { 0, 0 }
+};
+
+static const struct clk_div_table z_div_table[] = {
+ /* ZSEL == 0 */
+ { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 1 },
+ { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 10, 1 }, { 11, 1 },
+ { 12, 1 }, { 13, 1 }, { 14, 1 }, { 15, 1 },
+ /* ZSEL == 1 */
+ { 16, 2 }, { 17, 3 }, { 18, 4 }, { 19, 6 }, { 20, 8 }, { 21, 12 },
+ { 22, 16 }, { 24, 24 }, { 27, 48 }, { 0, 0 }
+};
+
+static struct clk * __init
+sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg,
+ const char *name)
+{
+ const struct clk_div_table *table = NULL;
+ unsigned int shift, reg, width;
+ const char *parent_name;
+ unsigned int mult = 1;
+ unsigned int div = 1;
+
+ if (!strcmp(name, "main")) {
+ /* extal1, extal1_div2, extal2, extal2_div2 */
+ u32 parent_idx = (clk_readl(cpg->reg + CPG_CKSCR) >> 28) & 3;
+
+ parent_name = of_clk_get_parent_name(np, parent_idx >> 1);
+ div = (parent_idx & 1) + 1;
+ } else if (!strncmp(name, "pll", 3)) {
+ void __iomem *enable_reg = cpg->reg;
+ u32 enable_bit = name[3] - '0';
+
+ parent_name = "main";
+ switch (enable_bit) {
+ case 0:
+ enable_reg += CPG_PLL0CR;
+ break;
+ case 1:
+ enable_reg += CPG_PLL1CR;
+ break;
+ case 2:
+ enable_reg += CPG_PLL2CR;
+ break;
+ case 3:
+ enable_reg += CPG_PLL3CR;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+ if (clk_readl(cpg->reg + CPG_PLLECR) & BIT(enable_bit)) {
+ mult = ((clk_readl(enable_reg) >> 24) & 0x3f) + 1;
+ /* handle CFG bit for PLL1 and PLL2 */
+ if (enable_bit == 1 || enable_bit == 2)
+ if (clk_readl(enable_reg) & BIT(20))
+ mult *= 2;
+ }
+ } else if (!strcmp(name, "dsi0phy") || !strcmp(name, "dsi1phy")) {
+ u32 phy_no = name[3] - '0';
+ void __iomem *dsi_reg = cpg->reg +
+ (phy_no ? CPG_DSI1PHYCR : CPG_DSI0PHYCR);
+
+ parent_name = phy_no ? "dsi1pck" : "dsi0pck";
+ mult = __raw_readl(dsi_reg);
+ if (!(mult & 0x8000))
+ mult = 1;
+ else
+ mult = (mult & 0x3f) + 1;
+ } else if (!strcmp(name, "z")) {
+ parent_name = "pll0";
+ table = z_div_table;
+ reg = CPG_FRQCRB;
+ shift = 24;
+ width = 5;
+ } else {
+ struct div4_clk *c;
+
+ for (c = div4_clks; c->name; c++) {
+ if (!strcmp(name, c->name)) {
+ parent_name = c->parent;
+ table = div4_div_table;
+ reg = c->reg;
+ shift = c->shift;
+ width = 4;
+ break;
+ }
+ }
+ if (!c->name)
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!table) {
+ return clk_register_fixed_factor(NULL, name, parent_name, 0,
+ mult, div);
+ } else {
+ return clk_register_divider_table(NULL, name, parent_name, 0,
+ cpg->reg + reg, shift, width, 0,
+ table, &cpg->lock);
+ }
+}
+
+static void __init sh73a0_cpg_clocks_init(struct device_node *np)
+{
+ struct sh73a0_cpg *cpg;
+ struct clk **clks;
+ unsigned int i;
+ int num_clks;
+
+ num_clks = of_property_count_strings(np, "clock-output-names");
+ if (num_clks < 0) {
+ pr_err("%s: failed to count clocks\n", __func__);
+ return;
+ }
+
+ cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
+ clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL);
+ if (cpg == NULL || clks == NULL) {
+ /* We're leaking memory on purpose, there's no point in cleaning
+ * up as the system won't boot anyway.
+ */
+ return;
+ }
+
+ spin_lock_init(&cpg->lock);
+
+ cpg->data.clks = clks;
+ cpg->data.clk_num = num_clks;
+
+ cpg->reg = of_iomap(np, 0);
+ if (WARN_ON(cpg->reg == NULL))
+ return;
+
+ /* Set SDHI clocks to a known state */
+ clk_writel(0x108, cpg->reg + CPG_SD0CKCR);
+ clk_writel(0x108, cpg->reg + CPG_SD1CKCR);
+ clk_writel(0x108, cpg->reg + CPG_SD2CKCR);
+
+ for (i = 0; i < num_clks; ++i) {
+ const char *name;
+ struct clk *clk;
+
+ of_property_read_string_index(np, "clock-output-names", i,
+ &name);
+
+ clk = sh73a0_cpg_register_clock(np, cpg, name);
+ if (IS_ERR(clk))
+ pr_err("%s: failed to register %s %s clock (%ld)\n",
+ __func__, np->name, name, PTR_ERR(clk));
+ else
+ cpg->data.clks[i] = clk;
+ }
+
+ of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+}
+CLK_OF_DECLARE(sh73a0_cpg_clks, "renesas,sh73a0-cpg-clocks",
+ sh73a0_cpg_clocks_init);
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 570202582dcf..1818f404538d 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -1226,6 +1226,7 @@ static void __init sun6i_init_clocks(struct device_node *node)
ARRAY_SIZE(sun6i_critical_clocks));
}
CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
+CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks);
CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
static void __init sun9i_init_clocks(struct device_node *node)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8a1479fc6479..1c2506f68122 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -18,6 +18,9 @@ config CLKBLD_I8253
config CLKSRC_MMIO
bool
+config DIGICOLOR_TIMER
+ bool
+
config DW_APB_TIMER
bool
@@ -26,6 +29,10 @@ config DW_APB_TIMER_OF
select DW_APB_TIMER
select CLKSRC_OF
+config ROCKCHIP_TIMER
+ bool
+ select CLKSRC_OF
+
config ARMADA_370_XP_TIMER
bool
select CLKSRC_OF
@@ -47,6 +54,9 @@ config SUN5I_HSTIMER
select CLKSRC_MMIO
bool
+config TEGRA_TIMER
+ bool
+
config VT8500_TIMER
bool
@@ -236,4 +246,14 @@ config CLKSRC_PXA
This enables OST0 support available on PXA and SA-11x0
platforms.
+config ASM9260_TIMER
+ bool "Alphascale ASM9260 timer driver"
+ depends on GENERIC_CLOCKEVENTS
+ select CLKSRC_MMIO
+ select CLKSRC_OF
+ default y if MACH_ASM9260
+ help
+ This enables build of a clocksource and clockevent driver for
+ the 32-bit System Timer hardware available on a Alphascale ASM9260.
+
endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index aa526f4bd3cf..752d5c70b0ef 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -10,15 +10,17 @@ obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o
obj-$(CONFIG_EM_TIMER_STI) += em_sti.o
obj-$(CONFIG_CLKBLD_I8253) += i8253.o
obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
+obj-$(CONFIG_DIGICOLOR_TIMER) += timer-digicolor.o
obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
+obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
obj-$(CONFIG_ORION_TIMER) += time-orion.o
obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
obj-$(CONFIG_ARCH_CLPS711X) += clps711x-timer.o
-obj-$(CONFIG_ARCH_MARCO) += timer-marco.o
+obj-$(CONFIG_ARCH_ATLAS7) += timer-atlas7.o
obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o
obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
obj-$(CONFIG_CLKSRC_PXA) += pxa_timer.o
@@ -27,7 +29,7 @@ obj-$(CONFIG_ARCH_U300) += timer-u300.o
obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o
obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o
-obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
+obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o
obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o
obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o
@@ -48,3 +50,4 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o
obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o
obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
+obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o
diff --git a/drivers/clocksource/asm9260_timer.c b/drivers/clocksource/asm9260_timer.c
new file mode 100644
index 000000000000..2c9c993727c8
--- /dev/null
+++ b/drivers/clocksource/asm9260_timer.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/bitops.h>
+
+#define DRIVER_NAME "asm9260-timer"
+
+/*
+ * this device provide 4 offsets for each register:
+ * 0x0 - plain read write mode
+ * 0x4 - set mode, OR logic.
+ * 0x8 - clr mode, XOR logic.
+ * 0xc - togle mode.
+ */
+#define SET_REG 4
+#define CLR_REG 8
+
+#define HW_IR 0x0000 /* RW. Interrupt */
+#define BM_IR_CR0 BIT(4)
+#define BM_IR_MR3 BIT(3)
+#define BM_IR_MR2 BIT(2)
+#define BM_IR_MR1 BIT(1)
+#define BM_IR_MR0 BIT(0)
+
+#define HW_TCR 0x0010 /* RW. Timer controller */
+/* BM_C*_RST
+ * Timer Counter and the Prescale Counter are synchronously reset on the
+ * next positive edge of PCLK. The counters remain reset until TCR[1] is
+ * returned to zero. */
+#define BM_C3_RST BIT(7)
+#define BM_C2_RST BIT(6)
+#define BM_C1_RST BIT(5)
+#define BM_C0_RST BIT(4)
+/* BM_C*_EN
+ * 1 - Timer Counter and Prescale Counter are enabled for counting
+ * 0 - counters are disabled */
+#define BM_C3_EN BIT(3)
+#define BM_C2_EN BIT(2)
+#define BM_C1_EN BIT(1)
+#define BM_C0_EN BIT(0)
+
+#define HW_DIR 0x0020 /* RW. Direction? */
+/* 00 - count up
+ * 01 - count down
+ * 10 - ?? 2^n/2 */
+#define BM_DIR_COUNT_UP 0
+#define BM_DIR_COUNT_DOWN 1
+#define BM_DIR0_SHIFT 0
+#define BM_DIR1_SHIFT 4
+#define BM_DIR2_SHIFT 8
+#define BM_DIR3_SHIFT 12
+#define BM_DIR_DEFAULT (BM_DIR_COUNT_UP << BM_DIR0_SHIFT | \
+ BM_DIR_COUNT_UP << BM_DIR1_SHIFT | \
+ BM_DIR_COUNT_UP << BM_DIR2_SHIFT | \
+ BM_DIR_COUNT_UP << BM_DIR3_SHIFT)
+
+#define HW_TC0 0x0030 /* RO. Timer counter 0 */
+/* HW_TC*. Timer counter owerflow (0xffff.ffff to 0x0000.0000) do not generate
+ * interrupt. This registers can be used to detect overflow */
+#define HW_TC1 0x0040
+#define HW_TC2 0x0050
+#define HW_TC3 0x0060
+
+#define HW_PR 0x0070 /* RW. prescaler */
+#define BM_PR_DISABLE 0
+#define HW_PC 0x0080 /* RO. Prescaler counter */
+#define HW_MCR 0x0090 /* RW. Match control */
+/* enable interrupt on match */
+#define BM_MCR_INT_EN(n) (1 << (n * 3 + 0))
+/* enable TC reset on match */
+#define BM_MCR_RES_EN(n) (1 << (n * 3 + 1))
+/* enable stop TC on match */
+#define BM_MCR_STOP_EN(n) (1 << (n * 3 + 2))
+
+#define HW_MR0 0x00a0 /* RW. Match reg */
+#define HW_MR1 0x00b0
+#define HW_MR2 0x00C0
+#define HW_MR3 0x00D0
+
+#define HW_CTCR 0x0180 /* Counter control */
+#define BM_CTCR0_SHIFT 0
+#define BM_CTCR1_SHIFT 2
+#define BM_CTCR2_SHIFT 4
+#define BM_CTCR3_SHIFT 6
+#define BM_CTCR_TM 0 /* Timer mode. Every rising PCLK edge. */
+#define BM_CTCR_DEFAULT (BM_CTCR_TM << BM_CTCR0_SHIFT | \
+ BM_CTCR_TM << BM_CTCR1_SHIFT | \
+ BM_CTCR_TM << BM_CTCR2_SHIFT | \
+ BM_CTCR_TM << BM_CTCR3_SHIFT)
+
+static struct asm9260_timer_priv {
+ void __iomem *base;
+ unsigned long ticks_per_jiffy;
+} priv;
+
+static int asm9260_timer_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ /* configure match count for TC0 */
+ writel_relaxed(delta, priv.base + HW_MR0);
+ /* enable TC0 */
+ writel_relaxed(BM_C0_EN, priv.base + HW_TCR + SET_REG);
+ return 0;
+}
+
+static void asm9260_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* stop timer0 */
+ writel_relaxed(BM_C0_EN, priv.base + HW_TCR + CLR_REG);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* disable reset and stop on match */
+ writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
+ priv.base + HW_MCR + CLR_REG);
+ /* configure match count for TC0 */
+ writel_relaxed(priv.ticks_per_jiffy, priv.base + HW_MR0);
+ /* enable TC0 */
+ writel_relaxed(BM_C0_EN, priv.base + HW_TCR + SET_REG);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* enable reset and stop on match */
+ writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0),
+ priv.base + HW_MCR + SET_REG);
+ break;
+ default:
+ break;
+ }
+}
+
+static struct clock_event_device event_dev = {
+ .name = DRIVER_NAME,
+ .rating = 200,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = asm9260_timer_set_next_event,
+ .set_mode = asm9260_timer_set_mode,
+};
+
+static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ evt->event_handler(evt);
+
+ writel_relaxed(BM_IR_MR0, priv.base + HW_IR);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+static void __init asm9260_timer_init(struct device_node *np)
+{
+ int irq;
+ struct clk *clk;
+ int ret;
+ unsigned long rate;
+
+ priv.base = of_io_request_and_map(np, 0, np->name);
+ if (!priv.base)
+ panic("%s: unable to map resource", np->name);
+
+ clk = of_clk_get(np, 0);
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ panic("Failed to enable clk!\n");
+
+ irq = irq_of_parse_and_map(np, 0);
+ ret = request_irq(irq, asm9260_timer_interrupt, IRQF_TIMER,
+ DRIVER_NAME, &event_dev);
+ if (ret)
+ panic("Failed to setup irq!\n");
+
+ /* set all timers for count-up */
+ writel_relaxed(BM_DIR_DEFAULT, priv.base + HW_DIR);
+ /* disable divider */
+ writel_relaxed(BM_PR_DISABLE, priv.base + HW_PR);
+ /* make sure all timers use every rising PCLK edge. */
+ writel_relaxed(BM_CTCR_DEFAULT, priv.base + HW_CTCR);
+ /* enable interrupt for TC0 and clean setting for all other lines */
+ writel_relaxed(BM_MCR_INT_EN(0) , priv.base + HW_MCR);
+
+ rate = clk_get_rate(clk);
+ clocksource_mmio_init(priv.base + HW_TC1, DRIVER_NAME, rate,
+ 200, 32, clocksource_mmio_readl_up);
+
+ /* Seems like we can't use counter without match register even if
+ * actions for MR are disabled. So, set MR to max value. */
+ writel_relaxed(0xffffffff, priv.base + HW_MR1);
+ /* enable TC1 */
+ writel_relaxed(BM_C1_EN, priv.base + HW_TCR + SET_REG);
+
+ priv.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
+ event_dev.cpumask = cpumask_of(0);
+ clockevents_config_and_register(&event_dev, rate, 0x2c00, 0xfffffffe);
+}
+CLOCKSOURCE_OF_DECLARE(asm9260_timer, "alphascale,asm9260-timer",
+ asm9260_timer_init);
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
new file mode 100644
index 000000000000..a35993bafb20
--- /dev/null
+++ b/drivers/clocksource/rockchip_timer.c
@@ -0,0 +1,180 @@
+/*
+ * Rockchip timer support
+ *
+ * Copyright (C) Daniel Lezcano <daniel.lezcano@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define TIMER_NAME "rk_timer"
+
+#define TIMER_LOAD_COUNT0 0x00
+#define TIMER_LOAD_COUNT1 0x04
+#define TIMER_CONTROL_REG 0x10
+#define TIMER_INT_STATUS 0x18
+
+#define TIMER_DISABLE 0x0
+#define TIMER_ENABLE 0x1
+#define TIMER_MODE_FREE_RUNNING (0 << 1)
+#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
+#define TIMER_INT_UNMASK (1 << 2)
+
+struct bc_timer {
+ struct clock_event_device ce;
+ void __iomem *base;
+ u32 freq;
+};
+
+static struct bc_timer bc_timer;
+
+static inline struct bc_timer *rk_timer(struct clock_event_device *ce)
+{
+ return container_of(ce, struct bc_timer, ce);
+}
+
+static inline void __iomem *rk_base(struct clock_event_device *ce)
+{
+ return rk_timer(ce)->base;
+}
+
+static inline void rk_timer_disable(struct clock_event_device *ce)
+{
+ writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG);
+ dsb();
+}
+
+static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags)
+{
+ writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags,
+ rk_base(ce) + TIMER_CONTROL_REG);
+ dsb();
+}
+
+static void rk_timer_update_counter(unsigned long cycles,
+ struct clock_event_device *ce)
+{
+ writel_relaxed(cycles, rk_base(ce) + TIMER_LOAD_COUNT0);
+ writel_relaxed(0, rk_base(ce) + TIMER_LOAD_COUNT1);
+ dsb();
+}
+
+static void rk_timer_interrupt_clear(struct clock_event_device *ce)
+{
+ writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS);
+ dsb();
+}
+
+static inline int rk_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *ce)
+{
+ rk_timer_disable(ce);
+ rk_timer_update_counter(cycles, ce);
+ rk_timer_enable(ce, TIMER_MODE_USER_DEFINED_COUNT);
+ return 0;
+}
+
+static inline void rk_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *ce)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ rk_timer_disable(ce);
+ rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce);
+ rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ rk_timer_disable(ce);
+ break;
+ }
+}
+
+static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *ce = dev_id;
+
+ rk_timer_interrupt_clear(ce);
+
+ if (ce->mode == CLOCK_EVT_MODE_ONESHOT)
+ rk_timer_disable(ce);
+
+ ce->event_handler(ce);
+
+ return IRQ_HANDLED;
+}
+
+static void __init rk_timer_init(struct device_node *np)
+{
+ struct clock_event_device *ce = &bc_timer.ce;
+ struct clk *timer_clk;
+ struct clk *pclk;
+ int ret, irq;
+
+ bc_timer.base = of_iomap(np, 0);
+ if (!bc_timer.base) {
+ pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
+ return;
+ }
+
+ pclk = of_clk_get_by_name(np, "pclk");
+ if (IS_ERR(pclk)) {
+ pr_err("Failed to get pclk for '%s'\n", TIMER_NAME);
+ return;
+ }
+
+ if (clk_prepare_enable(pclk)) {
+ pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME);
+ return;
+ }
+
+ timer_clk = of_clk_get_by_name(np, "timer");
+ if (IS_ERR(timer_clk)) {
+ pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME);
+ return;
+ }
+
+ if (clk_prepare_enable(timer_clk)) {
+ pr_err("Failed to enable timer clock\n");
+ return;
+ }
+
+ bc_timer.freq = clk_get_rate(timer_clk);
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq == NO_IRQ) {
+ pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME);
+ return;
+ }
+
+ ce->name = TIMER_NAME;
+ ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+ ce->set_next_event = rk_timer_set_next_event;
+ ce->set_mode = rk_timer_set_mode;
+ ce->irq = irq;
+ ce->cpumask = cpumask_of(0);
+ ce->rating = 250;
+
+ rk_timer_interrupt_clear(ce);
+ rk_timer_disable(ce);
+
+ ret = request_irq(irq, rk_timer_interrupt, IRQF_TIMER, TIMER_NAME, ce);
+ if (ret) {
+ pr_err("Failed to initialize '%s': %d\n", TIMER_NAME, ret);
+ return;
+ }
+
+ clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX);
+}
+CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init);
diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-atlas7.c
index 361a789d4bee..60f9de3438b0 100644
--- a/drivers/clocksource/timer-marco.c
+++ b/drivers/clocksource/timer-atlas7.c
@@ -38,7 +38,7 @@
#define SIRFSOC_TIMER_REG_CNT 6
-static unsigned long marco_timer_rate;
+static unsigned long atlas7_timer_rate;
static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
SIRFSOC_TIMER_WATCHDOG_EN,
@@ -195,7 +195,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
ce->rating = 200;
ce->set_mode = sirfsoc_timer_set_mode;
ce->set_next_event = sirfsoc_timer_set_next_event;
- clockevents_calc_mult_shift(ce, marco_timer_rate, 60);
+ clockevents_calc_mult_shift(ce, atlas7_timer_rate, 60);
ce->max_delta_ns = clockevent_delta2ns(-2, ce);
ce->min_delta_ns = clockevent_delta2ns(2, ce);
ce->cpumask = cpumask_of(cpu);
@@ -255,9 +255,8 @@ static void __init sirfsoc_clockevent_init(void)
}
/* initialize the kernel jiffy timer source */
-static void __init sirfsoc_marco_timer_init(struct device_node *np)
+static void __init sirfsoc_atlas7_timer_init(struct device_node *np)
{
- u32 timer_div;
struct clk *clk;
clk = of_clk_get(np, 0);
@@ -265,7 +264,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
BUG_ON(clk_prepare_enable(clk));
- marco_timer_rate = clk_get_rate(clk);
+ atlas7_timer_rate = clk_get_rate(clk);
/* timer dividers: 0, not divided */
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
@@ -283,7 +282,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
/* Clear all interrupts */
writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
- BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, marco_timer_rate));
+ BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, atlas7_timer_rate));
sirfsoc_clockevent_init();
}
@@ -302,6 +301,6 @@ static void __init sirfsoc_of_timer_init(struct device_node *np)
if (!sirfsoc_timer1_irq.irq)
panic("No irq passed for timer1 via DT\n");
- sirfsoc_marco_timer_init(np);
+ sirfsoc_atlas7_timer_init(np);
}
-CLOCKSOURCE_OF_DECLARE(sirfsoc_marco_timer, "sirf,marco-tick", sirfsoc_of_timer_init );
+CLOCKSOURCE_OF_DECLARE(sirfsoc_atlas7_timer, "sirf,atlas7-tick", sirfsoc_of_timer_init);
diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c
new file mode 100644
index 000000000000..7f8388cfa810
--- /dev/null
+++ b/drivers/clocksource/timer-digicolor.c
@@ -0,0 +1,199 @@
+/*
+ * Conexant Digicolor timer driver
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * Based on:
+ * Allwinner SoCs hstimer driver
+ *
+ * Copyright (C) 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * Conexant Digicolor SoCs have 8 configurable timers, named from "Timer A" to
+ * "Timer H". Timer A is the only one with watchdog support, so it is dedicated
+ * to the watchdog driver. This driver uses Timer B for sched_clock(), and
+ * Timer C for clockevents.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/sched_clock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+enum {
+ TIMER_A,
+ TIMER_B,
+ TIMER_C,
+ TIMER_D,
+ TIMER_E,
+ TIMER_F,
+ TIMER_G,
+ TIMER_H,
+};
+
+#define CONTROL(t) ((t)*8)
+#define COUNT(t) ((t)*8 + 4)
+
+#define CONTROL_DISABLE 0
+#define CONTROL_ENABLE BIT(0)
+#define CONTROL_MODE(m) ((m) << 4)
+#define CONTROL_MODE_ONESHOT CONTROL_MODE(1)
+#define CONTROL_MODE_PERIODIC CONTROL_MODE(2)
+
+struct digicolor_timer {
+ struct clock_event_device ce;
+ void __iomem *base;
+ u32 ticks_per_jiffy;
+ int timer_id; /* one of TIMER_* */
+};
+
+struct digicolor_timer *dc_timer(struct clock_event_device *ce)
+{
+ return container_of(ce, struct digicolor_timer, ce);
+}
+
+static inline void dc_timer_disable(struct clock_event_device *ce)
+{
+ struct digicolor_timer *dt = dc_timer(ce);
+ writeb(CONTROL_DISABLE, dt->base + CONTROL(dt->timer_id));
+}
+
+static inline void dc_timer_enable(struct clock_event_device *ce, u32 mode)
+{
+ struct digicolor_timer *dt = dc_timer(ce);
+ writeb(CONTROL_ENABLE | mode, dt->base + CONTROL(dt->timer_id));
+}
+
+static inline void dc_timer_set_count(struct clock_event_device *ce,
+ unsigned long count)
+{
+ struct digicolor_timer *dt = dc_timer(ce);
+ writel(count, dt->base + COUNT(dt->timer_id));
+}
+
+static void digicolor_clkevt_mode(enum clock_event_mode mode,
+ struct clock_event_device *ce)
+{
+ struct digicolor_timer *dt = dc_timer(ce);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ dc_timer_disable(ce);
+ dc_timer_set_count(ce, dt->ticks_per_jiffy);
+ dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ dc_timer_disable(ce);
+ dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ dc_timer_disable(ce);
+ break;
+ }
+}
+
+static int digicolor_clkevt_next_event(unsigned long evt,
+ struct clock_event_device *ce)
+{
+ dc_timer_disable(ce);
+ dc_timer_set_count(ce, evt);
+ dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
+
+ return 0;
+}
+
+static struct digicolor_timer dc_timer_dev = {
+ .ce = {
+ .name = "digicolor_tick",
+ .rating = 340,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = digicolor_clkevt_mode,
+ .set_next_event = digicolor_clkevt_next_event,
+ },
+ .timer_id = TIMER_C,
+};
+
+static irqreturn_t digicolor_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static u64 digicolor_timer_sched_read(void)
+{
+ return ~readl(dc_timer_dev.base + COUNT(TIMER_B));
+}
+
+static void __init digicolor_timer_init(struct device_node *node)
+{
+ unsigned long rate;
+ struct clk *clk;
+ int ret, irq;
+
+ /*
+ * timer registers are shared with the watchdog timer;
+ * don't map exclusively
+ */
+ dc_timer_dev.base = of_iomap(node, 0);
+ if (!dc_timer_dev.base) {
+ pr_err("Can't map registers");
+ return;
+ }
+
+ irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id);
+ if (irq <= 0) {
+ pr_err("Can't parse IRQ");
+ return;
+ }
+
+ clk = of_clk_get(node, 0);
+ if (IS_ERR(clk)) {
+ pr_err("Can't get timer clock");
+ return;
+ }
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+ dc_timer_dev.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
+
+ writeb(CONTROL_DISABLE, dc_timer_dev.base + CONTROL(TIMER_B));
+ writel(UINT_MAX, dc_timer_dev.base + COUNT(TIMER_B));
+ writeb(CONTROL_ENABLE, dc_timer_dev.base + CONTROL(TIMER_B));
+
+ sched_clock_register(digicolor_timer_sched_read, 32, rate);
+ clocksource_mmio_init(dc_timer_dev.base + COUNT(TIMER_B), node->name,
+ rate, 340, 32, clocksource_mmio_readl_down);
+
+ ret = request_irq(irq, digicolor_timer_interrupt,
+ IRQF_TIMER | IRQF_IRQPOLL, "digicolor_timerC",
+ &dc_timer_dev.ce);
+ if (ret)
+ pr_warn("request of timer irq %d failed (%d)\n", irq, ret);
+
+ dc_timer_dev.ce.cpumask = cpu_possible_mask;
+ dc_timer_dev.ce.irq = irq;
+
+ clockevents_config_and_register(&dc_timer_dev.ce, rate, 0, 0xffffffff);
+}
+CLOCKSOURCE_OF_DECLARE(conexant_digicolor, "cnxt,cx92755-timer",
+ digicolor_timer_init);
diff --git a/drivers/clocksource/versatile.c b/drivers/clocksource/versatile.c
index 2798e7492234..0a26d3dde6c0 100644
--- a/drivers/clocksource/versatile.c
+++ b/drivers/clocksource/versatile.c
@@ -36,5 +36,7 @@ static void __init versatile_sched_clock_init(struct device_node *node)
sched_clock_register(versatile_sys_24mhz_read, 32, 24000000);
}
-CLOCKSOURCE_OF_DECLARE(versatile, "arm,vexpress-sysreg",
+CLOCKSOURCE_OF_DECLARE(vexpress, "arm,vexpress-sysreg",
+ versatile_sched_clock_init);
+CLOCKSOURCE_OF_DECLARE(versatile, "arm,versatile-sysreg",
versatile_sched_clock_init);
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 8c16ab20fb15..8e07c9419153 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -55,6 +55,7 @@ config ARM_AT91_CPUIDLE
config ARM_EXYNOS_CPUIDLE
bool "Cpu Idle Driver for the Exynos processors"
depends on ARCH_EXYNOS
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
help
Select this to enable cpuidle for Exynos processors
diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c
index 4003a3160865..26f5f29fdb03 100644
--- a/drivers/cpuidle/cpuidle-exynos.c
+++ b/drivers/cpuidle/cpuidle-exynos.c
@@ -1,8 +1,11 @@
-/* linux/arch/arm/mach-exynos/cpuidle.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
+ * Coupled cpuidle support based on the work of:
+ * Colin Cross <ccross@android.com>
+ * Daniel Lezcano <daniel.lezcano@linaro.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -13,13 +16,49 @@
#include <linux/export.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/platform_data/cpuidle-exynos.h>
#include <asm/proc-fns.h>
#include <asm/suspend.h>
#include <asm/cpuidle.h>
+static atomic_t exynos_idle_barrier;
+
+static struct cpuidle_exynos_data *exynos_cpuidle_pdata;
static void (*exynos_enter_aftr)(void);
+static int exynos_enter_coupled_lowpower(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ int ret;
+
+ exynos_cpuidle_pdata->pre_enter_aftr();
+
+ /*
+ * Waiting all cpus to reach this point at the same moment
+ */
+ cpuidle_coupled_parallel_barrier(dev, &exynos_idle_barrier);
+
+ /*
+ * Both cpus will reach this point at the same time
+ */
+ ret = dev->cpu ? exynos_cpuidle_pdata->cpu1_powerdown()
+ : exynos_cpuidle_pdata->cpu0_enter_aftr();
+ if (ret)
+ index = ret;
+
+ /*
+ * Waiting all cpus to finish the power sequence before going further
+ */
+ cpuidle_coupled_parallel_barrier(dev, &exynos_idle_barrier);
+
+ exynos_cpuidle_pdata->post_enter_aftr();
+
+ return index;
+}
+
static int exynos_enter_lowpower(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
@@ -55,13 +94,40 @@ static struct cpuidle_driver exynos_idle_driver = {
.safe_state_index = 0,
};
+static struct cpuidle_driver exynos_coupled_idle_driver = {
+ .name = "exynos_coupled_idle",
+ .owner = THIS_MODULE,
+ .states = {
+ [0] = ARM_CPUIDLE_WFI_STATE,
+ [1] = {
+ .enter = exynos_enter_coupled_lowpower,
+ .exit_latency = 5000,
+ .target_residency = 10000,
+ .flags = CPUIDLE_FLAG_COUPLED |
+ CPUIDLE_FLAG_TIMER_STOP,
+ .name = "C1",
+ .desc = "ARM power down",
+ },
+ },
+ .state_count = 2,
+ .safe_state_index = 0,
+};
+
static int exynos_cpuidle_probe(struct platform_device *pdev)
{
int ret;
- exynos_enter_aftr = (void *)(pdev->dev.platform_data);
+ if (of_machine_is_compatible("samsung,exynos4210")) {
+ exynos_cpuidle_pdata = pdev->dev.platform_data;
+
+ ret = cpuidle_register(&exynos_coupled_idle_driver,
+ cpu_possible_mask);
+ } else {
+ exynos_enter_aftr = (void *)(pdev->dev.platform_data);
+
+ ret = cpuidle_register(&exynos_idle_driver, NULL);
+ }
- ret = cpuidle_register(&exynos_idle_driver, NULL);
if (ret) {
dev_err(&pdev->dev, "failed to register cpuidle driver\n");
return ret;
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 125150dc6e81..4d534582514e 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -19,6 +19,8 @@
#include <linux/ktime.h>
#include <linux/hrtimer.h>
#include <linux/module.h>
+#include <linux/suspend.h>
+#include <linux/tick.h>
#include <trace/events/power.h>
#include "cpuidle.h"
@@ -32,7 +34,6 @@ LIST_HEAD(cpuidle_detected_devices);
static int enabled_devices;
static int off __read_mostly;
static int initialized __read_mostly;
-static bool use_deepest_state __read_mostly;
int cpuidle_disabled(void)
{
@@ -66,36 +67,23 @@ int cpuidle_play_dead(void)
}
/**
- * cpuidle_use_deepest_state - Enable/disable the "deepest idle" mode.
- * @enable: Whether enable or disable the feature.
- *
- * If the "deepest idle" mode is enabled, cpuidle will ignore the governor and
- * always use the state with the greatest exit latency (out of the states that
- * are not disabled).
- *
- * This function can only be called after cpuidle_pause() to avoid races.
- */
-void cpuidle_use_deepest_state(bool enable)
-{
- use_deepest_state = enable;
-}
-
-/**
- * cpuidle_find_deepest_state - Find the state of the greatest exit latency.
- * @drv: cpuidle driver for a given CPU.
- * @dev: cpuidle device for a given CPU.
+ * cpuidle_find_deepest_state - Find deepest state meeting specific conditions.
+ * @drv: cpuidle driver for the given CPU.
+ * @dev: cpuidle device for the given CPU.
+ * @freeze: Whether or not the state should be suitable for suspend-to-idle.
*/
static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
- struct cpuidle_device *dev)
+ struct cpuidle_device *dev, bool freeze)
{
unsigned int latency_req = 0;
- int i, ret = CPUIDLE_DRIVER_STATE_START - 1;
+ int i, ret = freeze ? -1 : CPUIDLE_DRIVER_STATE_START - 1;
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
struct cpuidle_state *s = &drv->states[i];
struct cpuidle_state_usage *su = &dev->states_usage[i];
- if (s->disabled || su->disable || s->exit_latency <= latency_req)
+ if (s->disabled || su->disable || s->exit_latency <= latency_req
+ || (freeze && !s->enter_freeze))
continue;
latency_req = s->exit_latency;
@@ -104,6 +92,63 @@ static int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
return ret;
}
+static void enter_freeze_proper(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev, int index)
+{
+ tick_freeze();
+ /*
+ * The state used here cannot be a "coupled" one, because the "coupled"
+ * cpuidle mechanism enables interrupts and doing that with timekeeping
+ * suspended is generally unsafe.
+ */
+ drv->states[index].enter_freeze(dev, drv, index);
+ WARN_ON(!irqs_disabled());
+ /*
+ * timekeeping_resume() that will be called by tick_unfreeze() for the
+ * last CPU executing it calls functions containing RCU read-side
+ * critical sections, so tell RCU about that.
+ */
+ RCU_NONIDLE(tick_unfreeze());
+}
+
+/**
+ * cpuidle_enter_freeze - Enter an idle state suitable for suspend-to-idle.
+ *
+ * If there are states with the ->enter_freeze callback, find the deepest of
+ * them and enter it with frozen tick. Otherwise, find the deepest state
+ * available and enter it normally.
+ */
+void cpuidle_enter_freeze(void)
+{
+ struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+ int index;
+
+ /*
+ * Find the deepest state with ->enter_freeze present, which guarantees
+ * that interrupts won't be enabled when it exits and allows the tick to
+ * be frozen safely.
+ */
+ index = cpuidle_find_deepest_state(drv, dev, true);
+ if (index >= 0) {
+ enter_freeze_proper(drv, dev, index);
+ return;
+ }
+
+ /*
+ * It is not safe to freeze the tick, find the deepest state available
+ * at all and try to enter it normally.
+ */
+ index = cpuidle_find_deepest_state(drv, dev, false);
+ if (index >= 0)
+ cpuidle_enter(drv, dev, index);
+ else
+ arch_cpu_idle();
+
+ /* Interrupts are enabled again here. */
+ local_irq_disable();
+}
+
/**
* cpuidle_enter_state - enter the state and update stats
* @dev: cpuidle device for this cpu
@@ -166,9 +211,6 @@ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
if (!drv || !dev || !dev->enabled)
return -EBUSY;
- if (unlikely(use_deepest_state))
- return cpuidle_find_deepest_state(drv, dev);
-
return cpuidle_curr_governor->select(drv, dev);
}
@@ -200,7 +242,7 @@ int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev,
*/
void cpuidle_reflect(struct cpuidle_device *dev, int index)
{
- if (cpuidle_curr_governor->reflect && !unlikely(use_deepest_state))
+ if (cpuidle_curr_governor->reflect)
cpuidle_curr_governor->reflect(dev, index);
}
diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c
index d594ae962ed2..fded0a5cfcd7 100644
--- a/drivers/crypto/ux500/cryp/cryp_core.c
+++ b/drivers/crypto/ux500/cryp/cryp_core.c
@@ -606,12 +606,12 @@ static void cryp_dma_done(struct cryp_ctx *ctx)
dev_dbg(ctx->device->dev, "[%s]: ", __func__);
chan = ctx->device->dma.chan_mem2cryp;
- dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
+ dmaengine_terminate_all(chan);
dma_unmap_sg(chan->device->dev, ctx->device->dma.sg_src,
ctx->device->dma.sg_src_len, DMA_TO_DEVICE);
chan = ctx->device->dma.chan_cryp2mem;
- dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
+ dmaengine_terminate_all(chan);
dma_unmap_sg(chan->device->dev, ctx->device->dma.sg_dst,
ctx->device->dma.sg_dst_len, DMA_FROM_DEVICE);
}
diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c
index 70a20871e998..187a8fd7eee7 100644
--- a/drivers/crypto/ux500/hash/hash_core.c
+++ b/drivers/crypto/ux500/hash/hash_core.c
@@ -202,7 +202,7 @@ static void hash_dma_done(struct hash_ctx *ctx)
struct dma_chan *chan;
chan = ctx->device->dma.chan_mem2hash;
- dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
+ dmaengine_terminate_all(chan);
dma_unmap_sg(chan->device->dev, ctx->device->dma.sg,
ctx->device->dma.sg_len, DMA_TO_DEVICE);
}
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index f2b2c4e87aef..a874b6ec6650 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -184,7 +184,7 @@ config TEGRA20_APB_DMA
config S3C24XX_DMAC
tristate "Samsung S3C24XX DMA support"
- depends on ARCH_S3C24XX && !S3C24XX_DMA
+ depends on ARCH_S3C24XX
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
help
@@ -416,6 +416,15 @@ config NBPFAXI_DMA
help
Support for "Type-AXI" NBPF DMA IPs from Renesas
+config IMG_MDC_DMA
+ tristate "IMG MDC support"
+ depends on MIPS || COMPILE_TEST
+ depends on MFD_SYSCON
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+ help
+ Enable support for the IMG multi-threaded DMA controller (MDC).
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 2022b5451377..f915f61ec574 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -19,7 +19,7 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
obj-$(CONFIG_AT_XDMAC) += at_xdmac.o
obj-$(CONFIG_MX3_IPU) += ipu/
obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
-obj-$(CONFIG_SH_DMAE_BASE) += sh/
+obj-$(CONFIG_RENESAS_DMA) += sh/
obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
obj-$(CONFIG_IMX_SDMA) += imx-sdma.o
@@ -50,3 +50,4 @@ obj-y += xilinx/
obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o
obj-$(CONFIG_DMA_SUN6I) += sun6i-dma.o
+obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 1364d00881dd..4a5fd245014e 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1386,32 +1386,6 @@ static u32 pl08x_get_cctl(struct pl08x_dma_chan *plchan,
return pl08x_cctl(cctl);
}
-static int dma_set_runtime_config(struct dma_chan *chan,
- struct dma_slave_config *config)
-{
- struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
- struct pl08x_driver_data *pl08x = plchan->host;
-
- if (!plchan->slave)
- return -EINVAL;
-
- /* Reject definitely invalid configurations */
- if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
- config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
- return -EINVAL;
-
- if (config->device_fc && pl08x->vd->pl080s) {
- dev_err(&pl08x->adev->dev,
- "%s: PL080S does not support peripheral flow control\n",
- __func__);
- return -EINVAL;
- }
-
- plchan->cfg = *config;
-
- return 0;
-}
-
/*
* Slave transactions callback to the slave device to allow
* synchronization of slave DMA signals with the DMAC enable
@@ -1693,20 +1667,71 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_cyclic(
return vchan_tx_prep(&plchan->vc, &txd->vd, flags);
}
-static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int pl08x_config(struct dma_chan *chan,
+ struct dma_slave_config *config)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ struct pl08x_driver_data *pl08x = plchan->host;
+
+ if (!plchan->slave)
+ return -EINVAL;
+
+ /* Reject definitely invalid configurations */
+ if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
+ config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
+ return -EINVAL;
+
+ if (config->device_fc && pl08x->vd->pl080s) {
+ dev_err(&pl08x->adev->dev,
+ "%s: PL080S does not support peripheral flow control\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ plchan->cfg = *config;
+
+ return 0;
+}
+
+static int pl08x_terminate_all(struct dma_chan *chan)
{
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
struct pl08x_driver_data *pl08x = plchan->host;
unsigned long flags;
- int ret = 0;
- /* Controls applicable to inactive channels */
- if (cmd == DMA_SLAVE_CONFIG) {
- return dma_set_runtime_config(chan,
- (struct dma_slave_config *)arg);
+ spin_lock_irqsave(&plchan->vc.lock, flags);
+ if (!plchan->phychan && !plchan->at) {
+ spin_unlock_irqrestore(&plchan->vc.lock, flags);
+ return 0;
}
+ plchan->state = PL08X_CHAN_IDLE;
+
+ if (plchan->phychan) {
+ /*
+ * Mark physical channel as free and free any slave
+ * signal
+ */
+ pl08x_phy_free(plchan);
+ }
+ /* Dequeue jobs and free LLIs */
+ if (plchan->at) {
+ pl08x_desc_free(&plchan->at->vd);
+ plchan->at = NULL;
+ }
+ /* Dequeue jobs not yet fired as well */
+ pl08x_free_txd_list(pl08x, plchan);
+
+ spin_unlock_irqrestore(&plchan->vc.lock, flags);
+
+ return 0;
+}
+
+static int pl08x_pause(struct dma_chan *chan)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ unsigned long flags;
+
/*
* Anything succeeds on channels with no physical allocation and
* no queued transfers.
@@ -1717,42 +1742,35 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
return 0;
}
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- plchan->state = PL08X_CHAN_IDLE;
+ pl08x_pause_phy_chan(plchan->phychan);
+ plchan->state = PL08X_CHAN_PAUSED;
- if (plchan->phychan) {
- /*
- * Mark physical channel as free and free any slave
- * signal
- */
- pl08x_phy_free(plchan);
- }
- /* Dequeue jobs and free LLIs */
- if (plchan->at) {
- pl08x_desc_free(&plchan->at->vd);
- plchan->at = NULL;
- }
- /* Dequeue jobs not yet fired as well */
- pl08x_free_txd_list(pl08x, plchan);
- break;
- case DMA_PAUSE:
- pl08x_pause_phy_chan(plchan->phychan);
- plchan->state = PL08X_CHAN_PAUSED;
- break;
- case DMA_RESUME:
- pl08x_resume_phy_chan(plchan->phychan);
- plchan->state = PL08X_CHAN_RUNNING;
- break;
- default:
- /* Unknown command */
- ret = -ENXIO;
- break;
+ spin_unlock_irqrestore(&plchan->vc.lock, flags);
+
+ return 0;
+}
+
+static int pl08x_resume(struct dma_chan *chan)
+{
+ struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+ unsigned long flags;
+
+ /*
+ * Anything succeeds on channels with no physical allocation and
+ * no queued transfers.
+ */
+ spin_lock_irqsave(&plchan->vc.lock, flags);
+ if (!plchan->phychan && !plchan->at) {
+ spin_unlock_irqrestore(&plchan->vc.lock, flags);
+ return 0;
}
+ pl08x_resume_phy_chan(plchan->phychan);
+ plchan->state = PL08X_CHAN_RUNNING;
+
spin_unlock_irqrestore(&plchan->vc.lock, flags);
- return ret;
+ return 0;
}
bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
@@ -2048,7 +2066,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->memcpy.device_prep_dma_interrupt = pl08x_prep_dma_interrupt;
pl08x->memcpy.device_tx_status = pl08x_dma_tx_status;
pl08x->memcpy.device_issue_pending = pl08x_issue_pending;
- pl08x->memcpy.device_control = pl08x_control;
+ pl08x->memcpy.device_config = pl08x_config;
+ pl08x->memcpy.device_pause = pl08x_pause;
+ pl08x->memcpy.device_resume = pl08x_resume;
+ pl08x->memcpy.device_terminate_all = pl08x_terminate_all;
/* Initialize slave engine */
dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask);
@@ -2061,7 +2082,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->slave.device_issue_pending = pl08x_issue_pending;
pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg;
pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic;
- pl08x->slave.device_control = pl08x_control;
+ pl08x->slave.device_config = pl08x_config;
+ pl08x->slave.device_pause = pl08x_pause;
+ pl08x->slave.device_resume = pl08x_resume;
+ pl08x->slave.device_terminate_all = pl08x_terminate_all;
/* Get the platform data */
pl08x->pd = dev_get_platdata(&adev->dev);
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index ca9dd2613283..1e1a4c567542 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -42,6 +42,11 @@
#define ATC_DEFAULT_CFG (ATC_FIFOCFG_HALFFIFO)
#define ATC_DEFAULT_CTRLB (ATC_SIF(AT_DMA_MEM_IF) \
|ATC_DIF(AT_DMA_MEM_IF))
+#define ATC_DMA_BUSWIDTHS\
+ (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\
+ BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |\
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |\
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
/*
* Initial number of descriptors to allocate for each channel. This could
@@ -972,11 +977,13 @@ err_out:
return NULL;
}
-static int set_runtime_config(struct dma_chan *chan,
- struct dma_slave_config *sconfig)
+static int atc_config(struct dma_chan *chan,
+ struct dma_slave_config *sconfig)
{
struct at_dma_chan *atchan = to_at_dma_chan(chan);
+ dev_vdbg(chan2dev(chan), "%s\n", __func__);
+
/* Check if it is chan is configured for slave transfers */
if (!chan->private)
return -EINVAL;
@@ -989,9 +996,28 @@ static int set_runtime_config(struct dma_chan *chan,
return 0;
}
+static int atc_pause(struct dma_chan *chan)
+{
+ struct at_dma_chan *atchan = to_at_dma_chan(chan);
+ struct at_dma *atdma = to_at_dma(chan->device);
+ int chan_id = atchan->chan_common.chan_id;
+ unsigned long flags;
-static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+ LIST_HEAD(list);
+
+ dev_vdbg(chan2dev(chan), "%s\n", __func__);
+
+ spin_lock_irqsave(&atchan->lock, flags);
+
+ dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id));
+ set_bit(ATC_IS_PAUSED, &atchan->status);
+
+ spin_unlock_irqrestore(&atchan->lock, flags);
+
+ return 0;
+}
+
+static int atc_resume(struct dma_chan *chan)
{
struct at_dma_chan *atchan = to_at_dma_chan(chan);
struct at_dma *atdma = to_at_dma(chan->device);
@@ -1000,60 +1026,61 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
LIST_HEAD(list);
- dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd);
+ dev_vdbg(chan2dev(chan), "%s\n", __func__);
- if (cmd == DMA_PAUSE) {
- spin_lock_irqsave(&atchan->lock, flags);
+ if (!atc_chan_is_paused(atchan))
+ return 0;
- dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id));
- set_bit(ATC_IS_PAUSED, &atchan->status);
+ spin_lock_irqsave(&atchan->lock, flags);
- spin_unlock_irqrestore(&atchan->lock, flags);
- } else if (cmd == DMA_RESUME) {
- if (!atc_chan_is_paused(atchan))
- return 0;
+ dma_writel(atdma, CHDR, AT_DMA_RES(chan_id));
+ clear_bit(ATC_IS_PAUSED, &atchan->status);
- spin_lock_irqsave(&atchan->lock, flags);
+ spin_unlock_irqrestore(&atchan->lock, flags);
- dma_writel(atdma, CHDR, AT_DMA_RES(chan_id));
- clear_bit(ATC_IS_PAUSED, &atchan->status);
+ return 0;
+}
- spin_unlock_irqrestore(&atchan->lock, flags);
- } else if (cmd == DMA_TERMINATE_ALL) {
- struct at_desc *desc, *_desc;
- /*
- * This is only called when something went wrong elsewhere, so
- * we don't really care about the data. Just disable the
- * channel. We still have to poll the channel enable bit due
- * to AHB/HSB limitations.
- */
- spin_lock_irqsave(&atchan->lock, flags);
+static int atc_terminate_all(struct dma_chan *chan)
+{
+ struct at_dma_chan *atchan = to_at_dma_chan(chan);
+ struct at_dma *atdma = to_at_dma(chan->device);
+ int chan_id = atchan->chan_common.chan_id;
+ struct at_desc *desc, *_desc;
+ unsigned long flags;
- /* disabling channel: must also remove suspend state */
- dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask);
+ LIST_HEAD(list);
- /* confirm that this channel is disabled */
- while (dma_readl(atdma, CHSR) & atchan->mask)
- cpu_relax();
+ dev_vdbg(chan2dev(chan), "%s\n", __func__);
- /* active_list entries will end up before queued entries */
- list_splice_init(&atchan->queue, &list);
- list_splice_init(&atchan->active_list, &list);
+ /*
+ * This is only called when something went wrong elsewhere, so
+ * we don't really care about the data. Just disable the
+ * channel. We still have to poll the channel enable bit due
+ * to AHB/HSB limitations.
+ */
+ spin_lock_irqsave(&atchan->lock, flags);
- /* Flush all pending and queued descriptors */
- list_for_each_entry_safe(desc, _desc, &list, desc_node)
- atc_chain_complete(atchan, desc);
+ /* disabling channel: must also remove suspend state */
+ dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask);
- clear_bit(ATC_IS_PAUSED, &atchan->status);
- /* if channel dedicated to cyclic operations, free it */
- clear_bit(ATC_IS_CYCLIC, &atchan->status);
+ /* confirm that this channel is disabled */
+ while (dma_readl(atdma, CHSR) & atchan->mask)
+ cpu_relax();
- spin_unlock_irqrestore(&atchan->lock, flags);
- } else if (cmd == DMA_SLAVE_CONFIG) {
- return set_runtime_config(chan, (struct dma_slave_config *)arg);
- } else {
- return -ENXIO;
- }
+ /* active_list entries will end up before queued entries */
+ list_splice_init(&atchan->queue, &list);
+ list_splice_init(&atchan->active_list, &list);
+
+ /* Flush all pending and queued descriptors */
+ list_for_each_entry_safe(desc, _desc, &list, desc_node)
+ atc_chain_complete(atchan, desc);
+
+ clear_bit(ATC_IS_PAUSED, &atchan->status);
+ /* if channel dedicated to cyclic operations, free it */
+ clear_bit(ATC_IS_CYCLIC, &atchan->status);
+
+ spin_unlock_irqrestore(&atchan->lock, flags);
return 0;
}
@@ -1505,7 +1532,14 @@ static int __init at_dma_probe(struct platform_device *pdev)
/* controller can do slave DMA: can trigger cyclic transfers */
dma_cap_set(DMA_CYCLIC, atdma->dma_common.cap_mask);
atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic;
- atdma->dma_common.device_control = atc_control;
+ atdma->dma_common.device_config = atc_config;
+ atdma->dma_common.device_pause = atc_pause;
+ atdma->dma_common.device_resume = atc_resume;
+ atdma->dma_common.device_terminate_all = atc_terminate_all;
+ atdma->dma_common.src_addr_widths = ATC_DMA_BUSWIDTHS;
+ atdma->dma_common.dst_addr_widths = ATC_DMA_BUSWIDTHS;
+ atdma->dma_common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ atdma->dma_common.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
}
dma_writel(atdma, EN, AT_DMA_ENABLE);
@@ -1622,7 +1656,7 @@ static void atc_suspend_cyclic(struct at_dma_chan *atchan)
if (!atc_chan_is_paused(atchan)) {
dev_warn(chan2dev(chan),
"cyclic channel not paused, should be done by channel user\n");
- atc_control(chan, DMA_PAUSE, 0);
+ atc_pause(chan);
}
/* now preserve additional data for cyclic operations */
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index 2787aba60c6b..d6bba6c636c2 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -232,7 +232,8 @@ enum atc_status {
* @save_dscr: for cyclic operations, preserve next descriptor address in
* the cyclic list on suspend/resume cycle
* @remain_desc: to save remain desc length
- * @dma_sconfig: configuration for slave transfers, passed via DMA_SLAVE_CONFIG
+ * @dma_sconfig: configuration for slave transfers, passed via
+ * .device_config
* @lock: serializes enqueue/dequeue operations to descriptors lists
* @active_list: list of descriptors dmaengine is being running on
* @queue: list of descriptors ready to be submitted to engine
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index b60d77a22df6..09e2825a547a 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -25,6 +25,7 @@
#include <linux/dmapool.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of_dma.h>
@@ -174,6 +175,13 @@
#define AT_XDMAC_MAX_CHAN 0x20
+#define AT_XDMAC_DMA_BUSWIDTHS\
+ (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\
+ BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |\
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |\
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |\
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
+
enum atc_status {
AT_XDMAC_CHAN_IS_CYCLIC = 0,
AT_XDMAC_CHAN_IS_PAUSED,
@@ -184,15 +192,15 @@ struct at_xdmac_chan {
struct dma_chan chan;
void __iomem *ch_regs;
u32 mask; /* Channel Mask */
- u32 cfg[3]; /* Channel Configuration Register */
- #define AT_XDMAC_CUR_CFG 0 /* Current channel conf */
- #define AT_XDMAC_DEV_TO_MEM_CFG 1 /* Predifined dev to mem channel conf */
- #define AT_XDMAC_MEM_TO_DEV_CFG 2 /* Predifined mem to dev channel conf */
+ u32 cfg[2]; /* Channel Configuration Register */
+ #define AT_XDMAC_DEV_TO_MEM_CFG 0 /* Predifined dev to mem channel conf */
+ #define AT_XDMAC_MEM_TO_DEV_CFG 1 /* Predifined mem to dev channel conf */
u8 perid; /* Peripheral ID */
u8 perif; /* Peripheral Interface */
u8 memif; /* Memory Interface */
u32 per_src_addr;
u32 per_dst_addr;
+ u32 save_cc;
u32 save_cim;
u32 save_cnda;
u32 save_cndc;
@@ -344,20 +352,13 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan,
at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, reg);
/*
- * When doing memory to memory transfer we need to use the next
+ * When doing non cyclic transfer we need to use the next
* descriptor view 2 since some fields of the configuration register
* depend on transfer size and src/dest addresses.
*/
- if (is_slave_direction(first->direction)) {
+ if (at_xdmac_chan_is_cyclic(atchan)) {
reg = AT_XDMAC_CNDC_NDVIEW_NDV1;
- if (first->direction == DMA_MEM_TO_DEV)
- atchan->cfg[AT_XDMAC_CUR_CFG] =
- atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
- else
- atchan->cfg[AT_XDMAC_CUR_CFG] =
- atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG];
- at_xdmac_chan_write(atchan, AT_XDMAC_CC,
- atchan->cfg[AT_XDMAC_CUR_CFG]);
+ at_xdmac_chan_write(atchan, AT_XDMAC_CC, first->lld.mbr_cfg);
} else {
/*
* No need to write AT_XDMAC_CC reg, it will be done when the
@@ -561,7 +562,6 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct at_xdmac_desc *first = NULL, *prev = NULL;
struct scatterlist *sg;
int i;
- u32 cfg;
unsigned int xfer_size = 0;
if (!sgl)
@@ -583,7 +583,7 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
/* Prepare descriptors. */
for_each_sg(sgl, sg, sg_len, i) {
struct at_xdmac_desc *desc = NULL;
- u32 len, mem;
+ u32 len, mem, dwidth, fixed_dwidth;
len = sg_dma_len(sg);
mem = sg_dma_address(sg);
@@ -608,17 +608,21 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if (direction == DMA_DEV_TO_MEM) {
desc->lld.mbr_sa = atchan->per_src_addr;
desc->lld.mbr_da = mem;
- cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG];
+ desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_DEV_TO_MEM_CFG];
} else {
desc->lld.mbr_sa = mem;
desc->lld.mbr_da = atchan->per_dst_addr;
- cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
+ desc->lld.mbr_cfg = atchan->cfg[AT_XDMAC_MEM_TO_DEV_CFG];
}
- desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV1 /* next descriptor view */
- | AT_XDMAC_MBR_UBC_NDEN /* next descriptor dst parameter update */
- | AT_XDMAC_MBR_UBC_NSEN /* next descriptor src parameter update */
- | (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE) /* descriptor fetch */
- | len / (1 << at_xdmac_get_dwidth(cfg)); /* microblock length */
+ dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg);
+ fixed_dwidth = IS_ALIGNED(len, 1 << dwidth)
+ ? at_xdmac_get_dwidth(desc->lld.mbr_cfg)
+ : AT_XDMAC_CC_DWIDTH_BYTE;
+ desc->lld.mbr_ubc = AT_XDMAC_MBR_UBC_NDV2 /* next descriptor view */
+ | AT_XDMAC_MBR_UBC_NDEN /* next descriptor dst parameter update */
+ | AT_XDMAC_MBR_UBC_NSEN /* next descriptor src parameter update */
+ | (i == sg_len - 1 ? 0 : AT_XDMAC_MBR_UBC_NDE) /* descriptor fetch */
+ | (len >> fixed_dwidth); /* microblock length */
dev_dbg(chan2dev(chan),
"%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n",
__func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc);
@@ -882,7 +886,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
enum dma_status ret;
int residue;
u32 cur_nda, mask, value;
- u8 dwidth = at_xdmac_get_dwidth(atchan->cfg[AT_XDMAC_CUR_CFG]);
+ u8 dwidth = 0;
ret = dma_cookie_status(chan, cookie, txstate);
if (ret == DMA_COMPLETE)
@@ -912,7 +916,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
*/
mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
- if ((atchan->cfg[AT_XDMAC_CUR_CFG] & mask) == value) {
+ if ((desc->lld.mbr_cfg & mask) == value) {
at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
cpu_relax();
@@ -926,6 +930,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
*/
descs_list = &desc->descs_list;
list_for_each_entry_safe(desc, _desc, descs_list, desc_node) {
+ dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg);
residue -= (desc->lld.mbr_ubc & 0xffffff) << dwidth;
if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda)
break;
@@ -1107,58 +1112,80 @@ static void at_xdmac_issue_pending(struct dma_chan *chan)
return;
}
-static int at_xdmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int at_xdmac_device_config(struct dma_chan *chan,
+ struct dma_slave_config *config)
+{
+ struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan);
+ int ret;
+
+ dev_dbg(chan2dev(chan), "%s\n", __func__);
+
+ spin_lock_bh(&atchan->lock);
+ ret = at_xdmac_set_slave_config(chan, config);
+ spin_unlock_bh(&atchan->lock);
+
+ return ret;
+}
+
+static int at_xdmac_device_pause(struct dma_chan *chan)
{
- struct at_xdmac_desc *desc, *_desc;
struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan);
struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device);
- int ret = 0;
- dev_dbg(chan2dev(chan), "%s: cmd=%d\n", __func__, cmd);
+ dev_dbg(chan2dev(chan), "%s\n", __func__);
+
+ if (test_and_set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status))
+ return 0;
spin_lock_bh(&atchan->lock);
+ at_xdmac_write(atxdmac, AT_XDMAC_GRWS, atchan->mask);
+ while (at_xdmac_chan_read(atchan, AT_XDMAC_CC)
+ & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP))
+ cpu_relax();
+ spin_unlock_bh(&atchan->lock);
- switch (cmd) {
- case DMA_PAUSE:
- at_xdmac_write(atxdmac, AT_XDMAC_GRWS, atchan->mask);
- set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
- break;
+ return 0;
+}
- case DMA_RESUME:
- if (!at_xdmac_chan_is_paused(atchan))
- break;
+static int at_xdmac_device_resume(struct dma_chan *chan)
+{
+ struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan);
+ struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device);
- at_xdmac_write(atxdmac, AT_XDMAC_GRWR, atchan->mask);
- clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
- break;
+ dev_dbg(chan2dev(chan), "%s\n", __func__);
- case DMA_TERMINATE_ALL:
- at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask);
- while (at_xdmac_read(atxdmac, AT_XDMAC_GS) & atchan->mask)
- cpu_relax();
+ spin_lock_bh(&atchan->lock);
+ if (!at_xdmac_chan_is_paused(atchan))
+ return 0;
+
+ at_xdmac_write(atxdmac, AT_XDMAC_GRWR, atchan->mask);
+ clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
+ spin_unlock_bh(&atchan->lock);
- /* Cancel all pending transfers. */
- list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node)
- at_xdmac_remove_xfer(atchan, desc);
+ return 0;
+}
+
+static int at_xdmac_device_terminate_all(struct dma_chan *chan)
+{
+ struct at_xdmac_desc *desc, *_desc;
+ struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan);
+ struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device);
- clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status);
- break;
+ dev_dbg(chan2dev(chan), "%s\n", __func__);
- case DMA_SLAVE_CONFIG:
- ret = at_xdmac_set_slave_config(chan,
- (struct dma_slave_config *)arg);
- break;
+ spin_lock_bh(&atchan->lock);
+ at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask);
+ while (at_xdmac_read(atxdmac, AT_XDMAC_GS) & atchan->mask)
+ cpu_relax();
- default:
- dev_err(chan2dev(chan),
- "unmanaged or unknown dma control cmd: %d\n", cmd);
- ret = -ENXIO;
- }
+ /* Cancel all pending transfers. */
+ list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node)
+ at_xdmac_remove_xfer(atchan, desc);
+ clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status);
spin_unlock_bh(&atchan->lock);
- return ret;
+ return 0;
}
static int at_xdmac_alloc_chan_resources(struct dma_chan *chan)
@@ -1217,27 +1244,6 @@ static void at_xdmac_free_chan_resources(struct dma_chan *chan)
return;
}
-#define AT_XDMAC_DMA_BUSWIDTHS\
- (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\
- BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |\
- BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |\
- BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |\
- BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
-
-static int at_xdmac_device_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
-
- caps->src_addr_widths = AT_XDMAC_DMA_BUSWIDTHS;
- caps->dstn_addr_widths = AT_XDMAC_DMA_BUSWIDTHS;
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = true;
- caps->cmd_terminate = true;
- caps->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
-
- return 0;
-}
-
#ifdef CONFIG_PM
static int atmel_xdmac_prepare(struct device *dev)
{
@@ -1268,9 +1274,10 @@ static int atmel_xdmac_suspend(struct device *dev)
list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan);
+ atchan->save_cc = at_xdmac_chan_read(atchan, AT_XDMAC_CC);
if (at_xdmac_chan_is_cyclic(atchan)) {
if (!at_xdmac_chan_is_paused(atchan))
- at_xdmac_control(chan, DMA_PAUSE, 0);
+ at_xdmac_device_pause(chan);
atchan->save_cim = at_xdmac_chan_read(atchan, AT_XDMAC_CIM);
atchan->save_cnda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA);
atchan->save_cndc = at_xdmac_chan_read(atchan, AT_XDMAC_CNDC);
@@ -1290,7 +1297,6 @@ static int atmel_xdmac_resume(struct device *dev)
struct at_xdmac_chan *atchan;
struct dma_chan *chan, *_chan;
int i;
- u32 cfg;
clk_prepare_enable(atxdmac->clk);
@@ -1305,8 +1311,7 @@ static int atmel_xdmac_resume(struct device *dev)
at_xdmac_write(atxdmac, AT_XDMAC_GE, atxdmac->save_gs);
list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
atchan = to_at_xdmac_chan(chan);
- cfg = atchan->cfg[AT_XDMAC_CUR_CFG];
- at_xdmac_chan_write(atchan, AT_XDMAC_CC, cfg);
+ at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc);
if (at_xdmac_chan_is_cyclic(atchan)) {
at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda);
at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
@@ -1407,8 +1412,14 @@ static int at_xdmac_probe(struct platform_device *pdev)
atxdmac->dma.device_prep_dma_cyclic = at_xdmac_prep_dma_cyclic;
atxdmac->dma.device_prep_dma_memcpy = at_xdmac_prep_dma_memcpy;
atxdmac->dma.device_prep_slave_sg = at_xdmac_prep_slave_sg;
- atxdmac->dma.device_control = at_xdmac_control;
- atxdmac->dma.device_slave_caps = at_xdmac_device_slave_caps;
+ atxdmac->dma.device_config = at_xdmac_device_config;
+ atxdmac->dma.device_pause = at_xdmac_device_pause;
+ atxdmac->dma.device_resume = at_xdmac_device_resume;
+ atxdmac->dma.device_terminate_all = at_xdmac_device_terminate_all;
+ atxdmac->dma.src_addr_widths = AT_XDMAC_DMA_BUSWIDTHS;
+ atxdmac->dma.dst_addr_widths = AT_XDMAC_DMA_BUSWIDTHS;
+ atxdmac->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ atxdmac->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
/* Disable all chans and interrupts. */
at_xdmac_off(atxdmac);
@@ -1507,7 +1518,6 @@ static struct platform_driver at_xdmac_driver = {
.remove = at_xdmac_remove,
.driver = {
.name = "at_xdmac",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(atmel_xdmac_dt_ids),
.pm = &atmel_xdmac_dev_pm_ops,
}
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 918b7b3f766f..0723096fb50a 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -436,9 +436,11 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
return vchan_tx_prep(&c->vc, &d->vd, flags);
}
-static int bcm2835_dma_slave_config(struct bcm2835_chan *c,
- struct dma_slave_config *cfg)
+static int bcm2835_dma_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
{
+ struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+
if ((cfg->direction == DMA_DEV_TO_MEM &&
cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
(cfg->direction == DMA_MEM_TO_DEV &&
@@ -452,8 +454,9 @@ static int bcm2835_dma_slave_config(struct bcm2835_chan *c,
return 0;
}
-static int bcm2835_dma_terminate_all(struct bcm2835_chan *c)
+static int bcm2835_dma_terminate_all(struct dma_chan *chan)
{
+ struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
struct bcm2835_dmadev *d = to_bcm2835_dma_dev(c->vc.chan.device);
unsigned long flags;
int timeout = 10000;
@@ -495,24 +498,6 @@ static int bcm2835_dma_terminate_all(struct bcm2835_chan *c)
return 0;
}
-static int bcm2835_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
-
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- return bcm2835_dma_slave_config(c,
- (struct dma_slave_config *)arg);
-
- case DMA_TERMINATE_ALL:
- return bcm2835_dma_terminate_all(c);
-
- default:
- return -ENXIO;
- }
-}
-
static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq)
{
struct bcm2835_chan *c;
@@ -565,18 +550,6 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
return chan;
}
-static int bcm2835_dma_device_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
- caps->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
- caps->dstn_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = false;
- caps->cmd_terminate = true;
-
- return 0;
-}
-
static int bcm2835_dma_probe(struct platform_device *pdev)
{
struct bcm2835_dmadev *od;
@@ -615,9 +588,12 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
od->ddev.device_free_chan_resources = bcm2835_dma_free_chan_resources;
od->ddev.device_tx_status = bcm2835_dma_tx_status;
od->ddev.device_issue_pending = bcm2835_dma_issue_pending;
- od->ddev.device_slave_caps = bcm2835_dma_device_slave_caps;
od->ddev.device_prep_dma_cyclic = bcm2835_dma_prep_dma_cyclic;
- od->ddev.device_control = bcm2835_dma_control;
+ od->ddev.device_config = bcm2835_dma_slave_config;
+ od->ddev.device_terminate_all = bcm2835_dma_terminate_all;
+ od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
od->ddev.dev = &pdev->dev;
INIT_LIST_HEAD(&od->ddev.channels);
spin_lock_init(&od->lock);
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index e88588d8ecd3..fd22dd36985f 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -1690,7 +1690,7 @@ static u32 coh901318_get_bytes_left(struct dma_chan *chan)
* Pauses a transfer without losing data. Enables power save.
* Use this function in conjunction with coh901318_resume.
*/
-static void coh901318_pause(struct dma_chan *chan)
+static int coh901318_pause(struct dma_chan *chan)
{
u32 val;
unsigned long flags;
@@ -1730,12 +1730,13 @@ static void coh901318_pause(struct dma_chan *chan)
enable_powersave(cohc);
spin_unlock_irqrestore(&cohc->lock, flags);
+ return 0;
}
/* Resumes a transfer that has been stopped via 300_dma_stop(..).
Power save is handled.
*/
-static void coh901318_resume(struct dma_chan *chan)
+static int coh901318_resume(struct dma_chan *chan)
{
u32 val;
unsigned long flags;
@@ -1760,6 +1761,7 @@ static void coh901318_resume(struct dma_chan *chan)
}
spin_unlock_irqrestore(&cohc->lock, flags);
+ return 0;
}
bool coh901318_filter_id(struct dma_chan *chan, void *chan_id)
@@ -2114,6 +2116,57 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int coh901318_terminate_all(struct dma_chan *chan)
+{
+ unsigned long flags;
+ struct coh901318_chan *cohc = to_coh901318_chan(chan);
+ struct coh901318_desc *cohd;
+ void __iomem *virtbase = cohc->base->virtbase;
+
+ /* The remainder of this function terminates the transfer */
+ coh901318_pause(chan);
+ spin_lock_irqsave(&cohc->lock, flags);
+
+ /* Clear any pending BE or TC interrupt */
+ if (cohc->id < 32) {
+ writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1);
+ writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1);
+ } else {
+ writel(1 << (cohc->id - 32), virtbase +
+ COH901318_BE_INT_CLEAR2);
+ writel(1 << (cohc->id - 32), virtbase +
+ COH901318_TC_INT_CLEAR2);
+ }
+
+ enable_powersave(cohc);
+
+ while ((cohd = coh901318_first_active_get(cohc))) {
+ /* release the lli allocation*/
+ coh901318_lli_free(&cohc->base->pool, &cohd->lli);
+
+ /* return desc to free-list */
+ coh901318_desc_remove(cohd);
+ coh901318_desc_free(cohc, cohd);
+ }
+
+ while ((cohd = coh901318_first_queued(cohc))) {
+ /* release the lli allocation*/
+ coh901318_lli_free(&cohc->base->pool, &cohd->lli);
+
+ /* return desc to free-list */
+ coh901318_desc_remove(cohd);
+ coh901318_desc_free(cohc, cohd);
+ }
+
+
+ cohc->nbr_active_done = 0;
+ cohc->busy = 0;
+
+ spin_unlock_irqrestore(&cohc->lock, flags);
+
+ return 0;
+}
+
static int coh901318_alloc_chan_resources(struct dma_chan *chan)
{
struct coh901318_chan *cohc = to_coh901318_chan(chan);
@@ -2156,7 +2209,7 @@ coh901318_free_chan_resources(struct dma_chan *chan)
spin_unlock_irqrestore(&cohc->lock, flags);
- dmaengine_terminate_all(chan);
+ coh901318_terminate_all(chan);
}
@@ -2461,8 +2514,8 @@ static const struct burst_table burst_sizes[] = {
},
};
-static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
- struct dma_slave_config *config)
+static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
+ struct dma_slave_config *config)
{
struct coh901318_chan *cohc = to_coh901318_chan(chan);
dma_addr_t addr;
@@ -2482,7 +2535,7 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
maxburst = config->dst_maxburst;
} else {
dev_err(COHC_2_DEV(cohc), "illegal channel mode\n");
- return;
+ return -EINVAL;
}
dev_dbg(COHC_2_DEV(cohc), "configure channel for %d byte transfers\n",
@@ -2528,7 +2581,7 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
default:
dev_err(COHC_2_DEV(cohc),
"bad runtimeconfig: alien address width\n");
- return;
+ return -EINVAL;
}
ctrl |= burst_sizes[i].reg;
@@ -2538,84 +2591,12 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan,
cohc->addr = addr;
cohc->ctrl = ctrl;
-}
-
-static int
-coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- unsigned long flags;
- struct coh901318_chan *cohc = to_coh901318_chan(chan);
- struct coh901318_desc *cohd;
- void __iomem *virtbase = cohc->base->virtbase;
-
- if (cmd == DMA_SLAVE_CONFIG) {
- struct dma_slave_config *config =
- (struct dma_slave_config *) arg;
-
- coh901318_dma_set_runtimeconfig(chan, config);
- return 0;
- }
-
- if (cmd == DMA_PAUSE) {
- coh901318_pause(chan);
- return 0;
- }
-
- if (cmd == DMA_RESUME) {
- coh901318_resume(chan);
- return 0;
- }
-
- if (cmd != DMA_TERMINATE_ALL)
- return -ENXIO;
-
- /* The remainder of this function terminates the transfer */
- coh901318_pause(chan);
- spin_lock_irqsave(&cohc->lock, flags);
-
- /* Clear any pending BE or TC interrupt */
- if (cohc->id < 32) {
- writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1);
- writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1);
- } else {
- writel(1 << (cohc->id - 32), virtbase +
- COH901318_BE_INT_CLEAR2);
- writel(1 << (cohc->id - 32), virtbase +
- COH901318_TC_INT_CLEAR2);
- }
-
- enable_powersave(cohc);
-
- while ((cohd = coh901318_first_active_get(cohc))) {
- /* release the lli allocation*/
- coh901318_lli_free(&cohc->base->pool, &cohd->lli);
-
- /* return desc to free-list */
- coh901318_desc_remove(cohd);
- coh901318_desc_free(cohc, cohd);
- }
-
- while ((cohd = coh901318_first_queued(cohc))) {
- /* release the lli allocation*/
- coh901318_lli_free(&cohc->base->pool, &cohd->lli);
-
- /* return desc to free-list */
- coh901318_desc_remove(cohd);
- coh901318_desc_free(cohc, cohd);
- }
-
-
- cohc->nbr_active_done = 0;
- cohc->busy = 0;
-
- spin_unlock_irqrestore(&cohc->lock, flags);
return 0;
}
-void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
- struct coh901318_base *base)
+static void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
+ struct coh901318_base *base)
{
int chans_i;
int i = 0;
@@ -2717,7 +2698,10 @@ static int __init coh901318_probe(struct platform_device *pdev)
base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg;
base->dma_slave.device_tx_status = coh901318_tx_status;
base->dma_slave.device_issue_pending = coh901318_issue_pending;
- base->dma_slave.device_control = coh901318_control;
+ base->dma_slave.device_config = coh901318_dma_set_runtimeconfig;
+ base->dma_slave.device_pause = coh901318_pause;
+ base->dma_slave.device_resume = coh901318_resume;
+ base->dma_slave.device_terminate_all = coh901318_terminate_all;
base->dma_slave.dev = &pdev->dev;
err = dma_async_device_register(&base->dma_slave);
@@ -2737,7 +2721,10 @@ static int __init coh901318_probe(struct platform_device *pdev)
base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy;
base->dma_memcpy.device_tx_status = coh901318_tx_status;
base->dma_memcpy.device_issue_pending = coh901318_issue_pending;
- base->dma_memcpy.device_control = coh901318_control;
+ base->dma_memcpy.device_config = coh901318_dma_set_runtimeconfig;
+ base->dma_memcpy.device_pause = coh901318_pause;
+ base->dma_memcpy.device_resume = coh901318_resume;
+ base->dma_memcpy.device_terminate_all = coh901318_terminate_all;
base->dma_memcpy.dev = &pdev->dev;
/*
* This controller can only access address at even 32bit boundaries,
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
index b743adf56465..512cb8e2805e 100644
--- a/drivers/dma/cppi41.c
+++ b/drivers/dma/cppi41.c
@@ -525,12 +525,6 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg(
return &c->txd;
}
-static int cpp41_cfg_chan(struct cppi41_channel *c,
- struct dma_slave_config *cfg)
-{
- return 0;
-}
-
static void cppi41_compute_td_desc(struct cppi41_desc *d)
{
d->pd0 = DESC_TYPE_TEARD << DESC_TYPE;
@@ -647,28 +641,6 @@ static int cppi41_stop_chan(struct dma_chan *chan)
return 0;
}
-static int cppi41_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- struct cppi41_channel *c = to_cpp41_chan(chan);
- int ret;
-
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- ret = cpp41_cfg_chan(c, (struct dma_slave_config *) arg);
- break;
-
- case DMA_TERMINATE_ALL:
- ret = cppi41_stop_chan(chan);
- break;
-
- default:
- ret = -ENXIO;
- break;
- }
- return ret;
-}
-
static void cleanup_chans(struct cppi41_dd *cdd)
{
while (!list_empty(&cdd->ddev.channels)) {
@@ -953,7 +925,7 @@ static int cppi41_dma_probe(struct platform_device *pdev)
cdd->ddev.device_tx_status = cppi41_dma_tx_status;
cdd->ddev.device_issue_pending = cppi41_dma_issue_pending;
cdd->ddev.device_prep_slave_sg = cppi41_dma_prep_slave_sg;
- cdd->ddev.device_control = cppi41_dma_control;
+ cdd->ddev.device_terminate_all = cppi41_stop_chan;
cdd->ddev.dev = dev;
INIT_LIST_HEAD(&cdd->ddev.channels);
cpp41_dma_info.dma_cap = cdd->ddev.cap_mask;
diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c
index bdeafeefa5f6..4527a3ebeac4 100644
--- a/drivers/dma/dma-jz4740.c
+++ b/drivers/dma/dma-jz4740.c
@@ -210,7 +210,7 @@ static enum jz4740_dma_transfer_size jz4740_dma_maxburst(u32 maxburst)
}
static int jz4740_dma_slave_config(struct dma_chan *c,
- const struct dma_slave_config *config)
+ struct dma_slave_config *config)
{
struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
@@ -290,21 +290,6 @@ static int jz4740_dma_terminate_all(struct dma_chan *c)
return 0;
}
-static int jz4740_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- struct dma_slave_config *config = (struct dma_slave_config *)arg;
-
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- return jz4740_dma_slave_config(chan, config);
- case DMA_TERMINATE_ALL:
- return jz4740_dma_terminate_all(chan);
- default:
- return -ENOSYS;
- }
-}
-
static int jz4740_dma_start_transfer(struct jz4740_dmaengine_chan *chan)
{
struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
@@ -561,7 +546,8 @@ static int jz4740_dma_probe(struct platform_device *pdev)
dd->device_issue_pending = jz4740_dma_issue_pending;
dd->device_prep_slave_sg = jz4740_dma_prep_slave_sg;
dd->device_prep_dma_cyclic = jz4740_dma_prep_dma_cyclic;
- dd->device_control = jz4740_dma_control;
+ dd->device_config = jz4740_dma_slave_config;
+ dd->device_terminate_all = jz4740_dma_terminate_all;
dd->dev = &pdev->dev;
INIT_LIST_HEAD(&dd->channels);
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index e057935e3023..f15712f2fec6 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -222,31 +222,35 @@ static void balance_ref_count(struct dma_chan *chan)
*/
static int dma_chan_get(struct dma_chan *chan)
{
- int err = -ENODEV;
struct module *owner = dma_chan_to_owner(chan);
+ int ret;
+ /* The channel is already in use, update client count */
if (chan->client_count) {
__module_get(owner);
- err = 0;
- } else if (try_module_get(owner))
- err = 0;
+ goto out;
+ }
- if (err == 0)
- chan->client_count++;
+ if (!try_module_get(owner))
+ return -ENODEV;
/* allocate upon first client reference */
- if (chan->client_count == 1 && err == 0) {
- int desc_cnt = chan->device->device_alloc_chan_resources(chan);
-
- if (desc_cnt < 0) {
- err = desc_cnt;
- chan->client_count = 0;
- module_put(owner);
- } else if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
- balance_ref_count(chan);
+ if (chan->device->device_alloc_chan_resources) {
+ ret = chan->device->device_alloc_chan_resources(chan);
+ if (ret < 0)
+ goto err_out;
}
- return err;
+ if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
+ balance_ref_count(chan);
+
+out:
+ chan->client_count++;
+ return 0;
+
+err_out:
+ module_put(owner);
+ return ret;
}
/**
@@ -257,11 +261,15 @@ static int dma_chan_get(struct dma_chan *chan)
*/
static void dma_chan_put(struct dma_chan *chan)
{
+ /* This channel is not in use, bail out */
if (!chan->client_count)
- return; /* this channel failed alloc_chan_resources */
+ return;
+
chan->client_count--;
module_put(dma_chan_to_owner(chan));
- if (chan->client_count == 0)
+
+ /* This channel is not in use anymore, free it */
+ if (!chan->client_count && chan->device->device_free_chan_resources)
chan->device->device_free_chan_resources(chan);
}
@@ -471,6 +479,39 @@ static void dma_channel_rebalance(void)
}
}
+int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
+{
+ struct dma_device *device;
+
+ if (!chan || !caps)
+ return -EINVAL;
+
+ device = chan->device;
+
+ /* check if the channel supports slave transactions */
+ if (!test_bit(DMA_SLAVE, device->cap_mask.bits))
+ return -ENXIO;
+
+ /*
+ * Check whether it reports it uses the generic slave
+ * capabilities, if not, that means it doesn't support any
+ * kind of slave capabilities reporting.
+ */
+ if (!device->directions)
+ return -ENXIO;
+
+ caps->src_addr_widths = device->src_addr_widths;
+ caps->dst_addr_widths = device->dst_addr_widths;
+ caps->directions = device->directions;
+ caps->residue_granularity = device->residue_granularity;
+
+ caps->cmd_pause = !!device->device_pause;
+ caps->cmd_terminate = !!device->device_terminate_all;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dma_get_slave_caps);
+
static struct dma_chan *private_candidate(const dma_cap_mask_t *mask,
struct dma_device *dev,
dma_filter_fn fn, void *fn_param)
@@ -811,17 +852,16 @@ int dma_async_device_register(struct dma_device *device)
!device->device_prep_dma_sg);
BUG_ON(dma_has_cap(DMA_CYCLIC, device->cap_mask) &&
!device->device_prep_dma_cyclic);
- BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
- !device->device_control);
BUG_ON(dma_has_cap(DMA_INTERLEAVE, device->cap_mask) &&
!device->device_prep_interleaved_dma);
- BUG_ON(!device->device_alloc_chan_resources);
- BUG_ON(!device->device_free_chan_resources);
BUG_ON(!device->device_tx_status);
BUG_ON(!device->device_issue_pending);
BUG_ON(!device->dev);
+ WARN(dma_has_cap(DMA_SLAVE, device->cap_mask) && !device->directions,
+ "this driver doesn't support generic slave capabilities reporting\n");
+
/* note: this only matters in the
* CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=n case
*/
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index a8d7809e2f4c..220ee49633e4 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -349,14 +349,14 @@ static void dbg_result(const char *err, unsigned int n, unsigned int src_off,
unsigned long data)
{
pr_debug("%s: result #%u: '%s' with src_off=0x%x dst_off=0x%x len=0x%x (%lu)\n",
- current->comm, n, err, src_off, dst_off, len, data);
+ current->comm, n, err, src_off, dst_off, len, data);
}
-#define verbose_result(err, n, src_off, dst_off, len, data) ({ \
- if (verbose) \
- result(err, n, src_off, dst_off, len, data); \
- else \
- dbg_result(err, n, src_off, dst_off, len, data); \
+#define verbose_result(err, n, src_off, dst_off, len, data) ({ \
+ if (verbose) \
+ result(err, n, src_off, dst_off, len, data); \
+ else \
+ dbg_result(err, n, src_off, dst_off, len, data);\
})
static unsigned long long dmatest_persec(s64 runtime, unsigned int val)
@@ -405,7 +405,6 @@ static int dmatest_func(void *data)
struct dmatest_params *params;
struct dma_chan *chan;
struct dma_device *dev;
- unsigned int src_off, dst_off, len;
unsigned int error_count;
unsigned int failed_tests = 0;
unsigned int total_tests = 0;
@@ -484,6 +483,7 @@ static int dmatest_func(void *data)
struct dmaengine_unmap_data *um;
dma_addr_t srcs[src_cnt];
dma_addr_t *dsts;
+ unsigned int src_off, dst_off, len;
u8 align = 0;
total_tests++;
@@ -502,15 +502,21 @@ static int dmatest_func(void *data)
break;
}
- if (params->noverify) {
+ if (params->noverify)
len = params->buf_size;
+ else
+ len = dmatest_random() % params->buf_size + 1;
+
+ len = (len >> align) << align;
+ if (!len)
+ len = 1 << align;
+
+ total_len += len;
+
+ if (params->noverify) {
src_off = 0;
dst_off = 0;
} else {
- len = dmatest_random() % params->buf_size + 1;
- len = (len >> align) << align;
- if (!len)
- len = 1 << align;
src_off = dmatest_random() % (params->buf_size - len + 1);
dst_off = dmatest_random() % (params->buf_size - len + 1);
@@ -523,11 +529,6 @@ static int dmatest_func(void *data)
params->buf_size);
}
- len = (len >> align) << align;
- if (!len)
- len = 1 << align;
- total_len += len;
-
um = dmaengine_get_unmap_data(dev->dev, src_cnt+dst_cnt,
GFP_KERNEL);
if (!um) {
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 5c062548957c..455b7a4f1e87 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -61,6 +61,13 @@
*/
#define NR_DESCS_PER_CHANNEL 64
+/* The set of bus widths supported by the DMA controller */
+#define DW_DMA_BUSWIDTHS \
+ BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \
+ BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)
+
/*----------------------------------------------------------------------*/
static struct device *chan2dev(struct dma_chan *chan)
@@ -955,8 +962,7 @@ static inline void convert_burst(u32 *maxburst)
*maxburst = 0;
}
-static int
-set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
+static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
@@ -973,16 +979,25 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
return 0;
}
-static inline void dwc_chan_pause(struct dw_dma_chan *dwc)
+static int dwc_pause(struct dma_chan *chan)
{
- u32 cfglo = channel_readl(dwc, CFG_LO);
- unsigned int count = 20; /* timeout iterations */
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ unsigned long flags;
+ unsigned int count = 20; /* timeout iterations */
+ u32 cfglo;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ cfglo = channel_readl(dwc, CFG_LO);
channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--)
udelay(2);
dwc->paused = true;
+
+ spin_unlock_irqrestore(&dwc->lock, flags);
+
+ return 0;
}
static inline void dwc_chan_resume(struct dw_dma_chan *dwc)
@@ -994,53 +1009,48 @@ static inline void dwc_chan_resume(struct dw_dma_chan *dwc)
dwc->paused = false;
}
-static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int dwc_resume(struct dma_chan *chan)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
- struct dw_dma *dw = to_dw_dma(chan->device);
- struct dw_desc *desc, *_desc;
unsigned long flags;
- LIST_HEAD(list);
- if (cmd == DMA_PAUSE) {
- spin_lock_irqsave(&dwc->lock, flags);
+ if (!dwc->paused)
+ return 0;
- dwc_chan_pause(dwc);
+ spin_lock_irqsave(&dwc->lock, flags);
- spin_unlock_irqrestore(&dwc->lock, flags);
- } else if (cmd == DMA_RESUME) {
- if (!dwc->paused)
- return 0;
+ dwc_chan_resume(dwc);
- spin_lock_irqsave(&dwc->lock, flags);
+ spin_unlock_irqrestore(&dwc->lock, flags);
- dwc_chan_resume(dwc);
+ return 0;
+}
- spin_unlock_irqrestore(&dwc->lock, flags);
- } else if (cmd == DMA_TERMINATE_ALL) {
- spin_lock_irqsave(&dwc->lock, flags);
+static int dwc_terminate_all(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(chan->device);
+ struct dw_desc *desc, *_desc;
+ unsigned long flags;
+ LIST_HEAD(list);
- clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+ spin_lock_irqsave(&dwc->lock, flags);
- dwc_chan_disable(dw, dwc);
+ clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+
+ dwc_chan_disable(dw, dwc);
- dwc_chan_resume(dwc);
+ dwc_chan_resume(dwc);
- /* active_list entries will end up before queued entries */
- list_splice_init(&dwc->queue, &list);
- list_splice_init(&dwc->active_list, &list);
+ /* active_list entries will end up before queued entries */
+ list_splice_init(&dwc->queue, &list);
+ list_splice_init(&dwc->active_list, &list);
- spin_unlock_irqrestore(&dwc->lock, flags);
+ spin_unlock_irqrestore(&dwc->lock, flags);
- /* Flush all pending and queued descriptors */
- list_for_each_entry_safe(desc, _desc, &list, desc_node)
- dwc_descriptor_complete(dwc, desc, false);
- } else if (cmd == DMA_SLAVE_CONFIG) {
- return set_runtime_config(chan, (struct dma_slave_config *)arg);
- } else {
- return -ENXIO;
- }
+ /* Flush all pending and queued descriptors */
+ list_for_each_entry_safe(desc, _desc, &list, desc_node)
+ dwc_descriptor_complete(dwc, desc, false);
return 0;
}
@@ -1551,7 +1561,8 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
}
} else {
dw->nr_masters = pdata->nr_masters;
- memcpy(dw->data_width, pdata->data_width, 4);
+ for (i = 0; i < dw->nr_masters; i++)
+ dw->data_width[i] = pdata->data_width[i];
}
/* Calculate all channel mask before DMA setup */
@@ -1656,13 +1667,23 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
dw->dma.device_free_chan_resources = dwc_free_chan_resources;
dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy;
-
dw->dma.device_prep_slave_sg = dwc_prep_slave_sg;
- dw->dma.device_control = dwc_control;
+
+ dw->dma.device_config = dwc_config;
+ dw->dma.device_pause = dwc_pause;
+ dw->dma.device_resume = dwc_resume;
+ dw->dma.device_terminate_all = dwc_terminate_all;
dw->dma.device_tx_status = dwc_tx_status;
dw->dma.device_issue_pending = dwc_issue_pending;
+ /* DMA capabilities */
+ dw->dma.src_addr_widths = DW_DMA_BUSWIDTHS;
+ dw->dma.dst_addr_widths = DW_DMA_BUSWIDTHS;
+ dw->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) |
+ BIT(DMA_MEM_TO_MEM);
+ dw->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+
err = dma_async_device_register(&dw->dma);
if (err)
goto err_dma_register;
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index 32ea1aca7a0e..6565a361e7e5 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -100,7 +100,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct dw_dma_platform_data *pdata;
- u32 tmp, arr[4];
+ u32 tmp, arr[DW_DMA_MAX_NR_MASTERS];
if (!np) {
dev_err(&pdev->dev, "Missing DT data\n");
@@ -127,7 +127,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
pdata->block_size = tmp;
if (!of_property_read_u32(np, "dma-masters", &tmp)) {
- if (tmp > 4)
+ if (tmp > DW_DMA_MAX_NR_MASTERS)
return NULL;
pdata->nr_masters = tmp;
diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h
index 848e232f7cc7..241ff2b1402b 100644
--- a/drivers/dma/dw/regs.h
+++ b/drivers/dma/dw/regs.h
@@ -252,7 +252,7 @@ struct dw_dma_chan {
u8 src_master;
u8 dst_master;
- /* configuration passed via DMA_SLAVE_CONFIG */
+ /* configuration passed via .device_config */
struct dma_slave_config dma_sconfig;
};
@@ -285,7 +285,7 @@ struct dw_dma {
/* hardware configuration */
unsigned char nr_masters;
- unsigned char data_width[4];
+ unsigned char data_width[DW_DMA_MAX_NR_MASTERS];
};
static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index b969206439b7..276157f22612 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -15,6 +15,7 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
+#include <linux/edma.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -244,8 +245,9 @@ static void edma_execute(struct edma_chan *echan)
}
}
-static int edma_terminate_all(struct edma_chan *echan)
+static int edma_terminate_all(struct dma_chan *chan)
{
+ struct edma_chan *echan = to_edma_chan(chan);
unsigned long flags;
LIST_HEAD(head);
@@ -273,9 +275,11 @@ static int edma_terminate_all(struct edma_chan *echan)
return 0;
}
-static int edma_slave_config(struct edma_chan *echan,
+static int edma_slave_config(struct dma_chan *chan,
struct dma_slave_config *cfg)
{
+ struct edma_chan *echan = to_edma_chan(chan);
+
if (cfg->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
return -EINVAL;
@@ -285,8 +289,10 @@ static int edma_slave_config(struct edma_chan *echan,
return 0;
}
-static int edma_dma_pause(struct edma_chan *echan)
+static int edma_dma_pause(struct dma_chan *chan)
{
+ struct edma_chan *echan = to_edma_chan(chan);
+
/* Pause/Resume only allowed with cyclic mode */
if (!echan->edesc || !echan->edesc->cyclic)
return -EINVAL;
@@ -295,8 +301,10 @@ static int edma_dma_pause(struct edma_chan *echan)
return 0;
}
-static int edma_dma_resume(struct edma_chan *echan)
+static int edma_dma_resume(struct dma_chan *chan)
{
+ struct edma_chan *echan = to_edma_chan(chan);
+
/* Pause/Resume only allowed with cyclic mode */
if (!echan->edesc->cyclic)
return -EINVAL;
@@ -305,36 +313,6 @@ static int edma_dma_resume(struct edma_chan *echan)
return 0;
}
-static int edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- int ret = 0;
- struct dma_slave_config *config;
- struct edma_chan *echan = to_edma_chan(chan);
-
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- edma_terminate_all(echan);
- break;
- case DMA_SLAVE_CONFIG:
- config = (struct dma_slave_config *)arg;
- ret = edma_slave_config(echan, config);
- break;
- case DMA_PAUSE:
- ret = edma_dma_pause(echan);
- break;
-
- case DMA_RESUME:
- ret = edma_dma_resume(echan);
- break;
-
- default:
- ret = -ENOSYS;
- }
-
- return ret;
-}
-
/*
* A PaRAM set configuration abstraction used by other modes
* @chan: Channel who's PaRAM set we're configuring
@@ -557,7 +535,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg(
return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
}
-struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
+static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
size_t len, unsigned long tx_flags)
{
@@ -994,19 +972,6 @@ static void __init edma_chan_init(struct edma_cc *ecc,
BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
-static int edma_dma_device_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
- caps->src_addr_widths = EDMA_DMA_BUSWIDTHS;
- caps->dstn_addr_widths = EDMA_DMA_BUSWIDTHS;
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = true;
- caps->cmd_terminate = true;
- caps->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
-
- return 0;
-}
-
static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
struct device *dev)
{
@@ -1017,8 +982,16 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
dma->device_free_chan_resources = edma_free_chan_resources;
dma->device_issue_pending = edma_issue_pending;
dma->device_tx_status = edma_tx_status;
- dma->device_control = edma_control;
- dma->device_slave_caps = edma_dma_device_slave_caps;
+ dma->device_config = edma_slave_config;
+ dma->device_pause = edma_dma_pause;
+ dma->device_resume = edma_dma_resume;
+ dma->device_terminate_all = edma_terminate_all;
+
+ dma->src_addr_widths = EDMA_DMA_BUSWIDTHS;
+ dma->dst_addr_widths = EDMA_DMA_BUSWIDTHS;
+ dma->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ dma->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+
dma->dev = dev;
/*
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 7650470196c4..24e5290faa32 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -144,7 +144,7 @@ struct ep93xx_dma_desc {
* @queue: pending descriptors which are handled next
* @free_list: list of free descriptors which can be used
* @runtime_addr: physical address currently used as dest/src (M2M only). This
- * is set via %DMA_SLAVE_CONFIG before slave operation is
+ * is set via .device_config before slave operation is
* prepared
* @runtime_ctrl: M2M runtime values for the control register.
*
@@ -1164,13 +1164,14 @@ fail:
/**
* ep93xx_dma_terminate_all - terminate all transactions
- * @edmac: channel
+ * @chan: channel
*
* Stops all DMA transactions. All descriptors are put back to the
* @edmac->free_list and callbacks are _not_ called.
*/
-static int ep93xx_dma_terminate_all(struct ep93xx_dma_chan *edmac)
+static int ep93xx_dma_terminate_all(struct dma_chan *chan)
{
+ struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
struct ep93xx_dma_desc *desc, *_d;
unsigned long flags;
LIST_HEAD(list);
@@ -1194,9 +1195,10 @@ static int ep93xx_dma_terminate_all(struct ep93xx_dma_chan *edmac)
return 0;
}
-static int ep93xx_dma_slave_config(struct ep93xx_dma_chan *edmac,
+static int ep93xx_dma_slave_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
+ struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
enum dma_slave_buswidth width;
unsigned long flags;
u32 addr, ctrl;
@@ -1242,36 +1244,6 @@ static int ep93xx_dma_slave_config(struct ep93xx_dma_chan *edmac,
}
/**
- * ep93xx_dma_control - manipulate all pending operations on a channel
- * @chan: channel
- * @cmd: control command to perform
- * @arg: optional argument
- *
- * Controls the channel. Function returns %0 in case of success or negative
- * error in case of failure.
- */
-static int ep93xx_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
- struct dma_slave_config *config;
-
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- return ep93xx_dma_terminate_all(edmac);
-
- case DMA_SLAVE_CONFIG:
- config = (struct dma_slave_config *)arg;
- return ep93xx_dma_slave_config(edmac, config);
-
- default:
- break;
- }
-
- return -ENOSYS;
-}
-
-/**
* ep93xx_dma_tx_status - check if a transaction is completed
* @chan: channel
* @cookie: transaction specific cookie
@@ -1352,7 +1324,8 @@ static int __init ep93xx_dma_probe(struct platform_device *pdev)
dma_dev->device_free_chan_resources = ep93xx_dma_free_chan_resources;
dma_dev->device_prep_slave_sg = ep93xx_dma_prep_slave_sg;
dma_dev->device_prep_dma_cyclic = ep93xx_dma_prep_dma_cyclic;
- dma_dev->device_control = ep93xx_dma_control;
+ dma_dev->device_config = ep93xx_dma_slave_config;
+ dma_dev->device_terminate_all = ep93xx_dma_terminate_all;
dma_dev->device_issue_pending = ep93xx_dma_issue_pending;
dma_dev->device_tx_status = ep93xx_dma_tx_status;
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index e9ebb89e1711..09e2842d15ec 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -289,62 +289,69 @@ static void fsl_edma_free_desc(struct virt_dma_desc *vdesc)
kfree(fsl_desc);
}
-static int fsl_edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int fsl_edma_terminate_all(struct dma_chan *chan)
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
- struct dma_slave_config *cfg = (void *)arg;
unsigned long flags;
LIST_HEAD(head);
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ fsl_edma_disable_request(fsl_chan);
+ fsl_chan->edesc = NULL;
+ vchan_get_all_descriptors(&fsl_chan->vchan, &head);
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
+ return 0;
+}
+
+static int fsl_edma_pause(struct dma_chan *chan)
+{
+ struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ if (fsl_chan->edesc) {
fsl_edma_disable_request(fsl_chan);
- fsl_chan->edesc = NULL;
- vchan_get_all_descriptors(&fsl_chan->vchan, &head);
- spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
- vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
- return 0;
-
- case DMA_SLAVE_CONFIG:
- fsl_chan->fsc.dir = cfg->direction;
- if (cfg->direction == DMA_DEV_TO_MEM) {
- fsl_chan->fsc.dev_addr = cfg->src_addr;
- fsl_chan->fsc.addr_width = cfg->src_addr_width;
- fsl_chan->fsc.burst = cfg->src_maxburst;
- fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->src_addr_width);
- } else if (cfg->direction == DMA_MEM_TO_DEV) {
- fsl_chan->fsc.dev_addr = cfg->dst_addr;
- fsl_chan->fsc.addr_width = cfg->dst_addr_width;
- fsl_chan->fsc.burst = cfg->dst_maxburst;
- fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->dst_addr_width);
- } else {
- return -EINVAL;
- }
- return 0;
+ fsl_chan->status = DMA_PAUSED;
+ }
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ return 0;
+}
- case DMA_PAUSE:
- spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
- if (fsl_chan->edesc) {
- fsl_edma_disable_request(fsl_chan);
- fsl_chan->status = DMA_PAUSED;
- }
- spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
- return 0;
-
- case DMA_RESUME:
- spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
- if (fsl_chan->edesc) {
- fsl_edma_enable_request(fsl_chan);
- fsl_chan->status = DMA_IN_PROGRESS;
- }
- spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
- return 0;
+static int fsl_edma_resume(struct dma_chan *chan)
+{
+ struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+ unsigned long flags;
- default:
- return -ENXIO;
+ spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
+ if (fsl_chan->edesc) {
+ fsl_edma_enable_request(fsl_chan);
+ fsl_chan->status = DMA_IN_PROGRESS;
+ }
+ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
+ return 0;
+}
+
+static int fsl_edma_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
+{
+ struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
+
+ fsl_chan->fsc.dir = cfg->direction;
+ if (cfg->direction == DMA_DEV_TO_MEM) {
+ fsl_chan->fsc.dev_addr = cfg->src_addr;
+ fsl_chan->fsc.addr_width = cfg->src_addr_width;
+ fsl_chan->fsc.burst = cfg->src_maxburst;
+ fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->src_addr_width);
+ } else if (cfg->direction == DMA_MEM_TO_DEV) {
+ fsl_chan->fsc.dev_addr = cfg->dst_addr;
+ fsl_chan->fsc.addr_width = cfg->dst_addr_width;
+ fsl_chan->fsc.burst = cfg->dst_maxburst;
+ fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->dst_addr_width);
+ } else {
+ return -EINVAL;
}
+ return 0;
}
static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
@@ -780,18 +787,6 @@ static void fsl_edma_free_chan_resources(struct dma_chan *chan)
fsl_chan->tcd_pool = NULL;
}
-static int fsl_dma_device_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
- caps->src_addr_widths = FSL_EDMA_BUSWIDTHS;
- caps->dstn_addr_widths = FSL_EDMA_BUSWIDTHS;
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = true;
- caps->cmd_terminate = true;
-
- return 0;
-}
-
static int
fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
{
@@ -917,9 +912,15 @@ static int fsl_edma_probe(struct platform_device *pdev)
fsl_edma->dma_dev.device_tx_status = fsl_edma_tx_status;
fsl_edma->dma_dev.device_prep_slave_sg = fsl_edma_prep_slave_sg;
fsl_edma->dma_dev.device_prep_dma_cyclic = fsl_edma_prep_dma_cyclic;
- fsl_edma->dma_dev.device_control = fsl_edma_control;
+ fsl_edma->dma_dev.device_config = fsl_edma_slave_config;
+ fsl_edma->dma_dev.device_pause = fsl_edma_pause;
+ fsl_edma->dma_dev.device_resume = fsl_edma_resume;
+ fsl_edma->dma_dev.device_terminate_all = fsl_edma_terminate_all;
fsl_edma->dma_dev.device_issue_pending = fsl_edma_issue_pending;
- fsl_edma->dma_dev.device_slave_caps = fsl_dma_device_slave_caps;
+
+ fsl_edma->dma_dev.src_addr_widths = FSL_EDMA_BUSWIDTHS;
+ fsl_edma->dma_dev.dst_addr_widths = FSL_EDMA_BUSWIDTHS;
+ fsl_edma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
platform_set_drvdata(pdev, fsl_edma);
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 38821cdf862b..300f821f1890 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -941,84 +941,56 @@ fail:
return NULL;
}
-/**
- * fsl_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
- * @chan: DMA channel
- * @sgl: scatterlist to transfer to/from
- * @sg_len: number of entries in @scatterlist
- * @direction: DMA direction
- * @flags: DMAEngine flags
- * @context: transaction context (ignored)
- *
- * Prepare a set of descriptors for a DMA_SLAVE transaction. Following the
- * DMA_SLAVE API, this gets the device-specific information from the
- * chan->private variable.
- */
-static struct dma_async_tx_descriptor *fsl_dma_prep_slave_sg(
- struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
- enum dma_transfer_direction direction, unsigned long flags,
- void *context)
+static int fsl_dma_device_terminate_all(struct dma_chan *dchan)
{
- /*
- * This operation is not supported on the Freescale DMA controller
- *
- * However, we need to provide the function pointer to allow the
- * device_control() method to work.
- */
- return NULL;
-}
-
-static int fsl_dma_device_control(struct dma_chan *dchan,
- enum dma_ctrl_cmd cmd, unsigned long arg)
-{
- struct dma_slave_config *config;
struct fsldma_chan *chan;
- int size;
if (!dchan)
return -EINVAL;
chan = to_fsl_chan(dchan);
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- spin_lock_bh(&chan->desc_lock);
-
- /* Halt the DMA engine */
- dma_halt(chan);
+ spin_lock_bh(&chan->desc_lock);
- /* Remove and free all of the descriptors in the LD queue */
- fsldma_free_desc_list(chan, &chan->ld_pending);
- fsldma_free_desc_list(chan, &chan->ld_running);
- fsldma_free_desc_list(chan, &chan->ld_completed);
- chan->idle = true;
+ /* Halt the DMA engine */
+ dma_halt(chan);
- spin_unlock_bh(&chan->desc_lock);
- return 0;
+ /* Remove and free all of the descriptors in the LD queue */
+ fsldma_free_desc_list(chan, &chan->ld_pending);
+ fsldma_free_desc_list(chan, &chan->ld_running);
+ fsldma_free_desc_list(chan, &chan->ld_completed);
+ chan->idle = true;
- case DMA_SLAVE_CONFIG:
- config = (struct dma_slave_config *)arg;
+ spin_unlock_bh(&chan->desc_lock);
+ return 0;
+}
- /* make sure the channel supports setting burst size */
- if (!chan->set_request_count)
- return -ENXIO;
+static int fsl_dma_device_config(struct dma_chan *dchan,
+ struct dma_slave_config *config)
+{
+ struct fsldma_chan *chan;
+ int size;
- /* we set the controller burst size depending on direction */
- if (config->direction == DMA_MEM_TO_DEV)
- size = config->dst_addr_width * config->dst_maxburst;
- else
- size = config->src_addr_width * config->src_maxburst;
+ if (!dchan)
+ return -EINVAL;
- chan->set_request_count(chan, size);
- return 0;
+ chan = to_fsl_chan(dchan);
- default:
+ /* make sure the channel supports setting burst size */
+ if (!chan->set_request_count)
return -ENXIO;
- }
+ /* we set the controller burst size depending on direction */
+ if (config->direction == DMA_MEM_TO_DEV)
+ size = config->dst_addr_width * config->dst_maxburst;
+ else
+ size = config->src_addr_width * config->src_maxburst;
+
+ chan->set_request_count(chan, size);
return 0;
}
+
/**
* fsl_dma_memcpy_issue_pending - Issue the DMA start command
* @chan : Freescale DMA channel
@@ -1395,10 +1367,15 @@ static int fsldma_of_probe(struct platform_device *op)
fdev->common.device_prep_dma_sg = fsl_dma_prep_sg;
fdev->common.device_tx_status = fsl_tx_status;
fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
- fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg;
- fdev->common.device_control = fsl_dma_device_control;
+ fdev->common.device_config = fsl_dma_device_config;
+ fdev->common.device_terminate_all = fsl_dma_device_terminate_all;
fdev->common.dev = &op->dev;
+ fdev->common.src_addr_widths = FSL_DMA_BUSWIDTHS;
+ fdev->common.dst_addr_widths = FSL_DMA_BUSWIDTHS;
+ fdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ fdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
+
dma_set_mask(&(op->dev), DMA_BIT_MASK(36));
platform_set_drvdata(op, fdev);
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index 239c20c84382..31bffccdcc75 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -83,6 +83,10 @@
#define FSL_DMA_DGSR_EOSI 0x02
#define FSL_DMA_DGSR_EOLSI 0x01
+#define FSL_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
typedef u64 __bitwise v64;
typedef u32 __bitwise v32;
diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
new file mode 100644
index 000000000000..ed045a9ad634
--- /dev/null
+++ b/drivers/dma/img-mdc-dma.c
@@ -0,0 +1,1011 @@
+/*
+ * IMG Multi-threaded DMA Controller (MDC)
+ *
+ * Copyright (C) 2009,2012,2013 Imagination Technologies Ltd.
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define MDC_MAX_DMA_CHANNELS 32
+
+#define MDC_GENERAL_CONFIG 0x000
+#define MDC_GENERAL_CONFIG_LIST_IEN BIT(31)
+#define MDC_GENERAL_CONFIG_IEN BIT(29)
+#define MDC_GENERAL_CONFIG_LEVEL_INT BIT(28)
+#define MDC_GENERAL_CONFIG_INC_W BIT(12)
+#define MDC_GENERAL_CONFIG_INC_R BIT(8)
+#define MDC_GENERAL_CONFIG_PHYSICAL_W BIT(7)
+#define MDC_GENERAL_CONFIG_WIDTH_W_SHIFT 4
+#define MDC_GENERAL_CONFIG_WIDTH_W_MASK 0x7
+#define MDC_GENERAL_CONFIG_PHYSICAL_R BIT(3)
+#define MDC_GENERAL_CONFIG_WIDTH_R_SHIFT 0
+#define MDC_GENERAL_CONFIG_WIDTH_R_MASK 0x7
+
+#define MDC_READ_PORT_CONFIG 0x004
+#define MDC_READ_PORT_CONFIG_STHREAD_SHIFT 28
+#define MDC_READ_PORT_CONFIG_STHREAD_MASK 0xf
+#define MDC_READ_PORT_CONFIG_RTHREAD_SHIFT 24
+#define MDC_READ_PORT_CONFIG_RTHREAD_MASK 0xf
+#define MDC_READ_PORT_CONFIG_WTHREAD_SHIFT 16
+#define MDC_READ_PORT_CONFIG_WTHREAD_MASK 0xf
+#define MDC_READ_PORT_CONFIG_BURST_SIZE_SHIFT 4
+#define MDC_READ_PORT_CONFIG_BURST_SIZE_MASK 0xff
+#define MDC_READ_PORT_CONFIG_DREQ_ENABLE BIT(1)
+
+#define MDC_READ_ADDRESS 0x008
+
+#define MDC_WRITE_ADDRESS 0x00c
+
+#define MDC_TRANSFER_SIZE 0x010
+#define MDC_TRANSFER_SIZE_MASK 0xffffff
+
+#define MDC_LIST_NODE_ADDRESS 0x014
+
+#define MDC_CMDS_PROCESSED 0x018
+#define MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT 16
+#define MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK 0x3f
+#define MDC_CMDS_PROCESSED_INT_ACTIVE BIT(8)
+#define MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT 0
+#define MDC_CMDS_PROCESSED_CMDS_DONE_MASK 0x3f
+
+#define MDC_CONTROL_AND_STATUS 0x01c
+#define MDC_CONTROL_AND_STATUS_CANCEL BIT(20)
+#define MDC_CONTROL_AND_STATUS_LIST_EN BIT(4)
+#define MDC_CONTROL_AND_STATUS_EN BIT(0)
+
+#define MDC_ACTIVE_TRANSFER_SIZE 0x030
+
+#define MDC_GLOBAL_CONFIG_A 0x900
+#define MDC_GLOBAL_CONFIG_A_THREAD_ID_WIDTH_SHIFT 16
+#define MDC_GLOBAL_CONFIG_A_THREAD_ID_WIDTH_MASK 0xff
+#define MDC_GLOBAL_CONFIG_A_DMA_CONTEXTS_SHIFT 8
+#define MDC_GLOBAL_CONFIG_A_DMA_CONTEXTS_MASK 0xff
+#define MDC_GLOBAL_CONFIG_A_SYS_DAT_WIDTH_SHIFT 0
+#define MDC_GLOBAL_CONFIG_A_SYS_DAT_WIDTH_MASK 0xff
+
+struct mdc_hw_list_desc {
+ u32 gen_conf;
+ u32 readport_conf;
+ u32 read_addr;
+ u32 write_addr;
+ u32 xfer_size;
+ u32 node_addr;
+ u32 cmds_done;
+ u32 ctrl_status;
+ /*
+ * Not part of the list descriptor, but instead used by the CPU to
+ * traverse the list.
+ */
+ struct mdc_hw_list_desc *next_desc;
+};
+
+struct mdc_tx_desc {
+ struct mdc_chan *chan;
+ struct virt_dma_desc vd;
+ dma_addr_t list_phys;
+ struct mdc_hw_list_desc *list;
+ bool cyclic;
+ bool cmd_loaded;
+ unsigned int list_len;
+ unsigned int list_period_len;
+ size_t list_xfer_size;
+ unsigned int list_cmds_done;
+};
+
+struct mdc_chan {
+ struct mdc_dma *mdma;
+ struct virt_dma_chan vc;
+ struct dma_slave_config config;
+ struct mdc_tx_desc *desc;
+ int irq;
+ unsigned int periph;
+ unsigned int thread;
+ unsigned int chan_nr;
+};
+
+struct mdc_dma_soc_data {
+ void (*enable_chan)(struct mdc_chan *mchan);
+ void (*disable_chan)(struct mdc_chan *mchan);
+};
+
+struct mdc_dma {
+ struct dma_device dma_dev;
+ void __iomem *regs;
+ struct clk *clk;
+ struct dma_pool *desc_pool;
+ struct regmap *periph_regs;
+ spinlock_t lock;
+ unsigned int nr_threads;
+ unsigned int nr_channels;
+ unsigned int bus_width;
+ unsigned int max_burst_mult;
+ unsigned int max_xfer_size;
+ const struct mdc_dma_soc_data *soc;
+ struct mdc_chan channels[MDC_MAX_DMA_CHANNELS];
+};
+
+static inline u32 mdc_readl(struct mdc_dma *mdma, u32 reg)
+{
+ return readl(mdma->regs + reg);
+}
+
+static inline void mdc_writel(struct mdc_dma *mdma, u32 val, u32 reg)
+{
+ writel(val, mdma->regs + reg);
+}
+
+static inline u32 mdc_chan_readl(struct mdc_chan *mchan, u32 reg)
+{
+ return mdc_readl(mchan->mdma, mchan->chan_nr * 0x040 + reg);
+}
+
+static inline void mdc_chan_writel(struct mdc_chan *mchan, u32 val, u32 reg)
+{
+ mdc_writel(mchan->mdma, val, mchan->chan_nr * 0x040 + reg);
+}
+
+static inline struct mdc_chan *to_mdc_chan(struct dma_chan *c)
+{
+ return container_of(to_virt_chan(c), struct mdc_chan, vc);
+}
+
+static inline struct mdc_tx_desc *to_mdc_desc(struct dma_async_tx_descriptor *t)
+{
+ struct virt_dma_desc *vdesc = container_of(t, struct virt_dma_desc, tx);
+
+ return container_of(vdesc, struct mdc_tx_desc, vd);
+}
+
+static inline struct device *mdma2dev(struct mdc_dma *mdma)
+{
+ return mdma->dma_dev.dev;
+}
+
+static inline unsigned int to_mdc_width(unsigned int bytes)
+{
+ return ffs(bytes) - 1;
+}
+
+static inline void mdc_set_read_width(struct mdc_hw_list_desc *ldesc,
+ unsigned int bytes)
+{
+ ldesc->gen_conf |= to_mdc_width(bytes) <<
+ MDC_GENERAL_CONFIG_WIDTH_R_SHIFT;
+}
+
+static inline void mdc_set_write_width(struct mdc_hw_list_desc *ldesc,
+ unsigned int bytes)
+{
+ ldesc->gen_conf |= to_mdc_width(bytes) <<
+ MDC_GENERAL_CONFIG_WIDTH_W_SHIFT;
+}
+
+static void mdc_list_desc_config(struct mdc_chan *mchan,
+ struct mdc_hw_list_desc *ldesc,
+ enum dma_transfer_direction dir,
+ dma_addr_t src, dma_addr_t dst, size_t len)
+{
+ struct mdc_dma *mdma = mchan->mdma;
+ unsigned int max_burst, burst_size;
+
+ ldesc->gen_conf = MDC_GENERAL_CONFIG_IEN | MDC_GENERAL_CONFIG_LIST_IEN |
+ MDC_GENERAL_CONFIG_LEVEL_INT | MDC_GENERAL_CONFIG_PHYSICAL_W |
+ MDC_GENERAL_CONFIG_PHYSICAL_R;
+ ldesc->readport_conf =
+ (mchan->thread << MDC_READ_PORT_CONFIG_STHREAD_SHIFT) |
+ (mchan->thread << MDC_READ_PORT_CONFIG_RTHREAD_SHIFT) |
+ (mchan->thread << MDC_READ_PORT_CONFIG_WTHREAD_SHIFT);
+ ldesc->read_addr = src;
+ ldesc->write_addr = dst;
+ ldesc->xfer_size = len - 1;
+ ldesc->node_addr = 0;
+ ldesc->cmds_done = 0;
+ ldesc->ctrl_status = MDC_CONTROL_AND_STATUS_LIST_EN |
+ MDC_CONTROL_AND_STATUS_EN;
+ ldesc->next_desc = NULL;
+
+ if (IS_ALIGNED(dst, mdma->bus_width) &&
+ IS_ALIGNED(src, mdma->bus_width))
+ max_burst = mdma->bus_width * mdma->max_burst_mult;
+ else
+ max_burst = mdma->bus_width * (mdma->max_burst_mult - 1);
+
+ if (dir == DMA_MEM_TO_DEV) {
+ ldesc->gen_conf |= MDC_GENERAL_CONFIG_INC_R;
+ ldesc->readport_conf |= MDC_READ_PORT_CONFIG_DREQ_ENABLE;
+ mdc_set_read_width(ldesc, mdma->bus_width);
+ mdc_set_write_width(ldesc, mchan->config.dst_addr_width);
+ burst_size = min(max_burst, mchan->config.dst_maxburst *
+ mchan->config.dst_addr_width);
+ } else if (dir == DMA_DEV_TO_MEM) {
+ ldesc->gen_conf |= MDC_GENERAL_CONFIG_INC_W;
+ ldesc->readport_conf |= MDC_READ_PORT_CONFIG_DREQ_ENABLE;
+ mdc_set_read_width(ldesc, mchan->config.src_addr_width);
+ mdc_set_write_width(ldesc, mdma->bus_width);
+ burst_size = min(max_burst, mchan->config.src_maxburst *
+ mchan->config.src_addr_width);
+ } else {
+ ldesc->gen_conf |= MDC_GENERAL_CONFIG_INC_R |
+ MDC_GENERAL_CONFIG_INC_W;
+ mdc_set_read_width(ldesc, mdma->bus_width);
+ mdc_set_write_width(ldesc, mdma->bus_width);
+ burst_size = max_burst;
+ }
+ ldesc->readport_conf |= (burst_size - 1) <<
+ MDC_READ_PORT_CONFIG_BURST_SIZE_SHIFT;
+}
+
+static void mdc_list_desc_free(struct mdc_tx_desc *mdesc)
+{
+ struct mdc_dma *mdma = mdesc->chan->mdma;
+ struct mdc_hw_list_desc *curr, *next;
+ dma_addr_t curr_phys, next_phys;
+
+ curr = mdesc->list;
+ curr_phys = mdesc->list_phys;
+ while (curr) {
+ next = curr->next_desc;
+ next_phys = curr->node_addr;
+ dma_pool_free(mdma->desc_pool, curr, curr_phys);
+ curr = next;
+ curr_phys = next_phys;
+ }
+}
+
+static void mdc_desc_free(struct virt_dma_desc *vd)
+{
+ struct mdc_tx_desc *mdesc = to_mdc_desc(&vd->tx);
+
+ mdc_list_desc_free(mdesc);
+ kfree(mdesc);
+}
+
+static struct dma_async_tx_descriptor *mdc_prep_dma_memcpy(
+ struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, size_t len,
+ unsigned long flags)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ struct mdc_dma *mdma = mchan->mdma;
+ struct mdc_tx_desc *mdesc;
+ struct mdc_hw_list_desc *curr, *prev = NULL;
+ dma_addr_t curr_phys, prev_phys;
+
+ if (!len)
+ return NULL;
+
+ mdesc = kzalloc(sizeof(*mdesc), GFP_NOWAIT);
+ if (!mdesc)
+ return NULL;
+ mdesc->chan = mchan;
+ mdesc->list_xfer_size = len;
+
+ while (len > 0) {
+ size_t xfer_size;
+
+ curr = dma_pool_alloc(mdma->desc_pool, GFP_NOWAIT, &curr_phys);
+ if (!curr)
+ goto free_desc;
+
+ if (prev) {
+ prev->node_addr = curr_phys;
+ prev->next_desc = curr;
+ } else {
+ mdesc->list_phys = curr_phys;
+ mdesc->list = curr;
+ }
+
+ xfer_size = min_t(size_t, mdma->max_xfer_size, len);
+
+ mdc_list_desc_config(mchan, curr, DMA_MEM_TO_MEM, src, dest,
+ xfer_size);
+
+ prev = curr;
+ prev_phys = curr_phys;
+
+ mdesc->list_len++;
+ src += xfer_size;
+ dest += xfer_size;
+ len -= xfer_size;
+ }
+
+ return vchan_tx_prep(&mchan->vc, &mdesc->vd, flags);
+
+free_desc:
+ mdc_desc_free(&mdesc->vd);
+
+ return NULL;
+}
+
+static int mdc_check_slave_width(struct mdc_chan *mchan,
+ enum dma_transfer_direction dir)
+{
+ enum dma_slave_buswidth width;
+
+ if (dir == DMA_MEM_TO_DEV)
+ width = mchan->config.dst_addr_width;
+ else
+ width = mchan->config.src_addr_width;
+
+ switch (width) {
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ case DMA_SLAVE_BUSWIDTH_8_BYTES:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (width > mchan->mdma->bus_width)
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct dma_async_tx_descriptor *mdc_prep_dma_cyclic(
+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+ size_t period_len, enum dma_transfer_direction dir,
+ unsigned long flags)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ struct mdc_dma *mdma = mchan->mdma;
+ struct mdc_tx_desc *mdesc;
+ struct mdc_hw_list_desc *curr, *prev = NULL;
+ dma_addr_t curr_phys, prev_phys;
+
+ if (!buf_len && !period_len)
+ return NULL;
+
+ if (!is_slave_direction(dir))
+ return NULL;
+
+ if (mdc_check_slave_width(mchan, dir) < 0)
+ return NULL;
+
+ mdesc = kzalloc(sizeof(*mdesc), GFP_NOWAIT);
+ if (!mdesc)
+ return NULL;
+ mdesc->chan = mchan;
+ mdesc->cyclic = true;
+ mdesc->list_xfer_size = buf_len;
+ mdesc->list_period_len = DIV_ROUND_UP(period_len,
+ mdma->max_xfer_size);
+
+ while (buf_len > 0) {
+ size_t remainder = min(period_len, buf_len);
+
+ while (remainder > 0) {
+ size_t xfer_size;
+
+ curr = dma_pool_alloc(mdma->desc_pool, GFP_NOWAIT,
+ &curr_phys);
+ if (!curr)
+ goto free_desc;
+
+ if (!prev) {
+ mdesc->list_phys = curr_phys;
+ mdesc->list = curr;
+ } else {
+ prev->node_addr = curr_phys;
+ prev->next_desc = curr;
+ }
+
+ xfer_size = min_t(size_t, mdma->max_xfer_size,
+ remainder);
+
+ if (dir == DMA_MEM_TO_DEV) {
+ mdc_list_desc_config(mchan, curr, dir,
+ buf_addr,
+ mchan->config.dst_addr,
+ xfer_size);
+ } else {
+ mdc_list_desc_config(mchan, curr, dir,
+ mchan->config.src_addr,
+ buf_addr,
+ xfer_size);
+ }
+
+ prev = curr;
+ prev_phys = curr_phys;
+
+ mdesc->list_len++;
+ buf_addr += xfer_size;
+ buf_len -= xfer_size;
+ remainder -= xfer_size;
+ }
+ }
+ prev->node_addr = mdesc->list_phys;
+
+ return vchan_tx_prep(&mchan->vc, &mdesc->vd, flags);
+
+free_desc:
+ mdc_desc_free(&mdesc->vd);
+
+ return NULL;
+}
+
+static struct dma_async_tx_descriptor *mdc_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction dir,
+ unsigned long flags, void *context)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ struct mdc_dma *mdma = mchan->mdma;
+ struct mdc_tx_desc *mdesc;
+ struct scatterlist *sg;
+ struct mdc_hw_list_desc *curr, *prev = NULL;
+ dma_addr_t curr_phys, prev_phys;
+ unsigned int i;
+
+ if (!sgl)
+ return NULL;
+
+ if (!is_slave_direction(dir))
+ return NULL;
+
+ if (mdc_check_slave_width(mchan, dir) < 0)
+ return NULL;
+
+ mdesc = kzalloc(sizeof(*mdesc), GFP_NOWAIT);
+ if (!mdesc)
+ return NULL;
+ mdesc->chan = mchan;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ dma_addr_t buf = sg_dma_address(sg);
+ size_t buf_len = sg_dma_len(sg);
+
+ while (buf_len > 0) {
+ size_t xfer_size;
+
+ curr = dma_pool_alloc(mdma->desc_pool, GFP_NOWAIT,
+ &curr_phys);
+ if (!curr)
+ goto free_desc;
+
+ if (!prev) {
+ mdesc->list_phys = curr_phys;
+ mdesc->list = curr;
+ } else {
+ prev->node_addr = curr_phys;
+ prev->next_desc = curr;
+ }
+
+ xfer_size = min_t(size_t, mdma->max_xfer_size,
+ buf_len);
+
+ if (dir == DMA_MEM_TO_DEV) {
+ mdc_list_desc_config(mchan, curr, dir, buf,
+ mchan->config.dst_addr,
+ xfer_size);
+ } else {
+ mdc_list_desc_config(mchan, curr, dir,
+ mchan->config.src_addr,
+ buf, xfer_size);
+ }
+
+ prev = curr;
+ prev_phys = curr_phys;
+
+ mdesc->list_len++;
+ mdesc->list_xfer_size += xfer_size;
+ buf += xfer_size;
+ buf_len -= xfer_size;
+ }
+ }
+
+ return vchan_tx_prep(&mchan->vc, &mdesc->vd, flags);
+
+free_desc:
+ mdc_desc_free(&mdesc->vd);
+
+ return NULL;
+}
+
+static void mdc_issue_desc(struct mdc_chan *mchan)
+{
+ struct mdc_dma *mdma = mchan->mdma;
+ struct virt_dma_desc *vd;
+ struct mdc_tx_desc *mdesc;
+ u32 val;
+
+ vd = vchan_next_desc(&mchan->vc);
+ if (!vd)
+ return;
+
+ list_del(&vd->node);
+
+ mdesc = to_mdc_desc(&vd->tx);
+ mchan->desc = mdesc;
+
+ dev_dbg(mdma2dev(mdma), "Issuing descriptor on channel %d\n",
+ mchan->chan_nr);
+
+ mdma->soc->enable_chan(mchan);
+
+ val = mdc_chan_readl(mchan, MDC_GENERAL_CONFIG);
+ val |= MDC_GENERAL_CONFIG_LIST_IEN | MDC_GENERAL_CONFIG_IEN |
+ MDC_GENERAL_CONFIG_LEVEL_INT | MDC_GENERAL_CONFIG_PHYSICAL_W |
+ MDC_GENERAL_CONFIG_PHYSICAL_R;
+ mdc_chan_writel(mchan, val, MDC_GENERAL_CONFIG);
+ val = (mchan->thread << MDC_READ_PORT_CONFIG_STHREAD_SHIFT) |
+ (mchan->thread << MDC_READ_PORT_CONFIG_RTHREAD_SHIFT) |
+ (mchan->thread << MDC_READ_PORT_CONFIG_WTHREAD_SHIFT);
+ mdc_chan_writel(mchan, val, MDC_READ_PORT_CONFIG);
+ mdc_chan_writel(mchan, mdesc->list_phys, MDC_LIST_NODE_ADDRESS);
+ val = mdc_chan_readl(mchan, MDC_CONTROL_AND_STATUS);
+ val |= MDC_CONTROL_AND_STATUS_LIST_EN;
+ mdc_chan_writel(mchan, val, MDC_CONTROL_AND_STATUS);
+}
+
+static void mdc_issue_pending(struct dma_chan *chan)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mchan->vc.lock, flags);
+ if (vchan_issue_pending(&mchan->vc) && !mchan->desc)
+ mdc_issue_desc(mchan);
+ spin_unlock_irqrestore(&mchan->vc.lock, flags);
+}
+
+static enum dma_status mdc_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie, struct dma_tx_state *txstate)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ struct mdc_tx_desc *mdesc;
+ struct virt_dma_desc *vd;
+ unsigned long flags;
+ size_t bytes = 0;
+ int ret;
+
+ ret = dma_cookie_status(chan, cookie, txstate);
+ if (ret == DMA_COMPLETE)
+ return ret;
+
+ if (!txstate)
+ return ret;
+
+ spin_lock_irqsave(&mchan->vc.lock, flags);
+ vd = vchan_find_desc(&mchan->vc, cookie);
+ if (vd) {
+ mdesc = to_mdc_desc(&vd->tx);
+ bytes = mdesc->list_xfer_size;
+ } else if (mchan->desc && mchan->desc->vd.tx.cookie == cookie) {
+ struct mdc_hw_list_desc *ldesc;
+ u32 val1, val2, done, processed, residue;
+ int i, cmds;
+
+ mdesc = mchan->desc;
+
+ /*
+ * Determine the number of commands that haven't been
+ * processed (handled by the IRQ handler) yet.
+ */
+ do {
+ val1 = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED) &
+ ~MDC_CMDS_PROCESSED_INT_ACTIVE;
+ residue = mdc_chan_readl(mchan,
+ MDC_ACTIVE_TRANSFER_SIZE);
+ val2 = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED) &
+ ~MDC_CMDS_PROCESSED_INT_ACTIVE;
+ } while (val1 != val2);
+
+ done = (val1 >> MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT) &
+ MDC_CMDS_PROCESSED_CMDS_DONE_MASK;
+ processed = (val1 >> MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT) &
+ MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK;
+ cmds = (done - processed) %
+ (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1);
+
+ /*
+ * If the command loaded event hasn't been processed yet, then
+ * the difference above includes an extra command.
+ */
+ if (!mdesc->cmd_loaded)
+ cmds--;
+ else
+ cmds += mdesc->list_cmds_done;
+
+ bytes = mdesc->list_xfer_size;
+ ldesc = mdesc->list;
+ for (i = 0; i < cmds; i++) {
+ bytes -= ldesc->xfer_size + 1;
+ ldesc = ldesc->next_desc;
+ }
+ if (ldesc) {
+ if (residue != MDC_TRANSFER_SIZE_MASK)
+ bytes -= ldesc->xfer_size - residue;
+ else
+ bytes -= ldesc->xfer_size + 1;
+ }
+ }
+ spin_unlock_irqrestore(&mchan->vc.lock, flags);
+
+ dma_set_residue(txstate, bytes);
+
+ return ret;
+}
+
+static int mdc_terminate_all(struct dma_chan *chan)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ struct mdc_tx_desc *mdesc;
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock_irqsave(&mchan->vc.lock, flags);
+
+ mdc_chan_writel(mchan, MDC_CONTROL_AND_STATUS_CANCEL,
+ MDC_CONTROL_AND_STATUS);
+
+ mdesc = mchan->desc;
+ mchan->desc = NULL;
+ vchan_get_all_descriptors(&mchan->vc, &head);
+
+ spin_unlock_irqrestore(&mchan->vc.lock, flags);
+
+ if (mdesc)
+ mdc_desc_free(&mdesc->vd);
+ vchan_dma_desc_free_list(&mchan->vc, &head);
+
+ return 0;
+}
+
+static int mdc_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *config)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mchan->vc.lock, flags);
+ mchan->config = *config;
+ spin_unlock_irqrestore(&mchan->vc.lock, flags);
+
+ return 0;
+}
+
+static int mdc_alloc_chan_resources(struct dma_chan *chan)
+{
+ return 0;
+}
+
+static void mdc_free_chan_resources(struct dma_chan *chan)
+{
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+ struct mdc_dma *mdma = mchan->mdma;
+
+ mdc_terminate_all(chan);
+
+ mdma->soc->disable_chan(mchan);
+}
+
+static irqreturn_t mdc_chan_irq(int irq, void *dev_id)
+{
+ struct mdc_chan *mchan = (struct mdc_chan *)dev_id;
+ struct mdc_tx_desc *mdesc;
+ u32 val, processed, done1, done2;
+ unsigned int i;
+
+ spin_lock(&mchan->vc.lock);
+
+ val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED);
+ processed = (val >> MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT) &
+ MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK;
+ /*
+ * CMDS_DONE may have incremented between reading CMDS_PROCESSED
+ * and clearing INT_ACTIVE. Re-read CMDS_PROCESSED to ensure we
+ * didn't miss a command completion.
+ */
+ do {
+ val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED);
+ done1 = (val >> MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT) &
+ MDC_CMDS_PROCESSED_CMDS_DONE_MASK;
+ val &= ~((MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK <<
+ MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT) |
+ MDC_CMDS_PROCESSED_INT_ACTIVE);
+ val |= done1 << MDC_CMDS_PROCESSED_CMDS_PROCESSED_SHIFT;
+ mdc_chan_writel(mchan, val, MDC_CMDS_PROCESSED);
+ val = mdc_chan_readl(mchan, MDC_CMDS_PROCESSED);
+ done2 = (val >> MDC_CMDS_PROCESSED_CMDS_DONE_SHIFT) &
+ MDC_CMDS_PROCESSED_CMDS_DONE_MASK;
+ } while (done1 != done2);
+
+ dev_dbg(mdma2dev(mchan->mdma), "IRQ on channel %d\n", mchan->chan_nr);
+
+ mdesc = mchan->desc;
+ if (!mdesc) {
+ dev_warn(mdma2dev(mchan->mdma),
+ "IRQ with no active descriptor on channel %d\n",
+ mchan->chan_nr);
+ goto out;
+ }
+
+ for (i = processed; i != done1;
+ i = (i + 1) % (MDC_CMDS_PROCESSED_CMDS_PROCESSED_MASK + 1)) {
+ /*
+ * The first interrupt in a transfer indicates that the
+ * command list has been loaded, not that a command has
+ * been completed.
+ */
+ if (!mdesc->cmd_loaded) {
+ mdesc->cmd_loaded = true;
+ continue;
+ }
+
+ mdesc->list_cmds_done++;
+ if (mdesc->cyclic) {
+ mdesc->list_cmds_done %= mdesc->list_len;
+ if (mdesc->list_cmds_done % mdesc->list_period_len == 0)
+ vchan_cyclic_callback(&mdesc->vd);
+ } else if (mdesc->list_cmds_done == mdesc->list_len) {
+ mchan->desc = NULL;
+ vchan_cookie_complete(&mdesc->vd);
+ mdc_issue_desc(mchan);
+ break;
+ }
+ }
+out:
+ spin_unlock(&mchan->vc.lock);
+
+ return IRQ_HANDLED;
+}
+
+static struct dma_chan *mdc_of_xlate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct mdc_dma *mdma = ofdma->of_dma_data;
+ struct dma_chan *chan;
+
+ if (dma_spec->args_count != 3)
+ return NULL;
+
+ list_for_each_entry(chan, &mdma->dma_dev.channels, device_node) {
+ struct mdc_chan *mchan = to_mdc_chan(chan);
+
+ if (!(dma_spec->args[1] & BIT(mchan->chan_nr)))
+ continue;
+ if (dma_get_slave_channel(chan)) {
+ mchan->periph = dma_spec->args[0];
+ mchan->thread = dma_spec->args[2];
+ return chan;
+ }
+ }
+
+ return NULL;
+}
+
+#define PISTACHIO_CR_PERIPH_DMA_ROUTE(ch) (0x120 + 0x4 * ((ch) / 4))
+#define PISTACHIO_CR_PERIPH_DMA_ROUTE_SHIFT(ch) (8 * ((ch) % 4))
+#define PISTACHIO_CR_PERIPH_DMA_ROUTE_MASK 0x3f
+
+static void pistachio_mdc_enable_chan(struct mdc_chan *mchan)
+{
+ struct mdc_dma *mdma = mchan->mdma;
+
+ regmap_update_bits(mdma->periph_regs,
+ PISTACHIO_CR_PERIPH_DMA_ROUTE(mchan->chan_nr),
+ PISTACHIO_CR_PERIPH_DMA_ROUTE_MASK <<
+ PISTACHIO_CR_PERIPH_DMA_ROUTE_SHIFT(mchan->chan_nr),
+ mchan->periph <<
+ PISTACHIO_CR_PERIPH_DMA_ROUTE_SHIFT(mchan->chan_nr));
+}
+
+static void pistachio_mdc_disable_chan(struct mdc_chan *mchan)
+{
+ struct mdc_dma *mdma = mchan->mdma;
+
+ regmap_update_bits(mdma->periph_regs,
+ PISTACHIO_CR_PERIPH_DMA_ROUTE(mchan->chan_nr),
+ PISTACHIO_CR_PERIPH_DMA_ROUTE_MASK <<
+ PISTACHIO_CR_PERIPH_DMA_ROUTE_SHIFT(mchan->chan_nr),
+ 0);
+}
+
+static const struct mdc_dma_soc_data pistachio_mdc_data = {
+ .enable_chan = pistachio_mdc_enable_chan,
+ .disable_chan = pistachio_mdc_disable_chan,
+};
+
+static const struct of_device_id mdc_dma_of_match[] = {
+ { .compatible = "img,pistachio-mdc-dma", .data = &pistachio_mdc_data, },
+ { },
+};
+MODULE_DEVICE_TABLE(of, mdc_dma_of_match);
+
+static int mdc_dma_probe(struct platform_device *pdev)
+{
+ struct mdc_dma *mdma;
+ struct resource *res;
+ const struct of_device_id *match;
+ unsigned int i;
+ u32 val;
+ int ret;
+
+ mdma = devm_kzalloc(&pdev->dev, sizeof(*mdma), GFP_KERNEL);
+ if (!mdma)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, mdma);
+
+ match = of_match_device(mdc_dma_of_match, &pdev->dev);
+ mdma->soc = match->data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mdma->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mdma->regs))
+ return PTR_ERR(mdma->regs);
+
+ mdma->periph_regs = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ "img,cr-periph");
+ if (IS_ERR(mdma->periph_regs))
+ return PTR_ERR(mdma->periph_regs);
+
+ mdma->clk = devm_clk_get(&pdev->dev, "sys");
+ if (IS_ERR(mdma->clk))
+ return PTR_ERR(mdma->clk);
+
+ ret = clk_prepare_enable(mdma->clk);
+ if (ret)
+ return ret;
+
+ dma_cap_zero(mdma->dma_dev.cap_mask);
+ dma_cap_set(DMA_SLAVE, mdma->dma_dev.cap_mask);
+ dma_cap_set(DMA_PRIVATE, mdma->dma_dev.cap_mask);
+ dma_cap_set(DMA_CYCLIC, mdma->dma_dev.cap_mask);
+ dma_cap_set(DMA_MEMCPY, mdma->dma_dev.cap_mask);
+
+ val = mdc_readl(mdma, MDC_GLOBAL_CONFIG_A);
+ mdma->nr_channels = (val >> MDC_GLOBAL_CONFIG_A_DMA_CONTEXTS_SHIFT) &
+ MDC_GLOBAL_CONFIG_A_DMA_CONTEXTS_MASK;
+ mdma->nr_threads =
+ 1 << ((val >> MDC_GLOBAL_CONFIG_A_THREAD_ID_WIDTH_SHIFT) &
+ MDC_GLOBAL_CONFIG_A_THREAD_ID_WIDTH_MASK);
+ mdma->bus_width =
+ (1 << ((val >> MDC_GLOBAL_CONFIG_A_SYS_DAT_WIDTH_SHIFT) &
+ MDC_GLOBAL_CONFIG_A_SYS_DAT_WIDTH_MASK)) / 8;
+ /*
+ * Although transfer sizes of up to MDC_TRANSFER_SIZE_MASK + 1 bytes
+ * are supported, this makes it possible for the value reported in
+ * MDC_ACTIVE_TRANSFER_SIZE to be ambiguous - an active transfer size
+ * of MDC_TRANSFER_SIZE_MASK may indicate either that 0 bytes or
+ * MDC_TRANSFER_SIZE_MASK + 1 bytes are remaining. To eliminate this
+ * ambiguity, restrict transfer sizes to one bus-width less than the
+ * actual maximum.
+ */
+ mdma->max_xfer_size = MDC_TRANSFER_SIZE_MASK + 1 - mdma->bus_width;
+
+ of_property_read_u32(pdev->dev.of_node, "dma-channels",
+ &mdma->nr_channels);
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "img,max-burst-multiplier",
+ &mdma->max_burst_mult);
+ if (ret)
+ goto disable_clk;
+
+ mdma->dma_dev.dev = &pdev->dev;
+ mdma->dma_dev.device_prep_slave_sg = mdc_prep_slave_sg;
+ mdma->dma_dev.device_prep_dma_cyclic = mdc_prep_dma_cyclic;
+ mdma->dma_dev.device_prep_dma_memcpy = mdc_prep_dma_memcpy;
+ mdma->dma_dev.device_alloc_chan_resources = mdc_alloc_chan_resources;
+ mdma->dma_dev.device_free_chan_resources = mdc_free_chan_resources;
+ mdma->dma_dev.device_tx_status = mdc_tx_status;
+ mdma->dma_dev.device_issue_pending = mdc_issue_pending;
+ mdma->dma_dev.device_terminate_all = mdc_terminate_all;
+ mdma->dma_dev.device_config = mdc_slave_config;
+
+ mdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ mdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+ for (i = 1; i <= mdma->bus_width; i <<= 1) {
+ mdma->dma_dev.src_addr_widths |= BIT(i);
+ mdma->dma_dev.dst_addr_widths |= BIT(i);
+ }
+
+ INIT_LIST_HEAD(&mdma->dma_dev.channels);
+ for (i = 0; i < mdma->nr_channels; i++) {
+ struct mdc_chan *mchan = &mdma->channels[i];
+
+ mchan->mdma = mdma;
+ mchan->chan_nr = i;
+ mchan->irq = platform_get_irq(pdev, i);
+ if (mchan->irq < 0) {
+ ret = mchan->irq;
+ goto disable_clk;
+ }
+ ret = devm_request_irq(&pdev->dev, mchan->irq, mdc_chan_irq,
+ IRQ_TYPE_LEVEL_HIGH,
+ dev_name(&pdev->dev), mchan);
+ if (ret < 0)
+ goto disable_clk;
+
+ mchan->vc.desc_free = mdc_desc_free;
+ vchan_init(&mchan->vc, &mdma->dma_dev);
+ }
+
+ mdma->desc_pool = dmam_pool_create(dev_name(&pdev->dev), &pdev->dev,
+ sizeof(struct mdc_hw_list_desc),
+ 4, 0);
+ if (!mdma->desc_pool) {
+ ret = -ENOMEM;
+ goto disable_clk;
+ }
+
+ ret = dma_async_device_register(&mdma->dma_dev);
+ if (ret)
+ goto disable_clk;
+
+ ret = of_dma_controller_register(pdev->dev.of_node, mdc_of_xlate, mdma);
+ if (ret)
+ goto unregister;
+
+ dev_info(&pdev->dev, "MDC with %u channels and %u threads\n",
+ mdma->nr_channels, mdma->nr_threads);
+
+ return 0;
+
+unregister:
+ dma_async_device_unregister(&mdma->dma_dev);
+disable_clk:
+ clk_disable_unprepare(mdma->clk);
+ return ret;
+}
+
+static int mdc_dma_remove(struct platform_device *pdev)
+{
+ struct mdc_dma *mdma = platform_get_drvdata(pdev);
+ struct mdc_chan *mchan, *next;
+
+ of_dma_controller_free(pdev->dev.of_node);
+ dma_async_device_unregister(&mdma->dma_dev);
+
+ list_for_each_entry_safe(mchan, next, &mdma->dma_dev.channels,
+ vc.chan.device_node) {
+ list_del(&mchan->vc.chan.device_node);
+
+ synchronize_irq(mchan->irq);
+ devm_free_irq(&pdev->dev, mchan->irq, mchan);
+
+ tasklet_kill(&mchan->vc.task);
+ }
+
+ clk_disable_unprepare(mdma->clk);
+
+ return 0;
+}
+
+static struct platform_driver mdc_dma_driver = {
+ .driver = {
+ .name = "img-mdc-dma",
+ .of_match_table = of_match_ptr(mdc_dma_of_match),
+ },
+ .probe = mdc_dma_probe,
+ .remove = mdc_dma_remove,
+};
+module_platform_driver(mdc_dma_driver);
+
+MODULE_DESCRIPTION("IMG Multi-threaded DMA Controller (MDC) driver");
+MODULE_AUTHOR("Andrew Bresticker <abrestic@chromium.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 10bbc0a675b0..eed405976ea9 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -230,11 +230,6 @@ static inline int is_imx1_dma(struct imxdma_engine *imxdma)
return imxdma->devtype == IMX1_DMA;
}
-static inline int is_imx21_dma(struct imxdma_engine *imxdma)
-{
- return imxdma->devtype == IMX21_DMA;
-}
-
static inline int is_imx27_dma(struct imxdma_engine *imxdma)
{
return imxdma->devtype == IMX27_DMA;
@@ -669,69 +664,67 @@ out:
}
-static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int imxdma_terminate_all(struct dma_chan *chan)
{
struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
- struct dma_slave_config *dmaengine_cfg = (void *)arg;
struct imxdma_engine *imxdma = imxdmac->imxdma;
unsigned long flags;
- unsigned int mode = 0;
-
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- imxdma_disable_hw(imxdmac);
-
- spin_lock_irqsave(&imxdma->lock, flags);
- list_splice_tail_init(&imxdmac->ld_active, &imxdmac->ld_free);
- list_splice_tail_init(&imxdmac->ld_queue, &imxdmac->ld_free);
- spin_unlock_irqrestore(&imxdma->lock, flags);
- return 0;
- case DMA_SLAVE_CONFIG:
- if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
- imxdmac->per_address = dmaengine_cfg->src_addr;
- imxdmac->watermark_level = dmaengine_cfg->src_maxburst;
- imxdmac->word_size = dmaengine_cfg->src_addr_width;
- } else {
- imxdmac->per_address = dmaengine_cfg->dst_addr;
- imxdmac->watermark_level = dmaengine_cfg->dst_maxburst;
- imxdmac->word_size = dmaengine_cfg->dst_addr_width;
- }
- switch (imxdmac->word_size) {
- case DMA_SLAVE_BUSWIDTH_1_BYTE:
- mode = IMX_DMA_MEMSIZE_8;
- break;
- case DMA_SLAVE_BUSWIDTH_2_BYTES:
- mode = IMX_DMA_MEMSIZE_16;
- break;
- default:
- case DMA_SLAVE_BUSWIDTH_4_BYTES:
- mode = IMX_DMA_MEMSIZE_32;
- break;
- }
+ imxdma_disable_hw(imxdmac);
- imxdmac->hw_chaining = 0;
+ spin_lock_irqsave(&imxdma->lock, flags);
+ list_splice_tail_init(&imxdmac->ld_active, &imxdmac->ld_free);
+ list_splice_tail_init(&imxdmac->ld_queue, &imxdmac->ld_free);
+ spin_unlock_irqrestore(&imxdma->lock, flags);
+ return 0;
+}
- imxdmac->ccr_from_device = (mode | IMX_DMA_TYPE_FIFO) |
- ((IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) << 2) |
- CCR_REN;
- imxdmac->ccr_to_device =
- (IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) |
- ((mode | IMX_DMA_TYPE_FIFO) << 2) | CCR_REN;
- imx_dmav1_writel(imxdma, imxdmac->dma_request,
- DMA_RSSR(imxdmac->channel));
+static int imxdma_config(struct dma_chan *chan,
+ struct dma_slave_config *dmaengine_cfg)
+{
+ struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
+ struct imxdma_engine *imxdma = imxdmac->imxdma;
+ unsigned int mode = 0;
- /* Set burst length */
- imx_dmav1_writel(imxdma, imxdmac->watermark_level *
- imxdmac->word_size, DMA_BLR(imxdmac->channel));
+ if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
+ imxdmac->per_address = dmaengine_cfg->src_addr;
+ imxdmac->watermark_level = dmaengine_cfg->src_maxburst;
+ imxdmac->word_size = dmaengine_cfg->src_addr_width;
+ } else {
+ imxdmac->per_address = dmaengine_cfg->dst_addr;
+ imxdmac->watermark_level = dmaengine_cfg->dst_maxburst;
+ imxdmac->word_size = dmaengine_cfg->dst_addr_width;
+ }
- return 0;
+ switch (imxdmac->word_size) {
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ mode = IMX_DMA_MEMSIZE_8;
+ break;
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ mode = IMX_DMA_MEMSIZE_16;
+ break;
default:
- return -ENOSYS;
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ mode = IMX_DMA_MEMSIZE_32;
+ break;
}
- return -EINVAL;
+ imxdmac->hw_chaining = 0;
+
+ imxdmac->ccr_from_device = (mode | IMX_DMA_TYPE_FIFO) |
+ ((IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) << 2) |
+ CCR_REN;
+ imxdmac->ccr_to_device =
+ (IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) |
+ ((mode | IMX_DMA_TYPE_FIFO) << 2) | CCR_REN;
+ imx_dmav1_writel(imxdma, imxdmac->dma_request,
+ DMA_RSSR(imxdmac->channel));
+
+ /* Set burst length */
+ imx_dmav1_writel(imxdma, imxdmac->watermark_level *
+ imxdmac->word_size, DMA_BLR(imxdmac->channel));
+
+ return 0;
}
static enum dma_status imxdma_tx_status(struct dma_chan *chan,
@@ -1184,7 +1177,8 @@ static int __init imxdma_probe(struct platform_device *pdev)
imxdma->dma_device.device_prep_dma_cyclic = imxdma_prep_dma_cyclic;
imxdma->dma_device.device_prep_dma_memcpy = imxdma_prep_dma_memcpy;
imxdma->dma_device.device_prep_interleaved_dma = imxdma_prep_dma_interleaved;
- imxdma->dma_device.device_control = imxdma_control;
+ imxdma->dma_device.device_config = imxdma_config;
+ imxdma->dma_device.device_terminate_all = imxdma_terminate_all;
imxdma->dma_device.device_issue_pending = imxdma_issue_pending;
platform_set_drvdata(pdev, imxdma);
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index d0df198f62e9..18c0a131e4e4 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -830,20 +830,29 @@ static int sdma_load_context(struct sdma_channel *sdmac)
return ret;
}
-static void sdma_disable_channel(struct sdma_channel *sdmac)
+static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
+{
+ return container_of(chan, struct sdma_channel, chan);
+}
+
+static int sdma_disable_channel(struct dma_chan *chan)
{
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
struct sdma_engine *sdma = sdmac->sdma;
int channel = sdmac->channel;
writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
sdmac->status = DMA_ERROR;
+
+ return 0;
}
-static int sdma_config_channel(struct sdma_channel *sdmac)
+static int sdma_config_channel(struct dma_chan *chan)
{
+ struct sdma_channel *sdmac = to_sdma_chan(chan);
int ret;
- sdma_disable_channel(sdmac);
+ sdma_disable_channel(chan);
sdmac->event_mask[0] = 0;
sdmac->event_mask[1] = 0;
@@ -935,11 +944,6 @@ out:
return ret;
}
-static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
-{
- return container_of(chan, struct sdma_channel, chan);
-}
-
static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
{
unsigned long flags;
@@ -1004,7 +1008,7 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
struct sdma_channel *sdmac = to_sdma_chan(chan);
struct sdma_engine *sdma = sdmac->sdma;
- sdma_disable_channel(sdmac);
+ sdma_disable_channel(chan);
if (sdmac->event_id0)
sdma_event_disable(sdmac, sdmac->event_id0);
@@ -1203,35 +1207,24 @@ err_out:
return NULL;
}
-static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int sdma_config(struct dma_chan *chan,
+ struct dma_slave_config *dmaengine_cfg)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
- struct dma_slave_config *dmaengine_cfg = (void *)arg;
-
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- sdma_disable_channel(sdmac);
- return 0;
- case DMA_SLAVE_CONFIG:
- if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
- sdmac->per_address = dmaengine_cfg->src_addr;
- sdmac->watermark_level = dmaengine_cfg->src_maxburst *
- dmaengine_cfg->src_addr_width;
- sdmac->word_size = dmaengine_cfg->src_addr_width;
- } else {
- sdmac->per_address = dmaengine_cfg->dst_addr;
- sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
- dmaengine_cfg->dst_addr_width;
- sdmac->word_size = dmaengine_cfg->dst_addr_width;
- }
- sdmac->direction = dmaengine_cfg->direction;
- return sdma_config_channel(sdmac);
- default:
- return -ENOSYS;
- }
- return -EINVAL;
+ if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
+ sdmac->per_address = dmaengine_cfg->src_addr;
+ sdmac->watermark_level = dmaengine_cfg->src_maxburst *
+ dmaengine_cfg->src_addr_width;
+ sdmac->word_size = dmaengine_cfg->src_addr_width;
+ } else {
+ sdmac->per_address = dmaengine_cfg->dst_addr;
+ sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
+ dmaengine_cfg->dst_addr_width;
+ sdmac->word_size = dmaengine_cfg->dst_addr_width;
+ }
+ sdmac->direction = dmaengine_cfg->direction;
+ return sdma_config_channel(chan);
}
static enum dma_status sdma_tx_status(struct dma_chan *chan,
@@ -1303,15 +1296,15 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
if (header->ram_code_start + header->ram_code_size > fw->size)
goto err_firmware;
switch (header->version_major) {
- case 1:
- sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
- break;
- case 2:
- sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
- break;
- default:
- dev_err(sdma->dev, "unknown firmware version\n");
- goto err_firmware;
+ case 1:
+ sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
+ break;
+ case 2:
+ sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
+ break;
+ default:
+ dev_err(sdma->dev, "unknown firmware version\n");
+ goto err_firmware;
}
addr = (void *)header + header->script_addrs_start;
@@ -1479,7 +1472,7 @@ static int sdma_probe(struct platform_device *pdev)
if (ret)
return ret;
- sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
+ sdma = devm_kzalloc(&pdev->dev, sizeof(*sdma), GFP_KERNEL);
if (!sdma)
return -ENOMEM;
@@ -1488,48 +1481,34 @@ static int sdma_probe(struct platform_device *pdev)
sdma->dev = &pdev->dev;
sdma->drvdata = drvdata;
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
- if (!iores || irq < 0) {
- ret = -EINVAL;
- goto err_irq;
- }
+ if (irq < 0)
+ return irq;
- if (!request_mem_region(iores->start, resource_size(iores), pdev->name)) {
- ret = -EBUSY;
- goto err_request_region;
- }
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ sdma->regs = devm_ioremap_resource(&pdev->dev, iores);
+ if (IS_ERR(sdma->regs))
+ return PTR_ERR(sdma->regs);
sdma->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
- if (IS_ERR(sdma->clk_ipg)) {
- ret = PTR_ERR(sdma->clk_ipg);
- goto err_clk;
- }
+ if (IS_ERR(sdma->clk_ipg))
+ return PTR_ERR(sdma->clk_ipg);
sdma->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
- if (IS_ERR(sdma->clk_ahb)) {
- ret = PTR_ERR(sdma->clk_ahb);
- goto err_clk;
- }
+ if (IS_ERR(sdma->clk_ahb))
+ return PTR_ERR(sdma->clk_ahb);
clk_prepare(sdma->clk_ipg);
clk_prepare(sdma->clk_ahb);
- sdma->regs = ioremap(iores->start, resource_size(iores));
- if (!sdma->regs) {
- ret = -ENOMEM;
- goto err_ioremap;
- }
-
- ret = request_irq(irq, sdma_int_handler, 0, "sdma", sdma);
+ ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma",
+ sdma);
if (ret)
- goto err_request_irq;
+ return ret;
sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL);
- if (!sdma->script_addrs) {
- ret = -ENOMEM;
- goto err_alloc;
- }
+ if (!sdma->script_addrs)
+ return -ENOMEM;
/* initially no scripts available */
saddr_arr = (s32 *)sdma->script_addrs;
@@ -1600,7 +1579,12 @@ static int sdma_probe(struct platform_device *pdev)
sdma->dma_device.device_tx_status = sdma_tx_status;
sdma->dma_device.device_prep_slave_sg = sdma_prep_slave_sg;
sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic;
- sdma->dma_device.device_control = sdma_control;
+ sdma->dma_device.device_config = sdma_config;
+ sdma->dma_device.device_terminate_all = sdma_disable_channel;
+ sdma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ sdma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ sdma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ sdma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
sdma->dma_device.device_issue_pending = sdma_issue_pending;
sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
dma_set_max_seg_size(sdma->dma_device.dev, 65535);
@@ -1629,38 +1613,22 @@ err_register:
dma_async_device_unregister(&sdma->dma_device);
err_init:
kfree(sdma->script_addrs);
-err_alloc:
- free_irq(irq, sdma);
-err_request_irq:
- iounmap(sdma->regs);
-err_ioremap:
-err_clk:
- release_mem_region(iores->start, resource_size(iores));
-err_request_region:
-err_irq:
- kfree(sdma);
return ret;
}
static int sdma_remove(struct platform_device *pdev)
{
struct sdma_engine *sdma = platform_get_drvdata(pdev);
- struct resource *iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- int irq = platform_get_irq(pdev, 0);
int i;
dma_async_device_unregister(&sdma->dma_device);
kfree(sdma->script_addrs);
- free_irq(irq, sdma);
- iounmap(sdma->regs);
- release_mem_region(iores->start, resource_size(iores));
/* Kill the tasklet */
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
struct sdma_channel *sdmac = &sdma->channel[i];
tasklet_kill(&sdmac->tasklet);
}
- kfree(sdma);
platform_set_drvdata(pdev, NULL);
dev_info(&pdev->dev, "Removed...\n");
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 1aab8130efa1..5aaead9b56f7 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -492,10 +492,10 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan,
return ret;
}
-static int dma_slave_control(struct dma_chan *chan, unsigned long arg)
+static int intel_mid_dma_config(struct dma_chan *chan,
+ struct dma_slave_config *slave)
{
struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
- struct dma_slave_config *slave = (struct dma_slave_config *)arg;
struct intel_mid_dma_slave *mid_slave;
BUG_ON(!midc);
@@ -509,28 +509,14 @@ static int dma_slave_control(struct dma_chan *chan, unsigned long arg)
midc->mid_slave = mid_slave;
return 0;
}
-/**
- * intel_mid_dma_device_control - DMA device control
- * @chan: chan for DMA control
- * @cmd: control cmd
- * @arg: cmd arg value
- *
- * Perform DMA control command
- */
-static int intel_mid_dma_device_control(struct dma_chan *chan,
- enum dma_ctrl_cmd cmd, unsigned long arg)
+
+static int intel_mid_dma_terminate_all(struct dma_chan *chan)
{
struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan);
struct middma_device *mid = to_middma_device(chan->device);
struct intel_mid_dma_desc *desc, *_desc;
union intel_mid_dma_cfg_lo cfg_lo;
- if (cmd == DMA_SLAVE_CONFIG)
- return dma_slave_control(chan, arg);
-
- if (cmd != DMA_TERMINATE_ALL)
- return -ENXIO;
-
spin_lock_bh(&midc->lock);
if (midc->busy == false) {
spin_unlock_bh(&midc->lock);
@@ -1148,7 +1134,8 @@ static int mid_setup_dma(struct pci_dev *pdev)
dma->common.device_prep_dma_memcpy = intel_mid_dma_prep_memcpy;
dma->common.device_issue_pending = intel_mid_dma_issue_pending;
dma->common.device_prep_slave_sg = intel_mid_dma_prep_slave_sg;
- dma->common.device_control = intel_mid_dma_device_control;
+ dma->common.device_config = intel_mid_dma_config;
+ dma->common.device_terminate_all = intel_mid_dma_terminate_all;
/*enable dma cntrl*/
iowrite32(REG_BIT0, dma->dma_base + DMA_CFG);
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index 32eae38291e5..77a6dcf25b98 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -214,6 +214,11 @@ static bool is_bwd_ioat(struct pci_dev *pdev)
case PCI_DEVICE_ID_INTEL_IOAT_BWD1:
case PCI_DEVICE_ID_INTEL_IOAT_BWD2:
case PCI_DEVICE_ID_INTEL_IOAT_BWD3:
+ /* even though not Atom, BDX-DE has same DMA silicon */
+ case PCI_DEVICE_ID_INTEL_IOAT_BDXDE0:
+ case PCI_DEVICE_ID_INTEL_IOAT_BDXDE1:
+ case PCI_DEVICE_ID_INTEL_IOAT_BDXDE2:
+ case PCI_DEVICE_ID_INTEL_IOAT_BDXDE3:
return true;
default:
return false;
@@ -489,6 +494,7 @@ static void ioat3_eh(struct ioat2_dma_chan *ioat)
struct ioat_chan_common *chan = &ioat->base;
struct pci_dev *pdev = to_pdev(chan);
struct ioat_dma_descriptor *hw;
+ struct dma_async_tx_descriptor *tx;
u64 phys_complete;
struct ioat_ring_ent *desc;
u32 err_handled = 0;
@@ -534,6 +540,16 @@ static void ioat3_eh(struct ioat2_dma_chan *ioat)
dev_err(to_dev(chan), "%s: fatal error (%x:%x)\n",
__func__, chanerr, err_handled);
BUG();
+ } else { /* cleanup the faulty descriptor */
+ tx = &desc->txd;
+ if (tx->cookie) {
+ dma_cookie_complete(tx);
+ dma_descriptor_unmap(tx);
+ if (tx->callback) {
+ tx->callback(tx->callback_param);
+ tx->callback = NULL;
+ }
+ }
}
writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
@@ -1300,7 +1316,8 @@ static int ioat_xor_val_self_test(struct ioatdma_device *device)
tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
- if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_COMPLETE) {
+ if (tmo == 0 ||
+ dma->device_tx_status(dma_chan, cookie, NULL) != DMA_COMPLETE) {
dev_err(dev, "Self-test xor timed out\n");
err = -ENODEV;
goto dma_unmap;
@@ -1366,7 +1383,8 @@ static int ioat_xor_val_self_test(struct ioatdma_device *device)
tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
- if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_COMPLETE) {
+ if (tmo == 0 ||
+ dma->device_tx_status(dma_chan, cookie, NULL) != DMA_COMPLETE) {
dev_err(dev, "Self-test validate timed out\n");
err = -ENODEV;
goto dma_unmap;
@@ -1418,7 +1436,8 @@ static int ioat_xor_val_self_test(struct ioatdma_device *device)
tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
- if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_COMPLETE) {
+ if (tmo == 0 ||
+ dma->device_tx_status(dma_chan, cookie, NULL) != DMA_COMPLETE) {
dev_err(dev, "Self-test 2nd validate timed out\n");
err = -ENODEV;
goto dma_unmap;
diff --git a/drivers/dma/ioat/hw.h b/drivers/dma/ioat/hw.h
index 62f83e983d8d..02177ecf09f8 100644
--- a/drivers/dma/ioat/hw.h
+++ b/drivers/dma/ioat/hw.h
@@ -57,6 +57,11 @@
#define PCI_DEVICE_ID_INTEL_IOAT_BWD2 0x0C52
#define PCI_DEVICE_ID_INTEL_IOAT_BWD3 0x0C53
+#define PCI_DEVICE_ID_INTEL_IOAT_BDXDE0 0x6f50
+#define PCI_DEVICE_ID_INTEL_IOAT_BDXDE1 0x6f51
+#define PCI_DEVICE_ID_INTEL_IOAT_BDXDE2 0x6f52
+#define PCI_DEVICE_ID_INTEL_IOAT_BDXDE3 0x6f53
+
#define IOAT_VER_1_2 0x12 /* Version 1.2 */
#define IOAT_VER_2_0 0x20 /* Version 2.0 */
#define IOAT_VER_3_0 0x30 /* Version 3.0 */
diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c
index 1d051cd045db..5501eb072d69 100644
--- a/drivers/dma/ioat/pci.c
+++ b/drivers/dma/ioat/pci.c
@@ -111,6 +111,11 @@ static struct pci_device_id ioat_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD2) },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD3) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE0) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE1) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE2) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE3) },
+
{ 0, }
};
MODULE_DEVICE_TABLE(pci, ioat_pci_tbl);
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index c2b017ad139d..b54f62de9232 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1398,76 +1398,81 @@ static void idmac_issue_pending(struct dma_chan *chan)
*/
}
-static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int idmac_pause(struct dma_chan *chan)
{
struct idmac_channel *ichan = to_idmac_chan(chan);
struct idmac *idmac = to_idmac(chan->device);
struct ipu *ipu = to_ipu(idmac);
struct list_head *list, *tmp;
unsigned long flags;
- int i;
- switch (cmd) {
- case DMA_PAUSE:
- spin_lock_irqsave(&ipu->lock, flags);
- ipu_ic_disable_task(ipu, chan->chan_id);
+ mutex_lock(&ichan->chan_mutex);
- /* Return all descriptors into "prepared" state */
- list_for_each_safe(list, tmp, &ichan->queue)
- list_del_init(list);
+ spin_lock_irqsave(&ipu->lock, flags);
+ ipu_ic_disable_task(ipu, chan->chan_id);
- ichan->sg[0] = NULL;
- ichan->sg[1] = NULL;
+ /* Return all descriptors into "prepared" state */
+ list_for_each_safe(list, tmp, &ichan->queue)
+ list_del_init(list);
- spin_unlock_irqrestore(&ipu->lock, flags);
+ ichan->sg[0] = NULL;
+ ichan->sg[1] = NULL;
- ichan->status = IPU_CHANNEL_INITIALIZED;
- break;
- case DMA_TERMINATE_ALL:
- ipu_disable_channel(idmac, ichan,
- ichan->status >= IPU_CHANNEL_ENABLED);
+ spin_unlock_irqrestore(&ipu->lock, flags);
- tasklet_disable(&ipu->tasklet);
+ ichan->status = IPU_CHANNEL_INITIALIZED;
- /* ichan->queue is modified in ISR, have to spinlock */
- spin_lock_irqsave(&ichan->lock, flags);
- list_splice_init(&ichan->queue, &ichan->free_list);
+ mutex_unlock(&ichan->chan_mutex);
- if (ichan->desc)
- for (i = 0; i < ichan->n_tx_desc; i++) {
- struct idmac_tx_desc *desc = ichan->desc + i;
- if (list_empty(&desc->list))
- /* Descriptor was prepared, but not submitted */
- list_add(&desc->list, &ichan->free_list);
+ return 0;
+}
- async_tx_clear_ack(&desc->txd);
- }
+static int __idmac_terminate_all(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+ struct ipu *ipu = to_ipu(idmac);
+ unsigned long flags;
+ int i;
- ichan->sg[0] = NULL;
- ichan->sg[1] = NULL;
- spin_unlock_irqrestore(&ichan->lock, flags);
+ ipu_disable_channel(idmac, ichan,
+ ichan->status >= IPU_CHANNEL_ENABLED);
- tasklet_enable(&ipu->tasklet);
+ tasklet_disable(&ipu->tasklet);
- ichan->status = IPU_CHANNEL_INITIALIZED;
- break;
- default:
- return -ENOSYS;
- }
+ /* ichan->queue is modified in ISR, have to spinlock */
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_splice_init(&ichan->queue, &ichan->free_list);
+
+ if (ichan->desc)
+ for (i = 0; i < ichan->n_tx_desc; i++) {
+ struct idmac_tx_desc *desc = ichan->desc + i;
+ if (list_empty(&desc->list))
+ /* Descriptor was prepared, but not submitted */
+ list_add(&desc->list, &ichan->free_list);
+
+ async_tx_clear_ack(&desc->txd);
+ }
+
+ ichan->sg[0] = NULL;
+ ichan->sg[1] = NULL;
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ tasklet_enable(&ipu->tasklet);
+
+ ichan->status = IPU_CHANNEL_INITIALIZED;
return 0;
}
-static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int idmac_terminate_all(struct dma_chan *chan)
{
struct idmac_channel *ichan = to_idmac_chan(chan);
int ret;
mutex_lock(&ichan->chan_mutex);
- ret = __idmac_control(chan, cmd, arg);
+ ret = __idmac_terminate_all(chan);
mutex_unlock(&ichan->chan_mutex);
@@ -1568,7 +1573,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
mutex_lock(&ichan->chan_mutex);
- __idmac_control(chan, DMA_TERMINATE_ALL, 0);
+ __idmac_terminate_all(chan);
if (ichan->status > IPU_CHANNEL_FREE) {
#ifdef DEBUG
@@ -1622,7 +1627,8 @@ static int __init ipu_idmac_init(struct ipu *ipu)
/* Compulsory for DMA_SLAVE fields */
dma->device_prep_slave_sg = idmac_prep_slave_sg;
- dma->device_control = idmac_control;
+ dma->device_pause = idmac_pause;
+ dma->device_terminate_all = idmac_terminate_all;
INIT_LIST_HEAD(&dma->channels);
for (i = 0; i < IPU_CHANNELS_NUM; i++) {
@@ -1655,7 +1661,7 @@ static void ipu_idmac_exit(struct ipu *ipu)
for (i = 0; i < IPU_CHANNELS_NUM; i++) {
struct idmac_channel *ichan = ipu->channel + i;
- idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0);
+ idmac_terminate_all(&ichan->dma_chan);
}
dma_async_device_unregister(&idmac->dma);
diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
index a1de14ab2c51..6f7f43529ccb 100644
--- a/drivers/dma/k3dma.c
+++ b/drivers/dma/k3dma.c
@@ -441,7 +441,7 @@ static struct dma_async_tx_descriptor *k3_dma_prep_memcpy(
num = 0;
if (!c->ccfg) {
- /* default is memtomem, without calling device_control */
+ /* default is memtomem, without calling device_config */
c->ccfg = CX_CFG_SRCINCR | CX_CFG_DSTINCR | CX_CFG_EN;
c->ccfg |= (0xf << 20) | (0xf << 24); /* burst = 16 */
c->ccfg |= (0x3 << 12) | (0x3 << 16); /* width = 64 bit */
@@ -523,112 +523,126 @@ static struct dma_async_tx_descriptor *k3_dma_prep_slave_sg(
return vchan_tx_prep(&c->vc, &ds->vd, flags);
}
-static int k3_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int k3_dma_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
+{
+ struct k3_dma_chan *c = to_k3_chan(chan);
+ u32 maxburst = 0, val = 0;
+ enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
+
+ if (cfg == NULL)
+ return -EINVAL;
+ c->dir = cfg->direction;
+ if (c->dir == DMA_DEV_TO_MEM) {
+ c->ccfg = CX_CFG_DSTINCR;
+ c->dev_addr = cfg->src_addr;
+ maxburst = cfg->src_maxburst;
+ width = cfg->src_addr_width;
+ } else if (c->dir == DMA_MEM_TO_DEV) {
+ c->ccfg = CX_CFG_SRCINCR;
+ c->dev_addr = cfg->dst_addr;
+ maxburst = cfg->dst_maxburst;
+ width = cfg->dst_addr_width;
+ }
+ switch (width) {
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ case DMA_SLAVE_BUSWIDTH_8_BYTES:
+ val = __ffs(width);
+ break;
+ default:
+ val = 3;
+ break;
+ }
+ c->ccfg |= (val << 12) | (val << 16);
+
+ if ((maxburst == 0) || (maxburst > 16))
+ val = 16;
+ else
+ val = maxburst - 1;
+ c->ccfg |= (val << 20) | (val << 24);
+ c->ccfg |= CX_CFG_MEM2PER | CX_CFG_EN;
+
+ /* specific request line */
+ c->ccfg |= c->vc.chan.chan_id << 4;
+
+ return 0;
+}
+
+static int k3_dma_terminate_all(struct dma_chan *chan)
{
struct k3_dma_chan *c = to_k3_chan(chan);
struct k3_dma_dev *d = to_k3_dma(chan->device);
- struct dma_slave_config *cfg = (void *)arg;
struct k3_dma_phy *p = c->phy;
unsigned long flags;
- u32 maxburst = 0, val = 0;
- enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
LIST_HEAD(head);
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- if (cfg == NULL)
- return -EINVAL;
- c->dir = cfg->direction;
- if (c->dir == DMA_DEV_TO_MEM) {
- c->ccfg = CX_CFG_DSTINCR;
- c->dev_addr = cfg->src_addr;
- maxburst = cfg->src_maxburst;
- width = cfg->src_addr_width;
- } else if (c->dir == DMA_MEM_TO_DEV) {
- c->ccfg = CX_CFG_SRCINCR;
- c->dev_addr = cfg->dst_addr;
- maxburst = cfg->dst_maxburst;
- width = cfg->dst_addr_width;
- }
- switch (width) {
- case DMA_SLAVE_BUSWIDTH_1_BYTE:
- case DMA_SLAVE_BUSWIDTH_2_BYTES:
- case DMA_SLAVE_BUSWIDTH_4_BYTES:
- case DMA_SLAVE_BUSWIDTH_8_BYTES:
- val = __ffs(width);
- break;
- default:
- val = 3;
- break;
- }
- c->ccfg |= (val << 12) | (val << 16);
+ dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc);
- if ((maxburst == 0) || (maxburst > 16))
- val = 16;
- else
- val = maxburst - 1;
- c->ccfg |= (val << 20) | (val << 24);
- c->ccfg |= CX_CFG_MEM2PER | CX_CFG_EN;
+ /* Prevent this channel being scheduled */
+ spin_lock(&d->lock);
+ list_del_init(&c->node);
+ spin_unlock(&d->lock);
- /* specific request line */
- c->ccfg |= c->vc.chan.chan_id << 4;
- break;
+ /* Clear the tx descriptor lists */
+ spin_lock_irqsave(&c->vc.lock, flags);
+ vchan_get_all_descriptors(&c->vc, &head);
+ if (p) {
+ /* vchan is assigned to a pchan - stop the channel */
+ k3_dma_terminate_chan(p, d);
+ c->phy = NULL;
+ p->vchan = NULL;
+ p->ds_run = p->ds_done = NULL;
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+ vchan_dma_desc_free_list(&c->vc, &head);
- case DMA_TERMINATE_ALL:
- dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc);
+ return 0;
+}
- /* Prevent this channel being scheduled */
- spin_lock(&d->lock);
- list_del_init(&c->node);
- spin_unlock(&d->lock);
+static int k3_dma_transfer_pause(struct dma_chan *chan)
+{
+ struct k3_dma_chan *c = to_k3_chan(chan);
+ struct k3_dma_dev *d = to_k3_dma(chan->device);
+ struct k3_dma_phy *p = c->phy;
- /* Clear the tx descriptor lists */
- spin_lock_irqsave(&c->vc.lock, flags);
- vchan_get_all_descriptors(&c->vc, &head);
+ dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc);
+ if (c->status == DMA_IN_PROGRESS) {
+ c->status = DMA_PAUSED;
if (p) {
- /* vchan is assigned to a pchan - stop the channel */
- k3_dma_terminate_chan(p, d);
- c->phy = NULL;
- p->vchan = NULL;
- p->ds_run = p->ds_done = NULL;
+ k3_dma_pause_dma(p, false);
+ } else {
+ spin_lock(&d->lock);
+ list_del_init(&c->node);
+ spin_unlock(&d->lock);
}
- spin_unlock_irqrestore(&c->vc.lock, flags);
- vchan_dma_desc_free_list(&c->vc, &head);
- break;
+ }
- case DMA_PAUSE:
- dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc);
- if (c->status == DMA_IN_PROGRESS) {
- c->status = DMA_PAUSED;
- if (p) {
- k3_dma_pause_dma(p, false);
- } else {
- spin_lock(&d->lock);
- list_del_init(&c->node);
- spin_unlock(&d->lock);
- }
- }
- break;
+ return 0;
+}
- case DMA_RESUME:
- dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc);
- spin_lock_irqsave(&c->vc.lock, flags);
- if (c->status == DMA_PAUSED) {
- c->status = DMA_IN_PROGRESS;
- if (p) {
- k3_dma_pause_dma(p, true);
- } else if (!list_empty(&c->vc.desc_issued)) {
- spin_lock(&d->lock);
- list_add_tail(&c->node, &d->chan_pending);
- spin_unlock(&d->lock);
- }
+static int k3_dma_transfer_resume(struct dma_chan *chan)
+{
+ struct k3_dma_chan *c = to_k3_chan(chan);
+ struct k3_dma_dev *d = to_k3_dma(chan->device);
+ struct k3_dma_phy *p = c->phy;
+ unsigned long flags;
+
+ dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc);
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (c->status == DMA_PAUSED) {
+ c->status = DMA_IN_PROGRESS;
+ if (p) {
+ k3_dma_pause_dma(p, true);
+ } else if (!list_empty(&c->vc.desc_issued)) {
+ spin_lock(&d->lock);
+ list_add_tail(&c->node, &d->chan_pending);
+ spin_unlock(&d->lock);
}
- spin_unlock_irqrestore(&c->vc.lock, flags);
- break;
- default:
- return -ENXIO;
}
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+
return 0;
}
@@ -720,7 +734,10 @@ static int k3_dma_probe(struct platform_device *op)
d->slave.device_prep_dma_memcpy = k3_dma_prep_memcpy;
d->slave.device_prep_slave_sg = k3_dma_prep_slave_sg;
d->slave.device_issue_pending = k3_dma_issue_pending;
- d->slave.device_control = k3_dma_control;
+ d->slave.device_config = k3_dma_config;
+ d->slave.device_pause = k3_dma_transfer_pause;
+ d->slave.device_resume = k3_dma_transfer_resume;
+ d->slave.device_terminate_all = k3_dma_terminate_all;
d->slave.copy_align = DMA_ALIGN;
/* init virtual channel */
@@ -787,7 +804,7 @@ static int k3_dma_remove(struct platform_device *op)
}
#ifdef CONFIG_PM_SLEEP
-static int k3_dma_suspend(struct device *dev)
+static int k3_dma_suspend_dev(struct device *dev)
{
struct k3_dma_dev *d = dev_get_drvdata(dev);
u32 stat = 0;
@@ -803,7 +820,7 @@ static int k3_dma_suspend(struct device *dev)
return 0;
}
-static int k3_dma_resume(struct device *dev)
+static int k3_dma_resume_dev(struct device *dev)
{
struct k3_dma_dev *d = dev_get_drvdata(dev);
int ret = 0;
@@ -818,7 +835,7 @@ static int k3_dma_resume(struct device *dev)
}
#endif
-static SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend, k3_dma_resume);
+static SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend_dev, k3_dma_resume_dev);
static struct platform_driver k3_pdma_driver = {
.driver = {
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 8b8952f35e6c..8926f271904e 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -683,68 +683,70 @@ fail:
return NULL;
}
-static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int mmp_pdma_config(struct dma_chan *dchan,
+ struct dma_slave_config *cfg)
{
struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
- struct dma_slave_config *cfg = (void *)arg;
- unsigned long flags;
u32 maxburst = 0, addr = 0;
enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
if (!dchan)
return -EINVAL;
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- disable_chan(chan->phy);
- mmp_pdma_free_phy(chan);
- spin_lock_irqsave(&chan->desc_lock, flags);
- mmp_pdma_free_desc_list(chan, &chan->chain_pending);
- mmp_pdma_free_desc_list(chan, &chan->chain_running);
- spin_unlock_irqrestore(&chan->desc_lock, flags);
- chan->idle = true;
- break;
- case DMA_SLAVE_CONFIG:
- if (cfg->direction == DMA_DEV_TO_MEM) {
- chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC;
- maxburst = cfg->src_maxburst;
- width = cfg->src_addr_width;
- addr = cfg->src_addr;
- } else if (cfg->direction == DMA_MEM_TO_DEV) {
- chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
- maxburst = cfg->dst_maxburst;
- width = cfg->dst_addr_width;
- addr = cfg->dst_addr;
- }
-
- if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
- chan->dcmd |= DCMD_WIDTH1;
- else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
- chan->dcmd |= DCMD_WIDTH2;
- else if (width == DMA_SLAVE_BUSWIDTH_4_BYTES)
- chan->dcmd |= DCMD_WIDTH4;
-
- if (maxburst == 8)
- chan->dcmd |= DCMD_BURST8;
- else if (maxburst == 16)
- chan->dcmd |= DCMD_BURST16;
- else if (maxburst == 32)
- chan->dcmd |= DCMD_BURST32;
-
- chan->dir = cfg->direction;
- chan->dev_addr = addr;
- /* FIXME: drivers should be ported over to use the filter
- * function. Once that's done, the following two lines can
- * be removed.
- */
- if (cfg->slave_id)
- chan->drcmr = cfg->slave_id;
- break;
- default:
- return -ENOSYS;
+ if (cfg->direction == DMA_DEV_TO_MEM) {
+ chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC;
+ maxburst = cfg->src_maxburst;
+ width = cfg->src_addr_width;
+ addr = cfg->src_addr;
+ } else if (cfg->direction == DMA_MEM_TO_DEV) {
+ chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
+ maxburst = cfg->dst_maxburst;
+ width = cfg->dst_addr_width;
+ addr = cfg->dst_addr;
}
+ if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
+ chan->dcmd |= DCMD_WIDTH1;
+ else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
+ chan->dcmd |= DCMD_WIDTH2;
+ else if (width == DMA_SLAVE_BUSWIDTH_4_BYTES)
+ chan->dcmd |= DCMD_WIDTH4;
+
+ if (maxburst == 8)
+ chan->dcmd |= DCMD_BURST8;
+ else if (maxburst == 16)
+ chan->dcmd |= DCMD_BURST16;
+ else if (maxburst == 32)
+ chan->dcmd |= DCMD_BURST32;
+
+ chan->dir = cfg->direction;
+ chan->dev_addr = addr;
+ /* FIXME: drivers should be ported over to use the filter
+ * function. Once that's done, the following two lines can
+ * be removed.
+ */
+ if (cfg->slave_id)
+ chan->drcmr = cfg->slave_id;
+
+ return 0;
+}
+
+static int mmp_pdma_terminate_all(struct dma_chan *dchan)
+{
+ struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+ unsigned long flags;
+
+ if (!dchan)
+ return -EINVAL;
+
+ disable_chan(chan->phy);
+ mmp_pdma_free_phy(chan);
+ spin_lock_irqsave(&chan->desc_lock, flags);
+ mmp_pdma_free_desc_list(chan, &chan->chain_pending);
+ mmp_pdma_free_desc_list(chan, &chan->chain_running);
+ spin_unlock_irqrestore(&chan->desc_lock, flags);
+ chan->idle = true;
+
return 0;
}
@@ -1061,7 +1063,8 @@ static int mmp_pdma_probe(struct platform_device *op)
pdev->device.device_prep_slave_sg = mmp_pdma_prep_slave_sg;
pdev->device.device_prep_dma_cyclic = mmp_pdma_prep_dma_cyclic;
pdev->device.device_issue_pending = mmp_pdma_issue_pending;
- pdev->device.device_control = mmp_pdma_control;
+ pdev->device.device_config = mmp_pdma_config;
+ pdev->device.device_terminate_all = mmp_pdma_terminate_all;
pdev->device.copy_align = PDMA_ALIGNMENT;
if (pdev->dev->coherent_dma_mask)
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index bfb46957c3dc..70c2fa9963cd 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -19,7 +19,6 @@
#include <linux/dmaengine.h>
#include <linux/platform_device.h>
#include <linux/device.h>
-#include <mach/regs-icu.h>
#include <linux/platform_data/dma-mmp_tdma.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
@@ -164,33 +163,46 @@ static void mmp_tdma_enable_chan(struct mmp_tdma_chan *tdmac)
tdmac->status = DMA_IN_PROGRESS;
}
-static void mmp_tdma_disable_chan(struct mmp_tdma_chan *tdmac)
+static int mmp_tdma_disable_chan(struct dma_chan *chan)
{
+ struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
+
writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN,
tdmac->reg_base + TDCR);
tdmac->status = DMA_COMPLETE;
+
+ return 0;
}
-static void mmp_tdma_resume_chan(struct mmp_tdma_chan *tdmac)
+static int mmp_tdma_resume_chan(struct dma_chan *chan)
{
+ struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
+
writel(readl(tdmac->reg_base + TDCR) | TDCR_CHANEN,
tdmac->reg_base + TDCR);
tdmac->status = DMA_IN_PROGRESS;
+
+ return 0;
}
-static void mmp_tdma_pause_chan(struct mmp_tdma_chan *tdmac)
+static int mmp_tdma_pause_chan(struct dma_chan *chan)
{
+ struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
+
writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN,
tdmac->reg_base + TDCR);
tdmac->status = DMA_PAUSED;
+
+ return 0;
}
-static int mmp_tdma_config_chan(struct mmp_tdma_chan *tdmac)
+static int mmp_tdma_config_chan(struct dma_chan *chan)
{
+ struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
unsigned int tdcr = 0;
- mmp_tdma_disable_chan(tdmac);
+ mmp_tdma_disable_chan(chan);
if (tdmac->dir == DMA_MEM_TO_DEV)
tdcr = TDCR_DSTDIR_ADDR_HOLD | TDCR_SRCDIR_ADDR_INC;
@@ -452,42 +464,34 @@ err_out:
return NULL;
}
-static int mmp_tdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int mmp_tdma_terminate_all(struct dma_chan *chan)
{
struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
- struct dma_slave_config *dmaengine_cfg = (void *)arg;
- int ret = 0;
-
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- mmp_tdma_disable_chan(tdmac);
- /* disable interrupt */
- mmp_tdma_enable_irq(tdmac, false);
- break;
- case DMA_PAUSE:
- mmp_tdma_pause_chan(tdmac);
- break;
- case DMA_RESUME:
- mmp_tdma_resume_chan(tdmac);
- break;
- case DMA_SLAVE_CONFIG:
- if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
- tdmac->dev_addr = dmaengine_cfg->src_addr;
- tdmac->burst_sz = dmaengine_cfg->src_maxburst;
- tdmac->buswidth = dmaengine_cfg->src_addr_width;
- } else {
- tdmac->dev_addr = dmaengine_cfg->dst_addr;
- tdmac->burst_sz = dmaengine_cfg->dst_maxburst;
- tdmac->buswidth = dmaengine_cfg->dst_addr_width;
- }
- tdmac->dir = dmaengine_cfg->direction;
- return mmp_tdma_config_chan(tdmac);
- default:
- ret = -ENOSYS;
+
+ mmp_tdma_disable_chan(chan);
+ /* disable interrupt */
+ mmp_tdma_enable_irq(tdmac, false);
+
+ return 0;
+}
+
+static int mmp_tdma_config(struct dma_chan *chan,
+ struct dma_slave_config *dmaengine_cfg)
+{
+ struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
+
+ if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
+ tdmac->dev_addr = dmaengine_cfg->src_addr;
+ tdmac->burst_sz = dmaengine_cfg->src_maxburst;
+ tdmac->buswidth = dmaengine_cfg->src_addr_width;
+ } else {
+ tdmac->dev_addr = dmaengine_cfg->dst_addr;
+ tdmac->burst_sz = dmaengine_cfg->dst_maxburst;
+ tdmac->buswidth = dmaengine_cfg->dst_addr_width;
}
+ tdmac->dir = dmaengine_cfg->direction;
- return ret;
+ return mmp_tdma_config_chan(chan);
}
static enum dma_status mmp_tdma_tx_status(struct dma_chan *chan,
@@ -668,7 +672,10 @@ static int mmp_tdma_probe(struct platform_device *pdev)
tdev->device.device_prep_dma_cyclic = mmp_tdma_prep_dma_cyclic;
tdev->device.device_tx_status = mmp_tdma_tx_status;
tdev->device.device_issue_pending = mmp_tdma_issue_pending;
- tdev->device.device_control = mmp_tdma_control;
+ tdev->device.device_config = mmp_tdma_config;
+ tdev->device.device_pause = mmp_tdma_pause_chan;
+ tdev->device.device_resume = mmp_tdma_resume_chan;
+ tdev->device.device_terminate_all = mmp_tdma_terminate_all;
tdev->device.copy_align = TDMA_ALIGNMENT;
dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c
index 53032bac06e0..15cab7d79525 100644
--- a/drivers/dma/moxart-dma.c
+++ b/drivers/dma/moxart-dma.c
@@ -263,28 +263,6 @@ static int moxart_slave_config(struct dma_chan *chan,
return 0;
}
-static int moxart_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- int ret = 0;
-
- switch (cmd) {
- case DMA_PAUSE:
- case DMA_RESUME:
- return -EINVAL;
- case DMA_TERMINATE_ALL:
- moxart_terminate_all(chan);
- break;
- case DMA_SLAVE_CONFIG:
- ret = moxart_slave_config(chan, (struct dma_slave_config *)arg);
- break;
- default:
- ret = -ENOSYS;
- }
-
- return ret;
-}
-
static struct dma_async_tx_descriptor *moxart_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction dir,
@@ -531,7 +509,8 @@ static void moxart_dma_init(struct dma_device *dma, struct device *dev)
dma->device_free_chan_resources = moxart_free_chan_resources;
dma->device_issue_pending = moxart_issue_pending;
dma->device_tx_status = moxart_tx_status;
- dma->device_control = moxart_control;
+ dma->device_config = moxart_slave_config;
+ dma->device_terminate_all = moxart_terminate_all;
dma->dev = dev;
INIT_LIST_HEAD(&dma->channels);
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index 01bec4023de2..57d2457545f3 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -800,79 +800,69 @@ err_prep:
return NULL;
}
-static int mpc_dma_device_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int mpc_dma_device_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
{
- struct mpc_dma_chan *mchan;
- struct mpc_dma *mdma;
- struct dma_slave_config *cfg;
+ struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
unsigned long flags;
- mchan = dma_chan_to_mpc_dma_chan(chan);
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- /* Disable channel requests */
- mdma = dma_chan_to_mpc_dma(chan);
-
- spin_lock_irqsave(&mchan->lock, flags);
-
- out_8(&mdma->regs->dmacerq, chan->chan_id);
- list_splice_tail_init(&mchan->prepared, &mchan->free);
- list_splice_tail_init(&mchan->queued, &mchan->free);
- list_splice_tail_init(&mchan->active, &mchan->free);
-
- spin_unlock_irqrestore(&mchan->lock, flags);
+ /*
+ * Software constraints:
+ * - only transfers between a peripheral device and
+ * memory are supported;
+ * - only peripheral devices with 4-byte FIFO access register
+ * are supported;
+ * - minimal transfer chunk is 4 bytes and consequently
+ * source and destination addresses must be 4-byte aligned
+ * and transfer size must be aligned on (4 * maxburst)
+ * boundary;
+ * - during the transfer RAM address is being incremented by
+ * the size of minimal transfer chunk;
+ * - peripheral port's address is constant during the transfer.
+ */
- return 0;
+ if (cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
+ cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
+ !IS_ALIGNED(cfg->src_addr, 4) ||
+ !IS_ALIGNED(cfg->dst_addr, 4)) {
+ return -EINVAL;
+ }
- case DMA_SLAVE_CONFIG:
- /*
- * Software constraints:
- * - only transfers between a peripheral device and
- * memory are supported;
- * - only peripheral devices with 4-byte FIFO access register
- * are supported;
- * - minimal transfer chunk is 4 bytes and consequently
- * source and destination addresses must be 4-byte aligned
- * and transfer size must be aligned on (4 * maxburst)
- * boundary;
- * - during the transfer RAM address is being incremented by
- * the size of minimal transfer chunk;
- * - peripheral port's address is constant during the transfer.
- */
+ spin_lock_irqsave(&mchan->lock, flags);
- cfg = (void *)arg;
+ mchan->src_per_paddr = cfg->src_addr;
+ mchan->src_tcd_nunits = cfg->src_maxburst;
+ mchan->dst_per_paddr = cfg->dst_addr;
+ mchan->dst_tcd_nunits = cfg->dst_maxburst;
- if (cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
- cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
- !IS_ALIGNED(cfg->src_addr, 4) ||
- !IS_ALIGNED(cfg->dst_addr, 4)) {
- return -EINVAL;
- }
+ /* Apply defaults */
+ if (mchan->src_tcd_nunits == 0)
+ mchan->src_tcd_nunits = 1;
+ if (mchan->dst_tcd_nunits == 0)
+ mchan->dst_tcd_nunits = 1;
- spin_lock_irqsave(&mchan->lock, flags);
+ spin_unlock_irqrestore(&mchan->lock, flags);
- mchan->src_per_paddr = cfg->src_addr;
- mchan->src_tcd_nunits = cfg->src_maxburst;
- mchan->dst_per_paddr = cfg->dst_addr;
- mchan->dst_tcd_nunits = cfg->dst_maxburst;
+ return 0;
+}
- /* Apply defaults */
- if (mchan->src_tcd_nunits == 0)
- mchan->src_tcd_nunits = 1;
- if (mchan->dst_tcd_nunits == 0)
- mchan->dst_tcd_nunits = 1;
+static int mpc_dma_device_terminate_all(struct dma_chan *chan)
+{
+ struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
+ struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
+ unsigned long flags;
- spin_unlock_irqrestore(&mchan->lock, flags);
+ /* Disable channel requests */
+ spin_lock_irqsave(&mchan->lock, flags);
- return 0;
+ out_8(&mdma->regs->dmacerq, chan->chan_id);
+ list_splice_tail_init(&mchan->prepared, &mchan->free);
+ list_splice_tail_init(&mchan->queued, &mchan->free);
+ list_splice_tail_init(&mchan->active, &mchan->free);
- default:
- /* Unknown command */
- break;
- }
+ spin_unlock_irqrestore(&mchan->lock, flags);
- return -ENXIO;
+ return 0;
}
static int mpc_dma_probe(struct platform_device *op)
@@ -963,7 +953,8 @@ static int mpc_dma_probe(struct platform_device *op)
dma->device_tx_status = mpc_dma_tx_status;
dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy;
dma->device_prep_slave_sg = mpc_dma_prep_slave_sg;
- dma->device_control = mpc_dma_device_control;
+ dma->device_config = mpc_dma_device_config;
+ dma->device_terminate_all = mpc_dma_device_terminate_all;
INIT_LIST_HEAD(&dma->channels);
dma_cap_set(DMA_MEMCPY, dma->cap_mask);
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index d7ac558c2c1c..b03e8137b918 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -928,14 +928,6 @@ out:
return err;
}
-/* This driver does not implement any of the optional DMA operations. */
-static int
-mv_xor_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- return -ENOSYS;
-}
-
static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
{
struct dma_chan *chan, *_chan;
@@ -1008,7 +1000,6 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
dma_dev->device_free_chan_resources = mv_xor_free_chan_resources;
dma_dev->device_tx_status = mv_xor_status;
dma_dev->device_issue_pending = mv_xor_issue_pending;
- dma_dev->device_control = mv_xor_control;
dma_dev->dev = &pdev->dev;
/* set prep routines based on capability */
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 5ea61201dbf0..829ec686dac3 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -202,8 +202,9 @@ static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
return container_of(chan, struct mxs_dma_chan, chan);
}
-static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
+static void mxs_dma_reset_chan(struct dma_chan *chan)
{
+ struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int chan_id = mxs_chan->chan.chan_id;
@@ -250,8 +251,9 @@ static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
mxs_chan->status = DMA_COMPLETE;
}
-static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
+static void mxs_dma_enable_chan(struct dma_chan *chan)
{
+ struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int chan_id = mxs_chan->chan.chan_id;
@@ -272,13 +274,16 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
mxs_chan->reset = false;
}
-static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
+static void mxs_dma_disable_chan(struct dma_chan *chan)
{
+ struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
+
mxs_chan->status = DMA_COMPLETE;
}
-static void mxs_dma_pause_chan(struct mxs_dma_chan *mxs_chan)
+static int mxs_dma_pause_chan(struct dma_chan *chan)
{
+ struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int chan_id = mxs_chan->chan.chan_id;
@@ -291,10 +296,12 @@ static void mxs_dma_pause_chan(struct mxs_dma_chan *mxs_chan)
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
mxs_chan->status = DMA_PAUSED;
+ return 0;
}
-static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
+static int mxs_dma_resume_chan(struct dma_chan *chan)
{
+ struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int chan_id = mxs_chan->chan.chan_id;
@@ -307,6 +314,7 @@ static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_CLR);
mxs_chan->status = DMA_IN_PROGRESS;
+ return 0;
}
static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
@@ -383,7 +391,7 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
"%s: error in channel %d\n", __func__,
chan);
mxs_chan->status = DMA_ERROR;
- mxs_dma_reset_chan(mxs_chan);
+ mxs_dma_reset_chan(&mxs_chan->chan);
} else if (mxs_chan->status != DMA_COMPLETE) {
if (mxs_chan->flags & MXS_DMA_SG_LOOP) {
mxs_chan->status = DMA_IN_PROGRESS;
@@ -432,7 +440,7 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
if (ret)
goto err_clk;
- mxs_dma_reset_chan(mxs_chan);
+ mxs_dma_reset_chan(chan);
dma_async_tx_descriptor_init(&mxs_chan->desc, chan);
mxs_chan->desc.tx_submit = mxs_dma_tx_submit;
@@ -456,7 +464,7 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
- mxs_dma_disable_chan(mxs_chan);
+ mxs_dma_disable_chan(chan);
free_irq(mxs_chan->chan_irq, mxs_dma);
@@ -651,28 +659,12 @@ err_out:
return NULL;
}
-static int mxs_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int mxs_dma_terminate_all(struct dma_chan *chan)
{
- struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
- int ret = 0;
-
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- mxs_dma_reset_chan(mxs_chan);
- mxs_dma_disable_chan(mxs_chan);
- break;
- case DMA_PAUSE:
- mxs_dma_pause_chan(mxs_chan);
- break;
- case DMA_RESUME:
- mxs_dma_resume_chan(mxs_chan);
- break;
- default:
- ret = -ENOSYS;
- }
+ mxs_dma_reset_chan(chan);
+ mxs_dma_disable_chan(chan);
- return ret;
+ return 0;
}
static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,
@@ -701,13 +693,6 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,
return mxs_chan->status;
}
-static void mxs_dma_issue_pending(struct dma_chan *chan)
-{
- struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
-
- mxs_dma_enable_chan(mxs_chan);
-}
-
static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
{
int ret;
@@ -860,8 +845,14 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
mxs_dma->dma_device.device_tx_status = mxs_dma_tx_status;
mxs_dma->dma_device.device_prep_slave_sg = mxs_dma_prep_slave_sg;
mxs_dma->dma_device.device_prep_dma_cyclic = mxs_dma_prep_dma_cyclic;
- mxs_dma->dma_device.device_control = mxs_dma_control;
- mxs_dma->dma_device.device_issue_pending = mxs_dma_issue_pending;
+ mxs_dma->dma_device.device_pause = mxs_dma_pause_chan;
+ mxs_dma->dma_device.device_resume = mxs_dma_resume_chan;
+ mxs_dma->dma_device.device_terminate_all = mxs_dma_terminate_all;
+ mxs_dma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ mxs_dma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ mxs_dma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ mxs_dma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+ mxs_dma->dma_device.device_issue_pending = mxs_dma_enable_chan;
ret = dma_async_device_register(&mxs_dma->dma_device);
if (ret) {
diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c
index d7d61e1a01c3..88b77c98365d 100644
--- a/drivers/dma/nbpfaxi.c
+++ b/drivers/dma/nbpfaxi.c
@@ -504,7 +504,7 @@ static int nbpf_prep_one(struct nbpf_link_desc *ldesc,
* pauses DMA and reads out data received via DMA as well as those left
* in the Rx FIFO. For this to work with the RAM side using burst
* transfers we enable the SBE bit and terminate the transfer in our
- * DMA_PAUSE handler.
+ * .device_pause handler.
*/
mem_xfer = nbpf_xfer_ds(chan->nbpf, size);
@@ -565,13 +565,6 @@ static void nbpf_configure(struct nbpf_device *nbpf)
nbpf_write(nbpf, NBPF_CTRL, NBPF_CTRL_LVINT);
}
-static void nbpf_pause(struct nbpf_channel *chan)
-{
- nbpf_chan_write(chan, NBPF_CHAN_CTRL, NBPF_CHAN_CTRL_SETSUS);
- /* See comment in nbpf_prep_one() */
- nbpf_chan_write(chan, NBPF_CHAN_CTRL, NBPF_CHAN_CTRL_CLREN);
-}
-
/* Generic part */
/* DMA ENGINE functions */
@@ -837,54 +830,58 @@ static void nbpf_chan_idle(struct nbpf_channel *chan)
}
}
-static int nbpf_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int nbpf_pause(struct dma_chan *dchan)
{
struct nbpf_channel *chan = nbpf_to_chan(dchan);
- struct dma_slave_config *config;
- dev_dbg(dchan->device->dev, "Entry %s(%d)\n", __func__, cmd);
+ dev_dbg(dchan->device->dev, "Entry %s\n", __func__);
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- dev_dbg(dchan->device->dev, "Terminating\n");
- nbpf_chan_halt(chan);
- nbpf_chan_idle(chan);
- break;
+ chan->paused = true;
+ nbpf_chan_write(chan, NBPF_CHAN_CTRL, NBPF_CHAN_CTRL_SETSUS);
+ /* See comment in nbpf_prep_one() */
+ nbpf_chan_write(chan, NBPF_CHAN_CTRL, NBPF_CHAN_CTRL_CLREN);
- case DMA_SLAVE_CONFIG:
- if (!arg)
- return -EINVAL;
- config = (struct dma_slave_config *)arg;
+ return 0;
+}
- /*
- * We could check config->slave_id to match chan->terminal here,
- * but with DT they would be coming from the same source, so
- * such a check would be superflous
- */
+static int nbpf_terminate_all(struct dma_chan *dchan)
+{
+ struct nbpf_channel *chan = nbpf_to_chan(dchan);
- chan->slave_dst_addr = config->dst_addr;
- chan->slave_dst_width = nbpf_xfer_size(chan->nbpf,
- config->dst_addr_width, 1);
- chan->slave_dst_burst = nbpf_xfer_size(chan->nbpf,
- config->dst_addr_width,
- config->dst_maxburst);
- chan->slave_src_addr = config->src_addr;
- chan->slave_src_width = nbpf_xfer_size(chan->nbpf,
- config->src_addr_width, 1);
- chan->slave_src_burst = nbpf_xfer_size(chan->nbpf,
- config->src_addr_width,
- config->src_maxburst);
- break;
+ dev_dbg(dchan->device->dev, "Entry %s\n", __func__);
+ dev_dbg(dchan->device->dev, "Terminating\n");
- case DMA_PAUSE:
- chan->paused = true;
- nbpf_pause(chan);
- break;
+ nbpf_chan_halt(chan);
+ nbpf_chan_idle(chan);
- default:
- return -ENXIO;
- }
+ return 0;
+}
+
+static int nbpf_config(struct dma_chan *dchan,
+ struct dma_slave_config *config)
+{
+ struct nbpf_channel *chan = nbpf_to_chan(dchan);
+
+ dev_dbg(dchan->device->dev, "Entry %s\n", __func__);
+
+ /*
+ * We could check config->slave_id to match chan->terminal here,
+ * but with DT they would be coming from the same source, so
+ * such a check would be superflous
+ */
+
+ chan->slave_dst_addr = config->dst_addr;
+ chan->slave_dst_width = nbpf_xfer_size(chan->nbpf,
+ config->dst_addr_width, 1);
+ chan->slave_dst_burst = nbpf_xfer_size(chan->nbpf,
+ config->dst_addr_width,
+ config->dst_maxburst);
+ chan->slave_src_addr = config->src_addr;
+ chan->slave_src_width = nbpf_xfer_size(chan->nbpf,
+ config->src_addr_width, 1);
+ chan->slave_src_burst = nbpf_xfer_size(chan->nbpf,
+ config->src_addr_width,
+ config->src_maxburst);
return 0;
}
@@ -1072,18 +1069,6 @@ static void nbpf_free_chan_resources(struct dma_chan *dchan)
}
}
-static int nbpf_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
- caps->src_addr_widths = NBPF_DMA_BUSWIDTHS;
- caps->dstn_addr_widths = NBPF_DMA_BUSWIDTHS;
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = false;
- caps->cmd_terminate = true;
-
- return 0;
-}
-
static struct dma_chan *nbpf_of_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
@@ -1414,7 +1399,6 @@ static int nbpf_probe(struct platform_device *pdev)
dma_dev->device_prep_dma_memcpy = nbpf_prep_memcpy;
dma_dev->device_tx_status = nbpf_tx_status;
dma_dev->device_issue_pending = nbpf_issue_pending;
- dma_dev->device_slave_caps = nbpf_slave_caps;
/*
* If we drop support for unaligned MEMCPY buffer addresses and / or
@@ -1426,7 +1410,13 @@ static int nbpf_probe(struct platform_device *pdev)
/* Compulsory for DMA_SLAVE fields */
dma_dev->device_prep_slave_sg = nbpf_prep_slave_sg;
- dma_dev->device_control = nbpf_control;
+ dma_dev->device_config = nbpf_config;
+ dma_dev->device_pause = nbpf_pause;
+ dma_dev->device_terminate_all = nbpf_terminate_all;
+
+ dma_dev->src_addr_widths = NBPF_DMA_BUSWIDTHS;
+ dma_dev->dst_addr_widths = NBPF_DMA_BUSWIDTHS;
+ dma_dev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
platform_set_drvdata(pdev, nbpf);
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index d5fbeaa1e7ba..ca31f1b45366 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -159,6 +159,10 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
return ERR_PTR(-ENODEV);
}
+ /* Silently fail if there is not even the "dmas" property */
+ if (!of_find_property(np, "dmas", NULL))
+ return ERR_PTR(-ENODEV);
+
count = of_property_count_strings(np, "dma-names");
if (count < 0) {
pr_err("%s: dma-names property of node '%s' missing or empty\n",
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index c0016a68b446..7dd6dd121681 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -948,8 +948,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
return vchan_tx_prep(&c->vc, &d->vd, flags);
}
-static int omap_dma_slave_config(struct omap_chan *c, struct dma_slave_config *cfg)
+static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg)
{
+ struct omap_chan *c = to_omap_dma_chan(chan);
+
if (cfg->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
return -EINVAL;
@@ -959,8 +961,9 @@ static int omap_dma_slave_config(struct omap_chan *c, struct dma_slave_config *c
return 0;
}
-static int omap_dma_terminate_all(struct omap_chan *c)
+static int omap_dma_terminate_all(struct dma_chan *chan)
{
+ struct omap_chan *c = to_omap_dma_chan(chan);
struct omap_dmadev *d = to_omap_dma_dev(c->vc.chan.device);
unsigned long flags;
LIST_HEAD(head);
@@ -996,8 +999,10 @@ static int omap_dma_terminate_all(struct omap_chan *c)
return 0;
}
-static int omap_dma_pause(struct omap_chan *c)
+static int omap_dma_pause(struct dma_chan *chan)
{
+ struct omap_chan *c = to_omap_dma_chan(chan);
+
/* Pause/Resume only allowed with cyclic mode */
if (!c->cyclic)
return -EINVAL;
@@ -1010,8 +1015,10 @@ static int omap_dma_pause(struct omap_chan *c)
return 0;
}
-static int omap_dma_resume(struct omap_chan *c)
+static int omap_dma_resume(struct dma_chan *chan)
{
+ struct omap_chan *c = to_omap_dma_chan(chan);
+
/* Pause/Resume only allowed with cyclic mode */
if (!c->cyclic)
return -EINVAL;
@@ -1029,37 +1036,6 @@ static int omap_dma_resume(struct omap_chan *c)
return 0;
}
-static int omap_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- struct omap_chan *c = to_omap_dma_chan(chan);
- int ret;
-
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- ret = omap_dma_slave_config(c, (struct dma_slave_config *)arg);
- break;
-
- case DMA_TERMINATE_ALL:
- ret = omap_dma_terminate_all(c);
- break;
-
- case DMA_PAUSE:
- ret = omap_dma_pause(c);
- break;
-
- case DMA_RESUME:
- ret = omap_dma_resume(c);
- break;
-
- default:
- ret = -ENXIO;
- break;
- }
-
- return ret;
-}
-
static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
{
struct omap_chan *c;
@@ -1094,19 +1070,6 @@ static void omap_dma_free(struct omap_dmadev *od)
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
-static int omap_dma_device_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
- caps->src_addr_widths = OMAP_DMA_BUSWIDTHS;
- caps->dstn_addr_widths = OMAP_DMA_BUSWIDTHS;
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = true;
- caps->cmd_terminate = true;
- caps->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
-
- return 0;
-}
-
static int omap_dma_probe(struct platform_device *pdev)
{
struct omap_dmadev *od;
@@ -1136,8 +1099,14 @@ static int omap_dma_probe(struct platform_device *pdev)
od->ddev.device_issue_pending = omap_dma_issue_pending;
od->ddev.device_prep_slave_sg = omap_dma_prep_slave_sg;
od->ddev.device_prep_dma_cyclic = omap_dma_prep_dma_cyclic;
- od->ddev.device_control = omap_dma_control;
- od->ddev.device_slave_caps = omap_dma_device_slave_caps;
+ od->ddev.device_config = omap_dma_slave_config;
+ od->ddev.device_pause = omap_dma_pause;
+ od->ddev.device_resume = omap_dma_resume;
+ od->ddev.device_terminate_all = omap_dma_terminate_all;
+ od->ddev.src_addr_widths = OMAP_DMA_BUSWIDTHS;
+ od->ddev.dst_addr_widths = OMAP_DMA_BUSWIDTHS;
+ od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
od->ddev.dev = &pdev->dev;
INIT_LIST_HEAD(&od->ddev.channels);
INIT_LIST_HEAD(&od->pending);
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 6e0e47d76b23..35c143cb88da 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -665,16 +665,12 @@ err_desc_get:
return NULL;
}
-static int pd_device_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int pd_device_terminate_all(struct dma_chan *chan)
{
struct pch_dma_chan *pd_chan = to_pd_chan(chan);
struct pch_dma_desc *desc, *_d;
LIST_HEAD(list);
- if (cmd != DMA_TERMINATE_ALL)
- return -ENXIO;
-
spin_lock_irq(&pd_chan->lock);
pdc_set_mode(&pd_chan->chan, DMA_CTL0_DISABLE);
@@ -932,7 +928,7 @@ static int pch_dma_probe(struct pci_dev *pdev,
pd->dma.device_tx_status = pd_tx_status;
pd->dma.device_issue_pending = pd_issue_pending;
pd->dma.device_prep_slave_sg = pd_prep_slave_sg;
- pd->dma.device_control = pd_device_control;
+ pd->dma.device_terminate_all = pd_device_terminate_all;
err = dma_async_device_register(&pd->dma);
if (err) {
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index bdf40b530032..0e1f56772855 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -504,6 +504,9 @@ struct dma_pl330_desc {
enum desc_status status;
+ int bytes_requested;
+ bool last;
+
/* The channel which currently holds this desc */
struct dma_pl330_chan *pchan;
@@ -1048,6 +1051,10 @@ static bool _trigger(struct pl330_thread *thrd)
if (!req)
return true;
+ /* Return if req is running */
+ if (idx == thrd->req_running)
+ return true;
+
desc = req->desc;
ns = desc->rqcfg.nonsecure ? 1 : 0;
@@ -1587,6 +1594,8 @@ static int pl330_update(struct pl330_dmac *pl330)
descdone = thrd->req[active].desc;
thrd->req[active].desc = NULL;
+ thrd->req_running = -1;
+
/* Get going again ASAP */
_start(thrd);
@@ -2086,77 +2095,89 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
return 1;
}
-static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg)
+static int pl330_config(struct dma_chan *chan,
+ struct dma_slave_config *slave_config)
+{
+ struct dma_pl330_chan *pch = to_pchan(chan);
+
+ if (slave_config->direction == DMA_MEM_TO_DEV) {
+ if (slave_config->dst_addr)
+ pch->fifo_addr = slave_config->dst_addr;
+ if (slave_config->dst_addr_width)
+ pch->burst_sz = __ffs(slave_config->dst_addr_width);
+ if (slave_config->dst_maxburst)
+ pch->burst_len = slave_config->dst_maxburst;
+ } else if (slave_config->direction == DMA_DEV_TO_MEM) {
+ if (slave_config->src_addr)
+ pch->fifo_addr = slave_config->src_addr;
+ if (slave_config->src_addr_width)
+ pch->burst_sz = __ffs(slave_config->src_addr_width);
+ if (slave_config->src_maxburst)
+ pch->burst_len = slave_config->src_maxburst;
+ }
+
+ return 0;
+}
+
+static int pl330_terminate_all(struct dma_chan *chan)
{
struct dma_pl330_chan *pch = to_pchan(chan);
struct dma_pl330_desc *desc;
unsigned long flags;
struct pl330_dmac *pl330 = pch->dmac;
- struct dma_slave_config *slave_config;
LIST_HEAD(list);
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- pm_runtime_get_sync(pl330->ddma.dev);
- spin_lock_irqsave(&pch->lock, flags);
+ spin_lock_irqsave(&pch->lock, flags);
+ spin_lock(&pl330->lock);
+ _stop(pch->thread);
+ spin_unlock(&pl330->lock);
+
+ pch->thread->req[0].desc = NULL;
+ pch->thread->req[1].desc = NULL;
+ pch->thread->req_running = -1;
+
+ /* Mark all desc done */
+ list_for_each_entry(desc, &pch->submitted_list, node) {
+ desc->status = FREE;
+ dma_cookie_complete(&desc->txd);
+ }
- spin_lock(&pl330->lock);
- _stop(pch->thread);
- spin_unlock(&pl330->lock);
+ list_for_each_entry(desc, &pch->work_list , node) {
+ desc->status = FREE;
+ dma_cookie_complete(&desc->txd);
+ }
- pch->thread->req[0].desc = NULL;
- pch->thread->req[1].desc = NULL;
- pch->thread->req_running = -1;
+ list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool);
+ list_splice_tail_init(&pch->work_list, &pl330->desc_pool);
+ list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
+ spin_unlock_irqrestore(&pch->lock, flags);
- /* Mark all desc done */
- list_for_each_entry(desc, &pch->submitted_list, node) {
- desc->status = FREE;
- dma_cookie_complete(&desc->txd);
- }
+ return 0;
+}
- list_for_each_entry(desc, &pch->work_list , node) {
- desc->status = FREE;
- dma_cookie_complete(&desc->txd);
- }
+/*
+ * We don't support DMA_RESUME command because of hardware
+ * limitations, so after pausing the channel we cannot restore
+ * it to active state. We have to terminate channel and setup
+ * DMA transfer again. This pause feature was implemented to
+ * allow safely read residue before channel termination.
+ */
+int pl330_pause(struct dma_chan *chan)
+{
+ struct dma_pl330_chan *pch = to_pchan(chan);
+ struct pl330_dmac *pl330 = pch->dmac;
+ unsigned long flags;
- list_for_each_entry(desc, &pch->completed_list , node) {
- desc->status = FREE;
- dma_cookie_complete(&desc->txd);
- }
+ pm_runtime_get_sync(pl330->ddma.dev);
+ spin_lock_irqsave(&pch->lock, flags);
- if (!list_empty(&pch->work_list))
- pm_runtime_put(pl330->ddma.dev);
+ spin_lock(&pl330->lock);
+ _stop(pch->thread);
+ spin_unlock(&pl330->lock);
- list_splice_tail_init(&pch->submitted_list, &pl330->desc_pool);
- list_splice_tail_init(&pch->work_list, &pl330->desc_pool);
- list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
- spin_unlock_irqrestore(&pch->lock, flags);
- pm_runtime_mark_last_busy(pl330->ddma.dev);
- pm_runtime_put_autosuspend(pl330->ddma.dev);
- break;
- case DMA_SLAVE_CONFIG:
- slave_config = (struct dma_slave_config *)arg;
-
- if (slave_config->direction == DMA_MEM_TO_DEV) {
- if (slave_config->dst_addr)
- pch->fifo_addr = slave_config->dst_addr;
- if (slave_config->dst_addr_width)
- pch->burst_sz = __ffs(slave_config->dst_addr_width);
- if (slave_config->dst_maxburst)
- pch->burst_len = slave_config->dst_maxburst;
- } else if (slave_config->direction == DMA_DEV_TO_MEM) {
- if (slave_config->src_addr)
- pch->fifo_addr = slave_config->src_addr;
- if (slave_config->src_addr_width)
- pch->burst_sz = __ffs(slave_config->src_addr_width);
- if (slave_config->src_maxburst)
- pch->burst_len = slave_config->src_maxburst;
- }
- break;
- default:
- dev_err(pch->dmac->ddma.dev, "Not supported command.\n");
- return -ENXIO;
- }
+ spin_unlock_irqrestore(&pch->lock, flags);
+ pm_runtime_mark_last_busy(pl330->ddma.dev);
+ pm_runtime_put_autosuspend(pl330->ddma.dev);
return 0;
}
@@ -2182,11 +2203,74 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
pm_runtime_put_autosuspend(pch->dmac->ddma.dev);
}
+int pl330_get_current_xferred_count(struct dma_pl330_chan *pch,
+ struct dma_pl330_desc *desc)
+{
+ struct pl330_thread *thrd = pch->thread;
+ struct pl330_dmac *pl330 = pch->dmac;
+ void __iomem *regs = thrd->dmac->base;
+ u32 val, addr;
+
+ pm_runtime_get_sync(pl330->ddma.dev);
+ val = addr = 0;
+ if (desc->rqcfg.src_inc) {
+ val = readl(regs + SA(thrd->id));
+ addr = desc->px.src_addr;
+ } else {
+ val = readl(regs + DA(thrd->id));
+ addr = desc->px.dst_addr;
+ }
+ pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
+ pm_runtime_put_autosuspend(pl330->ddma.dev);
+ return val - addr;
+}
+
static enum dma_status
pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
- return dma_cookie_status(chan, cookie, txstate);
+ enum dma_status ret;
+ unsigned long flags;
+ struct dma_pl330_desc *desc, *running = NULL;
+ struct dma_pl330_chan *pch = to_pchan(chan);
+ unsigned int transferred, residual = 0;
+
+ ret = dma_cookie_status(chan, cookie, txstate);
+
+ if (!txstate)
+ return ret;
+
+ if (ret == DMA_COMPLETE)
+ goto out;
+
+ spin_lock_irqsave(&pch->lock, flags);
+
+ if (pch->thread->req_running != -1)
+ running = pch->thread->req[pch->thread->req_running].desc;
+
+ /* Check in pending list */
+ list_for_each_entry(desc, &pch->work_list, node) {
+ if (desc->status == DONE)
+ transferred = desc->bytes_requested;
+ else if (running && desc == running)
+ transferred =
+ pl330_get_current_xferred_count(pch, desc);
+ else
+ transferred = 0;
+ residual += desc->bytes_requested - transferred;
+ if (desc->txd.cookie == cookie) {
+ ret = desc->status;
+ break;
+ }
+ if (desc->last)
+ residual = 0;
+ }
+ spin_unlock_irqrestore(&pch->lock, flags);
+
+out:
+ dma_set_residue(txstate, residual);
+
+ return ret;
}
static void pl330_issue_pending(struct dma_chan *chan)
@@ -2231,12 +2315,14 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx)
desc->txd.callback = last->txd.callback;
desc->txd.callback_param = last->txd.callback_param;
}
+ last->last = false;
dma_cookie_assign(&desc->txd);
list_move_tail(&desc->node, &pch->submitted_list);
}
+ last->last = true;
cookie = dma_cookie_assign(&last->txd);
list_add_tail(&last->node, &pch->submitted_list);
spin_unlock_irqrestore(&pch->lock, flags);
@@ -2459,6 +2545,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
desc->rqtype = direction;
desc->rqcfg.brst_size = pch->burst_sz;
desc->rqcfg.brst_len = 1;
+ desc->bytes_requested = period_len;
fill_px(&desc->px, dst, src, period_len);
if (!first)
@@ -2601,6 +2688,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
desc->rqcfg.brst_size = pch->burst_sz;
desc->rqcfg.brst_len = 1;
desc->rqtype = direction;
+ desc->bytes_requested = sg_dma_len(sg);
}
/* Return the last desc in the chain */
@@ -2623,19 +2711,6 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)
-static int pl330_dma_device_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
- caps->src_addr_widths = PL330_DMA_BUSWIDTHS;
- caps->dstn_addr_widths = PL330_DMA_BUSWIDTHS;
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = false;
- caps->cmd_terminate = true;
- caps->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
-
- return 0;
-}
-
/*
* Runtime PM callbacks are provided by amba/bus.c driver.
*
@@ -2793,9 +2868,14 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic;
pd->device_tx_status = pl330_tx_status;
pd->device_prep_slave_sg = pl330_prep_slave_sg;
- pd->device_control = pl330_control;
+ pd->device_config = pl330_config;
+ pd->device_pause = pl330_pause;
+ pd->device_terminate_all = pl330_terminate_all;
pd->device_issue_pending = pl330_issue_pending;
- pd->device_slave_caps = pl330_dma_device_slave_caps;
+ pd->src_addr_widths = PL330_DMA_BUSWIDTHS;
+ pd->dst_addr_widths = PL330_DMA_BUSWIDTHS;
+ pd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ pd->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
ret = dma_async_device_register(pd);
if (ret) {
@@ -2847,7 +2927,7 @@ probe_err3:
/* Flush the channel */
if (pch->thread) {
- pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0);
+ pl330_terminate_all(&pch->chan);
pl330_free_chan_resources(&pch->chan);
}
}
@@ -2878,7 +2958,7 @@ static int pl330_remove(struct amba_device *adev)
/* Flush the channel */
if (pch->thread) {
- pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0);
+ pl330_terminate_all(&pch->chan);
pl330_free_chan_resources(&pch->chan);
}
}
diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
index 3122a99ec06b..d7a33b3ac466 100644
--- a/drivers/dma/qcom_bam_dma.c
+++ b/drivers/dma/qcom_bam_dma.c
@@ -530,11 +530,18 @@ static void bam_free_chan(struct dma_chan *chan)
* Sets slave configuration for channel
*
*/
-static void bam_slave_config(struct bam_chan *bchan,
- struct dma_slave_config *cfg)
+static int bam_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
{
+ struct bam_chan *bchan = to_bam_chan(chan);
+ unsigned long flag;
+
+ spin_lock_irqsave(&bchan->vc.lock, flag);
memcpy(&bchan->slave, cfg, sizeof(*cfg));
bchan->reconfigure = 1;
+ spin_unlock_irqrestore(&bchan->vc.lock, flag);
+
+ return 0;
}
/**
@@ -627,8 +634,9 @@ err_out:
* No callbacks are done
*
*/
-static void bam_dma_terminate_all(struct bam_chan *bchan)
+static int bam_dma_terminate_all(struct dma_chan *chan)
{
+ struct bam_chan *bchan = to_bam_chan(chan);
unsigned long flag;
LIST_HEAD(head);
@@ -643,56 +651,46 @@ static void bam_dma_terminate_all(struct bam_chan *bchan)
spin_unlock_irqrestore(&bchan->vc.lock, flag);
vchan_dma_desc_free_list(&bchan->vc, &head);
+
+ return 0;
}
/**
- * bam_control - DMA device control
+ * bam_pause - Pause DMA channel
* @chan: dma channel
- * @cmd: control cmd
- * @arg: cmd argument
*
- * Perform DMA control command
+ */
+static int bam_pause(struct dma_chan *chan)
+{
+ struct bam_chan *bchan = to_bam_chan(chan);
+ struct bam_device *bdev = bchan->bdev;
+ unsigned long flag;
+
+ spin_lock_irqsave(&bchan->vc.lock, flag);
+ writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT));
+ bchan->paused = 1;
+ spin_unlock_irqrestore(&bchan->vc.lock, flag);
+
+ return 0;
+}
+
+/**
+ * bam_resume - Resume DMA channel operations
+ * @chan: dma channel
*
*/
-static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int bam_resume(struct dma_chan *chan)
{
struct bam_chan *bchan = to_bam_chan(chan);
struct bam_device *bdev = bchan->bdev;
- int ret = 0;
unsigned long flag;
- switch (cmd) {
- case DMA_PAUSE:
- spin_lock_irqsave(&bchan->vc.lock, flag);
- writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT));
- bchan->paused = 1;
- spin_unlock_irqrestore(&bchan->vc.lock, flag);
- break;
-
- case DMA_RESUME:
- spin_lock_irqsave(&bchan->vc.lock, flag);
- writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
- bchan->paused = 0;
- spin_unlock_irqrestore(&bchan->vc.lock, flag);
- break;
-
- case DMA_TERMINATE_ALL:
- bam_dma_terminate_all(bchan);
- break;
-
- case DMA_SLAVE_CONFIG:
- spin_lock_irqsave(&bchan->vc.lock, flag);
- bam_slave_config(bchan, (struct dma_slave_config *)arg);
- spin_unlock_irqrestore(&bchan->vc.lock, flag);
- break;
-
- default:
- ret = -ENXIO;
- break;
- }
+ spin_lock_irqsave(&bchan->vc.lock, flag);
+ writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT));
+ bchan->paused = 0;
+ spin_unlock_irqrestore(&bchan->vc.lock, flag);
- return ret;
+ return 0;
}
/**
@@ -1148,7 +1146,10 @@ static int bam_dma_probe(struct platform_device *pdev)
bdev->common.device_alloc_chan_resources = bam_alloc_chan;
bdev->common.device_free_chan_resources = bam_free_chan;
bdev->common.device_prep_slave_sg = bam_prep_slave_sg;
- bdev->common.device_control = bam_control;
+ bdev->common.device_config = bam_slave_config;
+ bdev->common.device_pause = bam_pause;
+ bdev->common.device_resume = bam_resume;
+ bdev->common.device_terminate_all = bam_dma_terminate_all;
bdev->common.device_issue_pending = bam_issue_pending;
bdev->common.device_tx_status = bam_tx_status;
bdev->common.dev = bdev->dev;
@@ -1187,7 +1188,7 @@ static int bam_dma_remove(struct platform_device *pdev)
devm_free_irq(bdev->dev, bdev->irq, bdev);
for (i = 0; i < bdev->num_channels; i++) {
- bam_dma_terminate_all(&bdev->channels[i]);
+ bam_dma_terminate_all(&bdev->channels[i].vc.chan);
tasklet_kill(&bdev->channels[i].vc.task);
dma_free_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE,
diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c
index 6941a77521c3..2f91da3db836 100644
--- a/drivers/dma/s3c24xx-dma.c
+++ b/drivers/dma/s3c24xx-dma.c
@@ -384,20 +384,30 @@ static u32 s3c24xx_dma_getbytes_chan(struct s3c24xx_dma_chan *s3cchan)
return tc * txd->width;
}
-static int s3c24xx_dma_set_runtime_config(struct s3c24xx_dma_chan *s3cchan,
+static int s3c24xx_dma_set_runtime_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
- if (!s3cchan->slave)
- return -EINVAL;
+ struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(chan);
+ unsigned long flags;
+ int ret = 0;
/* Reject definitely invalid configurations */
if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
return -EINVAL;
+ spin_lock_irqsave(&s3cchan->vc.lock, flags);
+
+ if (!s3cchan->slave) {
+ ret = -EINVAL;
+ goto out;
+ }
+
s3cchan->cfg = *config;
- return 0;
+out:
+ spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
+ return ret;
}
/*
@@ -703,8 +713,7 @@ static irqreturn_t s3c24xx_dma_irq(int irq, void *data)
* The DMA ENGINE API
*/
-static int s3c24xx_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int s3c24xx_dma_terminate_all(struct dma_chan *chan)
{
struct s3c24xx_dma_chan *s3cchan = to_s3c24xx_dma_chan(chan);
struct s3c24xx_dma_engine *s3cdma = s3cchan->host;
@@ -713,40 +722,28 @@ static int s3c24xx_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
spin_lock_irqsave(&s3cchan->vc.lock, flags);
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- ret = s3c24xx_dma_set_runtime_config(s3cchan,
- (struct dma_slave_config *)arg);
- break;
- case DMA_TERMINATE_ALL:
- if (!s3cchan->phy && !s3cchan->at) {
- dev_err(&s3cdma->pdev->dev, "trying to terminate already stopped channel %d\n",
- s3cchan->id);
- ret = -EINVAL;
- break;
- }
+ if (!s3cchan->phy && !s3cchan->at) {
+ dev_err(&s3cdma->pdev->dev, "trying to terminate already stopped channel %d\n",
+ s3cchan->id);
+ ret = -EINVAL;
+ goto unlock;
+ }
- s3cchan->state = S3C24XX_DMA_CHAN_IDLE;
+ s3cchan->state = S3C24XX_DMA_CHAN_IDLE;
- /* Mark physical channel as free */
- if (s3cchan->phy)
- s3c24xx_dma_phy_free(s3cchan);
+ /* Mark physical channel as free */
+ if (s3cchan->phy)
+ s3c24xx_dma_phy_free(s3cchan);
- /* Dequeue current job */
- if (s3cchan->at) {
- s3c24xx_dma_desc_free(&s3cchan->at->vd);
- s3cchan->at = NULL;
- }
-
- /* Dequeue jobs not yet fired as well */
- s3c24xx_dma_free_txd_list(s3cdma, s3cchan);
- break;
- default:
- /* Unknown command */
- ret = -ENXIO;
- break;
+ /* Dequeue current job */
+ if (s3cchan->at) {
+ s3c24xx_dma_desc_free(&s3cchan->at->vd);
+ s3cchan->at = NULL;
}
+ /* Dequeue jobs not yet fired as well */
+ s3c24xx_dma_free_txd_list(s3cdma, s3cchan);
+unlock:
spin_unlock_irqrestore(&s3cchan->vc.lock, flags);
return ret;
@@ -1300,7 +1297,8 @@ static int s3c24xx_dma_probe(struct platform_device *pdev)
s3cdma->memcpy.device_prep_dma_memcpy = s3c24xx_dma_prep_memcpy;
s3cdma->memcpy.device_tx_status = s3c24xx_dma_tx_status;
s3cdma->memcpy.device_issue_pending = s3c24xx_dma_issue_pending;
- s3cdma->memcpy.device_control = s3c24xx_dma_control;
+ s3cdma->memcpy.device_config = s3c24xx_dma_set_runtime_config;
+ s3cdma->memcpy.device_terminate_all = s3c24xx_dma_terminate_all;
/* Initialize slave engine for SoC internal dedicated peripherals */
dma_cap_set(DMA_SLAVE, s3cdma->slave.cap_mask);
@@ -1315,7 +1313,8 @@ static int s3c24xx_dma_probe(struct platform_device *pdev)
s3cdma->slave.device_issue_pending = s3c24xx_dma_issue_pending;
s3cdma->slave.device_prep_slave_sg = s3c24xx_dma_prep_slave_sg;
s3cdma->slave.device_prep_dma_cyclic = s3c24xx_dma_prep_dma_cyclic;
- s3cdma->slave.device_control = s3c24xx_dma_control;
+ s3cdma->slave.device_config = s3c24xx_dma_set_runtime_config;
+ s3cdma->slave.device_terminate_all = s3c24xx_dma_terminate_all;
/* Register as many memcpy channels as there are physical channels */
ret = s3c24xx_dma_init_virtual_channels(s3cdma, &s3cdma->memcpy,
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 96bb62c39c41..5adf5407a8cb 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -669,8 +669,10 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic(
return vchan_tx_prep(&c->vc, &txd->vd, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
}
-static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_config *cfg)
+static int sa11x0_dma_device_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
{
+ struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW);
dma_addr_t addr;
enum dma_slave_buswidth width;
@@ -704,99 +706,101 @@ static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_c
return 0;
}
-static int sa11x0_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int sa11x0_dma_device_pause(struct dma_chan *chan)
{
struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
struct sa11x0_dma_phy *p;
LIST_HEAD(head);
unsigned long flags;
- int ret;
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- return sa11x0_dma_slave_config(c, (struct dma_slave_config *)arg);
-
- case DMA_TERMINATE_ALL:
- dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc);
- /* Clear the tx descriptor lists */
- spin_lock_irqsave(&c->vc.lock, flags);
- vchan_get_all_descriptors(&c->vc, &head);
+ dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc);
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (c->status == DMA_IN_PROGRESS) {
+ c->status = DMA_PAUSED;
p = c->phy;
if (p) {
- dev_dbg(d->slave.dev, "pchan %u: terminating\n", p->num);
- /* vchan is assigned to a pchan - stop the channel */
- writel(DCSR_RUN | DCSR_IE |
- DCSR_STRTA | DCSR_DONEA |
- DCSR_STRTB | DCSR_DONEB,
- p->base + DMA_DCSR_C);
-
- if (p->txd_load) {
- if (p->txd_load != p->txd_done)
- list_add_tail(&p->txd_load->vd.node, &head);
- p->txd_load = NULL;
- }
- if (p->txd_done) {
- list_add_tail(&p->txd_done->vd.node, &head);
- p->txd_done = NULL;
- }
- c->phy = NULL;
+ writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
+ } else {
spin_lock(&d->lock);
- p->vchan = NULL;
+ list_del_init(&c->node);
spin_unlock(&d->lock);
- tasklet_schedule(&d->task);
}
- spin_unlock_irqrestore(&c->vc.lock, flags);
- vchan_dma_desc_free_list(&c->vc, &head);
- ret = 0;
- break;
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
- case DMA_PAUSE:
- dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc);
- spin_lock_irqsave(&c->vc.lock, flags);
- if (c->status == DMA_IN_PROGRESS) {
- c->status = DMA_PAUSED;
+ return 0;
+}
- p = c->phy;
- if (p) {
- writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
- } else {
- spin_lock(&d->lock);
- list_del_init(&c->node);
- spin_unlock(&d->lock);
- }
- }
- spin_unlock_irqrestore(&c->vc.lock, flags);
- ret = 0;
- break;
+static int sa11x0_dma_device_resume(struct dma_chan *chan)
+{
+ struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+ struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+ struct sa11x0_dma_phy *p;
+ LIST_HEAD(head);
+ unsigned long flags;
- case DMA_RESUME:
- dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc);
- spin_lock_irqsave(&c->vc.lock, flags);
- if (c->status == DMA_PAUSED) {
- c->status = DMA_IN_PROGRESS;
-
- p = c->phy;
- if (p) {
- writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_S);
- } else if (!list_empty(&c->vc.desc_issued)) {
- spin_lock(&d->lock);
- list_add_tail(&c->node, &d->chan_pending);
- spin_unlock(&d->lock);
- }
+ dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc);
+ spin_lock_irqsave(&c->vc.lock, flags);
+ if (c->status == DMA_PAUSED) {
+ c->status = DMA_IN_PROGRESS;
+
+ p = c->phy;
+ if (p) {
+ writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_S);
+ } else if (!list_empty(&c->vc.desc_issued)) {
+ spin_lock(&d->lock);
+ list_add_tail(&c->node, &d->chan_pending);
+ spin_unlock(&d->lock);
}
- spin_unlock_irqrestore(&c->vc.lock, flags);
- ret = 0;
- break;
+ }
+ spin_unlock_irqrestore(&c->vc.lock, flags);
- default:
- ret = -ENXIO;
- break;
+ return 0;
+}
+
+static int sa11x0_dma_device_terminate_all(struct dma_chan *chan)
+{
+ struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+ struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+ struct sa11x0_dma_phy *p;
+ LIST_HEAD(head);
+ unsigned long flags;
+
+ dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc);
+ /* Clear the tx descriptor lists */
+ spin_lock_irqsave(&c->vc.lock, flags);
+ vchan_get_all_descriptors(&c->vc, &head);
+
+ p = c->phy;
+ if (p) {
+ dev_dbg(d->slave.dev, "pchan %u: terminating\n", p->num);
+ /* vchan is assigned to a pchan - stop the channel */
+ writel(DCSR_RUN | DCSR_IE |
+ DCSR_STRTA | DCSR_DONEA |
+ DCSR_STRTB | DCSR_DONEB,
+ p->base + DMA_DCSR_C);
+
+ if (p->txd_load) {
+ if (p->txd_load != p->txd_done)
+ list_add_tail(&p->txd_load->vd.node, &head);
+ p->txd_load = NULL;
+ }
+ if (p->txd_done) {
+ list_add_tail(&p->txd_done->vd.node, &head);
+ p->txd_done = NULL;
+ }
+ c->phy = NULL;
+ spin_lock(&d->lock);
+ p->vchan = NULL;
+ spin_unlock(&d->lock);
+ tasklet_schedule(&d->task);
}
+ spin_unlock_irqrestore(&c->vc.lock, flags);
+ vchan_dma_desc_free_list(&c->vc, &head);
- return ret;
+ return 0;
}
struct sa11x0_dma_channel_desc {
@@ -833,7 +837,10 @@ static int sa11x0_dma_init_dmadev(struct dma_device *dmadev,
dmadev->dev = dev;
dmadev->device_alloc_chan_resources = sa11x0_dma_alloc_chan_resources;
dmadev->device_free_chan_resources = sa11x0_dma_free_chan_resources;
- dmadev->device_control = sa11x0_dma_control;
+ dmadev->device_config = sa11x0_dma_device_config;
+ dmadev->device_pause = sa11x0_dma_device_pause;
+ dmadev->device_resume = sa11x0_dma_device_resume;
+ dmadev->device_terminate_all = sa11x0_dma_device_terminate_all;
dmadev->device_tx_status = sa11x0_dma_tx_status;
dmadev->device_issue_pending = sa11x0_dma_issue_pending;
diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig
index 0349125a2e20..8190ad225a1b 100644
--- a/drivers/dma/sh/Kconfig
+++ b/drivers/dma/sh/Kconfig
@@ -2,6 +2,10 @@
# DMA engine configuration for sh
#
+config RENESAS_DMA
+ bool
+ select DMA_ENGINE
+
#
# DMA Engine Helpers
#
@@ -12,7 +16,7 @@ config SH_DMAE_BASE
depends on !SUPERH || SH_DMA
depends on !SH_DMA_API
default y
- select DMA_ENGINE
+ select RENESAS_DMA
help
Enable support for the Renesas SuperH DMA controllers.
@@ -52,3 +56,11 @@ config RCAR_AUDMAC_PP
depends on SH_DMAE_BASE
help
Enable support for the Renesas R-Car Audio DMAC Peripheral Peripheral controllers.
+
+config RCAR_DMAC
+ tristate "Renesas R-Car Gen2 DMA Controller"
+ depends on ARCH_SHMOBILE || COMPILE_TEST
+ select RENESAS_DMA
+ help
+ This driver supports the general purpose DMA controller found in the
+ Renesas R-Car second generation SoCs.
diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
index 0a5cfdb76e45..2852f9db61a4 100644
--- a/drivers/dma/sh/Makefile
+++ b/drivers/dma/sh/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_SH_DMAE) += shdma.o
obj-$(CONFIG_SUDMAC) += sudmac.o
obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o
obj-$(CONFIG_RCAR_AUDMAC_PP) += rcar-audmapp.o
+obj-$(CONFIG_RCAR_DMAC) += rcar-dmac.o
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
new file mode 100644
index 000000000000..a18d16cc4795
--- /dev/null
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -0,0 +1,1770 @@
+/*
+ * Renesas R-Car Gen2 DMA Controller Driver
+ *
+ * Copyright (C) 2014 Renesas Electronics Inc.
+ *
+ * Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "../dmaengine.h"
+
+/*
+ * struct rcar_dmac_xfer_chunk - Descriptor for a hardware transfer
+ * @node: entry in the parent's chunks list
+ * @src_addr: device source address
+ * @dst_addr: device destination address
+ * @size: transfer size in bytes
+ */
+struct rcar_dmac_xfer_chunk {
+ struct list_head node;
+
+ dma_addr_t src_addr;
+ dma_addr_t dst_addr;
+ u32 size;
+};
+
+/*
+ * struct rcar_dmac_hw_desc - Hardware descriptor for a transfer chunk
+ * @sar: value of the SAR register (source address)
+ * @dar: value of the DAR register (destination address)
+ * @tcr: value of the TCR register (transfer count)
+ */
+struct rcar_dmac_hw_desc {
+ u32 sar;
+ u32 dar;
+ u32 tcr;
+ u32 reserved;
+} __attribute__((__packed__));
+
+/*
+ * struct rcar_dmac_desc - R-Car Gen2 DMA Transfer Descriptor
+ * @async_tx: base DMA asynchronous transaction descriptor
+ * @direction: direction of the DMA transfer
+ * @xfer_shift: log2 of the transfer size
+ * @chcr: value of the channel configuration register for this transfer
+ * @node: entry in the channel's descriptors lists
+ * @chunks: list of transfer chunks for this transfer
+ * @running: the transfer chunk being currently processed
+ * @nchunks: number of transfer chunks for this transfer
+ * @hwdescs.use: whether the transfer descriptor uses hardware descriptors
+ * @hwdescs.mem: hardware descriptors memory for the transfer
+ * @hwdescs.dma: device address of the hardware descriptors memory
+ * @hwdescs.size: size of the hardware descriptors in bytes
+ * @size: transfer size in bytes
+ * @cyclic: when set indicates that the DMA transfer is cyclic
+ */
+struct rcar_dmac_desc {
+ struct dma_async_tx_descriptor async_tx;
+ enum dma_transfer_direction direction;
+ unsigned int xfer_shift;
+ u32 chcr;
+
+ struct list_head node;
+ struct list_head chunks;
+ struct rcar_dmac_xfer_chunk *running;
+ unsigned int nchunks;
+
+ struct {
+ bool use;
+ struct rcar_dmac_hw_desc *mem;
+ dma_addr_t dma;
+ size_t size;
+ } hwdescs;
+
+ unsigned int size;
+ bool cyclic;
+};
+
+#define to_rcar_dmac_desc(d) container_of(d, struct rcar_dmac_desc, async_tx)
+
+/*
+ * struct rcar_dmac_desc_page - One page worth of descriptors
+ * @node: entry in the channel's pages list
+ * @descs: array of DMA descriptors
+ * @chunks: array of transfer chunk descriptors
+ */
+struct rcar_dmac_desc_page {
+ struct list_head node;
+
+ union {
+ struct rcar_dmac_desc descs[0];
+ struct rcar_dmac_xfer_chunk chunks[0];
+ };
+};
+
+#define RCAR_DMAC_DESCS_PER_PAGE \
+ ((PAGE_SIZE - offsetof(struct rcar_dmac_desc_page, descs)) / \
+ sizeof(struct rcar_dmac_desc))
+#define RCAR_DMAC_XFER_CHUNKS_PER_PAGE \
+ ((PAGE_SIZE - offsetof(struct rcar_dmac_desc_page, chunks)) / \
+ sizeof(struct rcar_dmac_xfer_chunk))
+
+/*
+ * struct rcar_dmac_chan - R-Car Gen2 DMA Controller Channel
+ * @chan: base DMA channel object
+ * @iomem: channel I/O memory base
+ * @index: index of this channel in the controller
+ * @src_xfer_size: size (in bytes) of hardware transfers on the source side
+ * @dst_xfer_size: size (in bytes) of hardware transfers on the destination side
+ * @src_slave_addr: slave source memory address
+ * @dst_slave_addr: slave destination memory address
+ * @mid_rid: hardware MID/RID for the DMA client using this channel
+ * @lock: protects the channel CHCR register and the desc members
+ * @desc.free: list of free descriptors
+ * @desc.pending: list of pending descriptors (submitted with tx_submit)
+ * @desc.active: list of active descriptors (activated with issue_pending)
+ * @desc.done: list of completed descriptors
+ * @desc.wait: list of descriptors waiting for an ack
+ * @desc.running: the descriptor being processed (a member of the active list)
+ * @desc.chunks_free: list of free transfer chunk descriptors
+ * @desc.pages: list of pages used by allocated descriptors
+ */
+struct rcar_dmac_chan {
+ struct dma_chan chan;
+ void __iomem *iomem;
+ unsigned int index;
+
+ unsigned int src_xfer_size;
+ unsigned int dst_xfer_size;
+ dma_addr_t src_slave_addr;
+ dma_addr_t dst_slave_addr;
+ int mid_rid;
+
+ spinlock_t lock;
+
+ struct {
+ struct list_head free;
+ struct list_head pending;
+ struct list_head active;
+ struct list_head done;
+ struct list_head wait;
+ struct rcar_dmac_desc *running;
+
+ struct list_head chunks_free;
+
+ struct list_head pages;
+ } desc;
+};
+
+#define to_rcar_dmac_chan(c) container_of(c, struct rcar_dmac_chan, chan)
+
+/*
+ * struct rcar_dmac - R-Car Gen2 DMA Controller
+ * @engine: base DMA engine object
+ * @dev: the hardware device
+ * @iomem: remapped I/O memory base
+ * @n_channels: number of available channels
+ * @channels: array of DMAC channels
+ * @modules: bitmask of client modules in use
+ */
+struct rcar_dmac {
+ struct dma_device engine;
+ struct device *dev;
+ void __iomem *iomem;
+
+ unsigned int n_channels;
+ struct rcar_dmac_chan *channels;
+
+ unsigned long modules[256 / BITS_PER_LONG];
+};
+
+#define to_rcar_dmac(d) container_of(d, struct rcar_dmac, engine)
+
+/* -----------------------------------------------------------------------------
+ * Registers
+ */
+
+#define RCAR_DMAC_CHAN_OFFSET(i) (0x8000 + 0x80 * (i))
+
+#define RCAR_DMAISTA 0x0020
+#define RCAR_DMASEC 0x0030
+#define RCAR_DMAOR 0x0060
+#define RCAR_DMAOR_PRI_FIXED (0 << 8)
+#define RCAR_DMAOR_PRI_ROUND_ROBIN (3 << 8)
+#define RCAR_DMAOR_AE (1 << 2)
+#define RCAR_DMAOR_DME (1 << 0)
+#define RCAR_DMACHCLR 0x0080
+#define RCAR_DMADPSEC 0x00a0
+
+#define RCAR_DMASAR 0x0000
+#define RCAR_DMADAR 0x0004
+#define RCAR_DMATCR 0x0008
+#define RCAR_DMATCR_MASK 0x00ffffff
+#define RCAR_DMATSR 0x0028
+#define RCAR_DMACHCR 0x000c
+#define RCAR_DMACHCR_CAE (1 << 31)
+#define RCAR_DMACHCR_CAIE (1 << 30)
+#define RCAR_DMACHCR_DPM_DISABLED (0 << 28)
+#define RCAR_DMACHCR_DPM_ENABLED (1 << 28)
+#define RCAR_DMACHCR_DPM_REPEAT (2 << 28)
+#define RCAR_DMACHCR_DPM_INFINITE (3 << 28)
+#define RCAR_DMACHCR_RPT_SAR (1 << 27)
+#define RCAR_DMACHCR_RPT_DAR (1 << 26)
+#define RCAR_DMACHCR_RPT_TCR (1 << 25)
+#define RCAR_DMACHCR_DPB (1 << 22)
+#define RCAR_DMACHCR_DSE (1 << 19)
+#define RCAR_DMACHCR_DSIE (1 << 18)
+#define RCAR_DMACHCR_TS_1B ((0 << 20) | (0 << 3))
+#define RCAR_DMACHCR_TS_2B ((0 << 20) | (1 << 3))
+#define RCAR_DMACHCR_TS_4B ((0 << 20) | (2 << 3))
+#define RCAR_DMACHCR_TS_16B ((0 << 20) | (3 << 3))
+#define RCAR_DMACHCR_TS_32B ((1 << 20) | (0 << 3))
+#define RCAR_DMACHCR_TS_64B ((1 << 20) | (1 << 3))
+#define RCAR_DMACHCR_TS_8B ((1 << 20) | (3 << 3))
+#define RCAR_DMACHCR_DM_FIXED (0 << 14)
+#define RCAR_DMACHCR_DM_INC (1 << 14)
+#define RCAR_DMACHCR_DM_DEC (2 << 14)
+#define RCAR_DMACHCR_SM_FIXED (0 << 12)
+#define RCAR_DMACHCR_SM_INC (1 << 12)
+#define RCAR_DMACHCR_SM_DEC (2 << 12)
+#define RCAR_DMACHCR_RS_AUTO (4 << 8)
+#define RCAR_DMACHCR_RS_DMARS (8 << 8)
+#define RCAR_DMACHCR_IE (1 << 2)
+#define RCAR_DMACHCR_TE (1 << 1)
+#define RCAR_DMACHCR_DE (1 << 0)
+#define RCAR_DMATCRB 0x0018
+#define RCAR_DMATSRB 0x0038
+#define RCAR_DMACHCRB 0x001c
+#define RCAR_DMACHCRB_DCNT(n) ((n) << 24)
+#define RCAR_DMACHCRB_DPTR_MASK (0xff << 16)
+#define RCAR_DMACHCRB_DPTR_SHIFT 16
+#define RCAR_DMACHCRB_DRST (1 << 15)
+#define RCAR_DMACHCRB_DTS (1 << 8)
+#define RCAR_DMACHCRB_SLM_NORMAL (0 << 4)
+#define RCAR_DMACHCRB_SLM_CLK(n) ((8 | (n)) << 4)
+#define RCAR_DMACHCRB_PRI(n) ((n) << 0)
+#define RCAR_DMARS 0x0040
+#define RCAR_DMABUFCR 0x0048
+#define RCAR_DMABUFCR_MBU(n) ((n) << 16)
+#define RCAR_DMABUFCR_ULB(n) ((n) << 0)
+#define RCAR_DMADPBASE 0x0050
+#define RCAR_DMADPBASE_MASK 0xfffffff0
+#define RCAR_DMADPBASE_SEL (1 << 0)
+#define RCAR_DMADPCR 0x0054
+#define RCAR_DMADPCR_DIPT(n) ((n) << 24)
+#define RCAR_DMAFIXSAR 0x0010
+#define RCAR_DMAFIXDAR 0x0014
+#define RCAR_DMAFIXDPBASE 0x0060
+
+/* Hardcode the MEMCPY transfer size to 4 bytes. */
+#define RCAR_DMAC_MEMCPY_XFER_SIZE 4
+
+/* -----------------------------------------------------------------------------
+ * Device access
+ */
+
+static void rcar_dmac_write(struct rcar_dmac *dmac, u32 reg, u32 data)
+{
+ if (reg == RCAR_DMAOR)
+ writew(data, dmac->iomem + reg);
+ else
+ writel(data, dmac->iomem + reg);
+}
+
+static u32 rcar_dmac_read(struct rcar_dmac *dmac, u32 reg)
+{
+ if (reg == RCAR_DMAOR)
+ return readw(dmac->iomem + reg);
+ else
+ return readl(dmac->iomem + reg);
+}
+
+static u32 rcar_dmac_chan_read(struct rcar_dmac_chan *chan, u32 reg)
+{
+ if (reg == RCAR_DMARS)
+ return readw(chan->iomem + reg);
+ else
+ return readl(chan->iomem + reg);
+}
+
+static void rcar_dmac_chan_write(struct rcar_dmac_chan *chan, u32 reg, u32 data)
+{
+ if (reg == RCAR_DMARS)
+ writew(data, chan->iomem + reg);
+ else
+ writel(data, chan->iomem + reg);
+}
+
+/* -----------------------------------------------------------------------------
+ * Initialization and configuration
+ */
+
+static bool rcar_dmac_chan_is_busy(struct rcar_dmac_chan *chan)
+{
+ u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+
+ return (chcr & (RCAR_DMACHCR_DE | RCAR_DMACHCR_TE)) == RCAR_DMACHCR_DE;
+}
+
+static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan)
+{
+ struct rcar_dmac_desc *desc = chan->desc.running;
+ u32 chcr = desc->chcr;
+
+ WARN_ON_ONCE(rcar_dmac_chan_is_busy(chan));
+
+ if (chan->mid_rid >= 0)
+ rcar_dmac_chan_write(chan, RCAR_DMARS, chan->mid_rid);
+
+ if (desc->hwdescs.use) {
+ struct rcar_dmac_xfer_chunk *chunk;
+
+ dev_dbg(chan->chan.device->dev,
+ "chan%u: queue desc %p: %u@%pad\n",
+ chan->index, desc, desc->nchunks, &desc->hwdescs.dma);
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ rcar_dmac_chan_write(chan, RCAR_DMAFIXDPBASE,
+ desc->hwdescs.dma >> 32);
+#endif
+ rcar_dmac_chan_write(chan, RCAR_DMADPBASE,
+ (desc->hwdescs.dma & 0xfffffff0) |
+ RCAR_DMADPBASE_SEL);
+ rcar_dmac_chan_write(chan, RCAR_DMACHCRB,
+ RCAR_DMACHCRB_DCNT(desc->nchunks - 1) |
+ RCAR_DMACHCRB_DRST);
+
+ /*
+ * Errata: When descriptor memory is accessed through an IOMMU
+ * the DMADAR register isn't initialized automatically from the
+ * first descriptor at beginning of transfer by the DMAC like it
+ * should. Initialize it manually with the destination address
+ * of the first chunk.
+ */
+ chunk = list_first_entry(&desc->chunks,
+ struct rcar_dmac_xfer_chunk, node);
+ rcar_dmac_chan_write(chan, RCAR_DMADAR,
+ chunk->dst_addr & 0xffffffff);
+
+ /*
+ * Program the descriptor stage interrupt to occur after the end
+ * of the first stage.
+ */
+ rcar_dmac_chan_write(chan, RCAR_DMADPCR, RCAR_DMADPCR_DIPT(1));
+
+ chcr |= RCAR_DMACHCR_RPT_SAR | RCAR_DMACHCR_RPT_DAR
+ | RCAR_DMACHCR_RPT_TCR | RCAR_DMACHCR_DPB;
+
+ /*
+ * If the descriptor isn't cyclic enable normal descriptor mode
+ * and the transfer completion interrupt.
+ */
+ if (!desc->cyclic)
+ chcr |= RCAR_DMACHCR_DPM_ENABLED | RCAR_DMACHCR_IE;
+ /*
+ * If the descriptor is cyclic and has a callback enable the
+ * descriptor stage interrupt in infinite repeat mode.
+ */
+ else if (desc->async_tx.callback)
+ chcr |= RCAR_DMACHCR_DPM_INFINITE | RCAR_DMACHCR_DSIE;
+ /*
+ * Otherwise just select infinite repeat mode without any
+ * interrupt.
+ */
+ else
+ chcr |= RCAR_DMACHCR_DPM_INFINITE;
+ } else {
+ struct rcar_dmac_xfer_chunk *chunk = desc->running;
+
+ dev_dbg(chan->chan.device->dev,
+ "chan%u: queue chunk %p: %u@%pad -> %pad\n",
+ chan->index, chunk, chunk->size, &chunk->src_addr,
+ &chunk->dst_addr);
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ rcar_dmac_chan_write(chan, RCAR_DMAFIXSAR,
+ chunk->src_addr >> 32);
+ rcar_dmac_chan_write(chan, RCAR_DMAFIXDAR,
+ chunk->dst_addr >> 32);
+#endif
+ rcar_dmac_chan_write(chan, RCAR_DMASAR,
+ chunk->src_addr & 0xffffffff);
+ rcar_dmac_chan_write(chan, RCAR_DMADAR,
+ chunk->dst_addr & 0xffffffff);
+ rcar_dmac_chan_write(chan, RCAR_DMATCR,
+ chunk->size >> desc->xfer_shift);
+
+ chcr |= RCAR_DMACHCR_DPM_DISABLED | RCAR_DMACHCR_IE;
+ }
+
+ rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr | RCAR_DMACHCR_DE);
+}
+
+static int rcar_dmac_init(struct rcar_dmac *dmac)
+{
+ u16 dmaor;
+
+ /* Clear all channels and enable the DMAC globally. */
+ rcar_dmac_write(dmac, RCAR_DMACHCLR, 0x7fff);
+ rcar_dmac_write(dmac, RCAR_DMAOR,
+ RCAR_DMAOR_PRI_FIXED | RCAR_DMAOR_DME);
+
+ dmaor = rcar_dmac_read(dmac, RCAR_DMAOR);
+ if ((dmaor & (RCAR_DMAOR_AE | RCAR_DMAOR_DME)) != RCAR_DMAOR_DME) {
+ dev_warn(dmac->dev, "DMAOR initialization failed.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Descriptors submission
+ */
+
+static dma_cookie_t rcar_dmac_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct rcar_dmac_chan *chan = to_rcar_dmac_chan(tx->chan);
+ struct rcar_dmac_desc *desc = to_rcar_dmac_desc(tx);
+ unsigned long flags;
+ dma_cookie_t cookie;
+
+ spin_lock_irqsave(&chan->lock, flags);
+
+ cookie = dma_cookie_assign(tx);
+
+ dev_dbg(chan->chan.device->dev, "chan%u: submit #%d@%p\n",
+ chan->index, tx->cookie, desc);
+
+ list_add_tail(&desc->node, &chan->desc.pending);
+ desc->running = list_first_entry(&desc->chunks,
+ struct rcar_dmac_xfer_chunk, node);
+
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ return cookie;
+}
+
+/* -----------------------------------------------------------------------------
+ * Descriptors allocation and free
+ */
+
+/*
+ * rcar_dmac_desc_alloc - Allocate a page worth of DMA descriptors
+ * @chan: the DMA channel
+ * @gfp: allocation flags
+ */
+static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
+{
+ struct rcar_dmac_desc_page *page;
+ LIST_HEAD(list);
+ unsigned int i;
+
+ page = (void *)get_zeroed_page(gfp);
+ if (!page)
+ return -ENOMEM;
+
+ for (i = 0; i < RCAR_DMAC_DESCS_PER_PAGE; ++i) {
+ struct rcar_dmac_desc *desc = &page->descs[i];
+
+ dma_async_tx_descriptor_init(&desc->async_tx, &chan->chan);
+ desc->async_tx.tx_submit = rcar_dmac_tx_submit;
+ INIT_LIST_HEAD(&desc->chunks);
+
+ list_add_tail(&desc->node, &list);
+ }
+
+ spin_lock_irq(&chan->lock);
+ list_splice_tail(&list, &chan->desc.free);
+ list_add_tail(&page->node, &chan->desc.pages);
+ spin_unlock_irq(&chan->lock);
+
+ return 0;
+}
+
+/*
+ * rcar_dmac_desc_put - Release a DMA transfer descriptor
+ * @chan: the DMA channel
+ * @desc: the descriptor
+ *
+ * Put the descriptor and its transfer chunk descriptors back in the channel's
+ * free descriptors lists. The descriptor's chunks list will be reinitialized to
+ * an empty list as a result.
+ *
+ * The descriptor must have been removed from the channel's lists before calling
+ * this function.
+ */
+static void rcar_dmac_desc_put(struct rcar_dmac_chan *chan,
+ struct rcar_dmac_desc *desc)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->lock, flags);
+ list_splice_tail_init(&desc->chunks, &chan->desc.chunks_free);
+ list_add_tail(&desc->node, &chan->desc.free);
+ spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
+{
+ struct rcar_dmac_desc *desc, *_desc;
+ LIST_HEAD(list);
+
+ /*
+ * We have to temporarily move all descriptors from the wait list to a
+ * local list as iterating over the wait list, even with
+ * list_for_each_entry_safe, isn't safe if we release the channel lock
+ * around the rcar_dmac_desc_put() call.
+ */
+ spin_lock_irq(&chan->lock);
+ list_splice_init(&chan->desc.wait, &list);
+ spin_unlock_irq(&chan->lock);
+
+ list_for_each_entry_safe(desc, _desc, &list, node) {
+ if (async_tx_test_ack(&desc->async_tx)) {
+ list_del(&desc->node);
+ rcar_dmac_desc_put(chan, desc);
+ }
+ }
+
+ if (list_empty(&list))
+ return;
+
+ /* Put the remaining descriptors back in the wait list. */
+ spin_lock_irq(&chan->lock);
+ list_splice(&list, &chan->desc.wait);
+ spin_unlock_irq(&chan->lock);
+}
+
+/*
+ * rcar_dmac_desc_get - Allocate a descriptor for a DMA transfer
+ * @chan: the DMA channel
+ *
+ * Locking: This function must be called in a non-atomic context.
+ *
+ * Return: A pointer to the allocated descriptor or NULL if no descriptor can
+ * be allocated.
+ */
+static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
+{
+ struct rcar_dmac_desc *desc;
+ int ret;
+
+ /* Recycle acked descriptors before attempting allocation. */
+ rcar_dmac_desc_recycle_acked(chan);
+
+ spin_lock_irq(&chan->lock);
+
+ while (list_empty(&chan->desc.free)) {
+ /*
+ * No free descriptors, allocate a page worth of them and try
+ * again, as someone else could race us to get the newly
+ * allocated descriptors. If the allocation fails return an
+ * error.
+ */
+ spin_unlock_irq(&chan->lock);
+ ret = rcar_dmac_desc_alloc(chan, GFP_NOWAIT);
+ if (ret < 0)
+ return NULL;
+ spin_lock_irq(&chan->lock);
+ }
+
+ desc = list_first_entry(&chan->desc.free, struct rcar_dmac_desc, node);
+ list_del(&desc->node);
+
+ spin_unlock_irq(&chan->lock);
+
+ return desc;
+}
+
+/*
+ * rcar_dmac_xfer_chunk_alloc - Allocate a page worth of transfer chunks
+ * @chan: the DMA channel
+ * @gfp: allocation flags
+ */
+static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
+{
+ struct rcar_dmac_desc_page *page;
+ LIST_HEAD(list);
+ unsigned int i;
+
+ page = (void *)get_zeroed_page(gfp);
+ if (!page)
+ return -ENOMEM;
+
+ for (i = 0; i < RCAR_DMAC_XFER_CHUNKS_PER_PAGE; ++i) {
+ struct rcar_dmac_xfer_chunk *chunk = &page->chunks[i];
+
+ list_add_tail(&chunk->node, &list);
+ }
+
+ spin_lock_irq(&chan->lock);
+ list_splice_tail(&list, &chan->desc.chunks_free);
+ list_add_tail(&page->node, &chan->desc.pages);
+ spin_unlock_irq(&chan->lock);
+
+ return 0;
+}
+
+/*
+ * rcar_dmac_xfer_chunk_get - Allocate a transfer chunk for a DMA transfer
+ * @chan: the DMA channel
+ *
+ * Locking: This function must be called in a non-atomic context.
+ *
+ * Return: A pointer to the allocated transfer chunk descriptor or NULL if no
+ * descriptor can be allocated.
+ */
+static struct rcar_dmac_xfer_chunk *
+rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan)
+{
+ struct rcar_dmac_xfer_chunk *chunk;
+ int ret;
+
+ spin_lock_irq(&chan->lock);
+
+ while (list_empty(&chan->desc.chunks_free)) {
+ /*
+ * No free descriptors, allocate a page worth of them and try
+ * again, as someone else could race us to get the newly
+ * allocated descriptors. If the allocation fails return an
+ * error.
+ */
+ spin_unlock_irq(&chan->lock);
+ ret = rcar_dmac_xfer_chunk_alloc(chan, GFP_NOWAIT);
+ if (ret < 0)
+ return NULL;
+ spin_lock_irq(&chan->lock);
+ }
+
+ chunk = list_first_entry(&chan->desc.chunks_free,
+ struct rcar_dmac_xfer_chunk, node);
+ list_del(&chunk->node);
+
+ spin_unlock_irq(&chan->lock);
+
+ return chunk;
+}
+
+static void rcar_dmac_realloc_hwdesc(struct rcar_dmac_chan *chan,
+ struct rcar_dmac_desc *desc, size_t size)
+{
+ /*
+ * dma_alloc_coherent() allocates memory in page size increments. To
+ * avoid reallocating the hardware descriptors when the allocated size
+ * wouldn't change align the requested size to a multiple of the page
+ * size.
+ */
+ size = PAGE_ALIGN(size);
+
+ if (desc->hwdescs.size == size)
+ return;
+
+ if (desc->hwdescs.mem) {
+ dma_free_coherent(chan->chan.device->dev, desc->hwdescs.size,
+ desc->hwdescs.mem, desc->hwdescs.dma);
+ desc->hwdescs.mem = NULL;
+ desc->hwdescs.size = 0;
+ }
+
+ if (!size)
+ return;
+
+ desc->hwdescs.mem = dma_alloc_coherent(chan->chan.device->dev, size,
+ &desc->hwdescs.dma, GFP_NOWAIT);
+ if (!desc->hwdescs.mem)
+ return;
+
+ desc->hwdescs.size = size;
+}
+
+static int rcar_dmac_fill_hwdesc(struct rcar_dmac_chan *chan,
+ struct rcar_dmac_desc *desc)
+{
+ struct rcar_dmac_xfer_chunk *chunk;
+ struct rcar_dmac_hw_desc *hwdesc;
+
+ rcar_dmac_realloc_hwdesc(chan, desc, desc->nchunks * sizeof(*hwdesc));
+
+ hwdesc = desc->hwdescs.mem;
+ if (!hwdesc)
+ return -ENOMEM;
+
+ list_for_each_entry(chunk, &desc->chunks, node) {
+ hwdesc->sar = chunk->src_addr;
+ hwdesc->dar = chunk->dst_addr;
+ hwdesc->tcr = chunk->size >> desc->xfer_shift;
+ hwdesc++;
+ }
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Stop and reset
+ */
+
+static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
+{
+ u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+
+ chcr &= ~(RCAR_DMACHCR_DSE | RCAR_DMACHCR_DSIE | RCAR_DMACHCR_IE |
+ RCAR_DMACHCR_TE | RCAR_DMACHCR_DE);
+ rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
+}
+
+static void rcar_dmac_chan_reinit(struct rcar_dmac_chan *chan)
+{
+ struct rcar_dmac_desc *desc, *_desc;
+ unsigned long flags;
+ LIST_HEAD(descs);
+
+ spin_lock_irqsave(&chan->lock, flags);
+
+ /* Move all non-free descriptors to the local lists. */
+ list_splice_init(&chan->desc.pending, &descs);
+ list_splice_init(&chan->desc.active, &descs);
+ list_splice_init(&chan->desc.done, &descs);
+ list_splice_init(&chan->desc.wait, &descs);
+
+ chan->desc.running = NULL;
+
+ spin_unlock_irqrestore(&chan->lock, flags);
+
+ list_for_each_entry_safe(desc, _desc, &descs, node) {
+ list_del(&desc->node);
+ rcar_dmac_desc_put(chan, desc);
+ }
+}
+
+static void rcar_dmac_stop(struct rcar_dmac *dmac)
+{
+ rcar_dmac_write(dmac, RCAR_DMAOR, 0);
+}
+
+static void rcar_dmac_abort(struct rcar_dmac *dmac)
+{
+ unsigned int i;
+
+ /* Stop all channels. */
+ for (i = 0; i < dmac->n_channels; ++i) {
+ struct rcar_dmac_chan *chan = &dmac->channels[i];
+
+ /* Stop and reinitialize the channel. */
+ spin_lock(&chan->lock);
+ rcar_dmac_chan_halt(chan);
+ spin_unlock(&chan->lock);
+
+ rcar_dmac_chan_reinit(chan);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Descriptors preparation
+ */
+
+static void rcar_dmac_chan_configure_desc(struct rcar_dmac_chan *chan,
+ struct rcar_dmac_desc *desc)
+{
+ static const u32 chcr_ts[] = {
+ RCAR_DMACHCR_TS_1B, RCAR_DMACHCR_TS_2B,
+ RCAR_DMACHCR_TS_4B, RCAR_DMACHCR_TS_8B,
+ RCAR_DMACHCR_TS_16B, RCAR_DMACHCR_TS_32B,
+ RCAR_DMACHCR_TS_64B,
+ };
+
+ unsigned int xfer_size;
+ u32 chcr;
+
+ switch (desc->direction) {
+ case DMA_DEV_TO_MEM:
+ chcr = RCAR_DMACHCR_DM_INC | RCAR_DMACHCR_SM_FIXED
+ | RCAR_DMACHCR_RS_DMARS;
+ xfer_size = chan->src_xfer_size;
+ break;
+
+ case DMA_MEM_TO_DEV:
+ chcr = RCAR_DMACHCR_DM_FIXED | RCAR_DMACHCR_SM_INC
+ | RCAR_DMACHCR_RS_DMARS;
+ xfer_size = chan->dst_xfer_size;
+ break;
+
+ case DMA_MEM_TO_MEM:
+ default:
+ chcr = RCAR_DMACHCR_DM_INC | RCAR_DMACHCR_SM_INC
+ | RCAR_DMACHCR_RS_AUTO;
+ xfer_size = RCAR_DMAC_MEMCPY_XFER_SIZE;
+ break;
+ }
+
+ desc->xfer_shift = ilog2(xfer_size);
+ desc->chcr = chcr | chcr_ts[desc->xfer_shift];
+}
+
+/*
+ * rcar_dmac_chan_prep_sg - prepare transfer descriptors from an SG list
+ *
+ * Common routine for public (MEMCPY) and slave DMA. The MEMCPY case is also
+ * converted to scatter-gather to guarantee consistent locking and a correct
+ * list manipulation. For slave DMA direction carries the usual meaning, and,
+ * logically, the SG list is RAM and the addr variable contains slave address,
+ * e.g., the FIFO I/O register. For MEMCPY direction equals DMA_MEM_TO_MEM
+ * and the SG list contains only one element and points at the source buffer.
+ */
+static struct dma_async_tx_descriptor *
+rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, dma_addr_t dev_addr,
+ enum dma_transfer_direction dir, unsigned long dma_flags,
+ bool cyclic)
+{
+ struct rcar_dmac_xfer_chunk *chunk;
+ struct rcar_dmac_desc *desc;
+ struct scatterlist *sg;
+ unsigned int nchunks = 0;
+ unsigned int max_chunk_size;
+ unsigned int full_size = 0;
+ bool highmem = false;
+ unsigned int i;
+
+ desc = rcar_dmac_desc_get(chan);
+ if (!desc)
+ return NULL;
+
+ desc->async_tx.flags = dma_flags;
+ desc->async_tx.cookie = -EBUSY;
+
+ desc->cyclic = cyclic;
+ desc->direction = dir;
+
+ rcar_dmac_chan_configure_desc(chan, desc);
+
+ max_chunk_size = (RCAR_DMATCR_MASK + 1) << desc->xfer_shift;
+
+ /*
+ * Allocate and fill the transfer chunk descriptors. We own the only
+ * reference to the DMA descriptor, there's no need for locking.
+ */
+ for_each_sg(sgl, sg, sg_len, i) {
+ dma_addr_t mem_addr = sg_dma_address(sg);
+ unsigned int len = sg_dma_len(sg);
+
+ full_size += len;
+
+ while (len) {
+ unsigned int size = min(len, max_chunk_size);
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ /*
+ * Prevent individual transfers from crossing 4GB
+ * boundaries.
+ */
+ if (dev_addr >> 32 != (dev_addr + size - 1) >> 32)
+ size = ALIGN(dev_addr, 1ULL << 32) - dev_addr;
+ if (mem_addr >> 32 != (mem_addr + size - 1) >> 32)
+ size = ALIGN(mem_addr, 1ULL << 32) - mem_addr;
+
+ /*
+ * Check if either of the source or destination address
+ * can't be expressed in 32 bits. If so we can't use
+ * hardware descriptor lists.
+ */
+ if (dev_addr >> 32 || mem_addr >> 32)
+ highmem = true;
+#endif
+
+ chunk = rcar_dmac_xfer_chunk_get(chan);
+ if (!chunk) {
+ rcar_dmac_desc_put(chan, desc);
+ return NULL;
+ }
+
+ if (dir == DMA_DEV_TO_MEM) {
+ chunk->src_addr = dev_addr;
+ chunk->dst_addr = mem_addr;
+ } else {
+ chunk->src_addr = mem_addr;
+ chunk->dst_addr = dev_addr;
+ }
+
+ chunk->size = size;
+
+ dev_dbg(chan->chan.device->dev,
+ "chan%u: chunk %p/%p sgl %u@%p, %u/%u %pad -> %pad\n",
+ chan->index, chunk, desc, i, sg, size, len,
+ &chunk->src_addr, &chunk->dst_addr);
+
+ mem_addr += size;
+ if (dir == DMA_MEM_TO_MEM)
+ dev_addr += size;
+
+ len -= size;
+
+ list_add_tail(&chunk->node, &desc->chunks);
+ nchunks++;
+ }
+ }
+
+ desc->nchunks = nchunks;
+ desc->size = full_size;
+
+ /*
+ * Use hardware descriptor lists if possible when more than one chunk
+ * needs to be transferred (otherwise they don't make much sense).
+ *
+ * The highmem check currently covers the whole transfer. As an
+ * optimization we could use descriptor lists for consecutive lowmem
+ * chunks and direct manual mode for highmem chunks. Whether the
+ * performance improvement would be significant enough compared to the
+ * additional complexity remains to be investigated.
+ */
+ desc->hwdescs.use = !highmem && nchunks > 1;
+ if (desc->hwdescs.use) {
+ if (rcar_dmac_fill_hwdesc(chan, desc) < 0)
+ desc->hwdescs.use = false;
+ }
+
+ return &desc->async_tx;
+}
+
+/* -----------------------------------------------------------------------------
+ * DMA engine operations
+ */
+
+static int rcar_dmac_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ int ret;
+
+ INIT_LIST_HEAD(&rchan->desc.chunks_free);
+ INIT_LIST_HEAD(&rchan->desc.pages);
+
+ /* Preallocate descriptors. */
+ ret = rcar_dmac_xfer_chunk_alloc(rchan, GFP_KERNEL);
+ if (ret < 0)
+ return -ENOMEM;
+
+ ret = rcar_dmac_desc_alloc(rchan, GFP_KERNEL);
+ if (ret < 0)
+ return -ENOMEM;
+
+ return pm_runtime_get_sync(chan->device->dev);
+}
+
+static void rcar_dmac_free_chan_resources(struct dma_chan *chan)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ struct rcar_dmac *dmac = to_rcar_dmac(chan->device);
+ struct rcar_dmac_desc_page *page, *_page;
+ struct rcar_dmac_desc *desc;
+ LIST_HEAD(list);
+
+ /* Protect against ISR */
+ spin_lock_irq(&rchan->lock);
+ rcar_dmac_chan_halt(rchan);
+ spin_unlock_irq(&rchan->lock);
+
+ /* Now no new interrupts will occur */
+
+ if (rchan->mid_rid >= 0) {
+ /* The caller is holding dma_list_mutex */
+ clear_bit(rchan->mid_rid, dmac->modules);
+ rchan->mid_rid = -EINVAL;
+ }
+
+ list_splice_init(&rchan->desc.free, &list);
+ list_splice_init(&rchan->desc.pending, &list);
+ list_splice_init(&rchan->desc.active, &list);
+ list_splice_init(&rchan->desc.done, &list);
+ list_splice_init(&rchan->desc.wait, &list);
+
+ list_for_each_entry(desc, &list, node)
+ rcar_dmac_realloc_hwdesc(rchan, desc, 0);
+
+ list_for_each_entry_safe(page, _page, &rchan->desc.pages, node) {
+ list_del(&page->node);
+ free_page((unsigned long)page);
+ }
+
+ pm_runtime_put(chan->device->dev);
+}
+
+static struct dma_async_tx_descriptor *
+rcar_dmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest,
+ dma_addr_t dma_src, size_t len, unsigned long flags)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ struct scatterlist sgl;
+
+ if (!len)
+ return NULL;
+
+ sg_init_table(&sgl, 1);
+ sg_set_page(&sgl, pfn_to_page(PFN_DOWN(dma_src)), len,
+ offset_in_page(dma_src));
+ sg_dma_address(&sgl) = dma_src;
+ sg_dma_len(&sgl) = len;
+
+ return rcar_dmac_chan_prep_sg(rchan, &sgl, 1, dma_dest,
+ DMA_MEM_TO_MEM, flags, false);
+}
+
+static struct dma_async_tx_descriptor *
+rcar_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction dir,
+ unsigned long flags, void *context)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ dma_addr_t dev_addr;
+
+ /* Someone calling slave DMA on a generic channel? */
+ if (rchan->mid_rid < 0 || !sg_len) {
+ dev_warn(chan->device->dev,
+ "%s: bad parameter: len=%d, id=%d\n",
+ __func__, sg_len, rchan->mid_rid);
+ return NULL;
+ }
+
+ dev_addr = dir == DMA_DEV_TO_MEM
+ ? rchan->src_slave_addr : rchan->dst_slave_addr;
+ return rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr,
+ dir, flags, false);
+}
+
+#define RCAR_DMAC_MAX_SG_LEN 32
+
+static struct dma_async_tx_descriptor *
+rcar_dmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
+ size_t buf_len, size_t period_len,
+ enum dma_transfer_direction dir, unsigned long flags)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ struct dma_async_tx_descriptor *desc;
+ struct scatterlist *sgl;
+ dma_addr_t dev_addr;
+ unsigned int sg_len;
+ unsigned int i;
+
+ /* Someone calling slave DMA on a generic channel? */
+ if (rchan->mid_rid < 0 || buf_len < period_len) {
+ dev_warn(chan->device->dev,
+ "%s: bad parameter: buf_len=%zu, period_len=%zu, id=%d\n",
+ __func__, buf_len, period_len, rchan->mid_rid);
+ return NULL;
+ }
+
+ sg_len = buf_len / period_len;
+ if (sg_len > RCAR_DMAC_MAX_SG_LEN) {
+ dev_err(chan->device->dev,
+ "chan%u: sg length %d exceds limit %d",
+ rchan->index, sg_len, RCAR_DMAC_MAX_SG_LEN);
+ return NULL;
+ }
+
+ /*
+ * Allocate the sg list dynamically as it would consume too much stack
+ * space.
+ */
+ sgl = kcalloc(sg_len, sizeof(*sgl), GFP_NOWAIT);
+ if (!sgl)
+ return NULL;
+
+ sg_init_table(sgl, sg_len);
+
+ for (i = 0; i < sg_len; ++i) {
+ dma_addr_t src = buf_addr + (period_len * i);
+
+ sg_set_page(&sgl[i], pfn_to_page(PFN_DOWN(src)), period_len,
+ offset_in_page(src));
+ sg_dma_address(&sgl[i]) = src;
+ sg_dma_len(&sgl[i]) = period_len;
+ }
+
+ dev_addr = dir == DMA_DEV_TO_MEM
+ ? rchan->src_slave_addr : rchan->dst_slave_addr;
+ desc = rcar_dmac_chan_prep_sg(rchan, sgl, sg_len, dev_addr,
+ dir, flags, true);
+
+ kfree(sgl);
+ return desc;
+}
+
+static int rcar_dmac_device_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+
+ /*
+ * We could lock this, but you shouldn't be configuring the
+ * channel, while using it...
+ */
+ rchan->src_slave_addr = cfg->src_addr;
+ rchan->dst_slave_addr = cfg->dst_addr;
+ rchan->src_xfer_size = cfg->src_addr_width;
+ rchan->dst_xfer_size = cfg->dst_addr_width;
+
+ return 0;
+}
+
+static int rcar_dmac_chan_terminate_all(struct dma_chan *chan)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&rchan->lock, flags);
+ rcar_dmac_chan_halt(rchan);
+ spin_unlock_irqrestore(&rchan->lock, flags);
+
+ /*
+ * FIXME: No new interrupt can occur now, but the IRQ thread might still
+ * be running.
+ */
+
+ rcar_dmac_chan_reinit(rchan);
+
+ return 0;
+}
+
+static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
+ dma_cookie_t cookie)
+{
+ struct rcar_dmac_desc *desc = chan->desc.running;
+ struct rcar_dmac_xfer_chunk *running = NULL;
+ struct rcar_dmac_xfer_chunk *chunk;
+ unsigned int residue = 0;
+ unsigned int dptr = 0;
+
+ if (!desc)
+ return 0;
+
+ /*
+ * If the cookie doesn't correspond to the currently running transfer
+ * then the descriptor hasn't been processed yet, and the residue is
+ * equal to the full descriptor size.
+ */
+ if (cookie != desc->async_tx.cookie)
+ return desc->size;
+
+ /*
+ * In descriptor mode the descriptor running pointer is not maintained
+ * by the interrupt handler, find the running descriptor from the
+ * descriptor pointer field in the CHCRB register. In non-descriptor
+ * mode just use the running descriptor pointer.
+ */
+ if (desc->hwdescs.use) {
+ dptr = (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) &
+ RCAR_DMACHCRB_DPTR_MASK) >> RCAR_DMACHCRB_DPTR_SHIFT;
+ WARN_ON(dptr >= desc->nchunks);
+ } else {
+ running = desc->running;
+ }
+
+ /* Compute the size of all chunks still to be transferred. */
+ list_for_each_entry_reverse(chunk, &desc->chunks, node) {
+ if (chunk == running || ++dptr == desc->nchunks)
+ break;
+
+ residue += chunk->size;
+ }
+
+ /* Add the residue for the current chunk. */
+ residue += rcar_dmac_chan_read(chan, RCAR_DMATCR) << desc->xfer_shift;
+
+ return residue;
+}
+
+static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ enum dma_status status;
+ unsigned long flags;
+ unsigned int residue;
+
+ status = dma_cookie_status(chan, cookie, txstate);
+ if (status == DMA_COMPLETE || !txstate)
+ return status;
+
+ spin_lock_irqsave(&rchan->lock, flags);
+ residue = rcar_dmac_chan_get_residue(rchan, cookie);
+ spin_unlock_irqrestore(&rchan->lock, flags);
+
+ dma_set_residue(txstate, residue);
+
+ return status;
+}
+
+static void rcar_dmac_issue_pending(struct dma_chan *chan)
+{
+ struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&rchan->lock, flags);
+
+ if (list_empty(&rchan->desc.pending))
+ goto done;
+
+ /* Append the pending list to the active list. */
+ list_splice_tail_init(&rchan->desc.pending, &rchan->desc.active);
+
+ /*
+ * If no transfer is running pick the first descriptor from the active
+ * list and start the transfer.
+ */
+ if (!rchan->desc.running) {
+ struct rcar_dmac_desc *desc;
+
+ desc = list_first_entry(&rchan->desc.active,
+ struct rcar_dmac_desc, node);
+ rchan->desc.running = desc;
+
+ rcar_dmac_chan_start_xfer(rchan);
+ }
+
+done:
+ spin_unlock_irqrestore(&rchan->lock, flags);
+}
+
+/* -----------------------------------------------------------------------------
+ * IRQ handling
+ */
+
+static irqreturn_t rcar_dmac_isr_desc_stage_end(struct rcar_dmac_chan *chan)
+{
+ struct rcar_dmac_desc *desc = chan->desc.running;
+ unsigned int stage;
+
+ if (WARN_ON(!desc || !desc->cyclic)) {
+ /*
+ * This should never happen, there should always be a running
+ * cyclic descriptor when a descriptor stage end interrupt is
+ * triggered. Warn and return.
+ */
+ return IRQ_NONE;
+ }
+
+ /* Program the interrupt pointer to the next stage. */
+ stage = (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) &
+ RCAR_DMACHCRB_DPTR_MASK) >> RCAR_DMACHCRB_DPTR_SHIFT;
+ rcar_dmac_chan_write(chan, RCAR_DMADPCR, RCAR_DMADPCR_DIPT(stage));
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t rcar_dmac_isr_transfer_end(struct rcar_dmac_chan *chan)
+{
+ struct rcar_dmac_desc *desc = chan->desc.running;
+ irqreturn_t ret = IRQ_WAKE_THREAD;
+
+ if (WARN_ON_ONCE(!desc)) {
+ /*
+ * This should never happen, there should always be a running
+ * descriptor when a transfer end interrupt is triggered. Warn
+ * and return.
+ */
+ return IRQ_NONE;
+ }
+
+ /*
+ * The transfer end interrupt isn't generated for each chunk when using
+ * descriptor mode. Only update the running chunk pointer in
+ * non-descriptor mode.
+ */
+ if (!desc->hwdescs.use) {
+ /*
+ * If we haven't completed the last transfer chunk simply move
+ * to the next one. Only wake the IRQ thread if the transfer is
+ * cyclic.
+ */
+ if (!list_is_last(&desc->running->node, &desc->chunks)) {
+ desc->running = list_next_entry(desc->running, node);
+ if (!desc->cyclic)
+ ret = IRQ_HANDLED;
+ goto done;
+ }
+
+ /*
+ * We've completed the last transfer chunk. If the transfer is
+ * cyclic, move back to the first one.
+ */
+ if (desc->cyclic) {
+ desc->running =
+ list_first_entry(&desc->chunks,
+ struct rcar_dmac_xfer_chunk,
+ node);
+ goto done;
+ }
+ }
+
+ /* The descriptor is complete, move it to the done list. */
+ list_move_tail(&desc->node, &chan->desc.done);
+
+ /* Queue the next descriptor, if any. */
+ if (!list_empty(&chan->desc.active))
+ chan->desc.running = list_first_entry(&chan->desc.active,
+ struct rcar_dmac_desc,
+ node);
+ else
+ chan->desc.running = NULL;
+
+done:
+ if (chan->desc.running)
+ rcar_dmac_chan_start_xfer(chan);
+
+ return ret;
+}
+
+static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
+{
+ u32 mask = RCAR_DMACHCR_DSE | RCAR_DMACHCR_TE;
+ struct rcar_dmac_chan *chan = dev;
+ irqreturn_t ret = IRQ_NONE;
+ u32 chcr;
+
+ spin_lock(&chan->lock);
+
+ chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+ if (chcr & RCAR_DMACHCR_TE)
+ mask |= RCAR_DMACHCR_DE;
+ rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr & ~mask);
+
+ if (chcr & RCAR_DMACHCR_DSE)
+ ret |= rcar_dmac_isr_desc_stage_end(chan);
+
+ if (chcr & RCAR_DMACHCR_TE)
+ ret |= rcar_dmac_isr_transfer_end(chan);
+
+ spin_unlock(&chan->lock);
+
+ return ret;
+}
+
+static irqreturn_t rcar_dmac_isr_channel_thread(int irq, void *dev)
+{
+ struct rcar_dmac_chan *chan = dev;
+ struct rcar_dmac_desc *desc;
+
+ spin_lock_irq(&chan->lock);
+
+ /* For cyclic transfers notify the user after every chunk. */
+ if (chan->desc.running && chan->desc.running->cyclic) {
+ dma_async_tx_callback callback;
+ void *callback_param;
+
+ desc = chan->desc.running;
+ callback = desc->async_tx.callback;
+ callback_param = desc->async_tx.callback_param;
+
+ if (callback) {
+ spin_unlock_irq(&chan->lock);
+ callback(callback_param);
+ spin_lock_irq(&chan->lock);
+ }
+ }
+
+ /*
+ * Call the callback function for all descriptors on the done list and
+ * move them to the ack wait list.
+ */
+ while (!list_empty(&chan->desc.done)) {
+ desc = list_first_entry(&chan->desc.done, struct rcar_dmac_desc,
+ node);
+ dma_cookie_complete(&desc->async_tx);
+ list_del(&desc->node);
+
+ if (desc->async_tx.callback) {
+ spin_unlock_irq(&chan->lock);
+ /*
+ * We own the only reference to this descriptor, we can
+ * safely dereference it without holding the channel
+ * lock.
+ */
+ desc->async_tx.callback(desc->async_tx.callback_param);
+ spin_lock_irq(&chan->lock);
+ }
+
+ list_add_tail(&desc->node, &chan->desc.wait);
+ }
+
+ spin_unlock_irq(&chan->lock);
+
+ /* Recycle all acked descriptors. */
+ rcar_dmac_desc_recycle_acked(chan);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t rcar_dmac_isr_error(int irq, void *data)
+{
+ struct rcar_dmac *dmac = data;
+
+ if (!(rcar_dmac_read(dmac, RCAR_DMAOR) & RCAR_DMAOR_AE))
+ return IRQ_NONE;
+
+ /*
+ * An unrecoverable error occurred on an unknown channel. Halt the DMAC,
+ * abort transfers on all channels, and reinitialize the DMAC.
+ */
+ rcar_dmac_stop(dmac);
+ rcar_dmac_abort(dmac);
+ rcar_dmac_init(dmac);
+
+ return IRQ_HANDLED;
+}
+
+/* -----------------------------------------------------------------------------
+ * OF xlate and channel filter
+ */
+
+static bool rcar_dmac_chan_filter(struct dma_chan *chan, void *arg)
+{
+ struct rcar_dmac *dmac = to_rcar_dmac(chan->device);
+ struct of_phandle_args *dma_spec = arg;
+
+ /*
+ * FIXME: Using a filter on OF platforms is a nonsense. The OF xlate
+ * function knows from which device it wants to allocate a channel from,
+ * and would be perfectly capable of selecting the channel it wants.
+ * Forcing it to call dma_request_channel() and iterate through all
+ * channels from all controllers is just pointless.
+ */
+ if (chan->device->device_config != rcar_dmac_device_config ||
+ dma_spec->np != chan->device->dev->of_node)
+ return false;
+
+ return !test_and_set_bit(dma_spec->args[0], dmac->modules);
+}
+
+static struct dma_chan *rcar_dmac_of_xlate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct rcar_dmac_chan *rchan;
+ struct dma_chan *chan;
+ dma_cap_mask_t mask;
+
+ if (dma_spec->args_count != 1)
+ return NULL;
+
+ /* Only slave DMA channels can be allocated via DT */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ chan = dma_request_channel(mask, rcar_dmac_chan_filter, dma_spec);
+ if (!chan)
+ return NULL;
+
+ rchan = to_rcar_dmac_chan(chan);
+ rchan->mid_rid = dma_spec->args[0];
+
+ return chan;
+}
+
+/* -----------------------------------------------------------------------------
+ * Power management
+ */
+
+#ifdef CONFIG_PM_SLEEP
+static int rcar_dmac_sleep_suspend(struct device *dev)
+{
+ /*
+ * TODO: Wait for the current transfer to complete and stop the device.
+ */
+ return 0;
+}
+
+static int rcar_dmac_sleep_resume(struct device *dev)
+{
+ /* TODO: Resume transfers, if any. */
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int rcar_dmac_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int rcar_dmac_runtime_resume(struct device *dev)
+{
+ struct rcar_dmac *dmac = dev_get_drvdata(dev);
+
+ return rcar_dmac_init(dmac);
+}
+#endif
+
+static const struct dev_pm_ops rcar_dmac_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(rcar_dmac_sleep_suspend, rcar_dmac_sleep_resume)
+ SET_RUNTIME_PM_OPS(rcar_dmac_runtime_suspend, rcar_dmac_runtime_resume,
+ NULL)
+};
+
+/* -----------------------------------------------------------------------------
+ * Probe and remove
+ */
+
+static int rcar_dmac_chan_probe(struct rcar_dmac *dmac,
+ struct rcar_dmac_chan *rchan,
+ unsigned int index)
+{
+ struct platform_device *pdev = to_platform_device(dmac->dev);
+ struct dma_chan *chan = &rchan->chan;
+ char pdev_irqname[5];
+ char *irqname;
+ int irq;
+ int ret;
+
+ rchan->index = index;
+ rchan->iomem = dmac->iomem + RCAR_DMAC_CHAN_OFFSET(index);
+ rchan->mid_rid = -EINVAL;
+
+ spin_lock_init(&rchan->lock);
+
+ INIT_LIST_HEAD(&rchan->desc.free);
+ INIT_LIST_HEAD(&rchan->desc.pending);
+ INIT_LIST_HEAD(&rchan->desc.active);
+ INIT_LIST_HEAD(&rchan->desc.done);
+ INIT_LIST_HEAD(&rchan->desc.wait);
+
+ /* Request the channel interrupt. */
+ sprintf(pdev_irqname, "ch%u", index);
+ irq = platform_get_irq_byname(pdev, pdev_irqname);
+ if (irq < 0) {
+ dev_err(dmac->dev, "no IRQ specified for channel %u\n", index);
+ return -ENODEV;
+ }
+
+ irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u",
+ dev_name(dmac->dev), index);
+ if (!irqname)
+ return -ENOMEM;
+
+ ret = devm_request_threaded_irq(dmac->dev, irq, rcar_dmac_isr_channel,
+ rcar_dmac_isr_channel_thread, 0,
+ irqname, rchan);
+ if (ret) {
+ dev_err(dmac->dev, "failed to request IRQ %u (%d)\n", irq, ret);
+ return ret;
+ }
+
+ /*
+ * Initialize the DMA engine channel and add it to the DMA engine
+ * channels list.
+ */
+ chan->device = &dmac->engine;
+ dma_cookie_init(chan);
+
+ list_add_tail(&chan->device_node, &dmac->engine.channels);
+
+ return 0;
+}
+
+static int rcar_dmac_parse_of(struct device *dev, struct rcar_dmac *dmac)
+{
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ ret = of_property_read_u32(np, "dma-channels", &dmac->n_channels);
+ if (ret < 0) {
+ dev_err(dev, "unable to read dma-channels property\n");
+ return ret;
+ }
+
+ if (dmac->n_channels <= 0 || dmac->n_channels >= 100) {
+ dev_err(dev, "invalid number of channels %u\n",
+ dmac->n_channels);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rcar_dmac_probe(struct platform_device *pdev)
+{
+ const enum dma_slave_buswidth widths = DMA_SLAVE_BUSWIDTH_1_BYTE |
+ DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES |
+ DMA_SLAVE_BUSWIDTH_8_BYTES | DMA_SLAVE_BUSWIDTH_16_BYTES |
+ DMA_SLAVE_BUSWIDTH_32_BYTES | DMA_SLAVE_BUSWIDTH_64_BYTES;
+ unsigned int channels_offset = 0;
+ struct dma_device *engine;
+ struct rcar_dmac *dmac;
+ struct resource *mem;
+ unsigned int i;
+ char *irqname;
+ int irq;
+ int ret;
+
+ dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL);
+ if (!dmac)
+ return -ENOMEM;
+
+ dmac->dev = &pdev->dev;
+ platform_set_drvdata(pdev, dmac);
+
+ ret = rcar_dmac_parse_of(&pdev->dev, dmac);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * A still unconfirmed hardware bug prevents the IPMMU microTLB 0 to be
+ * flushed correctly, resulting in memory corruption. DMAC 0 channel 0
+ * is connected to microTLB 0 on currently supported platforms, so we
+ * can't use it with the IPMMU. As the IOMMU API operates at the device
+ * level we can't disable it selectively, so ignore channel 0 for now if
+ * the device is part of an IOMMU group.
+ */
+ if (pdev->dev.iommu_group) {
+ dmac->n_channels--;
+ channels_offset = 1;
+ }
+
+ dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels,
+ sizeof(*dmac->channels), GFP_KERNEL);
+ if (!dmac->channels)
+ return -ENOMEM;
+
+ /* Request resources. */
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dmac->iomem = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(dmac->iomem))
+ return PTR_ERR(dmac->iomem);
+
+ irq = platform_get_irq_byname(pdev, "error");
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no error IRQ specified\n");
+ return -ENODEV;
+ }
+
+ irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:error",
+ dev_name(dmac->dev));
+ if (!irqname)
+ return -ENOMEM;
+
+ ret = devm_request_irq(&pdev->dev, irq, rcar_dmac_isr_error, 0,
+ irqname, dmac);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request IRQ %u (%d)\n",
+ irq, ret);
+ return ret;
+ }
+
+ /* Enable runtime PM and initialize the device. */
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "runtime PM get sync failed (%d)\n", ret);
+ return ret;
+ }
+
+ ret = rcar_dmac_init(dmac);
+ pm_runtime_put(&pdev->dev);
+
+ if (ret) {
+ dev_err(&pdev->dev, "failed to reset device\n");
+ goto error;
+ }
+
+ /* Initialize the channels. */
+ INIT_LIST_HEAD(&dmac->engine.channels);
+
+ for (i = 0; i < dmac->n_channels; ++i) {
+ ret = rcar_dmac_chan_probe(dmac, &dmac->channels[i],
+ i + channels_offset);
+ if (ret < 0)
+ goto error;
+ }
+
+ /* Register the DMAC as a DMA provider for DT. */
+ ret = of_dma_controller_register(pdev->dev.of_node, rcar_dmac_of_xlate,
+ NULL);
+ if (ret < 0)
+ goto error;
+
+ /*
+ * Register the DMA engine device.
+ *
+ * Default transfer size of 32 bytes requires 32-byte alignment.
+ */
+ engine = &dmac->engine;
+ dma_cap_set(DMA_MEMCPY, engine->cap_mask);
+ dma_cap_set(DMA_SLAVE, engine->cap_mask);
+
+ engine->dev = &pdev->dev;
+ engine->copy_align = ilog2(RCAR_DMAC_MEMCPY_XFER_SIZE);
+
+ engine->src_addr_widths = widths;
+ engine->dst_addr_widths = widths;
+ engine->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
+ engine->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+
+ engine->device_alloc_chan_resources = rcar_dmac_alloc_chan_resources;
+ engine->device_free_chan_resources = rcar_dmac_free_chan_resources;
+ engine->device_prep_dma_memcpy = rcar_dmac_prep_dma_memcpy;
+ engine->device_prep_slave_sg = rcar_dmac_prep_slave_sg;
+ engine->device_prep_dma_cyclic = rcar_dmac_prep_dma_cyclic;
+ engine->device_config = rcar_dmac_device_config;
+ engine->device_terminate_all = rcar_dmac_chan_terminate_all;
+ engine->device_tx_status = rcar_dmac_tx_status;
+ engine->device_issue_pending = rcar_dmac_issue_pending;
+
+ ret = dma_async_device_register(engine);
+ if (ret < 0)
+ goto error;
+
+ return 0;
+
+error:
+ of_dma_controller_free(pdev->dev.of_node);
+ pm_runtime_disable(&pdev->dev);
+ return ret;
+}
+
+static int rcar_dmac_remove(struct platform_device *pdev)
+{
+ struct rcar_dmac *dmac = platform_get_drvdata(pdev);
+
+ of_dma_controller_free(pdev->dev.of_node);
+ dma_async_device_unregister(&dmac->engine);
+
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static void rcar_dmac_shutdown(struct platform_device *pdev)
+{
+ struct rcar_dmac *dmac = platform_get_drvdata(pdev);
+
+ rcar_dmac_stop(dmac);
+}
+
+static const struct of_device_id rcar_dmac_of_ids[] = {
+ { .compatible = "renesas,rcar-dmac", },
+ { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rcar_dmac_of_ids);
+
+static struct platform_driver rcar_dmac_driver = {
+ .driver = {
+ .pm = &rcar_dmac_pm,
+ .name = "rcar-dmac",
+ .of_match_table = rcar_dmac_of_ids,
+ },
+ .probe = rcar_dmac_probe,
+ .remove = rcar_dmac_remove,
+ .shutdown = rcar_dmac_shutdown,
+};
+
+module_platform_driver(rcar_dmac_driver);
+
+MODULE_DESCRIPTION("R-Car Gen2 DMA Controller Driver");
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/sh/rcar-hpbdma.c b/drivers/dma/sh/rcar-hpbdma.c
index 20a6f6f2a018..749f26ecd3b3 100644
--- a/drivers/dma/sh/rcar-hpbdma.c
+++ b/drivers/dma/sh/rcar-hpbdma.c
@@ -534,6 +534,8 @@ static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id)
static int hpb_dmae_probe(struct platform_device *pdev)
{
+ const enum dma_slave_buswidth widths = DMA_SLAVE_BUSWIDTH_1_BYTE |
+ DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES;
struct hpb_dmae_pdata *pdata = pdev->dev.platform_data;
struct hpb_dmae_device *hpbdev;
struct dma_device *dma_dev;
@@ -595,6 +597,10 @@ static int hpb_dmae_probe(struct platform_device *pdev)
dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask);
dma_cap_set(DMA_SLAVE, dma_dev->cap_mask);
+ dma_dev->src_addr_widths = widths;
+ dma_dev->dst_addr_widths = widths;
+ dma_dev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
+ dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
hpbdev->shdma_dev.ops = &hpb_dmae_ops;
hpbdev->shdma_dev.desc_size = sizeof(struct hpb_desc);
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
index 3a2adb131d46..8ee383d339a5 100644
--- a/drivers/dma/sh/shdma-base.c
+++ b/drivers/dma/sh/shdma-base.c
@@ -729,57 +729,50 @@ static struct dma_async_tx_descriptor *shdma_prep_dma_cyclic(
return desc;
}
-static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int shdma_terminate_all(struct dma_chan *chan)
{
struct shdma_chan *schan = to_shdma_chan(chan);
struct shdma_dev *sdev = to_shdma_dev(chan->device);
const struct shdma_ops *ops = sdev->ops;
- struct dma_slave_config *config;
unsigned long flags;
- int ret;
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- spin_lock_irqsave(&schan->chan_lock, flags);
- ops->halt_channel(schan);
+ spin_lock_irqsave(&schan->chan_lock, flags);
+ ops->halt_channel(schan);
- if (ops->get_partial && !list_empty(&schan->ld_queue)) {
- /* Record partial transfer */
- struct shdma_desc *desc = list_first_entry(&schan->ld_queue,
- struct shdma_desc, node);
- desc->partial = ops->get_partial(schan, desc);
- }
+ if (ops->get_partial && !list_empty(&schan->ld_queue)) {
+ /* Record partial transfer */
+ struct shdma_desc *desc = list_first_entry(&schan->ld_queue,
+ struct shdma_desc, node);
+ desc->partial = ops->get_partial(schan, desc);
+ }
- spin_unlock_irqrestore(&schan->chan_lock, flags);
+ spin_unlock_irqrestore(&schan->chan_lock, flags);
- shdma_chan_ld_cleanup(schan, true);
- break;
- case DMA_SLAVE_CONFIG:
- /*
- * So far only .slave_id is used, but the slave drivers are
- * encouraged to also set a transfer direction and an address.
- */
- if (!arg)
- return -EINVAL;
- /*
- * We could lock this, but you shouldn't be configuring the
- * channel, while using it...
- */
- config = (struct dma_slave_config *)arg;
- ret = shdma_setup_slave(schan, config->slave_id,
- config->direction == DMA_DEV_TO_MEM ?
- config->src_addr : config->dst_addr);
- if (ret < 0)
- return ret;
- break;
- default:
- return -ENXIO;
- }
+ shdma_chan_ld_cleanup(schan, true);
return 0;
}
+static int shdma_config(struct dma_chan *chan,
+ struct dma_slave_config *config)
+{
+ struct shdma_chan *schan = to_shdma_chan(chan);
+
+ /*
+ * So far only .slave_id is used, but the slave drivers are
+ * encouraged to also set a transfer direction and an address.
+ */
+ if (!config)
+ return -EINVAL;
+ /*
+ * We could lock this, but you shouldn't be configuring the
+ * channel, while using it...
+ */
+ return shdma_setup_slave(schan, config->slave_id,
+ config->direction == DMA_DEV_TO_MEM ?
+ config->src_addr : config->dst_addr);
+}
+
static void shdma_issue_pending(struct dma_chan *chan)
{
struct shdma_chan *schan = to_shdma_chan(chan);
@@ -1002,7 +995,8 @@ int shdma_init(struct device *dev, struct shdma_dev *sdev,
/* Compulsory for DMA_SLAVE fields */
dma_dev->device_prep_slave_sg = shdma_prep_slave_sg;
dma_dev->device_prep_dma_cyclic = shdma_prep_dma_cyclic;
- dma_dev->device_control = shdma_control;
+ dma_dev->device_config = shdma_config;
+ dma_dev->device_terminate_all = shdma_terminate_all;
dma_dev->dev = dev;
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index aec8a84784a4..b2431aa30033 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -588,6 +588,7 @@ static void sh_dmae_shutdown(struct platform_device *pdev)
sh_dmae_ctl_stop(shdev);
}
+#ifdef CONFIG_PM
static int sh_dmae_runtime_suspend(struct device *dev)
{
return 0;
@@ -599,8 +600,9 @@ static int sh_dmae_runtime_resume(struct device *dev)
return sh_dmae_rst(shdev);
}
+#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int sh_dmae_suspend(struct device *dev)
{
return 0;
@@ -632,16 +634,12 @@ static int sh_dmae_resume(struct device *dev)
return 0;
}
-#else
-#define sh_dmae_suspend NULL
-#define sh_dmae_resume NULL
#endif
static const struct dev_pm_ops sh_dmae_pm = {
- .suspend = sh_dmae_suspend,
- .resume = sh_dmae_resume,
- .runtime_suspend = sh_dmae_runtime_suspend,
- .runtime_resume = sh_dmae_runtime_resume,
+ SET_SYSTEM_SLEEP_PM_OPS(sh_dmae_suspend, sh_dmae_resume)
+ SET_RUNTIME_PM_OPS(sh_dmae_runtime_suspend, sh_dmae_runtime_resume,
+ NULL)
};
static dma_addr_t sh_dmae_slave_addr(struct shdma_chan *schan)
@@ -684,6 +682,10 @@ MODULE_DEVICE_TABLE(of, sh_dmae_of_match);
static int sh_dmae_probe(struct platform_device *pdev)
{
+ const enum dma_slave_buswidth widths =
+ DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES |
+ DMA_SLAVE_BUSWIDTH_4_BYTES | DMA_SLAVE_BUSWIDTH_8_BYTES |
+ DMA_SLAVE_BUSWIDTH_16_BYTES | DMA_SLAVE_BUSWIDTH_32_BYTES;
const struct sh_dmae_pdata *pdata;
unsigned long chan_flag[SH_DMAE_MAX_CHANNELS] = {};
int chan_irq[SH_DMAE_MAX_CHANNELS];
@@ -746,6 +748,11 @@ static int sh_dmae_probe(struct platform_device *pdev)
return PTR_ERR(shdev->dmars);
}
+ dma_dev->src_addr_widths = widths;
+ dma_dev->dst_addr_widths = widths;
+ dma_dev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
+ dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
+
if (!pdata->slave_only)
dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask);
if (pdata->slave && pdata->slave_num)
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 3492a5f91d31..d0086e9f2082 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -281,9 +281,10 @@ static dma_cookie_t sirfsoc_dma_tx_submit(struct dma_async_tx_descriptor *txd)
return cookie;
}
-static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
- struct dma_slave_config *config)
+static int sirfsoc_dma_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *config)
{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
unsigned long flags;
if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
@@ -297,8 +298,9 @@ static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
return 0;
}
-static int sirfsoc_dma_terminate_all(struct sirfsoc_dma_chan *schan)
+static int sirfsoc_dma_terminate_all(struct dma_chan *chan)
{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan);
int cid = schan->chan.chan_id;
unsigned long flags;
@@ -327,8 +329,9 @@ static int sirfsoc_dma_terminate_all(struct sirfsoc_dma_chan *schan)
return 0;
}
-static int sirfsoc_dma_pause_chan(struct sirfsoc_dma_chan *schan)
+static int sirfsoc_dma_pause_chan(struct dma_chan *chan)
{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan);
int cid = schan->chan.chan_id;
unsigned long flags;
@@ -348,8 +351,9 @@ static int sirfsoc_dma_pause_chan(struct sirfsoc_dma_chan *schan)
return 0;
}
-static int sirfsoc_dma_resume_chan(struct sirfsoc_dma_chan *schan)
+static int sirfsoc_dma_resume_chan(struct dma_chan *chan)
{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan);
int cid = schan->chan.chan_id;
unsigned long flags;
@@ -369,30 +373,6 @@ static int sirfsoc_dma_resume_chan(struct sirfsoc_dma_chan *schan)
return 0;
}
-static int sirfsoc_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- struct dma_slave_config *config;
- struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
-
- switch (cmd) {
- case DMA_PAUSE:
- return sirfsoc_dma_pause_chan(schan);
- case DMA_RESUME:
- return sirfsoc_dma_resume_chan(schan);
- case DMA_TERMINATE_ALL:
- return sirfsoc_dma_terminate_all(schan);
- case DMA_SLAVE_CONFIG:
- config = (struct dma_slave_config *)arg;
- return sirfsoc_dma_slave_config(schan, config);
-
- default:
- break;
- }
-
- return -ENOSYS;
-}
-
/* Alloc channel resources */
static int sirfsoc_dma_alloc_chan_resources(struct dma_chan *chan)
{
@@ -648,18 +628,6 @@ EXPORT_SYMBOL(sirfsoc_dma_filter_id);
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
-static int sirfsoc_dma_device_slave_caps(struct dma_chan *dchan,
- struct dma_slave_caps *caps)
-{
- caps->src_addr_widths = SIRFSOC_DMA_BUSWIDTHS;
- caps->dstn_addr_widths = SIRFSOC_DMA_BUSWIDTHS;
- caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
- caps->cmd_pause = true;
- caps->cmd_terminate = true;
-
- return 0;
-}
-
static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
@@ -739,11 +707,16 @@ static int sirfsoc_dma_probe(struct platform_device *op)
dma->device_alloc_chan_resources = sirfsoc_dma_alloc_chan_resources;
dma->device_free_chan_resources = sirfsoc_dma_free_chan_resources;
dma->device_issue_pending = sirfsoc_dma_issue_pending;
- dma->device_control = sirfsoc_dma_control;
+ dma->device_config = sirfsoc_dma_slave_config;
+ dma->device_pause = sirfsoc_dma_pause_chan;
+ dma->device_resume = sirfsoc_dma_resume_chan;
+ dma->device_terminate_all = sirfsoc_dma_terminate_all;
dma->device_tx_status = sirfsoc_dma_tx_status;
dma->device_prep_interleaved_dma = sirfsoc_dma_prep_interleaved;
dma->device_prep_dma_cyclic = sirfsoc_dma_prep_cyclic;
- dma->device_slave_caps = sirfsoc_dma_device_slave_caps;
+ dma->src_addr_widths = SIRFSOC_DMA_BUSWIDTHS;
+ dma->dst_addr_widths = SIRFSOC_DMA_BUSWIDTHS;
+ dma->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
INIT_LIST_HEAD(&dma->channels);
dma_cap_set(DMA_SLAVE, dma->cap_mask);
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 15d49461c0d2..68aca3334a17 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1429,11 +1429,17 @@ static bool d40_tx_is_linked(struct d40_chan *d40c)
return is_link;
}
-static int d40_pause(struct d40_chan *d40c)
+static int d40_pause(struct dma_chan *chan)
{
+ struct d40_chan *d40c = container_of(chan, struct d40_chan, chan);
int res = 0;
unsigned long flags;
+ if (d40c->phy_chan == NULL) {
+ chan_err(d40c, "Channel is not allocated!\n");
+ return -EINVAL;
+ }
+
if (!d40c->busy)
return 0;
@@ -1448,11 +1454,17 @@ static int d40_pause(struct d40_chan *d40c)
return res;
}
-static int d40_resume(struct d40_chan *d40c)
+static int d40_resume(struct dma_chan *chan)
{
+ struct d40_chan *d40c = container_of(chan, struct d40_chan, chan);
int res = 0;
unsigned long flags;
+ if (d40c->phy_chan == NULL) {
+ chan_err(d40c, "Channel is not allocated!\n");
+ return -EINVAL;
+ }
+
if (!d40c->busy)
return 0;
@@ -2604,12 +2616,17 @@ static void d40_issue_pending(struct dma_chan *chan)
spin_unlock_irqrestore(&d40c->lock, flags);
}
-static void d40_terminate_all(struct dma_chan *chan)
+static int d40_terminate_all(struct dma_chan *chan)
{
unsigned long flags;
struct d40_chan *d40c = container_of(chan, struct d40_chan, chan);
int ret;
+ if (d40c->phy_chan == NULL) {
+ chan_err(d40c, "Channel is not allocated!\n");
+ return -EINVAL;
+ }
+
spin_lock_irqsave(&d40c->lock, flags);
pm_runtime_get_sync(d40c->base->dev);
@@ -2627,6 +2644,7 @@ static void d40_terminate_all(struct dma_chan *chan)
d40c->busy = false;
spin_unlock_irqrestore(&d40c->lock, flags);
+ return 0;
}
static int
@@ -2673,6 +2691,11 @@ static int d40_set_runtime_config(struct dma_chan *chan,
u32 src_maxburst, dst_maxburst;
int ret;
+ if (d40c->phy_chan == NULL) {
+ chan_err(d40c, "Channel is not allocated!\n");
+ return -EINVAL;
+ }
+
src_addr_width = config->src_addr_width;
src_maxburst = config->src_maxburst;
dst_addr_width = config->dst_addr_width;
@@ -2781,35 +2804,6 @@ static int d40_set_runtime_config(struct dma_chan *chan,
return 0;
}
-static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- struct d40_chan *d40c = container_of(chan, struct d40_chan, chan);
-
- if (d40c->phy_chan == NULL) {
- chan_err(d40c, "Channel is not allocated!\n");
- return -EINVAL;
- }
-
- switch (cmd) {
- case DMA_TERMINATE_ALL:
- d40_terminate_all(chan);
- return 0;
- case DMA_PAUSE:
- return d40_pause(d40c);
- case DMA_RESUME:
- return d40_resume(d40c);
- case DMA_SLAVE_CONFIG:
- return d40_set_runtime_config(chan,
- (struct dma_slave_config *) arg);
- default:
- break;
- }
-
- /* Other commands are unimplemented */
- return -ENXIO;
-}
-
/* Initialization functions */
static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma,
@@ -2870,7 +2864,10 @@ static void d40_ops_init(struct d40_base *base, struct dma_device *dev)
dev->device_free_chan_resources = d40_free_chan_resources;
dev->device_issue_pending = d40_issue_pending;
dev->device_tx_status = d40_tx_status;
- dev->device_control = d40_control;
+ dev->device_config = d40_set_runtime_config;
+ dev->device_pause = d40_pause;
+ dev->device_resume = d40_resume;
+ dev->device_terminate_all = d40_terminate_all;
dev->dev = base->dev;
}
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 159f1736a16f..7ebcf9bec698 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -355,38 +355,6 @@ static void sun6i_dma_free_desc(struct virt_dma_desc *vd)
kfree(txd);
}
-static int sun6i_dma_terminate_all(struct sun6i_vchan *vchan)
-{
- struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vchan->vc.chan.device);
- struct sun6i_pchan *pchan = vchan->phy;
- unsigned long flags;
- LIST_HEAD(head);
-
- spin_lock(&sdev->lock);
- list_del_init(&vchan->node);
- spin_unlock(&sdev->lock);
-
- spin_lock_irqsave(&vchan->vc.lock, flags);
-
- vchan_get_all_descriptors(&vchan->vc, &head);
-
- if (pchan) {
- writel(DMA_CHAN_ENABLE_STOP, pchan->base + DMA_CHAN_ENABLE);
- writel(DMA_CHAN_PAUSE_RESUME, pchan->base + DMA_CHAN_PAUSE);
-
- vchan->phy = NULL;
- pchan->vchan = NULL;
- pchan->desc = NULL;
- pchan->done = NULL;
- }
-
- spin_unlock_irqrestore(&vchan->vc.lock, flags);
-
- vchan_dma_desc_free_list(&vchan->vc, &head);
-
- return 0;
-}
-
static int sun6i_dma_start_desc(struct sun6i_vchan *vchan)
{
struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vchan->vc.chan.device);
@@ -675,57 +643,92 @@ err_lli_free:
return NULL;
}
-static int sun6i_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int sun6i_dma_config(struct dma_chan *chan,
+ struct dma_slave_config *config)
+{
+ struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
+
+ memcpy(&vchan->cfg, config, sizeof(*config));
+
+ return 0;
+}
+
+static int sun6i_dma_pause(struct dma_chan *chan)
+{
+ struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
+ struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
+ struct sun6i_pchan *pchan = vchan->phy;
+
+ dev_dbg(chan2dev(chan), "vchan %p: pause\n", &vchan->vc);
+
+ if (pchan) {
+ writel(DMA_CHAN_PAUSE_PAUSE,
+ pchan->base + DMA_CHAN_PAUSE);
+ } else {
+ spin_lock(&sdev->lock);
+ list_del_init(&vchan->node);
+ spin_unlock(&sdev->lock);
+ }
+
+ return 0;
+}
+
+static int sun6i_dma_resume(struct dma_chan *chan)
{
struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
struct sun6i_pchan *pchan = vchan->phy;
unsigned long flags;
- int ret = 0;
- switch (cmd) {
- case DMA_RESUME:
- dev_dbg(chan2dev(chan), "vchan %p: resume\n", &vchan->vc);
+ dev_dbg(chan2dev(chan), "vchan %p: resume\n", &vchan->vc);
- spin_lock_irqsave(&vchan->vc.lock, flags);
+ spin_lock_irqsave(&vchan->vc.lock, flags);
- if (pchan) {
- writel(DMA_CHAN_PAUSE_RESUME,
- pchan->base + DMA_CHAN_PAUSE);
- } else if (!list_empty(&vchan->vc.desc_issued)) {
- spin_lock(&sdev->lock);
- list_add_tail(&vchan->node, &sdev->pending);
- spin_unlock(&sdev->lock);
- }
+ if (pchan) {
+ writel(DMA_CHAN_PAUSE_RESUME,
+ pchan->base + DMA_CHAN_PAUSE);
+ } else if (!list_empty(&vchan->vc.desc_issued)) {
+ spin_lock(&sdev->lock);
+ list_add_tail(&vchan->node, &sdev->pending);
+ spin_unlock(&sdev->lock);
+ }
- spin_unlock_irqrestore(&vchan->vc.lock, flags);
- break;
+ spin_unlock_irqrestore(&vchan->vc.lock, flags);
- case DMA_PAUSE:
- dev_dbg(chan2dev(chan), "vchan %p: pause\n", &vchan->vc);
+ return 0;
+}
- if (pchan) {
- writel(DMA_CHAN_PAUSE_PAUSE,
- pchan->base + DMA_CHAN_PAUSE);
- } else {
- spin_lock(&sdev->lock);
- list_del_init(&vchan->node);
- spin_unlock(&sdev->lock);
- }
- break;
-
- case DMA_TERMINATE_ALL:
- ret = sun6i_dma_terminate_all(vchan);
- break;
- case DMA_SLAVE_CONFIG:
- memcpy(&vchan->cfg, (void *)arg, sizeof(struct dma_slave_config));
- break;
- default:
- ret = -ENXIO;
- break;
+static int sun6i_dma_terminate_all(struct dma_chan *chan)
+{
+ struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
+ struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
+ struct sun6i_pchan *pchan = vchan->phy;
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock(&sdev->lock);
+ list_del_init(&vchan->node);
+ spin_unlock(&sdev->lock);
+
+ spin_lock_irqsave(&vchan->vc.lock, flags);
+
+ vchan_get_all_descriptors(&vchan->vc, &head);
+
+ if (pchan) {
+ writel(DMA_CHAN_ENABLE_STOP, pchan->base + DMA_CHAN_ENABLE);
+ writel(DMA_CHAN_PAUSE_RESUME, pchan->base + DMA_CHAN_PAUSE);
+
+ vchan->phy = NULL;
+ pchan->vchan = NULL;
+ pchan->desc = NULL;
+ pchan->done = NULL;
}
- return ret;
+
+ spin_unlock_irqrestore(&vchan->vc.lock, flags);
+
+ vchan_dma_desc_free_list(&vchan->vc, &head);
+
+ return 0;
}
static enum dma_status sun6i_dma_tx_status(struct dma_chan *chan,
@@ -960,9 +963,20 @@ static int sun6i_dma_probe(struct platform_device *pdev)
sdc->slave.device_issue_pending = sun6i_dma_issue_pending;
sdc->slave.device_prep_slave_sg = sun6i_dma_prep_slave_sg;
sdc->slave.device_prep_dma_memcpy = sun6i_dma_prep_dma_memcpy;
- sdc->slave.device_control = sun6i_dma_control;
sdc->slave.copy_align = 4;
-
+ sdc->slave.device_config = sun6i_dma_config;
+ sdc->slave.device_pause = sun6i_dma_pause;
+ sdc->slave.device_resume = sun6i_dma_resume;
+ sdc->slave.device_terminate_all = sun6i_dma_terminate_all;
+ sdc->slave.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ sdc->slave.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+ sdc->slave.directions = BIT(DMA_DEV_TO_MEM) |
+ BIT(DMA_MEM_TO_DEV);
+ sdc->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
sdc->slave.dev = &pdev->dev;
sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index d8450c3f35f0..eaf585e8286b 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -723,7 +723,7 @@ end:
return;
}
-static void tegra_dma_terminate_all(struct dma_chan *dc)
+static int tegra_dma_terminate_all(struct dma_chan *dc)
{
struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
struct tegra_dma_sg_req *sgreq;
@@ -736,7 +736,7 @@ static void tegra_dma_terminate_all(struct dma_chan *dc)
spin_lock_irqsave(&tdc->lock, flags);
if (list_empty(&tdc->pending_sg_req)) {
spin_unlock_irqrestore(&tdc->lock, flags);
- return;
+ return 0;
}
if (!tdc->busy)
@@ -777,6 +777,7 @@ skip_dma_stop:
dma_desc->cb_count = 0;
}
spin_unlock_irqrestore(&tdc->lock, flags);
+ return 0;
}
static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
@@ -827,25 +828,6 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
return ret;
}
-static int tegra_dma_device_control(struct dma_chan *dc, enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- switch (cmd) {
- case DMA_SLAVE_CONFIG:
- return tegra_dma_slave_config(dc,
- (struct dma_slave_config *)arg);
-
- case DMA_TERMINATE_ALL:
- tegra_dma_terminate_all(dc);
- return 0;
-
- default:
- break;
- }
-
- return -ENXIO;
-}
-
static inline int get_bus_width(struct tegra_dma_channel *tdc,
enum dma_slave_buswidth slave_bw)
{
@@ -1443,7 +1425,23 @@ static int tegra_dma_probe(struct platform_device *pdev)
tegra_dma_free_chan_resources;
tdma->dma_dev.device_prep_slave_sg = tegra_dma_prep_slave_sg;
tdma->dma_dev.device_prep_dma_cyclic = tegra_dma_prep_dma_cyclic;
- tdma->dma_dev.device_control = tegra_dma_device_control;
+ tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
+ tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
+ tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+ /*
+ * XXX The hardware appears to support
+ * DMA_RESIDUE_GRANULARITY_BURST-level reporting, but it's
+ * only used by this driver during tegra_dma_terminate_all()
+ */
+ tdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+ tdma->dma_dev.device_config = tegra_dma_slave_config;
+ tdma->dma_dev.device_terminate_all = tegra_dma_terminate_all;
tdma->dma_dev.device_tx_status = tegra_dma_tx_status;
tdma->dma_dev.device_issue_pending = tegra_dma_issue_pending;
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index 2407ccf1a64b..c4c3d93fdd1b 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -561,8 +561,7 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan,
return &td_desc->txd;
}
-static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int td_terminate_all(struct dma_chan *chan)
{
struct timb_dma_chan *td_chan =
container_of(chan, struct timb_dma_chan, chan);
@@ -570,9 +569,6 @@ static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
- if (cmd != DMA_TERMINATE_ALL)
- return -ENXIO;
-
/* first the easy part, put the queue into the free list */
spin_lock_bh(&td_chan->lock);
list_for_each_entry_safe(td_desc, _td_desc, &td_chan->queue,
@@ -697,7 +693,7 @@ static int td_probe(struct platform_device *pdev)
dma_cap_set(DMA_SLAVE, td->dma.cap_mask);
dma_cap_set(DMA_PRIVATE, td->dma.cap_mask);
td->dma.device_prep_slave_sg = td_prep_slave_sg;
- td->dma.device_control = td_control;
+ td->dma.device_terminate_all = td_terminate_all;
td->dma.dev = &pdev->dev;
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 0659ec9c4488..8849318b32b7 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -901,17 +901,12 @@ txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
return &first->txd;
}
-static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int txx9dmac_terminate_all(struct dma_chan *chan)
{
struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
struct txx9dmac_desc *desc, *_desc;
LIST_HEAD(list);
- /* Only supports DMA_TERMINATE_ALL */
- if (cmd != DMA_TERMINATE_ALL)
- return -EINVAL;
-
dev_vdbg(chan2dev(chan), "terminate_all\n");
spin_lock_bh(&dc->lock);
@@ -1109,7 +1104,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev)
dc->dma.dev = &pdev->dev;
dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources;
dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources;
- dc->dma.device_control = txx9dmac_control;
+ dc->dma.device_terminate_all = txx9dmac_terminate_all;
dc->dma.device_tx_status = txx9dmac_tx_status;
dc->dma.device_issue_pending = txx9dmac_issue_pending;
if (pdata && pdata->memcpy_chan == ch) {
diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
index 4a3a8f3137b3..bdd2a5dd7220 100644
--- a/drivers/dma/xilinx/xilinx_vdma.c
+++ b/drivers/dma/xilinx/xilinx_vdma.c
@@ -1001,13 +1001,17 @@ error:
* xilinx_vdma_terminate_all - Halt the channel and free descriptors
* @chan: Driver specific VDMA Channel pointer
*/
-static void xilinx_vdma_terminate_all(struct xilinx_vdma_chan *chan)
+static int xilinx_vdma_terminate_all(struct dma_chan *dchan)
{
+ struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
+
/* Halt the DMA engine */
xilinx_vdma_halt(chan);
/* Remove and free all of the descriptors in the lists */
xilinx_vdma_free_descriptors(chan);
+
+ return 0;
}
/**
@@ -1075,27 +1079,6 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan,
}
EXPORT_SYMBOL(xilinx_vdma_channel_set_config);
-/**
- * xilinx_vdma_device_control - Configure DMA channel of the device
- * @dchan: DMA Channel pointer
- * @cmd: DMA control command
- * @arg: Channel configuration
- *
- * Return: '0' on success and failure value on error
- */
-static int xilinx_vdma_device_control(struct dma_chan *dchan,
- enum dma_ctrl_cmd cmd, unsigned long arg)
-{
- struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
-
- if (cmd != DMA_TERMINATE_ALL)
- return -ENXIO;
-
- xilinx_vdma_terminate_all(chan);
-
- return 0;
-}
-
/* -----------------------------------------------------------------------------
* Probe and remove
*/
@@ -1300,7 +1283,7 @@ static int xilinx_vdma_probe(struct platform_device *pdev)
xilinx_vdma_free_chan_resources;
xdev->common.device_prep_interleaved_dma =
xilinx_vdma_dma_prep_interleaved;
- xdev->common.device_control = xilinx_vdma_device_control;
+ xdev->common.device_terminate_all = xilinx_vdma_terminate_all;
xdev->common.device_tx_status = xilinx_vdma_tx_status;
xdev->common.device_issue_pending = xilinx_vdma_issue_pending;
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index eb6935c8ad94..d6a09b9cd8cc 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -1246,14 +1246,14 @@ static const u32 model_textual_descriptor[] = {
static struct fw_descriptor vendor_id_descriptor = {
.length = ARRAY_SIZE(vendor_textual_descriptor),
- .immediate = 0x03d00d1e,
+ .immediate = 0x03001f11,
.key = 0x81000000,
.data = vendor_textual_descriptor,
};
static struct fw_descriptor model_id_descriptor = {
.length = ARRAY_SIZE(model_textual_descriptor),
- .immediate = 0x17000001,
+ .immediate = 0x17023901,
.key = 0x81000000,
.data = model_textual_descriptor,
};
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index aff9018d0658..f51d376d10ba 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -718,11 +718,6 @@ static inline unsigned int ar_next_buffer_index(unsigned int index)
return (index + 1) % AR_BUFFERS;
}
-static inline unsigned int ar_prev_buffer_index(unsigned int index)
-{
- return (index - 1 + AR_BUFFERS) % AR_BUFFERS;
-}
-
static inline unsigned int ar_first_buffer_index(struct ar_context *ctx)
{
return ar_next_buffer_index(ctx->last_buffer_index);
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 64ac8f8f5098..c22606fe3d44 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1463,17 +1463,6 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost,
struct sbp2_command_orb *orb;
int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
- /*
- * Bidirectional commands are not yet implemented, and unknown
- * transfer direction not handled.
- */
- if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
- dev_err(lu_dev(lu), "cannot handle bidirectional command\n");
- cmd->result = DID_ERROR << 16;
- cmd->scsi_done(cmd);
- return 0;
- }
-
orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
if (orb == NULL)
return SCSI_MLQUEUE_HOST_BUSY;
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 70da9eb52a42..e9ed439a5b65 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1,3 +1,6 @@
-obj-y += drm/ vga/
+# drm/tegra depends on host1x, so if both drivers are built-in care must be
+# taken to initialize them in the correct order. Link order is the only way
+# to ensure this currently.
obj-$(CONFIG_TEGRA_HOST1X) += host1x/
+obj-y += drm/ vga/
obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index c3413b6adb17..151a050129e7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -62,12 +62,13 @@ config DRM_TTM
config DRM_GEM_CMA_HELPER
bool
- depends on DRM
+ depends on DRM && HAVE_DMA_ATTRS
help
Choose this if you need the GEM CMA helper functions
config DRM_KMS_CMA_HELPER
bool
+ depends on DRM && HAVE_DMA_ATTRS
select DRM_GEM_CMA_HELPER
select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT
@@ -110,7 +111,6 @@ config DRM_RADEON
select HWMON
select BACKLIGHT_CLASS_DEVICE
select INTERVAL_TREE
- select MMU_NOTIFIER
help
Choose this option if you have an ATI Radeon graphics card. There
are both PCI and AGP versions. You don't need to choose this to
@@ -183,6 +183,8 @@ source "drivers/gpu/drm/cirrus/Kconfig"
source "drivers/gpu/drm/armada/Kconfig"
+source "drivers/gpu/drm/atmel-hlcdc/Kconfig"
+
source "drivers/gpu/drm/rcar-du/Kconfig"
source "drivers/gpu/drm/shmobile/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e620807418ea..2c239b99de64 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o \
drm_trace_points.o drm_global.o drm_prime.o \
drm_rect.o drm_vma_manager.o drm_flip_work.o \
- drm_modeset_lock.o drm_atomic.o
+ drm_modeset_lock.o drm_atomic.o drm_bridge.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
@@ -55,6 +55,7 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_UDL) += udl/
obj-$(CONFIG_DRM_AST) += ast/
obj-$(CONFIG_DRM_ARMADA) += armada/
+obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
obj-$(CONFIG_DRM_OMAP) += omapdrm/
diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile
index 307a309110e6..0f4960148126 100644
--- a/drivers/gpu/drm/amd/amdkfd/Makefile
+++ b/drivers/gpu/drm/amd/amdkfd/Makefile
@@ -7,7 +7,10 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/
amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \
kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \
kfd_process.o kfd_queue.o kfd_mqd_manager.o \
- kfd_kernel_queue.o kfd_packet_manager.o \
- kfd_process_queue_manager.o kfd_device_queue_manager.o
+ kfd_mqd_manager_cik.o kfd_mqd_manager_vi.o \
+ kfd_kernel_queue.o kfd_kernel_queue_cik.o \
+ kfd_kernel_queue_vi.o kfd_packet_manager.o \
+ kfd_process_queue_manager.o kfd_device_queue_manager.o \
+ kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \
obj-$(CONFIG_HSA_AMD) += amdkfd.o
diff --git a/drivers/gpu/drm/amd/amdkfd/cik_regs.h b/drivers/gpu/drm/amd/amdkfd/cik_regs.h
index 607fc5ceadbe..01ff332fabd4 100644
--- a/drivers/gpu/drm/amd/amdkfd/cik_regs.h
+++ b/drivers/gpu/drm/amd/amdkfd/cik_regs.h
@@ -168,6 +168,8 @@
#define IB_ATC_EN (1U << 23)
#define DEFAULT_MIN_IB_AVAIL_SIZE (3U << 20)
+#define AQL_ENABLE 1
+
#define CP_HQD_DEQUEUE_REQUEST 0xC974
#define DEQUEUE_REQUEST_DRAIN 1
#define DEQUEUE_REQUEST_RESET 2
@@ -188,6 +190,17 @@
#define MQD_VMID_MASK (0xf << 0)
#define MQD_CONTROL_PRIV_STATE_EN (1U << 8)
+#define SDMA_RB_VMID(x) (x << 24)
+#define SDMA_RB_ENABLE (1 << 0)
+#define SDMA_RB_SIZE(x) ((x) << 1) /* log2 */
+#define SDMA_RPTR_WRITEBACK_ENABLE (1 << 12)
+#define SDMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */
+#define SDMA_OFFSET(x) (x << 0)
+#define SDMA_DB_ENABLE (1 << 28)
+#define SDMA_ATC (1 << 0)
+#define SDMA_VA_PTR32 (1 << 4)
+#define SDMA_VA_SHARED_BASE(x) (x << 8)
+
#define GRBM_GFX_INDEX 0x30800
#define INSTANCE_INDEX(x) ((x) << 0)
#define SH_INDEX(x) ((x) << 8)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index fcfdf23e1913..5c50aa8a8908 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -178,6 +178,22 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
return -EFAULT;
}
+ if (args->eop_buffer_address &&
+ !access_ok(VERIFY_WRITE,
+ (const void __user *) args->eop_buffer_address,
+ sizeof(uint32_t))) {
+ pr_debug("kfd: can't access eop buffer");
+ return -EFAULT;
+ }
+
+ if (args->ctx_save_restore_address &&
+ !access_ok(VERIFY_WRITE,
+ (const void __user *) args->ctx_save_restore_address,
+ sizeof(uint32_t))) {
+ pr_debug("kfd: can't access ctx save restore buffer");
+ return -EFAULT;
+ }
+
q_properties->is_interop = false;
q_properties->queue_percent = args->queue_percentage;
q_properties->priority = args->queue_priority;
@@ -185,9 +201,16 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
q_properties->queue_size = args->ring_size;
q_properties->read_ptr = (uint32_t *) args->read_pointer_address;
q_properties->write_ptr = (uint32_t *) args->write_pointer_address;
+ q_properties->eop_ring_buffer_address = args->eop_buffer_address;
+ q_properties->eop_ring_buffer_size = args->eop_buffer_size;
+ q_properties->ctx_save_restore_area_address =
+ args->ctx_save_restore_address;
+ q_properties->ctx_save_restore_area_size = args->ctx_save_restore_size;
if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE ||
args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL)
q_properties->type = KFD_QUEUE_TYPE_COMPUTE;
+ else if (args->queue_type == KFD_IOC_QUEUE_TYPE_SDMA)
+ q_properties->type = KFD_QUEUE_TYPE_SDMA;
else
return -ENOTSUPP;
@@ -214,6 +237,11 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
pr_debug("Queue Format (%d)\n", q_properties->format);
+ pr_debug("Queue EOP (0x%llX)\n", q_properties->eop_ring_buffer_address);
+
+ pr_debug("Queue CTX save arex (0x%llX)\n",
+ q_properties->ctx_save_restore_area_address);
+
return 0;
}
@@ -235,9 +263,12 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
if (err)
return err;
+ pr_debug("kfd: looking for gpu id 0x%x\n", args->gpu_id);
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (dev == NULL) {
+ pr_debug("kfd: gpu id 0x%x was not found\n", args->gpu_id);
return -EINVAL;
+ }
mutex_lock(&p->mutex);
@@ -251,8 +282,8 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
p->pasid,
dev->id);
- err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, 0,
- KFD_QUEUE_TYPE_COMPUTE, &queue_id);
+ err = pqm_create_queue(&p->pqm, dev, filep, &q_properties,
+ 0, q_properties.type, &queue_id);
if (err != 0)
goto err_create_queue;
@@ -385,7 +416,7 @@ static int kfd_ioctl_set_memory_policy(struct file *filep,
(args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
? cache_policy_coherent : cache_policy_noncoherent;
- if (!dev->dqm->set_cache_memory_policy(dev->dqm,
+ if (!dev->dqm->ops.set_cache_memory_policy(dev->dqm,
&pdd->qpd,
default_policy,
alternate_policy,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 25bc47f3c1cf..5bc32c26b989 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -31,11 +31,20 @@
#define MQD_SIZE_ALIGNED 768
static const struct kfd_device_info kaveri_device_info = {
+ .asic_family = CHIP_KAVERI,
.max_pasid_bits = 16,
.ih_ring_entry_size = 4 * sizeof(uint32_t),
.mqd_size_aligned = MQD_SIZE_ALIGNED
};
+static const struct kfd_device_info carrizo_device_info = {
+ .asic_family = CHIP_CARRIZO,
+ .max_pasid_bits = 16,
+ .ih_ring_entry_size = 4 * sizeof(uint32_t),
+ .num_of_watch_points = 4,
+ .mqd_size_aligned = MQD_SIZE_ALIGNED
+};
+
struct kfd_deviceid {
unsigned short did;
const struct kfd_device_info *device_info;
@@ -64,9 +73,13 @@ static const struct kfd_deviceid supported_devices[] = {
{ 0x1318, &kaveri_device_info }, /* Kaveri */
{ 0x131B, &kaveri_device_info }, /* Kaveri */
{ 0x131C, &kaveri_device_info }, /* Kaveri */
- { 0x131D, &kaveri_device_info }, /* Kaveri */
+ { 0x131D, &kaveri_device_info } /* Kaveri */
};
+static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
+ unsigned int chunk_size);
+static void kfd_gtt_sa_fini(struct kfd_dev *kfd);
+
static const struct kfd_device_info *lookup_device_info(unsigned short did)
{
size_t i;
@@ -173,16 +186,39 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
size = max_num_of_queues_per_device *
kfd->device_info->mqd_size_aligned;
- /* add another 512KB for all other allocations on gart */
+ /*
+ * calculate max size of runlist packet.
+ * There can be only 2 packets at once
+ */
+ size += (KFD_MAX_NUM_OF_PROCESSES * sizeof(struct pm4_map_process) +
+ max_num_of_queues_per_device *
+ sizeof(struct pm4_map_queues) + sizeof(struct pm4_runlist)) * 2;
+
+ /* Add size of HIQ & DIQ */
+ size += KFD_KERNEL_QUEUE_SIZE * 2;
+
+ /* add another 512KB for all other allocations on gart (HPD, fences) */
size += 512 * 1024;
- if (kfd2kgd->init_sa_manager(kfd->kgd, size)) {
+ if (kfd2kgd->init_gtt_mem_allocation(kfd->kgd, size, &kfd->gtt_mem,
+ &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)) {
dev_err(kfd_device,
- "Error initializing sa manager for device (%x:%x)\n",
- kfd->pdev->vendor, kfd->pdev->device);
+ "Could not allocate %d bytes for device (%x:%x)\n",
+ size, kfd->pdev->vendor, kfd->pdev->device);
goto out;
}
+ dev_info(kfd_device,
+ "Allocated %d bytes on gart for device(%x:%x)\n",
+ size, kfd->pdev->vendor, kfd->pdev->device);
+
+ /* Initialize GTT sa with 512 byte chunk size */
+ if (kfd_gtt_sa_init(kfd, size, 512) != 0) {
+ dev_err(kfd_device,
+ "Error initializing gtt sub-allocator\n");
+ goto kfd_gtt_sa_init_error;
+ }
+
kfd_doorbell_init(kfd);
if (kfd_topology_add_device(kfd) != 0) {
@@ -209,7 +245,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
goto device_queue_manager_error;
}
- if (kfd->dqm->start(kfd->dqm) != 0) {
+ if (kfd->dqm->ops.start(kfd->dqm) != 0) {
dev_err(kfd_device,
"Error starting queuen manager for device (%x:%x)\n",
kfd->pdev->vendor, kfd->pdev->device);
@@ -232,7 +268,9 @@ device_queue_manager_error:
device_iommu_pasid_error:
kfd_topology_remove_device(kfd);
kfd_topology_add_device_error:
- kfd2kgd->fini_sa_manager(kfd->kgd);
+ kfd_gtt_sa_fini(kfd);
+kfd_gtt_sa_init_error:
+ kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
dev_err(kfd_device,
"device (%x:%x) NOT added due to errors\n",
kfd->pdev->vendor, kfd->pdev->device);
@@ -246,6 +284,8 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
device_queue_manager_uninit(kfd->dqm);
amd_iommu_free_device(kfd->pdev);
kfd_topology_remove_device(kfd);
+ kfd_gtt_sa_fini(kfd);
+ kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
}
kfree(kfd);
@@ -256,7 +296,7 @@ void kgd2kfd_suspend(struct kfd_dev *kfd)
BUG_ON(kfd == NULL);
if (kfd->init_complete) {
- kfd->dqm->stop(kfd->dqm);
+ kfd->dqm->ops.stop(kfd->dqm);
amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
amd_iommu_free_device(kfd->pdev);
}
@@ -277,7 +317,7 @@ int kgd2kfd_resume(struct kfd_dev *kfd)
return -ENXIO;
amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
iommu_pasid_shutdown_callback);
- kfd->dqm->start(kfd->dqm);
+ kfd->dqm->ops.start(kfd->dqm);
}
return 0;
@@ -288,3 +328,188 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
{
/* Process interrupts / schedule work as necessary */
}
+
+static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
+ unsigned int chunk_size)
+{
+ unsigned int num_of_bits;
+
+ BUG_ON(!kfd);
+ BUG_ON(!kfd->gtt_mem);
+ BUG_ON(buf_size < chunk_size);
+ BUG_ON(buf_size == 0);
+ BUG_ON(chunk_size == 0);
+
+ kfd->gtt_sa_chunk_size = chunk_size;
+ kfd->gtt_sa_num_of_chunks = buf_size / chunk_size;
+
+ num_of_bits = kfd->gtt_sa_num_of_chunks / BITS_PER_BYTE;
+ BUG_ON(num_of_bits == 0);
+
+ kfd->gtt_sa_bitmap = kzalloc(num_of_bits, GFP_KERNEL);
+
+ if (!kfd->gtt_sa_bitmap)
+ return -ENOMEM;
+
+ pr_debug("kfd: gtt_sa_num_of_chunks = %d, gtt_sa_bitmap = %p\n",
+ kfd->gtt_sa_num_of_chunks, kfd->gtt_sa_bitmap);
+
+ mutex_init(&kfd->gtt_sa_lock);
+
+ return 0;
+
+}
+
+static void kfd_gtt_sa_fini(struct kfd_dev *kfd)
+{
+ mutex_destroy(&kfd->gtt_sa_lock);
+ kfree(kfd->gtt_sa_bitmap);
+}
+
+static inline uint64_t kfd_gtt_sa_calc_gpu_addr(uint64_t start_addr,
+ unsigned int bit_num,
+ unsigned int chunk_size)
+{
+ return start_addr + bit_num * chunk_size;
+}
+
+static inline uint32_t *kfd_gtt_sa_calc_cpu_addr(void *start_addr,
+ unsigned int bit_num,
+ unsigned int chunk_size)
+{
+ return (uint32_t *) ((uint64_t) start_addr + bit_num * chunk_size);
+}
+
+int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
+ struct kfd_mem_obj **mem_obj)
+{
+ unsigned int found, start_search, cur_size;
+
+ BUG_ON(!kfd);
+
+ if (size == 0)
+ return -EINVAL;
+
+ if (size > kfd->gtt_sa_num_of_chunks * kfd->gtt_sa_chunk_size)
+ return -ENOMEM;
+
+ *mem_obj = kmalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL);
+ if ((*mem_obj) == NULL)
+ return -ENOMEM;
+
+ pr_debug("kfd: allocated mem_obj = %p for size = %d\n", *mem_obj, size);
+
+ start_search = 0;
+
+ mutex_lock(&kfd->gtt_sa_lock);
+
+kfd_gtt_restart_search:
+ /* Find the first chunk that is free */
+ found = find_next_zero_bit(kfd->gtt_sa_bitmap,
+ kfd->gtt_sa_num_of_chunks,
+ start_search);
+
+ pr_debug("kfd: found = %d\n", found);
+
+ /* If there wasn't any free chunk, bail out */
+ if (found == kfd->gtt_sa_num_of_chunks)
+ goto kfd_gtt_no_free_chunk;
+
+ /* Update fields of mem_obj */
+ (*mem_obj)->range_start = found;
+ (*mem_obj)->range_end = found;
+ (*mem_obj)->gpu_addr = kfd_gtt_sa_calc_gpu_addr(
+ kfd->gtt_start_gpu_addr,
+ found,
+ kfd->gtt_sa_chunk_size);
+ (*mem_obj)->cpu_ptr = kfd_gtt_sa_calc_cpu_addr(
+ kfd->gtt_start_cpu_ptr,
+ found,
+ kfd->gtt_sa_chunk_size);
+
+ pr_debug("kfd: gpu_addr = %p, cpu_addr = %p\n",
+ (uint64_t *) (*mem_obj)->gpu_addr, (*mem_obj)->cpu_ptr);
+
+ /* If we need only one chunk, mark it as allocated and get out */
+ if (size <= kfd->gtt_sa_chunk_size) {
+ pr_debug("kfd: single bit\n");
+ set_bit(found, kfd->gtt_sa_bitmap);
+ goto kfd_gtt_out;
+ }
+
+ /* Otherwise, try to see if we have enough contiguous chunks */
+ cur_size = size - kfd->gtt_sa_chunk_size;
+ do {
+ (*mem_obj)->range_end =
+ find_next_zero_bit(kfd->gtt_sa_bitmap,
+ kfd->gtt_sa_num_of_chunks, ++found);
+ /*
+ * If next free chunk is not contiguous than we need to
+ * restart our search from the last free chunk we found (which
+ * wasn't contiguous to the previous ones
+ */
+ if ((*mem_obj)->range_end != found) {
+ start_search = found;
+ goto kfd_gtt_restart_search;
+ }
+
+ /*
+ * If we reached end of buffer, bail out with error
+ */
+ if (found == kfd->gtt_sa_num_of_chunks)
+ goto kfd_gtt_no_free_chunk;
+
+ /* Check if we don't need another chunk */
+ if (cur_size <= kfd->gtt_sa_chunk_size)
+ cur_size = 0;
+ else
+ cur_size -= kfd->gtt_sa_chunk_size;
+
+ } while (cur_size > 0);
+
+ pr_debug("kfd: range_start = %d, range_end = %d\n",
+ (*mem_obj)->range_start, (*mem_obj)->range_end);
+
+ /* Mark the chunks as allocated */
+ for (found = (*mem_obj)->range_start;
+ found <= (*mem_obj)->range_end;
+ found++)
+ set_bit(found, kfd->gtt_sa_bitmap);
+
+kfd_gtt_out:
+ mutex_unlock(&kfd->gtt_sa_lock);
+ return 0;
+
+kfd_gtt_no_free_chunk:
+ pr_debug("kfd: allocation failed with mem_obj = %p\n", mem_obj);
+ mutex_unlock(&kfd->gtt_sa_lock);
+ kfree(mem_obj);
+ return -ENOMEM;
+}
+
+int kfd_gtt_sa_free(struct kfd_dev *kfd, struct kfd_mem_obj *mem_obj)
+{
+ unsigned int bit;
+
+ BUG_ON(!kfd);
+
+ /* Act like kfree when trying to free a NULL object */
+ if (!mem_obj)
+ return 0;
+
+ pr_debug("kfd: free mem_obj = %p, range_start = %d, range_end = %d\n",
+ mem_obj, mem_obj->range_start, mem_obj->range_end);
+
+ mutex_lock(&kfd->gtt_sa_lock);
+
+ /* Mark the chunks as free */
+ for (bit = mem_obj->range_start;
+ bit <= mem_obj->range_end;
+ bit++)
+ clear_bit(bit, kfd->gtt_sa_bitmap);
+
+ mutex_unlock(&kfd->gtt_sa_lock);
+
+ kfree(mem_obj);
+ return 0;
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 0fd592799d58..b3589d0e39b9 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -26,34 +26,40 @@
#include <linux/types.h>
#include <linux/printk.h>
#include <linux/bitops.h>
+#include <linux/sched.h>
#include "kfd_priv.h"
#include "kfd_device_queue_manager.h"
#include "kfd_mqd_manager.h"
#include "cik_regs.h"
#include "kfd_kernel_queue.h"
-#include "../../radeon/cik_reg.h"
/* Size of the per-pipe EOP queue */
#define CIK_HPD_EOP_BYTES_LOG2 11
#define CIK_HPD_EOP_BYTES (1U << CIK_HPD_EOP_BYTES_LOG2)
-static bool is_mem_initialized;
-
-static int init_memory(struct device_queue_manager *dqm);
static int set_pasid_vmid_mapping(struct device_queue_manager *dqm,
unsigned int pasid, unsigned int vmid);
static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
struct queue *q,
struct qcm_process_device *qpd);
+
static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock);
static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock);
+static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
+ struct queue *q,
+ struct qcm_process_device *qpd);
+
+static void deallocate_sdma_queue(struct device_queue_manager *dqm,
+ unsigned int sdma_queue_id);
-static inline unsigned int get_pipes_num(struct device_queue_manager *dqm)
+static inline
+enum KFD_MQD_TYPE get_mqd_type_from_queue_type(enum kfd_queue_type type)
{
- BUG_ON(!dqm || !dqm->dev);
- return dqm->dev->shared_resources.compute_pipe_count;
+ if (type == KFD_QUEUE_TYPE_SDMA)
+ return KFD_MQD_TYPE_SDMA;
+ return KFD_MQD_TYPE_CP;
}
static inline unsigned int get_first_pipe(struct device_queue_manager *dqm)
@@ -67,61 +73,7 @@ static inline unsigned int get_pipes_num_cpsch(void)
return PIPE_PER_ME_CP_SCHEDULING;
}
-static inline unsigned int
-get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd)
-{
- uint32_t nybble;
-
- nybble = (pdd->lds_base >> 60) & 0x0E;
-
- return nybble;
-
-}
-
-static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
-{
- unsigned int shared_base;
-
- shared_base = (pdd->lds_base >> 16) & 0xFF;
-
- return shared_base;
-}
-
-static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble);
-static void init_process_memory(struct device_queue_manager *dqm,
- struct qcm_process_device *qpd)
-{
- struct kfd_process_device *pdd;
- unsigned int temp;
-
- BUG_ON(!dqm || !qpd);
-
- pdd = qpd_to_pdd(qpd);
-
- /* check if sh_mem_config register already configured */
- if (qpd->sh_mem_config == 0) {
- qpd->sh_mem_config =
- ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) |
- DEFAULT_MTYPE(MTYPE_NONCACHED) |
- APE1_MTYPE(MTYPE_NONCACHED);
- qpd->sh_mem_ape1_limit = 0;
- qpd->sh_mem_ape1_base = 0;
- }
-
- if (qpd->pqm->process->is_32bit_user_mode) {
- temp = get_sh_mem_bases_32(pdd);
- qpd->sh_mem_bases = SHARED_BASE(temp);
- qpd->sh_mem_config |= PTR32;
- } else {
- temp = get_sh_mem_bases_nybble_64(pdd);
- qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
- }
-
- pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
- qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
-}
-
-static void program_sh_mem_settings(struct device_queue_manager *dqm,
+void program_sh_mem_settings(struct device_queue_manager *dqm,
struct qcm_process_device *qpd)
{
return kfd2kgd->program_sh_mem_settings(dqm->dev->kgd, qpd->vmid,
@@ -200,7 +152,10 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
*allocated_vmid = qpd->vmid;
q->properties.vmid = qpd->vmid;
- retval = create_compute_queue_nocpsch(dqm, q, qpd);
+ if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE)
+ retval = create_compute_queue_nocpsch(dqm, q, qpd);
+ if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+ retval = create_sdma_queue_nocpsch(dqm, q, qpd);
if (retval != 0) {
if (list_empty(&qpd->queues_list)) {
@@ -212,7 +167,11 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
}
list_add(&q->list, &qpd->queues_list);
- dqm->queue_count++;
+ if (q->properties.is_active)
+ dqm->queue_count++;
+
+ if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+ dqm->sdma_queue_count++;
/*
* Unconditionally increment this counter, regardless of the queue's
@@ -229,12 +188,12 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
{
bool set;
- int pipe, bit;
+ int pipe, bit, i;
set = false;
- for (pipe = dqm->next_pipe_to_allocate; pipe < get_pipes_num(dqm);
- pipe = (pipe + 1) % get_pipes_num(dqm)) {
+ for (pipe = dqm->next_pipe_to_allocate, i = 0; i < get_pipes_num(dqm);
+ pipe = ((pipe + 1) % get_pipes_num(dqm)), ++i) {
if (dqm->allocated_queues[pipe] != 0) {
bit = find_first_bit(
(unsigned long *)&dqm->allocated_queues[pipe],
@@ -275,7 +234,7 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
BUG_ON(!dqm || !q || !qpd);
- mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
+ mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
if (mqd == NULL)
return -ENOMEM;
@@ -319,28 +278,44 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
pr_debug("kfd: In Func %s\n", __func__);
mutex_lock(&dqm->lock);
- mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
- if (mqd == NULL) {
- retval = -ENOMEM;
+
+ if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE) {
+ mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
+ if (mqd == NULL) {
+ retval = -ENOMEM;
+ goto out;
+ }
+ deallocate_hqd(dqm, q);
+ } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
+ mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_SDMA);
+ if (mqd == NULL) {
+ retval = -ENOMEM;
+ goto out;
+ }
+ dqm->sdma_queue_count--;
+ deallocate_sdma_queue(dqm, q->sdma_id);
+ } else {
+ pr_debug("q->properties.type is invalid (%d)\n",
+ q->properties.type);
+ retval = -EINVAL;
goto out;
}
retval = mqd->destroy_mqd(mqd, q->mqd,
- KFD_PREEMPT_TYPE_WAVEFRONT,
+ KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
q->pipe, q->queue);
if (retval != 0)
goto out;
- deallocate_hqd(dqm, q);
-
mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
list_del(&q->list);
if (list_empty(&qpd->queues_list))
deallocate_vmid(dqm, qpd, q);
- dqm->queue_count--;
+ if (q->properties.is_active)
+ dqm->queue_count--;
/*
* Unconditionally decrement this counter, regardless of the queue's
@@ -364,7 +339,8 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
BUG_ON(!dqm || !q || !q->mqd);
mutex_lock(&dqm->lock);
- mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
+ mqd = dqm->ops.get_mqd_manager(dqm,
+ get_mqd_type_from_queue_type(q->properties.type));
if (mqd == NULL) {
mutex_unlock(&dqm->lock);
return -ENOMEM;
@@ -415,6 +391,7 @@ static int register_process_nocpsch(struct device_queue_manager *dqm,
struct qcm_process_device *qpd)
{
struct device_process_node *n;
+ int retval;
BUG_ON(!dqm || !qpd);
@@ -429,12 +406,13 @@ static int register_process_nocpsch(struct device_queue_manager *dqm,
mutex_lock(&dqm->lock);
list_add(&n->list, &dqm->queues);
- init_process_memory(dqm, qpd);
+ retval = dqm->ops_asic_specific.register_process(dqm, qpd);
+
dqm->processes_count++;
mutex_unlock(&dqm->lock);
- return 0;
+ return retval;
}
static int unregister_process_nocpsch(struct device_queue_manager *dqm,
@@ -479,48 +457,7 @@ set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid,
vmid);
}
-static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
-{
- /* In 64-bit mode, we can only control the top 3 bits of the LDS,
- * scratch and GPUVM apertures.
- * The hardware fills in the remaining 59 bits according to the
- * following pattern:
- * LDS: X0000000'00000000 - X0000001'00000000 (4GB)
- * Scratch: X0000001'00000000 - X0000002'00000000 (4GB)
- * GPUVM: Y0010000'00000000 - Y0020000'00000000 (1TB)
- *
- * (where X/Y is the configurable nybble with the low-bit 0)
- *
- * LDS and scratch will have the same top nybble programmed in the
- * top 3 bits of SH_MEM_BASES.PRIVATE_BASE.
- * GPUVM can have a different top nybble programmed in the
- * top 3 bits of SH_MEM_BASES.SHARED_BASE.
- * We don't bother to support different top nybbles
- * for LDS/Scratch and GPUVM.
- */
-
- BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
- top_address_nybble == 0);
-
- return PRIVATE_BASE(top_address_nybble << 12) |
- SHARED_BASE(top_address_nybble << 12);
-}
-
-static int init_memory(struct device_queue_manager *dqm)
-{
- int i, retval;
-
- for (i = 8; i < 16; i++)
- set_pasid_vmid_mapping(dqm, 0, i);
-
- retval = kfd2kgd->init_memory(dqm->dev->kgd);
- if (retval == 0)
- is_mem_initialized = true;
- return retval;
-}
-
-
-static int init_pipelines(struct device_queue_manager *dqm,
+int init_pipelines(struct device_queue_manager *dqm,
unsigned int pipes_num, unsigned int first_pipe)
{
void *hpdptr;
@@ -539,11 +476,8 @@ static int init_pipelines(struct device_queue_manager *dqm,
* because it contains no data when there are no active queues.
*/
- err = kfd2kgd->allocate_mem(dqm->dev->kgd,
- CIK_HPD_EOP_BYTES * pipes_num,
- PAGE_SIZE,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) &dqm->pipeline_mem);
+ err = kfd_gtt_sa_allocate(dqm->dev, CIK_HPD_EOP_BYTES * pipes_num,
+ &dqm->pipeline_mem);
if (err) {
pr_err("kfd: error allocate vidmem num pipes: %d\n",
@@ -556,10 +490,9 @@ static int init_pipelines(struct device_queue_manager *dqm,
memset(hpdptr, 0, CIK_HPD_EOP_BYTES * pipes_num);
- mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
+ mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
if (mqd == NULL) {
- kfd2kgd->free_mem(dqm->dev->kgd,
- (struct kgd_mem *) dqm->pipeline_mem);
+ kfd_gtt_sa_free(dqm->dev, dqm->pipeline_mem);
return -ENOMEM;
}
@@ -579,7 +512,6 @@ static int init_pipelines(struct device_queue_manager *dqm,
return 0;
}
-
static int init_scheduler(struct device_queue_manager *dqm)
{
int retval;
@@ -589,11 +521,6 @@ static int init_scheduler(struct device_queue_manager *dqm)
pr_debug("kfd: In %s\n", __func__);
retval = init_pipelines(dqm, get_pipes_num(dqm), get_first_pipe(dqm));
- if (retval != 0)
- return retval;
-
- retval = init_memory(dqm);
-
return retval;
}
@@ -609,6 +536,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
mutex_init(&dqm->lock);
INIT_LIST_HEAD(&dqm->queues);
dqm->queue_count = dqm->next_pipe_to_allocate = 0;
+ dqm->sdma_queue_count = 0;
dqm->allocated_queues = kcalloc(get_pipes_num(dqm),
sizeof(unsigned int), GFP_KERNEL);
if (!dqm->allocated_queues) {
@@ -620,6 +548,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
dqm->allocated_queues[i] = (1 << QUEUES_PER_PIPE) - 1;
dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1;
+ dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1;
init_scheduler(dqm);
return 0;
@@ -637,8 +566,7 @@ static void uninitialize_nocpsch(struct device_queue_manager *dqm)
for (i = 0 ; i < KFD_MQD_TYPE_MAX ; i++)
kfree(dqm->mqds[i]);
mutex_destroy(&dqm->lock);
- kfd2kgd->free_mem(dqm->dev->kgd,
- (struct kgd_mem *) dqm->pipeline_mem);
+ kfd_gtt_sa_free(dqm->dev, dqm->pipeline_mem);
}
static int start_nocpsch(struct device_queue_manager *dqm)
@@ -651,6 +579,77 @@ static int stop_nocpsch(struct device_queue_manager *dqm)
return 0;
}
+static int allocate_sdma_queue(struct device_queue_manager *dqm,
+ unsigned int *sdma_queue_id)
+{
+ int bit;
+
+ if (dqm->sdma_bitmap == 0)
+ return -ENOMEM;
+
+ bit = find_first_bit((unsigned long *)&dqm->sdma_bitmap,
+ CIK_SDMA_QUEUES);
+
+ clear_bit(bit, (unsigned long *)&dqm->sdma_bitmap);
+ *sdma_queue_id = bit;
+
+ return 0;
+}
+
+static void deallocate_sdma_queue(struct device_queue_manager *dqm,
+ unsigned int sdma_queue_id)
+{
+ if (sdma_queue_id >= CIK_SDMA_QUEUES)
+ return;
+ set_bit(sdma_queue_id, (unsigned long *)&dqm->sdma_bitmap);
+}
+
+static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
+ struct qcm_process_device *qpd)
+{
+ uint32_t value = SDMA_ATC;
+
+ if (q->process->is_32bit_user_mode)
+ value |= SDMA_VA_PTR32 | get_sh_mem_bases_32(qpd_to_pdd(qpd));
+ else
+ value |= SDMA_VA_SHARED_BASE(get_sh_mem_bases_nybble_64(
+ qpd_to_pdd(qpd)));
+ q->properties.sdma_vm_addr = value;
+}
+
+static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
+ struct queue *q,
+ struct qcm_process_device *qpd)
+{
+ struct mqd_manager *mqd;
+ int retval;
+
+ mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_SDMA);
+ if (!mqd)
+ return -ENOMEM;
+
+ retval = allocate_sdma_queue(dqm, &q->sdma_id);
+ if (retval != 0)
+ return retval;
+
+ q->properties.sdma_queue_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE;
+ q->properties.sdma_engine_id = q->sdma_id / CIK_SDMA_ENGINE_NUM;
+
+ pr_debug("kfd: sdma id is: %d\n", q->sdma_id);
+ pr_debug(" sdma queue id: %d\n", q->properties.sdma_queue_id);
+ pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_id);
+
+ retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
+ &q->gart_mqd_addr, &q->properties);
+ if (retval != 0) {
+ deallocate_sdma_queue(dqm, q->sdma_id);
+ return retval;
+ }
+
+ init_sdma_vm(dqm, q, qpd);
+ return 0;
+}
+
/*
* Device Queue Manager implementation for cp scheduler
*/
@@ -692,8 +691,9 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
mutex_init(&dqm->lock);
INIT_LIST_HEAD(&dqm->queues);
dqm->queue_count = dqm->processes_count = 0;
+ dqm->sdma_queue_count = 0;
dqm->active_runlist = false;
- retval = init_pipelines(dqm, get_pipes_num(dqm), 0);
+ retval = dqm->ops_asic_specific.initialize(dqm);
if (retval != 0)
goto fail_init_pipelines;
@@ -724,18 +724,14 @@ static int start_cpsch(struct device_queue_manager *dqm)
pr_debug("kfd: allocating fence memory\n");
/* allocate fence memory on the gart */
- retval = kfd2kgd->allocate_mem(dqm->dev->kgd,
- sizeof(*dqm->fence_addr),
- 32,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) &dqm->fence_mem);
+ retval = kfd_gtt_sa_allocate(dqm->dev, sizeof(*dqm->fence_addr),
+ &dqm->fence_mem);
if (retval != 0)
goto fail_allocate_vidmem;
dqm->fence_addr = dqm->fence_mem->cpu_ptr;
dqm->fence_gpu_addr = dqm->fence_mem->gpu_addr;
-
list_for_each_entry(node, &dqm->queues, list)
if (node->qpd->pqm->process && dqm->dev)
kfd_bind_process_to_device(dqm->dev,
@@ -764,8 +760,7 @@ static int stop_cpsch(struct device_queue_manager *dqm)
pdd = qpd_to_pdd(node->qpd);
pdd->bound = false;
}
- kfd2kgd->free_mem(dqm->dev->kgd,
- (struct kgd_mem *) dqm->fence_mem);
+ kfd_gtt_sa_free(dqm->dev, dqm->fence_mem);
pm_uninit(&dqm->packets);
return 0;
@@ -828,6 +823,14 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm,
mutex_unlock(&dqm->lock);
}
+static void select_sdma_engine_id(struct queue *q)
+{
+ static int sdma_id;
+
+ q->sdma_id = sdma_id;
+ sdma_id = (sdma_id + 1) % 2;
+}
+
static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
struct qcm_process_device *qpd, int *allocate_vmid)
{
@@ -850,7 +853,12 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
goto out;
}
- mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP);
+ if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+ select_sdma_engine_id(q);
+
+ mqd = dqm->ops.get_mqd_manager(dqm,
+ get_mqd_type_from_queue_type(q->properties.type));
+
if (mqd == NULL) {
mutex_unlock(&dqm->lock);
return -ENOMEM;
@@ -867,6 +875,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
retval = execute_queues_cpsch(dqm, false);
}
+ if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+ dqm->sdma_queue_count++;
/*
* Unconditionally increment this counter, regardless of the queue's
* type or whether the queue is active.
@@ -893,12 +903,20 @@ static int fence_wait_timeout(unsigned int *fence_addr,
pr_err("kfd: qcm fence wait loop timeout expired\n");
return -ETIME;
}
- cpu_relax();
+ schedule();
}
return 0;
}
+static int destroy_sdma_queues(struct device_queue_manager *dqm,
+ unsigned int sdma_engine)
+{
+ return pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA,
+ KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false,
+ sdma_engine);
+}
+
static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock)
{
int retval;
@@ -911,6 +929,15 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock)
mutex_lock(&dqm->lock);
if (dqm->active_runlist == false)
goto out;
+
+ pr_debug("kfd: Before destroying queues, sdma queue count is : %u\n",
+ dqm->sdma_queue_count);
+
+ if (dqm->sdma_queue_count > 0) {
+ destroy_sdma_queues(dqm, 0);
+ destroy_sdma_queues(dqm, 1);
+ }
+
retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE,
KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false, 0);
if (retval != 0)
@@ -982,15 +1009,19 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
/* remove queue from list to prevent rescheduling after preemption */
mutex_lock(&dqm->lock);
-
- mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP);
+ mqd = dqm->ops.get_mqd_manager(dqm,
+ get_mqd_type_from_queue_type(q->properties.type));
if (!mqd) {
retval = -ENOMEM;
goto failed;
}
+ if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+ dqm->sdma_queue_count--;
+
list_del(&q->list);
- dqm->queue_count--;
+ if (q->properties.is_active)
+ dqm->queue_count--;
execute_queues_cpsch(dqm, false);
@@ -1028,8 +1059,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
void __user *alternate_aperture_base,
uint64_t alternate_aperture_size)
{
- uint32_t default_mtype;
- uint32_t ape1_mtype;
+ bool retval;
pr_debug("kfd: In func %s\n", __func__);
@@ -1066,18 +1096,13 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
qpd->sh_mem_ape1_limit = limit >> 16;
}
- default_mtype = (default_policy == cache_policy_coherent) ?
- MTYPE_NONCACHED :
- MTYPE_CACHED;
-
- ape1_mtype = (alternate_policy == cache_policy_coherent) ?
- MTYPE_NONCACHED :
- MTYPE_CACHED;
-
- qpd->sh_mem_config = (qpd->sh_mem_config & PTR32)
- | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED)
- | DEFAULT_MTYPE(default_mtype)
- | APE1_MTYPE(ape1_mtype);
+ retval = dqm->ops_asic_specific.set_cache_memory_policy(
+ dqm,
+ qpd,
+ default_policy,
+ alternate_policy,
+ alternate_aperture_base,
+ alternate_aperture_size);
if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0))
program_sh_mem_settings(dqm, qpd);
@@ -1087,7 +1112,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
qpd->sh_mem_ape1_limit);
mutex_unlock(&dqm->lock);
- return true;
+ return retval;
out:
mutex_unlock(&dqm->lock);
@@ -1100,6 +1125,8 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
BUG_ON(!dev);
+ pr_debug("kfd: loading device queue manager\n");
+
dqm = kzalloc(sizeof(struct device_queue_manager), GFP_KERNEL);
if (!dqm)
return NULL;
@@ -1109,40 +1136,50 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
case KFD_SCHED_POLICY_HWS:
case KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION:
/* initialize dqm for cp scheduling */
- dqm->create_queue = create_queue_cpsch;
- dqm->initialize = initialize_cpsch;
- dqm->start = start_cpsch;
- dqm->stop = stop_cpsch;
- dqm->destroy_queue = destroy_queue_cpsch;
- dqm->update_queue = update_queue;
- dqm->get_mqd_manager = get_mqd_manager_nocpsch;
- dqm->register_process = register_process_nocpsch;
- dqm->unregister_process = unregister_process_nocpsch;
- dqm->uninitialize = uninitialize_nocpsch;
- dqm->create_kernel_queue = create_kernel_queue_cpsch;
- dqm->destroy_kernel_queue = destroy_kernel_queue_cpsch;
- dqm->set_cache_memory_policy = set_cache_memory_policy;
+ dqm->ops.create_queue = create_queue_cpsch;
+ dqm->ops.initialize = initialize_cpsch;
+ dqm->ops.start = start_cpsch;
+ dqm->ops.stop = stop_cpsch;
+ dqm->ops.destroy_queue = destroy_queue_cpsch;
+ dqm->ops.update_queue = update_queue;
+ dqm->ops.get_mqd_manager = get_mqd_manager_nocpsch;
+ dqm->ops.register_process = register_process_nocpsch;
+ dqm->ops.unregister_process = unregister_process_nocpsch;
+ dqm->ops.uninitialize = uninitialize_nocpsch;
+ dqm->ops.create_kernel_queue = create_kernel_queue_cpsch;
+ dqm->ops.destroy_kernel_queue = destroy_kernel_queue_cpsch;
+ dqm->ops.set_cache_memory_policy = set_cache_memory_policy;
break;
case KFD_SCHED_POLICY_NO_HWS:
/* initialize dqm for no cp scheduling */
- dqm->start = start_nocpsch;
- dqm->stop = stop_nocpsch;
- dqm->create_queue = create_queue_nocpsch;
- dqm->destroy_queue = destroy_queue_nocpsch;
- dqm->update_queue = update_queue;
- dqm->get_mqd_manager = get_mqd_manager_nocpsch;
- dqm->register_process = register_process_nocpsch;
- dqm->unregister_process = unregister_process_nocpsch;
- dqm->initialize = initialize_nocpsch;
- dqm->uninitialize = uninitialize_nocpsch;
- dqm->set_cache_memory_policy = set_cache_memory_policy;
+ dqm->ops.start = start_nocpsch;
+ dqm->ops.stop = stop_nocpsch;
+ dqm->ops.create_queue = create_queue_nocpsch;
+ dqm->ops.destroy_queue = destroy_queue_nocpsch;
+ dqm->ops.update_queue = update_queue;
+ dqm->ops.get_mqd_manager = get_mqd_manager_nocpsch;
+ dqm->ops.register_process = register_process_nocpsch;
+ dqm->ops.unregister_process = unregister_process_nocpsch;
+ dqm->ops.initialize = initialize_nocpsch;
+ dqm->ops.uninitialize = uninitialize_nocpsch;
+ dqm->ops.set_cache_memory_policy = set_cache_memory_policy;
break;
default:
BUG();
break;
}
- if (dqm->initialize(dqm) != 0) {
+ switch (dev->device_info->asic_family) {
+ case CHIP_CARRIZO:
+ device_queue_manager_init_vi(&dqm->ops_asic_specific);
+ break;
+
+ case CHIP_KAVERI:
+ device_queue_manager_init_cik(&dqm->ops_asic_specific);
+ break;
+ }
+
+ if (dqm->ops.initialize(dqm) != 0) {
kfree(dqm);
return NULL;
}
@@ -1154,7 +1191,6 @@ void device_queue_manager_uninit(struct device_queue_manager *dqm)
{
BUG_ON(!dqm);
- dqm->uninitialize(dqm);
+ dqm->ops.uninitialize(dqm);
kfree(dqm);
}
-
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index 52035bf0c1cb..d64f86cda34f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -36,6 +36,9 @@
#define KFD_VMID_START_OFFSET (8)
#define VMID_PER_DEVICE CIK_VMID_NUM
#define KFD_DQM_FIRST_PIPE (0)
+#define CIK_SDMA_QUEUES (4)
+#define CIK_SDMA_QUEUES_PER_ENGINE (2)
+#define CIK_SDMA_ENGINE_NUM (2)
struct device_process_node {
struct qcm_process_device *qpd;
@@ -43,7 +46,7 @@ struct device_process_node {
};
/**
- * struct device_queue_manager
+ * struct device_queue_manager_ops
*
* @create_queue: Queue creation routine.
*
@@ -78,15 +81,9 @@ struct device_process_node {
* @set_cache_memory_policy: Sets memory policy (cached/ non cached) for the
* memory apertures.
*
- * This struct is a base class for the kfd queues scheduler in the
- * device level. The device base class should expose the basic operations
- * for queue creation and queue destruction. This base class hides the
- * scheduling mode of the driver and the specific implementation of the
- * concrete device. This class is the only class in the queues scheduler
- * that configures the H/W.
*/
-struct device_queue_manager {
+struct device_queue_manager_ops {
int (*create_queue)(struct device_queue_manager *dqm,
struct queue *q,
struct qcm_process_device *qpd,
@@ -121,7 +118,23 @@ struct device_queue_manager {
enum cache_policy alternate_policy,
void __user *alternate_aperture_base,
uint64_t alternate_aperture_size);
+};
+/**
+ * struct device_queue_manager
+ *
+ * This struct is a base class for the kfd queues scheduler in the
+ * device level. The device base class should expose the basic operations
+ * for queue creation and queue destruction. This base class hides the
+ * scheduling mode of the driver and the specific implementation of the
+ * concrete device. This class is the only class in the queues scheduler
+ * that configures the H/W.
+ *
+ */
+
+struct device_queue_manager {
+ struct device_queue_manager_ops ops;
+ struct device_queue_manager_ops ops_asic_specific;
struct mqd_manager *mqds[KFD_MQD_TYPE_MAX];
struct packet_manager packets;
@@ -130,9 +143,11 @@ struct device_queue_manager {
struct list_head queues;
unsigned int processes_count;
unsigned int queue_count;
+ unsigned int sdma_queue_count;
unsigned int total_queue_count;
unsigned int next_pipe_to_allocate;
unsigned int *allocated_queues;
+ unsigned int sdma_bitmap;
unsigned int vmid_bitmap;
uint64_t pipelines_addr;
struct kfd_mem_obj *pipeline_mem;
@@ -142,6 +157,28 @@ struct device_queue_manager {
bool active_runlist;
};
+void device_queue_manager_init_cik(struct device_queue_manager_ops *ops);
+void device_queue_manager_init_vi(struct device_queue_manager_ops *ops);
+void program_sh_mem_settings(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd);
+int init_pipelines(struct device_queue_manager *dqm,
+ unsigned int pipes_num, unsigned int first_pipe);
+
+extern inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
+{
+ return (pdd->lds_base >> 16) & 0xFF;
+}
+
+extern inline unsigned int
+get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd)
+{
+ return (pdd->lds_base >> 60) & 0x0E;
+}
+extern inline unsigned int get_pipes_num(struct device_queue_manager *dqm)
+{
+ BUG_ON(!dqm || !dqm->dev);
+ return dqm->dev->shared_resources.compute_pipe_count;
+}
#endif /* KFD_DEVICE_QUEUE_MANAGER_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
new file mode 100644
index 000000000000..6b072466e2a6
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "kfd_device_queue_manager.h"
+#include "cik_regs.h"
+
+static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd,
+ enum cache_policy default_policy,
+ enum cache_policy alternate_policy,
+ void __user *alternate_aperture_base,
+ uint64_t alternate_aperture_size);
+static int register_process_cik(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd);
+static int initialize_cpsch_cik(struct device_queue_manager *dqm);
+
+void device_queue_manager_init_cik(struct device_queue_manager_ops *ops)
+{
+ ops->set_cache_memory_policy = set_cache_memory_policy_cik;
+ ops->register_process = register_process_cik;
+ ops->initialize = initialize_cpsch_cik;
+}
+
+static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
+{
+ /* In 64-bit mode, we can only control the top 3 bits of the LDS,
+ * scratch and GPUVM apertures.
+ * The hardware fills in the remaining 59 bits according to the
+ * following pattern:
+ * LDS: X0000000'00000000 - X0000001'00000000 (4GB)
+ * Scratch: X0000001'00000000 - X0000002'00000000 (4GB)
+ * GPUVM: Y0010000'00000000 - Y0020000'00000000 (1TB)
+ *
+ * (where X/Y is the configurable nybble with the low-bit 0)
+ *
+ * LDS and scratch will have the same top nybble programmed in the
+ * top 3 bits of SH_MEM_BASES.PRIVATE_BASE.
+ * GPUVM can have a different top nybble programmed in the
+ * top 3 bits of SH_MEM_BASES.SHARED_BASE.
+ * We don't bother to support different top nybbles
+ * for LDS/Scratch and GPUVM.
+ */
+
+ BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
+ top_address_nybble == 0);
+
+ return PRIVATE_BASE(top_address_nybble << 12) |
+ SHARED_BASE(top_address_nybble << 12);
+}
+
+static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd,
+ enum cache_policy default_policy,
+ enum cache_policy alternate_policy,
+ void __user *alternate_aperture_base,
+ uint64_t alternate_aperture_size)
+{
+ uint32_t default_mtype;
+ uint32_t ape1_mtype;
+
+ default_mtype = (default_policy == cache_policy_coherent) ?
+ MTYPE_NONCACHED :
+ MTYPE_CACHED;
+
+ ape1_mtype = (alternate_policy == cache_policy_coherent) ?
+ MTYPE_NONCACHED :
+ MTYPE_CACHED;
+
+ qpd->sh_mem_config = (qpd->sh_mem_config & PTR32)
+ | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED)
+ | DEFAULT_MTYPE(default_mtype)
+ | APE1_MTYPE(ape1_mtype);
+
+ return true;
+}
+
+static int register_process_cik(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd)
+{
+ struct kfd_process_device *pdd;
+ unsigned int temp;
+
+ BUG_ON(!dqm || !qpd);
+
+ pdd = qpd_to_pdd(qpd);
+
+ /* check if sh_mem_config register already configured */
+ if (qpd->sh_mem_config == 0) {
+ qpd->sh_mem_config =
+ ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) |
+ DEFAULT_MTYPE(MTYPE_NONCACHED) |
+ APE1_MTYPE(MTYPE_NONCACHED);
+ qpd->sh_mem_ape1_limit = 0;
+ qpd->sh_mem_ape1_base = 0;
+ }
+
+ if (qpd->pqm->process->is_32bit_user_mode) {
+ temp = get_sh_mem_bases_32(pdd);
+ qpd->sh_mem_bases = SHARED_BASE(temp);
+ qpd->sh_mem_config |= PTR32;
+ } else {
+ temp = get_sh_mem_bases_nybble_64(pdd);
+ qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
+ }
+
+ pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
+ qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
+
+ return 0;
+}
+
+static int initialize_cpsch_cik(struct device_queue_manager *dqm)
+{
+ return init_pipelines(dqm, get_pipes_num(dqm), 0);
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
new file mode 100644
index 000000000000..20553dcd257d
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "kfd_device_queue_manager.h"
+
+static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd,
+ enum cache_policy default_policy,
+ enum cache_policy alternate_policy,
+ void __user *alternate_aperture_base,
+ uint64_t alternate_aperture_size);
+static int register_process_vi(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd);
+static int initialize_cpsch_vi(struct device_queue_manager *dqm);
+
+void device_queue_manager_init_vi(struct device_queue_manager_ops *ops)
+{
+ pr_warn("amdkfd: VI DQM is not currently supported\n");
+
+ ops->set_cache_memory_policy = set_cache_memory_policy_vi;
+ ops->register_process = register_process_vi;
+ ops->initialize = initialize_cpsch_vi;
+}
+
+static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd,
+ enum cache_policy default_policy,
+ enum cache_policy alternate_policy,
+ void __user *alternate_aperture_base,
+ uint64_t alternate_aperture_size)
+{
+ return false;
+}
+
+static int register_process_vi(struct device_queue_manager *dqm,
+ struct qcm_process_device *qpd)
+{
+ return -1;
+}
+
+static int initialize_cpsch_vi(struct device_queue_manager *dqm)
+{
+ return 0;
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index b5791a5c7c06..1a9b355dd114 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -137,10 +137,6 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
if (dev == NULL)
return -EINVAL;
- /* Find if pdd exists for combination of process and gpu id */
- if (!kfd_get_process_device_data(dev, process, 0))
- return -EINVAL;
-
/* Calculate physical address of doorbell */
address = kfd_get_process_doorbells(dev, process);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
index e64aa99e5e41..35b987574633 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
@@ -303,10 +303,11 @@ int kfd_init_apertures(struct kfd_process *process)
while ((dev = kfd_topology_enum_kfd_devices(id)) != NULL &&
id < NUM_OF_SUPPORTED_GPUS) {
- pdd = kfd_get_process_device_data(dev, process, 1);
- if (!pdd)
+ pdd = kfd_create_process_device_data(dev, process);
+ if (pdd == NULL) {
+ pr_err("Failed to create process device data\n");
return -1;
-
+ }
/*
* For 64 bit process aperture will be statically reserved in
* the x86_64 non canonical process address space
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
index 935071410724..e415a2a9207e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -56,8 +56,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
switch (type) {
case KFD_QUEUE_TYPE_DIQ:
case KFD_QUEUE_TYPE_HIQ:
- kq->mqd = dev->dqm->get_mqd_manager(dev->dqm,
- KFD_MQD_TYPE_CIK_HIQ);
+ kq->mqd = dev->dqm->ops.get_mqd_manager(dev->dqm,
+ KFD_MQD_TYPE_HIQ);
break;
default:
BUG();
@@ -72,23 +72,19 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
if (prop.doorbell_ptr == NULL)
goto err_get_kernel_doorbell;
- retval = kfd2kgd->allocate_mem(dev->kgd,
- queue_size,
- PAGE_SIZE,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) &kq->pq);
-
+ retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq);
if (retval != 0)
goto err_pq_allocate_vidmem;
kq->pq_kernel_addr = kq->pq->cpu_ptr;
kq->pq_gpu_addr = kq->pq->gpu_addr;
- retval = kfd2kgd->allocate_mem(dev->kgd,
- sizeof(*kq->rptr_kernel),
- 32,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) &kq->rptr_mem);
+ retval = kq->ops_asic_specific.initialize(kq, dev, type, queue_size);
+ if (retval == false)
+ goto err_eop_allocate_vidmem;
+
+ retval = kfd_gtt_sa_allocate(dev, sizeof(*kq->rptr_kernel),
+ &kq->rptr_mem);
if (retval != 0)
goto err_rptr_allocate_vidmem;
@@ -96,11 +92,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
kq->rptr_kernel = kq->rptr_mem->cpu_ptr;
kq->rptr_gpu_addr = kq->rptr_mem->gpu_addr;
- retval = kfd2kgd->allocate_mem(dev->kgd,
- sizeof(*kq->wptr_kernel),
- 32,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) &kq->wptr_mem);
+ retval = kfd_gtt_sa_allocate(dev, sizeof(*kq->wptr_kernel),
+ &kq->wptr_mem);
if (retval != 0)
goto err_wptr_allocate_vidmem;
@@ -121,6 +114,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
prop.queue_address = kq->pq_gpu_addr;
prop.read_ptr = (uint32_t *) kq->rptr_gpu_addr;
prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr;
+ prop.eop_ring_buffer_address = kq->eop_gpu_addr;
+ prop.eop_ring_buffer_size = PAGE_SIZE;
if (init_queue(&kq->queue, prop) != 0)
goto err_init_queue;
@@ -145,11 +140,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
} else {
/* allocate fence for DIQ */
- retval = kfd2kgd->allocate_mem(dev->kgd,
- sizeof(uint32_t),
- 32,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) &kq->fence_mem_obj);
+ retval = kfd_gtt_sa_allocate(dev, sizeof(uint32_t),
+ &kq->fence_mem_obj);
if (retval != 0)
goto err_alloc_fence;
@@ -165,11 +157,13 @@ err_alloc_fence:
err_init_mqd:
uninit_queue(kq->queue);
err_init_queue:
- kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->wptr_mem);
+ kfd_gtt_sa_free(dev, kq->wptr_mem);
err_wptr_allocate_vidmem:
- kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->rptr_mem);
+ kfd_gtt_sa_free(dev, kq->rptr_mem);
err_rptr_allocate_vidmem:
- kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->pq);
+ kfd_gtt_sa_free(dev, kq->eop_mem);
+err_eop_allocate_vidmem:
+ kfd_gtt_sa_free(dev, kq->pq);
err_pq_allocate_vidmem:
pr_err("kfd: error init pq\n");
kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
@@ -190,10 +184,13 @@ static void uninitialize(struct kernel_queue *kq)
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
kq->queue->pipe,
kq->queue->queue);
+ else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ)
+ kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj);
- kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->rptr_mem);
- kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->wptr_mem);
- kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->pq);
+ kfd_gtt_sa_free(kq->dev, kq->rptr_mem);
+ kfd_gtt_sa_free(kq->dev, kq->wptr_mem);
+ kq->ops_asic_specific.uninitialize(kq);
+ kfd_gtt_sa_free(kq->dev, kq->pq);
kfd_release_kernel_doorbell(kq->dev,
kq->queue->properties.doorbell_ptr);
uninit_queue(kq->queue);
@@ -265,28 +262,6 @@ static void submit_packet(struct kernel_queue *kq)
kq->pending_wptr);
}
-static int sync_with_hw(struct kernel_queue *kq, unsigned long timeout_ms)
-{
- unsigned long org_timeout_ms;
-
- BUG_ON(!kq);
-
- org_timeout_ms = timeout_ms;
- timeout_ms += jiffies * 1000 / HZ;
- while (*kq->wptr_kernel != *kq->rptr_kernel) {
- if (time_after(jiffies * 1000 / HZ, timeout_ms)) {
- pr_err("kfd: kernel_queue %s timeout expired %lu\n",
- __func__, org_timeout_ms);
- pr_err("kfd: wptr: %d rptr: %d\n",
- *kq->wptr_kernel, *kq->rptr_kernel);
- return -ETIME;
- }
- schedule();
- }
-
- return 0;
-}
-
static void rollback_packet(struct kernel_queue *kq)
{
BUG_ON(!kq);
@@ -304,14 +279,23 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
if (!kq)
return NULL;
- kq->initialize = initialize;
- kq->uninitialize = uninitialize;
- kq->acquire_packet_buffer = acquire_packet_buffer;
- kq->submit_packet = submit_packet;
- kq->sync_with_hw = sync_with_hw;
- kq->rollback_packet = rollback_packet;
+ kq->ops.initialize = initialize;
+ kq->ops.uninitialize = uninitialize;
+ kq->ops.acquire_packet_buffer = acquire_packet_buffer;
+ kq->ops.submit_packet = submit_packet;
+ kq->ops.rollback_packet = rollback_packet;
+
+ switch (dev->device_info->asic_family) {
+ case CHIP_CARRIZO:
+ kernel_queue_init_vi(&kq->ops_asic_specific);
+ break;
+
+ case CHIP_KAVERI:
+ kernel_queue_init_cik(&kq->ops_asic_specific);
+ break;
+ }
- if (kq->initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
+ if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
pr_err("kfd: failed to init kernel queue\n");
kfree(kq);
return NULL;
@@ -323,7 +307,7 @@ void kernel_queue_uninit(struct kernel_queue *kq)
{
BUG_ON(!kq);
- kq->uninitialize(kq);
+ kq->ops.uninitialize(kq);
kfree(kq);
}
@@ -335,19 +319,18 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
BUG_ON(!dev);
- pr_debug("kfd: starting kernel queue test\n");
+ pr_err("kfd: starting kernel queue test\n");
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
BUG_ON(!kq);
- retval = kq->acquire_packet_buffer(kq, 5, &buffer);
+ retval = kq->ops.acquire_packet_buffer(kq, 5, &buffer);
BUG_ON(retval != 0);
for (i = 0; i < 5; i++)
buffer[i] = kq->nop_packet;
- kq->submit_packet(kq);
- kq->sync_with_hw(kq, 1000);
+ kq->ops.submit_packet(kq);
- pr_debug("kfd: ending kernel queue test\n");
+ pr_err("kfd: ending kernel queue test\n");
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
index dcd2bdb68d44..594053136ee4 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h
@@ -28,8 +28,31 @@
#include <linux/types.h>
#include "kfd_priv.h"
-struct kernel_queue {
- /* interface */
+/**
+ * struct kernel_queue_ops
+ *
+ * @initialize: Initialize a kernel queue, including allocations of GART memory
+ * needed for the queue.
+ *
+ * @uninitialize: Uninitialize a kernel queue and free all its memory usages.
+ *
+ * @acquire_packet_buffer: Returns a pointer to the location in the kernel
+ * queue ring buffer where the calling function can write its packet. It is
+ * Guaranteed that there is enough space for that packet. It also updates the
+ * pending write pointer to that location so subsequent calls to
+ * acquire_packet_buffer will get a correct write pointer
+ *
+ * @submit_packet: Update the write pointer and doorbell of a kernel queue.
+ *
+ * @sync_with_hw: Wait until the write pointer and the read pointer of a kernel
+ * queue are equal, which means the CP has read all the submitted packets.
+ *
+ * @rollback_packet: This routine is called if we failed to build an acquired
+ * packet for some reason. It just overwrites the pending wptr with the current
+ * one
+ *
+ */
+struct kernel_queue_ops {
bool (*initialize)(struct kernel_queue *kq, struct kfd_dev *dev,
enum kfd_queue_type type, unsigned int queue_size);
void (*uninitialize)(struct kernel_queue *kq);
@@ -38,9 +61,12 @@ struct kernel_queue {
unsigned int **buffer_ptr);
void (*submit_packet)(struct kernel_queue *kq);
- int (*sync_with_hw)(struct kernel_queue *kq,
- unsigned long timeout_ms);
void (*rollback_packet)(struct kernel_queue *kq);
+};
+
+struct kernel_queue {
+ struct kernel_queue_ops ops;
+ struct kernel_queue_ops ops_asic_specific;
/* data */
struct kfd_dev *dev;
@@ -58,6 +84,9 @@ struct kernel_queue {
struct kfd_mem_obj *pq;
uint64_t pq_gpu_addr;
uint32_t *pq_kernel_addr;
+ struct kfd_mem_obj *eop_mem;
+ uint64_t eop_gpu_addr;
+ uint32_t *eop_kernel_addr;
struct kfd_mem_obj *fence_mem_obj;
uint64_t fence_gpu_addr;
@@ -66,4 +95,7 @@ struct kernel_queue {
struct list_head list;
};
+void kernel_queue_init_cik(struct kernel_queue_ops *ops);
+void kernel_queue_init_vi(struct kernel_queue_ops *ops);
+
#endif /* KFD_KERNEL_QUEUE_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c
new file mode 100644
index 000000000000..a90eb440b1fb
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_cik.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "kfd_kernel_queue.h"
+
+static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev,
+ enum kfd_queue_type type, unsigned int queue_size);
+static void uninitialize_cik(struct kernel_queue *kq);
+
+void kernel_queue_init_cik(struct kernel_queue_ops *ops)
+{
+ ops->initialize = initialize_cik;
+ ops->uninitialize = uninitialize_cik;
+}
+
+static bool initialize_cik(struct kernel_queue *kq, struct kfd_dev *dev,
+ enum kfd_queue_type type, unsigned int queue_size)
+{
+ return true;
+}
+
+static void uninitialize_cik(struct kernel_queue *kq)
+{
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c
new file mode 100644
index 000000000000..f1d48281e322
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue_vi.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "kfd_kernel_queue.h"
+
+static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev,
+ enum kfd_queue_type type, unsigned int queue_size);
+static void uninitialize_vi(struct kernel_queue *kq);
+
+void kernel_queue_init_vi(struct kernel_queue_ops *ops)
+{
+ ops->initialize = initialize_vi;
+ ops->uninitialize = uninitialize_vi;
+}
+
+static bool initialize_vi(struct kernel_queue *kq, struct kfd_dev *dev,
+ enum kfd_queue_type type, unsigned int queue_size)
+{
+ int retval;
+
+ retval = kfd_gtt_sa_allocate(dev, PAGE_SIZE, &kq->eop_mem);
+ if (retval != 0)
+ return false;
+
+ kq->eop_gpu_addr = kq->eop_mem->gpu_addr;
+ kq->eop_kernel_addr = kq->eop_mem->cpu_ptr;
+
+ memset(kq->eop_kernel_addr, 0, PAGE_SIZE);
+
+ return true;
+}
+
+static void uninitialize_vi(struct kernel_queue *kq)
+{
+ kfd_gtt_sa_free(kq->dev, kq->eop_mem);
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
index 1c385c23dd0b..3f34ae16f075 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
@@ -29,10 +29,10 @@
#define KFD_DRIVER_AUTHOR "AMD Inc. and others"
#define KFD_DRIVER_DESC "Standalone HSA driver for AMD's GPUs"
-#define KFD_DRIVER_DATE "20141113"
+#define KFD_DRIVER_DATE "20150122"
#define KFD_DRIVER_MAJOR 0
#define KFD_DRIVER_MINOR 7
-#define KFD_DRIVER_PATCHLEVEL 0
+#define KFD_DRIVER_PATCHLEVEL 1
const struct kfd2kgd_calls *kfd2kgd;
static const struct kgd2kfd_calls kgd2kfd = {
@@ -48,7 +48,7 @@ static const struct kgd2kfd_calls kgd2kfd = {
int sched_policy = KFD_SCHED_POLICY_HWS;
module_param(sched_policy, int, 0444);
MODULE_PARM_DESC(sched_policy,
- "Kernel cmdline parameter that defines the amdkfd scheduling policy");
+ "Scheduling policy (0 = HWS (Default), 1 = HWS without over-subscription, 2 = Non-HWS (Used for debugging only)");
int max_num_of_queues_per_device = KFD_MAX_NUM_OF_QUEUES_PER_DEVICE_DEFAULT;
module_param(max_num_of_queues_per_device, int, 0444);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
index 4c3828cf45bf..b1ef1368c3bb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
@@ -21,326 +21,17 @@
*
*/
-#include <linux/printk.h>
-#include <linux/slab.h>
#include "kfd_priv.h"
-#include "kfd_mqd_manager.h"
-#include "cik_regs.h"
-#include "../../radeon/cik_reg.h"
-
-inline void busy_wait(unsigned long ms)
-{
- while (time_before(jiffies, ms))
- cpu_relax();
-}
-
-static inline struct cik_mqd *get_mqd(void *mqd)
-{
- return (struct cik_mqd *)mqd;
-}
-
-static int init_mqd(struct mqd_manager *mm, void **mqd,
- struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
- struct queue_properties *q)
-{
- uint64_t addr;
- struct cik_mqd *m;
- int retval;
-
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- retval = kfd2kgd->allocate_mem(mm->dev->kgd,
- sizeof(struct cik_mqd),
- 256,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) mqd_mem_obj);
-
- if (retval != 0)
- return -ENOMEM;
-
- m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
- addr = (*mqd_mem_obj)->gpu_addr;
-
- memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
-
- m->header = 0xC0310800;
- m->compute_pipelinestat_enable = 1;
- m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
- m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
- m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
- m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
-
- /*
- * Make sure to use the last queue state saved on mqd when the cp
- * reassigns the queue, so when queue is switched on/off (e.g over
- * subscription or quantum timeout) the context will be consistent
- */
- m->cp_hqd_persistent_state =
- DEFAULT_CP_HQD_PERSISTENT_STATE | PRELOAD_REQ;
-
- m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
- m->cp_mqd_base_addr_lo = lower_32_bits(addr);
- m->cp_mqd_base_addr_hi = upper_32_bits(addr);
-
- m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE | IB_ATC_EN;
- /* Although WinKFD writes this, I suspect it should not be necessary */
- m->cp_hqd_ib_control = IB_ATC_EN | DEFAULT_MIN_IB_AVAIL_SIZE;
-
- m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
- QUANTUM_DURATION(10);
-
- /*
- * Pipe Priority
- * Identifies the pipe relative priority when this queue is connected
- * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
- * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
- * 0 = CS_LOW (typically below GFX)
- * 1 = CS_MEDIUM (typically between HP3D and GFX
- * 2 = CS_HIGH (typically above HP3D)
- */
- m->cp_hqd_pipe_priority = 1;
- m->cp_hqd_queue_priority = 15;
-
- *mqd = m;
- if (gart_addr != NULL)
- *gart_addr = addr;
- retval = mm->update_mqd(mm, m, q);
-
- return retval;
-}
-
-static void uninit_mqd(struct mqd_manager *mm, void *mqd,
- struct kfd_mem_obj *mqd_mem_obj)
-{
- BUG_ON(!mm || !mqd);
- kfd2kgd->free_mem(mm->dev->kgd, (struct kgd_mem *) mqd_mem_obj);
-}
-
-static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
-{
- return kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
-
-}
-
-static int update_mqd(struct mqd_manager *mm, void *mqd,
- struct queue_properties *q)
-{
- struct cik_mqd *m;
-
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- m = get_mqd(mqd);
- m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
- DEFAULT_MIN_AVAIL_SIZE | PQ_ATC_EN;
-
- /*
- * Calculating queue size which is log base 2 of actual queue size -1
- * dwords and another -1 for ffs
- */
- m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
- - 1 - 1;
- m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
- m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
- m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
- m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
- m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
- DOORBELL_OFFSET(q->doorbell_off);
-
- m->cp_hqd_vmid = q->vmid;
-
- if (q->format == KFD_QUEUE_FORMAT_AQL) {
- m->cp_hqd_iq_rptr = AQL_ENABLE;
- m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
- }
-
- m->cp_hqd_active = 0;
- q->is_active = false;
- if (q->queue_size > 0 &&
- q->queue_address != 0 &&
- q->queue_percent > 0) {
- m->cp_hqd_active = 1;
- q->is_active = true;
- }
-
- return 0;
-}
-
-static int destroy_mqd(struct mqd_manager *mm, void *mqd,
- enum kfd_preempt_type type,
- unsigned int timeout, uint32_t pipe_id,
- uint32_t queue_id)
-{
- return kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
- pipe_id, queue_id);
-}
-
-static bool is_occupied(struct mqd_manager *mm, void *mqd,
- uint64_t queue_address, uint32_t pipe_id,
- uint32_t queue_id)
-{
-
- return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
- pipe_id, queue_id);
-
-}
-
-/*
- * HIQ MQD Implementation, concrete implementation for HIQ MQD implementation.
- * The HIQ queue in Kaveri is using the same MQD structure as all the user mode
- * queues but with different initial values.
- */
-
-static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
- struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
- struct queue_properties *q)
-{
- uint64_t addr;
- struct cik_mqd *m;
- int retval;
-
- BUG_ON(!mm || !q || !mqd || !mqd_mem_obj);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- retval = kfd2kgd->allocate_mem(mm->dev->kgd,
- sizeof(struct cik_mqd),
- 256,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) mqd_mem_obj);
-
- if (retval != 0)
- return -ENOMEM;
-
- m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
- addr = (*mqd_mem_obj)->gpu_addr;
-
- memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
-
- m->header = 0xC0310800;
- m->compute_pipelinestat_enable = 1;
- m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
- m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
- m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
- m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
-
- m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE |
- PRELOAD_REQ;
- m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
- QUANTUM_DURATION(10);
-
- m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
- m->cp_mqd_base_addr_lo = lower_32_bits(addr);
- m->cp_mqd_base_addr_hi = upper_32_bits(addr);
-
- m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE;
-
- /*
- * Pipe Priority
- * Identifies the pipe relative priority when this queue is connected
- * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
- * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
- * 0 = CS_LOW (typically below GFX)
- * 1 = CS_MEDIUM (typically between HP3D and GFX
- * 2 = CS_HIGH (typically above HP3D)
- */
- m->cp_hqd_pipe_priority = 1;
- m->cp_hqd_queue_priority = 15;
-
- *mqd = m;
- if (gart_addr)
- *gart_addr = addr;
- retval = mm->update_mqd(mm, m, q);
-
- return retval;
-}
-
-static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
- struct queue_properties *q)
-{
- struct cik_mqd *m;
-
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- m = get_mqd(mqd);
- m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
- DEFAULT_MIN_AVAIL_SIZE |
- PRIV_STATE |
- KMD_QUEUE;
-
- /*
- * Calculating queue size which is log base 2 of actual queue
- * size -1 dwords
- */
- m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
- - 1 - 1;
- m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
- m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
- m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
- m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
- m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
- DOORBELL_OFFSET(q->doorbell_off);
-
- m->cp_hqd_vmid = q->vmid;
-
- m->cp_hqd_active = 0;
- q->is_active = false;
- if (q->queue_size > 0 &&
- q->queue_address != 0 &&
- q->queue_percent > 0) {
- m->cp_hqd_active = 1;
- q->is_active = true;
- }
-
- return 0;
-}
struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
struct kfd_dev *dev)
{
- struct mqd_manager *mqd;
-
- BUG_ON(!dev);
- BUG_ON(type >= KFD_MQD_TYPE_MAX);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
- if (!mqd)
- return NULL;
-
- mqd->dev = dev;
-
- switch (type) {
- case KFD_MQD_TYPE_CIK_CP:
- case KFD_MQD_TYPE_CIK_COMPUTE:
- mqd->init_mqd = init_mqd;
- mqd->uninit_mqd = uninit_mqd;
- mqd->load_mqd = load_mqd;
- mqd->update_mqd = update_mqd;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
- break;
- case KFD_MQD_TYPE_CIK_HIQ:
- mqd->init_mqd = init_mqd_hiq;
- mqd->uninit_mqd = uninit_mqd;
- mqd->load_mqd = load_mqd;
- mqd->update_mqd = update_mqd_hiq;
- mqd->destroy_mqd = destroy_mqd;
- mqd->is_occupied = is_occupied;
- break;
- default:
- kfree(mqd);
- return NULL;
+ switch (dev->device_info->asic_family) {
+ case CHIP_KAVERI:
+ return mqd_manager_init_cik(type, dev);
+ case CHIP_CARRIZO:
+ return mqd_manager_init_vi(type, dev);
}
- return mqd;
+ return NULL;
}
-
-/* SDMA queues should be implemented here when the cp will supports them */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
new file mode 100644
index 000000000000..a09e18a339f3
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include "kfd_priv.h"
+#include "kfd_mqd_manager.h"
+#include "cik_regs.h"
+#include "cik_structs.h"
+
+static inline struct cik_mqd *get_mqd(void *mqd)
+{
+ return (struct cik_mqd *)mqd;
+}
+
+static int init_mqd(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *q)
+{
+ uint64_t addr;
+ struct cik_mqd *m;
+ int retval;
+
+ BUG_ON(!mm || !q || !mqd);
+
+ pr_debug("kfd: In func %s\n", __func__);
+
+ retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
+ mqd_mem_obj);
+
+ if (retval != 0)
+ return -ENOMEM;
+
+ m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
+ addr = (*mqd_mem_obj)->gpu_addr;
+
+ memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
+
+ m->header = 0xC0310800;
+ m->compute_pipelinestat_enable = 1;
+ m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
+ m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
+ m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
+ m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
+
+ /*
+ * Make sure to use the last queue state saved on mqd when the cp
+ * reassigns the queue, so when queue is switched on/off (e.g over
+ * subscription or quantum timeout) the context will be consistent
+ */
+ m->cp_hqd_persistent_state =
+ DEFAULT_CP_HQD_PERSISTENT_STATE | PRELOAD_REQ;
+
+ m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
+ m->cp_mqd_base_addr_hi = upper_32_bits(addr);
+
+ m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE | IB_ATC_EN;
+ /* Although WinKFD writes this, I suspect it should not be necessary */
+ m->cp_hqd_ib_control = IB_ATC_EN | DEFAULT_MIN_IB_AVAIL_SIZE;
+
+ m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
+ QUANTUM_DURATION(10);
+
+ /*
+ * Pipe Priority
+ * Identifies the pipe relative priority when this queue is connected
+ * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
+ * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
+ * 0 = CS_LOW (typically below GFX)
+ * 1 = CS_MEDIUM (typically between HP3D and GFX
+ * 2 = CS_HIGH (typically above HP3D)
+ */
+ m->cp_hqd_pipe_priority = 1;
+ m->cp_hqd_queue_priority = 15;
+
+ if (q->format == KFD_QUEUE_FORMAT_AQL)
+ m->cp_hqd_iq_rptr = AQL_ENABLE;
+
+ *mqd = m;
+ if (gart_addr != NULL)
+ *gart_addr = addr;
+ retval = mm->update_mqd(mm, m, q);
+
+ return retval;
+}
+
+static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *q)
+{
+ int retval;
+ struct cik_sdma_rlc_registers *m;
+
+ BUG_ON(!mm || !mqd || !mqd_mem_obj);
+
+ retval = kfd_gtt_sa_allocate(mm->dev,
+ sizeof(struct cik_sdma_rlc_registers),
+ mqd_mem_obj);
+
+ if (retval != 0)
+ return -ENOMEM;
+
+ m = (struct cik_sdma_rlc_registers *) (*mqd_mem_obj)->cpu_ptr;
+
+ memset(m, 0, sizeof(struct cik_sdma_rlc_registers));
+
+ *mqd = m;
+ if (gart_addr != NULL)
+ *gart_addr = (*mqd_mem_obj)->gpu_addr;
+
+ retval = mm->update_mqd(mm, m, q);
+
+ return retval;
+}
+
+static void uninit_mqd(struct mqd_manager *mm, void *mqd,
+ struct kfd_mem_obj *mqd_mem_obj)
+{
+ BUG_ON(!mm || !mqd);
+ kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
+}
+
+static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ struct kfd_mem_obj *mqd_mem_obj)
+{
+ BUG_ON(!mm || !mqd);
+ kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
+}
+
+static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
+ uint32_t queue_id, uint32_t __user *wptr)
+{
+ return kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
+}
+
+static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+ uint32_t __user *wptr)
+{
+ return kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd);
+}
+
+static int update_mqd(struct mqd_manager *mm, void *mqd,
+ struct queue_properties *q)
+{
+ struct cik_mqd *m;
+
+ BUG_ON(!mm || !q || !mqd);
+
+ pr_debug("kfd: In func %s\n", __func__);
+
+ m = get_mqd(mqd);
+ m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
+ DEFAULT_MIN_AVAIL_SIZE | PQ_ATC_EN;
+
+ /*
+ * Calculating queue size which is log base 2 of actual queue size -1
+ * dwords and another -1 for ffs
+ */
+ m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
+ - 1 - 1;
+ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
+ m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
+ m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
+ m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
+ m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
+ DOORBELL_OFFSET(q->doorbell_off);
+
+ m->cp_hqd_vmid = q->vmid;
+
+ if (q->format == KFD_QUEUE_FORMAT_AQL) {
+ m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
+ }
+
+ m->cp_hqd_active = 0;
+ q->is_active = false;
+ if (q->queue_size > 0 &&
+ q->queue_address != 0 &&
+ q->queue_percent > 0) {
+ m->cp_hqd_active = 1;
+ q->is_active = true;
+ }
+
+ return 0;
+}
+
+static int update_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ struct queue_properties *q)
+{
+ struct cik_sdma_rlc_registers *m;
+
+ BUG_ON(!mm || !mqd || !q);
+
+ m = get_sdma_mqd(mqd);
+ m->sdma_rlc_rb_cntl =
+ SDMA_RB_SIZE((ffs(q->queue_size / sizeof(unsigned int)))) |
+ SDMA_RB_VMID(q->vmid) |
+ SDMA_RPTR_WRITEBACK_ENABLE |
+ SDMA_RPTR_WRITEBACK_TIMER(6);
+
+ m->sdma_rlc_rb_base = lower_32_bits(q->queue_address >> 8);
+ m->sdma_rlc_rb_base_hi = upper_32_bits(q->queue_address >> 8);
+ m->sdma_rlc_rb_rptr_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
+ m->sdma_rlc_rb_rptr_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
+ m->sdma_rlc_doorbell = SDMA_OFFSET(q->doorbell_off) | SDMA_DB_ENABLE;
+ m->sdma_rlc_virtual_addr = q->sdma_vm_addr;
+
+ m->sdma_engine_id = q->sdma_engine_id;
+ m->sdma_queue_id = q->sdma_queue_id;
+
+ q->is_active = false;
+ if (q->queue_size > 0 &&
+ q->queue_address != 0 &&
+ q->queue_percent > 0) {
+ m->sdma_rlc_rb_cntl |= SDMA_RB_ENABLE;
+ q->is_active = true;
+ }
+
+ return 0;
+}
+
+static int destroy_mqd(struct mqd_manager *mm, void *mqd,
+ enum kfd_preempt_type type,
+ unsigned int timeout, uint32_t pipe_id,
+ uint32_t queue_id)
+{
+ return kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
+ pipe_id, queue_id);
+}
+
+/*
+ * preempt type here is ignored because there is only one way
+ * to preempt sdma queue
+ */
+static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ enum kfd_preempt_type type,
+ unsigned int timeout, uint32_t pipe_id,
+ uint32_t queue_id)
+{
+ return kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
+}
+
+static bool is_occupied(struct mqd_manager *mm, void *mqd,
+ uint64_t queue_address, uint32_t pipe_id,
+ uint32_t queue_id)
+{
+
+ return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
+ pipe_id, queue_id);
+
+}
+
+static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
+ uint64_t queue_address, uint32_t pipe_id,
+ uint32_t queue_id)
+{
+ return kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
+}
+
+/*
+ * HIQ MQD Implementation, concrete implementation for HIQ MQD implementation.
+ * The HIQ queue in Kaveri is using the same MQD structure as all the user mode
+ * queues but with different initial values.
+ */
+
+static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
+ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
+ struct queue_properties *q)
+{
+ uint64_t addr;
+ struct cik_mqd *m;
+ int retval;
+
+ BUG_ON(!mm || !q || !mqd || !mqd_mem_obj);
+
+ pr_debug("kfd: In func %s\n", __func__);
+
+ retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
+ mqd_mem_obj);
+
+ if (retval != 0)
+ return -ENOMEM;
+
+ m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
+ addr = (*mqd_mem_obj)->gpu_addr;
+
+ memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
+
+ m->header = 0xC0310800;
+ m->compute_pipelinestat_enable = 1;
+ m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
+ m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
+ m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
+ m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
+
+ m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE |
+ PRELOAD_REQ;
+ m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
+ QUANTUM_DURATION(10);
+
+ m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
+ m->cp_mqd_base_addr_hi = upper_32_bits(addr);
+
+ m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE;
+
+ /*
+ * Pipe Priority
+ * Identifies the pipe relative priority when this queue is connected
+ * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
+ * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
+ * 0 = CS_LOW (typically below GFX)
+ * 1 = CS_MEDIUM (typically between HP3D and GFX
+ * 2 = CS_HIGH (typically above HP3D)
+ */
+ m->cp_hqd_pipe_priority = 1;
+ m->cp_hqd_queue_priority = 15;
+
+ *mqd = m;
+ if (gart_addr)
+ *gart_addr = addr;
+ retval = mm->update_mqd(mm, m, q);
+
+ return retval;
+}
+
+static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
+ struct queue_properties *q)
+{
+ struct cik_mqd *m;
+
+ BUG_ON(!mm || !q || !mqd);
+
+ pr_debug("kfd: In func %s\n", __func__);
+
+ m = get_mqd(mqd);
+ m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
+ DEFAULT_MIN_AVAIL_SIZE |
+ PRIV_STATE |
+ KMD_QUEUE;
+
+ /*
+ * Calculating queue size which is log base 2 of actual queue
+ * size -1 dwords
+ */
+ m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
+ - 1 - 1;
+ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
+ m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
+ m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
+ m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
+ m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
+ DOORBELL_OFFSET(q->doorbell_off);
+
+ m->cp_hqd_vmid = q->vmid;
+
+ m->cp_hqd_active = 0;
+ q->is_active = false;
+ if (q->queue_size > 0 &&
+ q->queue_address != 0 &&
+ q->queue_percent > 0) {
+ m->cp_hqd_active = 1;
+ q->is_active = true;
+ }
+
+ return 0;
+}
+
+struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
+{
+ struct cik_sdma_rlc_registers *m;
+
+ BUG_ON(!mqd);
+
+ m = (struct cik_sdma_rlc_registers *)mqd;
+
+ return m;
+}
+
+struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
+ struct kfd_dev *dev)
+{
+ struct mqd_manager *mqd;
+
+ BUG_ON(!dev);
+ BUG_ON(type >= KFD_MQD_TYPE_MAX);
+
+ pr_debug("kfd: In func %s\n", __func__);
+
+ mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
+ if (!mqd)
+ return NULL;
+
+ mqd->dev = dev;
+
+ switch (type) {
+ case KFD_MQD_TYPE_CP:
+ case KFD_MQD_TYPE_COMPUTE:
+ mqd->init_mqd = init_mqd;
+ mqd->uninit_mqd = uninit_mqd;
+ mqd->load_mqd = load_mqd;
+ mqd->update_mqd = update_mqd;
+ mqd->destroy_mqd = destroy_mqd;
+ mqd->is_occupied = is_occupied;
+ break;
+ case KFD_MQD_TYPE_HIQ:
+ mqd->init_mqd = init_mqd_hiq;
+ mqd->uninit_mqd = uninit_mqd;
+ mqd->load_mqd = load_mqd;
+ mqd->update_mqd = update_mqd_hiq;
+ mqd->destroy_mqd = destroy_mqd;
+ mqd->is_occupied = is_occupied;
+ break;
+ case KFD_MQD_TYPE_SDMA:
+ mqd->init_mqd = init_mqd_sdma;
+ mqd->uninit_mqd = uninit_mqd_sdma;
+ mqd->load_mqd = load_mqd_sdma;
+ mqd->update_mqd = update_mqd_sdma;
+ mqd->destroy_mqd = destroy_mqd_sdma;
+ mqd->is_occupied = is_occupied_sdma;
+ break;
+ default:
+ kfree(mqd);
+ return NULL;
+ }
+
+ return mqd;
+}
+
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
new file mode 100644
index 000000000000..b3a7e3ba1e38
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/printk.h>
+#include "kfd_priv.h"
+#include "kfd_mqd_manager.h"
+
+struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
+ struct kfd_dev *dev)
+{
+ pr_warn("amdkfd: VI MQD is not currently supported\n");
+ return NULL;
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
index 5ce9233d2004..e2533d875f43 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
@@ -97,11 +97,8 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription);
- retval = kfd2kgd->allocate_mem(pm->dqm->dev->kgd,
- *rl_buffer_size,
- PAGE_SIZE,
- KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
- (struct kgd_mem **) &pm->ib_buffer_obj);
+ retval = kfd_gtt_sa_allocate(pm->dqm->dev, *rl_buffer_size,
+ &pm->ib_buffer_obj);
if (retval != 0) {
pr_err("kfd: failed to allocate runlist IB\n");
@@ -351,7 +348,7 @@ int pm_send_set_resources(struct packet_manager *pm,
pr_debug("kfd: In func %s\n", __func__);
mutex_lock(&pm->lock);
- pm->priv_queue->acquire_packet_buffer(pm->priv_queue,
+ pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
sizeof(*packet) / sizeof(uint32_t),
(unsigned int **)&packet);
if (packet == NULL) {
@@ -378,8 +375,7 @@ int pm_send_set_resources(struct packet_manager *pm,
packet->queue_mask_lo = lower_32_bits(res->queue_mask);
packet->queue_mask_hi = upper_32_bits(res->queue_mask);
- pm->priv_queue->submit_packet(pm->priv_queue);
- pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
+ pm->priv_queue->ops.submit_packet(pm->priv_queue);
mutex_unlock(&pm->lock);
@@ -405,7 +401,7 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t);
mutex_lock(&pm->lock);
- retval = pm->priv_queue->acquire_packet_buffer(pm->priv_queue,
+ retval = pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
packet_size_dwords, &rl_buffer);
if (retval != 0)
goto fail_acquire_packet_buffer;
@@ -415,15 +411,14 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
if (retval != 0)
goto fail_create_runlist;
- pm->priv_queue->submit_packet(pm->priv_queue);
- pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
+ pm->priv_queue->ops.submit_packet(pm->priv_queue);
mutex_unlock(&pm->lock);
return retval;
fail_create_runlist:
- pm->priv_queue->rollback_packet(pm->priv_queue);
+ pm->priv_queue->ops.rollback_packet(pm->priv_queue);
fail_acquire_packet_buffer:
mutex_unlock(&pm->lock);
fail_create_runlist_ib:
@@ -441,7 +436,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
BUG_ON(!pm || !fence_address);
mutex_lock(&pm->lock);
- retval = pm->priv_queue->acquire_packet_buffer(
+ retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue,
sizeof(struct pm4_query_status) / sizeof(uint32_t),
(unsigned int **)&packet);
@@ -462,8 +457,7 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
packet->data_hi = upper_32_bits((uint64_t)fence_value);
packet->data_lo = lower_32_bits((uint64_t)fence_value);
- pm->priv_queue->submit_packet(pm->priv_queue);
- pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
+ pm->priv_queue->ops.submit_packet(pm->priv_queue);
mutex_unlock(&pm->lock);
return 0;
@@ -485,7 +479,7 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
BUG_ON(!pm);
mutex_lock(&pm->lock);
- retval = pm->priv_queue->acquire_packet_buffer(
+ retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue,
sizeof(struct pm4_unmap_queues) / sizeof(uint32_t),
&buffer);
@@ -540,8 +534,7 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
break;
};
- pm->priv_queue->submit_packet(pm->priv_queue);
- pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
+ pm->priv_queue->ops.submit_packet(pm->priv_queue);
mutex_unlock(&pm->lock);
return 0;
@@ -557,8 +550,7 @@ void pm_release_ib(struct packet_manager *pm)
mutex_lock(&pm->lock);
if (pm->allocated) {
- kfd2kgd->free_mem(pm->dqm->dev->kgd,
- (struct kgd_mem *) pm->ib_buffer_obj);
+ kfd_gtt_sa_free(pm->dqm->dev, pm->ib_buffer_obj);
pm->allocated = false;
}
mutex_unlock(&pm->lock);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 96dc10e8904a..5a44f2fecf38 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -103,12 +103,26 @@ enum cache_policy {
cache_policy_noncoherent
};
+enum asic_family_type {
+ CHIP_KAVERI = 0,
+ CHIP_CARRIZO
+};
+
struct kfd_device_info {
+ unsigned int asic_family;
unsigned int max_pasid_bits;
size_t ih_ring_entry_size;
+ uint8_t num_of_watch_points;
uint16_t mqd_size_aligned;
};
+struct kfd_mem_obj {
+ uint32_t range_start;
+ uint32_t range_end;
+ uint64_t gpu_addr;
+ uint32_t *cpu_ptr;
+};
+
struct kfd_dev {
struct kgd_dev *kgd;
@@ -134,6 +148,14 @@ struct kfd_dev {
struct kgd2kfd_shared_resources shared_resources;
+ void *gtt_mem;
+ uint64_t gtt_start_gpu_addr;
+ void *gtt_start_cpu_ptr;
+ void *gtt_sa_bitmap;
+ struct mutex gtt_sa_lock;
+ unsigned int gtt_sa_chunk_size;
+ unsigned int gtt_sa_num_of_chunks;
+
/* QCM Device instance */
struct device_queue_manager *dqm;
@@ -149,12 +171,6 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd);
extern const struct kfd2kgd_calls *kfd2kgd;
-struct kfd_mem_obj {
- void *bo;
- uint64_t gpu_addr;
- uint32_t *cpu_ptr;
-};
-
enum kfd_mempool {
KFD_MEMPOOL_SYSTEM_CACHEABLE = 1,
KFD_MEMPOOL_SYSTEM_WRITECOMBINE = 2,
@@ -272,6 +288,15 @@ struct queue_properties {
bool is_active;
/* Not relevant for user mode queues in cp scheduling */
unsigned int vmid;
+ /* Relevant only for sdma queues*/
+ uint32_t sdma_engine_id;
+ uint32_t sdma_queue_id;
+ uint32_t sdma_vm_addr;
+ /* Relevant only for VI */
+ uint64_t eop_ring_buffer_address;
+ uint32_t eop_ring_buffer_size;
+ uint64_t ctx_save_restore_area_address;
+ uint32_t ctx_save_restore_area_size;
};
/**
@@ -314,6 +339,8 @@ struct queue {
uint32_t pipe;
uint32_t queue;
+ unsigned int sdma_id;
+
struct kfd_process *process;
struct kfd_dev *device;
};
@@ -322,10 +349,10 @@ struct queue {
* Please read the kfd_mqd_manager.h description.
*/
enum KFD_MQD_TYPE {
- KFD_MQD_TYPE_CIK_COMPUTE = 0, /* for no cp scheduling */
- KFD_MQD_TYPE_CIK_HIQ, /* for hiq */
- KFD_MQD_TYPE_CIK_CP, /* for cp queues and diq */
- KFD_MQD_TYPE_CIK_SDMA, /* for sdma queues */
+ KFD_MQD_TYPE_COMPUTE = 0, /* for no cp scheduling */
+ KFD_MQD_TYPE_HIQ, /* for hiq */
+ KFD_MQD_TYPE_CP, /* for cp queues and diq */
+ KFD_MQD_TYPE_SDMA, /* for sdma queues */
KFD_MQD_TYPE_MAX
};
@@ -477,8 +504,9 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
struct kfd_process *p);
void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid);
struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
- struct kfd_process *p,
- int create_pdd);
+ struct kfd_process *p);
+struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
+ struct kfd_process *p);
/* Process device data iterator */
struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p);
@@ -506,6 +534,13 @@ unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd,
struct kfd_process *process,
unsigned int queue_id);
+/* GTT Sub-Allocator */
+
+int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
+ struct kfd_mem_obj **mem_obj);
+
+int kfd_gtt_sa_free(struct kfd_dev *kfd, struct kfd_mem_obj *mem_obj);
+
extern struct device *kfd_device;
/* Topology */
@@ -530,6 +565,8 @@ int kfd_init_apertures(struct kfd_process *process);
/* Queue Context Management */
inline uint32_t lower_32(uint64_t x);
inline uint32_t upper_32(uint64_t x);
+struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd);
+inline uint32_t get_sdma_base_addr(struct cik_sdma_rlc_registers *m);
int init_queue(struct queue **q, struct queue_properties properties);
void uninit_queue(struct queue *q);
@@ -538,6 +575,10 @@ void print_queue(struct queue *q);
struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
struct kfd_dev *dev);
+struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
+ struct kfd_dev *dev);
+struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
+ struct kfd_dev *dev);
struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev);
void device_queue_manager_uninit(struct device_queue_manager *dqm);
struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 3c76ef05cbcf..a369c149d172 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -311,24 +311,29 @@ err_alloc_process:
}
struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
- struct kfd_process *p,
- int create_pdd)
+ struct kfd_process *p)
{
struct kfd_process_device *pdd = NULL;
list_for_each_entry(pdd, &p->per_device_data, per_device_list)
if (pdd->dev == dev)
- return pdd;
-
- if (create_pdd) {
- pdd = kzalloc(sizeof(*pdd), GFP_KERNEL);
- if (pdd != NULL) {
- pdd->dev = dev;
- INIT_LIST_HEAD(&pdd->qpd.queues_list);
- INIT_LIST_HEAD(&pdd->qpd.priv_queue_list);
- pdd->qpd.dqm = dev->dqm;
- list_add(&pdd->per_device_list, &p->per_device_data);
- }
+ break;
+
+ return pdd;
+}
+
+struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
+ struct kfd_process *p)
+{
+ struct kfd_process_device *pdd = NULL;
+
+ pdd = kzalloc(sizeof(*pdd), GFP_KERNEL);
+ if (pdd != NULL) {
+ pdd->dev = dev;
+ INIT_LIST_HEAD(&pdd->qpd.queues_list);
+ INIT_LIST_HEAD(&pdd->qpd.priv_queue_list);
+ pdd->qpd.dqm = dev->dqm;
+ list_add(&pdd->per_device_list, &p->per_device_data);
}
return pdd;
@@ -344,11 +349,14 @@ struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
struct kfd_process *p)
{
- struct kfd_process_device *pdd = kfd_get_process_device_data(dev, p, 1);
+ struct kfd_process_device *pdd;
int err;
- if (pdd == NULL)
+ pdd = kfd_get_process_device_data(dev, p);
+ if (!pdd) {
+ pr_err("Process device data doesn't exist\n");
return ERR_PTR(-ENOMEM);
+ }
if (pdd->bound)
return pdd;
@@ -384,7 +392,7 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
pqm_uninit(&p->pqm);
- pdd = kfd_get_process_device_data(dev, p, 0);
+ pdd = kfd_get_process_device_data(dev, p);
/*
* Just mark pdd as unbound, because we still need it to call
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 2fda1927bff7..530b82c4e78b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -128,7 +128,6 @@ static int create_cp_queue(struct process_queue_manager *pqm,
/* let DQM handle it*/
q_properties->vmid = 0;
q_properties->queue_id = qid;
- q_properties->type = KFD_QUEUE_TYPE_COMPUTE;
retval = init_queue(q, *q_properties);
if (retval != 0)
@@ -167,8 +166,11 @@ int pqm_create_queue(struct process_queue_manager *pqm,
q = NULL;
kq = NULL;
- pdd = kfd_get_process_device_data(dev, pqm->process, 1);
- BUG_ON(!pdd);
+ pdd = kfd_get_process_device_data(dev, pqm->process);
+ if (!pdd) {
+ pr_err("Process device data doesn't exist\n");
+ return -1;
+ }
retval = find_available_queue_slot(pqm, qid);
if (retval != 0)
@@ -176,7 +178,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
if (list_empty(&pqm->queues)) {
pdd->qpd.pqm = pqm;
- dev->dqm->register_process(dev->dqm, &pdd->qpd);
+ dev->dqm->ops.register_process(dev->dqm, &pdd->qpd);
}
pqn = kzalloc(sizeof(struct process_queue_node), GFP_KERNEL);
@@ -186,6 +188,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
}
switch (type) {
+ case KFD_QUEUE_TYPE_SDMA:
case KFD_QUEUE_TYPE_COMPUTE:
/* check if there is over subscription */
if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&
@@ -201,7 +204,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
goto err_create_queue;
pqn->q = q;
pqn->kq = NULL;
- retval = dev->dqm->create_queue(dev->dqm, q, &pdd->qpd,
+ retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd,
&q->properties.vmid);
pr_debug("DQM returned %d for create_queue\n", retval);
print_queue(q);
@@ -215,7 +218,8 @@ int pqm_create_queue(struct process_queue_manager *pqm,
kq->queue->properties.queue_id = *qid;
pqn->kq = kq;
pqn->q = NULL;
- retval = dev->dqm->create_kernel_queue(dev->dqm, kq, &pdd->qpd);
+ retval = dev->dqm->ops.create_kernel_queue(dev->dqm,
+ kq, &pdd->qpd);
break;
default:
BUG();
@@ -245,7 +249,7 @@ err_allocate_pqn:
/* check if queues list is empty unregister process from device */
clear_bit(*qid, pqm->queue_slot_bitmap);
if (list_empty(&pqm->queues))
- dev->dqm->unregister_process(dev->dqm, &pdd->qpd);
+ dev->dqm->ops.unregister_process(dev->dqm, &pdd->qpd);
return retval;
}
@@ -277,19 +281,22 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
dev = pqn->q->device;
BUG_ON(!dev);
- pdd = kfd_get_process_device_data(dev, pqm->process, 1);
- BUG_ON(!pdd);
+ pdd = kfd_get_process_device_data(dev, pqm->process);
+ if (!pdd) {
+ pr_err("Process device data doesn't exist\n");
+ return -1;
+ }
if (pqn->kq) {
/* destroy kernel queue (DIQ) */
dqm = pqn->kq->dev->dqm;
- dqm->destroy_kernel_queue(dqm, pqn->kq, &pdd->qpd);
+ dqm->ops.destroy_kernel_queue(dqm, pqn->kq, &pdd->qpd);
kernel_queue_uninit(pqn->kq);
}
if (pqn->q) {
dqm = pqn->q->device->dqm;
- retval = dqm->destroy_queue(dqm, &pdd->qpd, pqn->q);
+ retval = dqm->ops.destroy_queue(dqm, &pdd->qpd, pqn->q);
if (retval != 0)
return retval;
@@ -301,7 +308,7 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
clear_bit(qid, pqm->queue_slot_bitmap);
if (list_empty(&pqm->queues))
- dqm->unregister_process(dqm, &pdd->qpd);
+ dqm->ops.unregister_process(dqm, &pdd->qpd);
return retval;
}
@@ -326,7 +333,8 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
pqn->q->properties.queue_percent = p->queue_percent;
pqn->q->properties.priority = p->priority;
- retval = pqn->q->device->dqm->update_queue(pqn->q->device->dqm, pqn->q);
+ retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
+ pqn->q);
if (retval != 0)
return retval;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index cca1708fd811..498399323a8c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -27,6 +27,7 @@
#include <linux/acpi.h>
#include <linux/hash.h>
#include <linux/cpufreq.h>
+#include <linux/log2.h>
#include "kfd_priv.h"
#include "kfd_crat.h"
@@ -630,10 +631,10 @@ static struct kobj_type cache_type = {
static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
char *buffer)
{
- ssize_t ret;
struct kfd_topology_device *dev;
char public_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE];
uint32_t i;
+ uint32_t log_max_watch_addr;
/* Making sure that the buffer is an empty string */
buffer[0] = 0;
@@ -641,8 +642,10 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
if (strcmp(attr->name, "gpu_id") == 0) {
dev = container_of(attr, struct kfd_topology_device,
attr_gpuid);
- ret = sysfs_show_32bit_val(buffer, dev->gpu_id);
- } else if (strcmp(attr->name, "name") == 0) {
+ return sysfs_show_32bit_val(buffer, dev->gpu_id);
+ }
+
+ if (strcmp(attr->name, "name") == 0) {
dev = container_of(attr, struct kfd_topology_device,
attr_name);
for (i = 0; i < KFD_TOPOLOGY_PUBLIC_NAME_SIZE; i++) {
@@ -652,80 +655,90 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
break;
}
public_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE-1] = 0x0;
- ret = sysfs_show_str_val(buffer, public_name);
- } else {
- dev = container_of(attr, struct kfd_topology_device,
- attr_props);
- sysfs_show_32bit_prop(buffer, "cpu_cores_count",
- dev->node_props.cpu_cores_count);
- sysfs_show_32bit_prop(buffer, "simd_count",
- dev->node_props.simd_count);
-
- if (dev->mem_bank_count < dev->node_props.mem_banks_count) {
- pr_warn("kfd: mem_banks_count truncated from %d to %d\n",
- dev->node_props.mem_banks_count,
- dev->mem_bank_count);
- sysfs_show_32bit_prop(buffer, "mem_banks_count",
- dev->mem_bank_count);
- } else {
- sysfs_show_32bit_prop(buffer, "mem_banks_count",
- dev->node_props.mem_banks_count);
- }
+ return sysfs_show_str_val(buffer, public_name);
+ }
- sysfs_show_32bit_prop(buffer, "caches_count",
- dev->node_props.caches_count);
- sysfs_show_32bit_prop(buffer, "io_links_count",
- dev->node_props.io_links_count);
- sysfs_show_32bit_prop(buffer, "cpu_core_id_base",
- dev->node_props.cpu_core_id_base);
- sysfs_show_32bit_prop(buffer, "simd_id_base",
- dev->node_props.simd_id_base);
- sysfs_show_32bit_prop(buffer, "capability",
- dev->node_props.capability);
- sysfs_show_32bit_prop(buffer, "max_waves_per_simd",
- dev->node_props.max_waves_per_simd);
- sysfs_show_32bit_prop(buffer, "lds_size_in_kb",
- dev->node_props.lds_size_in_kb);
- sysfs_show_32bit_prop(buffer, "gds_size_in_kb",
- dev->node_props.gds_size_in_kb);
- sysfs_show_32bit_prop(buffer, "wave_front_size",
- dev->node_props.wave_front_size);
- sysfs_show_32bit_prop(buffer, "array_count",
- dev->node_props.array_count);
- sysfs_show_32bit_prop(buffer, "simd_arrays_per_engine",
- dev->node_props.simd_arrays_per_engine);
- sysfs_show_32bit_prop(buffer, "cu_per_simd_array",
- dev->node_props.cu_per_simd_array);
- sysfs_show_32bit_prop(buffer, "simd_per_cu",
- dev->node_props.simd_per_cu);
- sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu",
- dev->node_props.max_slots_scratch_cu);
- sysfs_show_32bit_prop(buffer, "vendor_id",
- dev->node_props.vendor_id);
- sysfs_show_32bit_prop(buffer, "device_id",
- dev->node_props.device_id);
- sysfs_show_32bit_prop(buffer, "location_id",
- dev->node_props.location_id);
-
- if (dev->gpu) {
- sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute",
- kfd2kgd->get_max_engine_clock_in_mhz(
- dev->gpu->kgd));
- sysfs_show_64bit_prop(buffer, "local_mem_size",
- kfd2kgd->get_vmem_size(dev->gpu->kgd));
-
- sysfs_show_32bit_prop(buffer, "fw_version",
- kfd2kgd->get_fw_version(
- dev->gpu->kgd,
- KGD_ENGINE_MEC1));
+ dev = container_of(attr, struct kfd_topology_device,
+ attr_props);
+ sysfs_show_32bit_prop(buffer, "cpu_cores_count",
+ dev->node_props.cpu_cores_count);
+ sysfs_show_32bit_prop(buffer, "simd_count",
+ dev->node_props.simd_count);
+
+ if (dev->mem_bank_count < dev->node_props.mem_banks_count) {
+ pr_warn("kfd: mem_banks_count truncated from %d to %d\n",
+ dev->node_props.mem_banks_count,
+ dev->mem_bank_count);
+ sysfs_show_32bit_prop(buffer, "mem_banks_count",
+ dev->mem_bank_count);
+ } else {
+ sysfs_show_32bit_prop(buffer, "mem_banks_count",
+ dev->node_props.mem_banks_count);
+ }
+ sysfs_show_32bit_prop(buffer, "caches_count",
+ dev->node_props.caches_count);
+ sysfs_show_32bit_prop(buffer, "io_links_count",
+ dev->node_props.io_links_count);
+ sysfs_show_32bit_prop(buffer, "cpu_core_id_base",
+ dev->node_props.cpu_core_id_base);
+ sysfs_show_32bit_prop(buffer, "simd_id_base",
+ dev->node_props.simd_id_base);
+ sysfs_show_32bit_prop(buffer, "capability",
+ dev->node_props.capability);
+ sysfs_show_32bit_prop(buffer, "max_waves_per_simd",
+ dev->node_props.max_waves_per_simd);
+ sysfs_show_32bit_prop(buffer, "lds_size_in_kb",
+ dev->node_props.lds_size_in_kb);
+ sysfs_show_32bit_prop(buffer, "gds_size_in_kb",
+ dev->node_props.gds_size_in_kb);
+ sysfs_show_32bit_prop(buffer, "wave_front_size",
+ dev->node_props.wave_front_size);
+ sysfs_show_32bit_prop(buffer, "array_count",
+ dev->node_props.array_count);
+ sysfs_show_32bit_prop(buffer, "simd_arrays_per_engine",
+ dev->node_props.simd_arrays_per_engine);
+ sysfs_show_32bit_prop(buffer, "cu_per_simd_array",
+ dev->node_props.cu_per_simd_array);
+ sysfs_show_32bit_prop(buffer, "simd_per_cu",
+ dev->node_props.simd_per_cu);
+ sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu",
+ dev->node_props.max_slots_scratch_cu);
+ sysfs_show_32bit_prop(buffer, "vendor_id",
+ dev->node_props.vendor_id);
+ sysfs_show_32bit_prop(buffer, "device_id",
+ dev->node_props.device_id);
+ sysfs_show_32bit_prop(buffer, "location_id",
+ dev->node_props.location_id);
+
+ if (dev->gpu) {
+ log_max_watch_addr =
+ __ilog2_u32(dev->gpu->device_info->num_of_watch_points);
+
+ if (log_max_watch_addr) {
+ dev->node_props.capability |=
+ HSA_CAP_WATCH_POINTS_SUPPORTED;
+
+ dev->node_props.capability |=
+ ((log_max_watch_addr <<
+ HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT) &
+ HSA_CAP_WATCH_POINTS_TOTALBITS_MASK);
}
- ret = sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute",
- cpufreq_quick_get_max(0)/1000);
+ sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute",
+ kfd2kgd->get_max_engine_clock_in_mhz(
+ dev->gpu->kgd));
+ sysfs_show_64bit_prop(buffer, "local_mem_size",
+ kfd2kgd->get_vmem_size(dev->gpu->kgd));
+
+ sysfs_show_32bit_prop(buffer, "fw_version",
+ kfd2kgd->get_fw_version(
+ dev->gpu->kgd,
+ KGD_ENGINE_MEC1));
}
- return ret;
+ return sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute",
+ cpufreq_quick_get_max(0)/1000);
}
static const struct sysfs_ops node_ops = {
diff --git a/drivers/gpu/drm/amd/include/cik_structs.h b/drivers/gpu/drm/amd/include/cik_structs.h
new file mode 100644
index 000000000000..749eab94e335
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/cik_structs.h
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef CIK_STRUCTS_H_
+#define CIK_STRUCTS_H_
+
+struct cik_mqd {
+ uint32_t header;
+ uint32_t compute_dispatch_initiator;
+ uint32_t compute_dim_x;
+ uint32_t compute_dim_y;
+ uint32_t compute_dim_z;
+ uint32_t compute_start_x;
+ uint32_t compute_start_y;
+ uint32_t compute_start_z;
+ uint32_t compute_num_thread_x;
+ uint32_t compute_num_thread_y;
+ uint32_t compute_num_thread_z;
+ uint32_t compute_pipelinestat_enable;
+ uint32_t compute_perfcount_enable;
+ uint32_t compute_pgm_lo;
+ uint32_t compute_pgm_hi;
+ uint32_t compute_tba_lo;
+ uint32_t compute_tba_hi;
+ uint32_t compute_tma_lo;
+ uint32_t compute_tma_hi;
+ uint32_t compute_pgm_rsrc1;
+ uint32_t compute_pgm_rsrc2;
+ uint32_t compute_vmid;
+ uint32_t compute_resource_limits;
+ uint32_t compute_static_thread_mgmt_se0;
+ uint32_t compute_static_thread_mgmt_se1;
+ uint32_t compute_tmpring_size;
+ uint32_t compute_static_thread_mgmt_se2;
+ uint32_t compute_static_thread_mgmt_se3;
+ uint32_t compute_restart_x;
+ uint32_t compute_restart_y;
+ uint32_t compute_restart_z;
+ uint32_t compute_thread_trace_enable;
+ uint32_t compute_misc_reserved;
+ uint32_t compute_user_data_0;
+ uint32_t compute_user_data_1;
+ uint32_t compute_user_data_2;
+ uint32_t compute_user_data_3;
+ uint32_t compute_user_data_4;
+ uint32_t compute_user_data_5;
+ uint32_t compute_user_data_6;
+ uint32_t compute_user_data_7;
+ uint32_t compute_user_data_8;
+ uint32_t compute_user_data_9;
+ uint32_t compute_user_data_10;
+ uint32_t compute_user_data_11;
+ uint32_t compute_user_data_12;
+ uint32_t compute_user_data_13;
+ uint32_t compute_user_data_14;
+ uint32_t compute_user_data_15;
+ uint32_t cp_compute_csinvoc_count_lo;
+ uint32_t cp_compute_csinvoc_count_hi;
+ uint32_t cp_mqd_base_addr_lo;
+ uint32_t cp_mqd_base_addr_hi;
+ uint32_t cp_hqd_active;
+ uint32_t cp_hqd_vmid;
+ uint32_t cp_hqd_persistent_state;
+ uint32_t cp_hqd_pipe_priority;
+ uint32_t cp_hqd_queue_priority;
+ uint32_t cp_hqd_quantum;
+ uint32_t cp_hqd_pq_base_lo;
+ uint32_t cp_hqd_pq_base_hi;
+ uint32_t cp_hqd_pq_rptr;
+ uint32_t cp_hqd_pq_rptr_report_addr_lo;
+ uint32_t cp_hqd_pq_rptr_report_addr_hi;
+ uint32_t cp_hqd_pq_wptr_poll_addr_lo;
+ uint32_t cp_hqd_pq_wptr_poll_addr_hi;
+ uint32_t cp_hqd_pq_doorbell_control;
+ uint32_t cp_hqd_pq_wptr;
+ uint32_t cp_hqd_pq_control;
+ uint32_t cp_hqd_ib_base_addr_lo;
+ uint32_t cp_hqd_ib_base_addr_hi;
+ uint32_t cp_hqd_ib_rptr;
+ uint32_t cp_hqd_ib_control;
+ uint32_t cp_hqd_iq_timer;
+ uint32_t cp_hqd_iq_rptr;
+ uint32_t cp_hqd_dequeue_request;
+ uint32_t cp_hqd_dma_offload;
+ uint32_t cp_hqd_sema_cmd;
+ uint32_t cp_hqd_msg_type;
+ uint32_t cp_hqd_atomic0_preop_lo;
+ uint32_t cp_hqd_atomic0_preop_hi;
+ uint32_t cp_hqd_atomic1_preop_lo;
+ uint32_t cp_hqd_atomic1_preop_hi;
+ uint32_t cp_hqd_hq_status0;
+ uint32_t cp_hqd_hq_control0;
+ uint32_t cp_mqd_control;
+ uint32_t cp_mqd_query_time_lo;
+ uint32_t cp_mqd_query_time_hi;
+ uint32_t cp_mqd_connect_start_time_lo;
+ uint32_t cp_mqd_connect_start_time_hi;
+ uint32_t cp_mqd_connect_end_time_lo;
+ uint32_t cp_mqd_connect_end_time_hi;
+ uint32_t cp_mqd_connect_end_wf_count;
+ uint32_t cp_mqd_connect_end_pq_rptr;
+ uint32_t cp_mqd_connect_end_pq_wptr;
+ uint32_t cp_mqd_connect_end_ib_rptr;
+ uint32_t reserved_96;
+ uint32_t reserved_97;
+ uint32_t reserved_98;
+ uint32_t reserved_99;
+ uint32_t iqtimer_pkt_header;
+ uint32_t iqtimer_pkt_dw0;
+ uint32_t iqtimer_pkt_dw1;
+ uint32_t iqtimer_pkt_dw2;
+ uint32_t iqtimer_pkt_dw3;
+ uint32_t iqtimer_pkt_dw4;
+ uint32_t iqtimer_pkt_dw5;
+ uint32_t iqtimer_pkt_dw6;
+ uint32_t reserved_108;
+ uint32_t reserved_109;
+ uint32_t reserved_110;
+ uint32_t reserved_111;
+ uint32_t queue_doorbell_id0;
+ uint32_t queue_doorbell_id1;
+ uint32_t queue_doorbell_id2;
+ uint32_t queue_doorbell_id3;
+ uint32_t queue_doorbell_id4;
+ uint32_t queue_doorbell_id5;
+ uint32_t queue_doorbell_id6;
+ uint32_t queue_doorbell_id7;
+ uint32_t queue_doorbell_id8;
+ uint32_t queue_doorbell_id9;
+ uint32_t queue_doorbell_id10;
+ uint32_t queue_doorbell_id11;
+ uint32_t queue_doorbell_id12;
+ uint32_t queue_doorbell_id13;
+ uint32_t queue_doorbell_id14;
+ uint32_t queue_doorbell_id15;
+};
+
+struct cik_sdma_rlc_registers {
+ uint32_t sdma_rlc_rb_cntl;
+ uint32_t sdma_rlc_rb_base;
+ uint32_t sdma_rlc_rb_base_hi;
+ uint32_t sdma_rlc_rb_rptr;
+ uint32_t sdma_rlc_rb_wptr;
+ uint32_t sdma_rlc_rb_wptr_poll_cntl;
+ uint32_t sdma_rlc_rb_wptr_poll_addr_hi;
+ uint32_t sdma_rlc_rb_wptr_poll_addr_lo;
+ uint32_t sdma_rlc_rb_rptr_addr_hi;
+ uint32_t sdma_rlc_rb_rptr_addr_lo;
+ uint32_t sdma_rlc_ib_cntl;
+ uint32_t sdma_rlc_ib_rptr;
+ uint32_t sdma_rlc_ib_offset;
+ uint32_t sdma_rlc_ib_base_lo;
+ uint32_t sdma_rlc_ib_base_hi;
+ uint32_t sdma_rlc_ib_size;
+ uint32_t sdma_rlc_skip_cntl;
+ uint32_t sdma_rlc_context_status;
+ uint32_t sdma_rlc_doorbell;
+ uint32_t sdma_rlc_virtual_addr;
+ uint32_t sdma_rlc_ape1_cntl;
+ uint32_t sdma_rlc_doorbell_log;
+ uint32_t reserved_22;
+ uint32_t reserved_23;
+ uint32_t reserved_24;
+ uint32_t reserved_25;
+ uint32_t reserved_26;
+ uint32_t reserved_27;
+ uint32_t reserved_28;
+ uint32_t reserved_29;
+ uint32_t reserved_30;
+ uint32_t reserved_31;
+ uint32_t reserved_32;
+ uint32_t reserved_33;
+ uint32_t reserved_34;
+ uint32_t reserved_35;
+ uint32_t reserved_36;
+ uint32_t reserved_37;
+ uint32_t reserved_38;
+ uint32_t reserved_39;
+ uint32_t reserved_40;
+ uint32_t reserved_41;
+ uint32_t reserved_42;
+ uint32_t reserved_43;
+ uint32_t reserved_44;
+ uint32_t reserved_45;
+ uint32_t reserved_46;
+ uint32_t reserved_47;
+ uint32_t reserved_48;
+ uint32_t reserved_49;
+ uint32_t reserved_50;
+ uint32_t reserved_51;
+ uint32_t reserved_52;
+ uint32_t reserved_53;
+ uint32_t reserved_54;
+ uint32_t reserved_55;
+ uint32_t reserved_56;
+ uint32_t reserved_57;
+ uint32_t reserved_58;
+ uint32_t reserved_59;
+ uint32_t reserved_60;
+ uint32_t reserved_61;
+ uint32_t reserved_62;
+ uint32_t reserved_63;
+ uint32_t reserved_64;
+ uint32_t reserved_65;
+ uint32_t reserved_66;
+ uint32_t reserved_67;
+ uint32_t reserved_68;
+ uint32_t reserved_69;
+ uint32_t reserved_70;
+ uint32_t reserved_71;
+ uint32_t reserved_72;
+ uint32_t reserved_73;
+ uint32_t reserved_74;
+ uint32_t reserved_75;
+ uint32_t reserved_76;
+ uint32_t reserved_77;
+ uint32_t reserved_78;
+ uint32_t reserved_79;
+ uint32_t reserved_80;
+ uint32_t reserved_81;
+ uint32_t reserved_82;
+ uint32_t reserved_83;
+ uint32_t reserved_84;
+ uint32_t reserved_85;
+ uint32_t reserved_86;
+ uint32_t reserved_87;
+ uint32_t reserved_88;
+ uint32_t reserved_89;
+ uint32_t reserved_90;
+ uint32_t reserved_91;
+ uint32_t reserved_92;
+ uint32_t reserved_93;
+ uint32_t reserved_94;
+ uint32_t reserved_95;
+ uint32_t reserved_96;
+ uint32_t reserved_97;
+ uint32_t reserved_98;
+ uint32_t reserved_99;
+ uint32_t reserved_100;
+ uint32_t reserved_101;
+ uint32_t reserved_102;
+ uint32_t reserved_103;
+ uint32_t reserved_104;
+ uint32_t reserved_105;
+ uint32_t reserved_106;
+ uint32_t reserved_107;
+ uint32_t reserved_108;
+ uint32_t reserved_109;
+ uint32_t reserved_110;
+ uint32_t reserved_111;
+ uint32_t reserved_112;
+ uint32_t reserved_113;
+ uint32_t reserved_114;
+ uint32_t reserved_115;
+ uint32_t reserved_116;
+ uint32_t reserved_117;
+ uint32_t reserved_118;
+ uint32_t reserved_119;
+ uint32_t reserved_120;
+ uint32_t reserved_121;
+ uint32_t reserved_122;
+ uint32_t reserved_123;
+ uint32_t reserved_124;
+ uint32_t reserved_125;
+ uint32_t reserved_126;
+ uint32_t reserved_127;
+ uint32_t sdma_engine_id;
+ uint32_t sdma_queue_id;
+};
+
+
+
+#endif /* CIK_STRUCTS_H_ */
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 96a512208fad..239bc16a1ddd 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -110,17 +110,10 @@ struct kgd2kfd_calls {
/**
* struct kfd2kgd_calls
*
- * @init_sa_manager: Initialize an instance of the sa manager, used by
- * amdkfd for all system memory allocations that are mapped to the GART
- * address space
+ * @init_gtt_mem_allocation: Allocate a buffer on the gart aperture.
+ * The buffer can be used for mqds, hpds, kernel queue, fence and runlists
*
- * @fini_sa_manager: Releases all memory allocations for amdkfd that are
- * handled by kgd sa manager
- *
- * @allocate_mem: Allocate a buffer from amdkfd's sa manager. The buffer can
- * be used for mqds, hpds, kernel queue, fence and runlists
- *
- * @free_mem: Frees a buffer that was allocated by amdkfd's sa manager
+ * @free_gtt_mem: Frees a buffer that was allocated on the gart aperture
*
* @get_vmem_size: Retrieves (physical) size of VRAM
*
@@ -136,18 +129,23 @@ struct kgd2kfd_calls {
* @set_pasid_vmid_mapping: Exposes pasid/vmid pair to the H/W for no cp
* scheduling mode. Only used for no cp scheduling mode.
*
- * @init_memory: Initializes memory apertures to fixed base/limit address
- * and non cached memory types.
- *
* @init_pipeline: Initialized the compute pipelines.
*
* @hqd_load: Loads the mqd structure to a H/W hqd slot. used only for no cp
* sceduling mode.
*
+ * @hqd_sdma_load: Loads the SDMA mqd structure to a H/W SDMA hqd slot.
+ * used only for no HWS mode.
+ *
* @hqd_is_occupies: Checks if a hqd slot is occupied.
*
* @hqd_destroy: Destructs and preempts the queue assigned to that hqd slot.
*
+ * @hqd_sdma_is_occupied: Checks if an SDMA hqd slot is occupied.
+ *
+ * @hqd_sdma_destroy: Destructs and preempts the SDMA queue assigned to that
+ * SDMA hqd slot.
+ *
* @get_fw_version: Returns FW versions from the header
*
* This structure contains function pointers to services that the kgd driver
@@ -155,13 +153,11 @@ struct kgd2kfd_calls {
*
*/
struct kfd2kgd_calls {
- /* Memory management. */
- int (*init_sa_manager)(struct kgd_dev *kgd, unsigned int size);
- void (*fini_sa_manager)(struct kgd_dev *kgd);
- int (*allocate_mem)(struct kgd_dev *kgd, size_t size, size_t alignment,
- enum kgd_memory_pool pool, struct kgd_mem **mem);
+ int (*init_gtt_mem_allocation)(struct kgd_dev *kgd, size_t size,
+ void **mem_obj, uint64_t *gpu_addr,
+ void **cpu_ptr);
- void (*free_mem)(struct kgd_dev *kgd, struct kgd_mem *mem);
+ void (*free_gtt_mem)(struct kgd_dev *kgd, void *mem_obj);
uint64_t (*get_vmem_size)(struct kgd_dev *kgd);
uint64_t (*get_gpu_clock_counter)(struct kgd_dev *kgd);
@@ -176,25 +172,32 @@ struct kfd2kgd_calls {
int (*set_pasid_vmid_mapping)(struct kgd_dev *kgd, unsigned int pasid,
unsigned int vmid);
- int (*init_memory)(struct kgd_dev *kgd);
int (*init_pipeline)(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
uint32_t queue_id, uint32_t __user *wptr);
+ int (*hqd_sdma_load)(struct kgd_dev *kgd, void *mqd);
+
bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id);
+
+ bool (*hqd_sdma_is_occupied)(struct kgd_dev *kgd, void *mqd);
+
+ int (*hqd_sdma_destroy)(struct kgd_dev *kgd, void *mqd,
+ unsigned int timeout);
+
uint16_t (*get_fw_version)(struct kgd_dev *kgd,
enum kgd_engine_type type);
};
bool kgd2kfd_init(unsigned interface_version,
- const struct kfd2kgd_calls *f2g,
- const struct kgd2kfd_calls **g2f);
+ const struct kfd2kgd_calls *f2g,
+ const struct kgd2kfd_calls **g2f);
-#endif /* KGD_KFD_INTERFACE_H_INCLUDED */
+#endif /* KGD_KFD_INTERFACE_H_INCLUDED */
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index e3a7a5078e5c..42d2ffa08716 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -653,10 +653,6 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
-static void armada_drm_crtc_load_lut(struct drm_crtc *crtc)
-{
-}
-
/* The mode_config.mutex will be held for this call */
static void armada_drm_crtc_disable(struct drm_crtc *crtc)
{
@@ -678,7 +674,6 @@ static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
.mode_fixup = armada_drm_crtc_mode_fixup,
.mode_set = armada_drm_crtc_mode_set,
.mode_set_base = armada_drm_crtc_mode_set_base,
- .load_lut = armada_drm_crtc_load_lut,
.disable = armada_drm_crtc_disable,
};
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index 5c60ae524c45..ff68eefae273 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -335,18 +335,27 @@ int ast_fbdev_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &afbdev->helper,
1, 1);
- if (ret) {
- kfree(afbdev);
- return ret;
- }
+ if (ret)
+ goto free;
- drm_fb_helper_single_add_all_connectors(&afbdev->helper);
+ ret = drm_fb_helper_single_add_all_connectors(&afbdev->helper);
+ if (ret)
+ goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);
- drm_fb_helper_initial_config(&afbdev->helper, 32);
+ ret = drm_fb_helper_initial_config(&afbdev->helper, 32);
+ if (ret)
+ goto fini;
+
return 0;
+
+fini:
+ drm_fb_helper_fini(&afbdev->helper);
+free:
+ kfree(afbdev);
+ return ret;
}
void ast_fbdev_fini(struct drm_device *dev)
diff --git a/drivers/gpu/drm/atmel-hlcdc/Kconfig b/drivers/gpu/drm/atmel-hlcdc/Kconfig
new file mode 100644
index 000000000000..99b4f0698a30
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/Kconfig
@@ -0,0 +1,11 @@
+config DRM_ATMEL_HLCDC
+ tristate "DRM Support for ATMEL HLCDC Display Controller"
+ depends on DRM && OF && COMMON_CLK && MFD_ATMEL_HLCDC && ARM
+ select DRM_GEM_CMA_HELPER
+ select DRM_KMS_HELPER
+ select DRM_KMS_FB_HELPER
+ select DRM_KMS_CMA_HELPER
+ select DRM_PANEL
+ help
+ Choose this option if you have an ATMEL SoC with an HLCDC display
+ controller (i.e. at91sam9n12, at91sam9x5 family or sama5d3 family).
diff --git a/drivers/gpu/drm/atmel-hlcdc/Makefile b/drivers/gpu/drm/atmel-hlcdc/Makefile
new file mode 100644
index 000000000000..10ae426e60bd
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/Makefile
@@ -0,0 +1,7 @@
+atmel-hlcdc-dc-y := atmel_hlcdc_crtc.o \
+ atmel_hlcdc_dc.o \
+ atmel_hlcdc_layer.o \
+ atmel_hlcdc_output.o \
+ atmel_hlcdc_plane.o
+
+obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc-dc.o
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
new file mode 100644
index 000000000000..0409b907de5d
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2014 Traphandler
+ * Copyright (C) 2014 Free Electrons
+ *
+ * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drmP.h>
+
+#include <video/videomode.h>
+
+#include "atmel_hlcdc_dc.h"
+
+/**
+ * Atmel HLCDC CRTC structure
+ *
+ * @base: base DRM CRTC structure
+ * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
+ * @event: pointer to the current page flip event
+ * @id: CRTC id (returned by drm_crtc_index)
+ * @dpms: DPMS mode
+ */
+struct atmel_hlcdc_crtc {
+ struct drm_crtc base;
+ struct atmel_hlcdc_dc *dc;
+ struct drm_pending_vblank_event *event;
+ int id;
+ int dpms;
+};
+
+static inline struct atmel_hlcdc_crtc *
+drm_crtc_to_atmel_hlcdc_crtc(struct drm_crtc *crtc)
+{
+ return container_of(crtc, struct atmel_hlcdc_crtc, base);
+}
+
+static void atmel_hlcdc_crtc_dpms(struct drm_crtc *c, int mode)
+{
+ struct drm_device *dev = c->dev;
+ struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
+ struct regmap *regmap = crtc->dc->hlcdc->regmap;
+ unsigned int status;
+
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
+ if (crtc->dpms == mode)
+ return;
+
+ pm_runtime_get_sync(dev->dev);
+
+ if (mode != DRM_MODE_DPMS_ON) {
+ regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
+ while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
+ (status & ATMEL_HLCDC_DISP))
+ cpu_relax();
+
+ regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_SYNC);
+ while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
+ (status & ATMEL_HLCDC_SYNC))
+ cpu_relax();
+
+ regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PIXEL_CLK);
+ while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
+ (status & ATMEL_HLCDC_PIXEL_CLK))
+ cpu_relax();
+
+ clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
+
+ pm_runtime_allow(dev->dev);
+ } else {
+ pm_runtime_forbid(dev->dev);
+
+ clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
+
+ regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK);
+ while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
+ !(status & ATMEL_HLCDC_PIXEL_CLK))
+ cpu_relax();
+
+
+ regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_SYNC);
+ while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
+ !(status & ATMEL_HLCDC_SYNC))
+ cpu_relax();
+
+ regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_DISP);
+ while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
+ !(status & ATMEL_HLCDC_DISP))
+ cpu_relax();
+ }
+
+ pm_runtime_put_sync(dev->dev);
+
+ crtc->dpms = mode;
+}
+
+static int atmel_hlcdc_crtc_mode_set(struct drm_crtc *c,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adj,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
+ struct regmap *regmap = crtc->dc->hlcdc->regmap;
+ struct drm_plane *plane = c->primary;
+ struct drm_framebuffer *fb;
+ unsigned long mode_rate;
+ struct videomode vm;
+ unsigned long prate;
+ unsigned int cfg;
+ int div;
+
+ if (atmel_hlcdc_dc_mode_valid(crtc->dc, adj) != MODE_OK)
+ return -EINVAL;
+
+ vm.vfront_porch = adj->crtc_vsync_start - adj->crtc_vdisplay;
+ vm.vback_porch = adj->crtc_vtotal - adj->crtc_vsync_end;
+ vm.vsync_len = adj->crtc_vsync_end - adj->crtc_vsync_start;
+ vm.hfront_porch = adj->crtc_hsync_start - adj->crtc_hdisplay;
+ vm.hback_porch = adj->crtc_htotal - adj->crtc_hsync_end;
+ vm.hsync_len = adj->crtc_hsync_end - adj->crtc_hsync_start;
+
+ regmap_write(regmap, ATMEL_HLCDC_CFG(1),
+ (vm.hsync_len - 1) | ((vm.vsync_len - 1) << 16));
+
+ regmap_write(regmap, ATMEL_HLCDC_CFG(2),
+ (vm.vfront_porch - 1) | (vm.vback_porch << 16));
+
+ regmap_write(regmap, ATMEL_HLCDC_CFG(3),
+ (vm.hfront_porch - 1) | ((vm.hback_porch - 1) << 16));
+
+ regmap_write(regmap, ATMEL_HLCDC_CFG(4),
+ (adj->crtc_hdisplay - 1) |
+ ((adj->crtc_vdisplay - 1) << 16));
+
+ cfg = ATMEL_HLCDC_CLKPOL;
+
+ prate = clk_get_rate(crtc->dc->hlcdc->sys_clk);
+ mode_rate = mode->crtc_clock * 1000;
+ if ((prate / 2) < mode_rate) {
+ prate *= 2;
+ cfg |= ATMEL_HLCDC_CLKSEL;
+ }
+
+ div = DIV_ROUND_UP(prate, mode_rate);
+ if (div < 2)
+ div = 2;
+
+ cfg |= ATMEL_HLCDC_CLKDIV(div);
+
+ regmap_update_bits(regmap, ATMEL_HLCDC_CFG(0),
+ ATMEL_HLCDC_CLKSEL | ATMEL_HLCDC_CLKDIV_MASK |
+ ATMEL_HLCDC_CLKPOL, cfg);
+
+ cfg = 0;
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ cfg |= ATMEL_HLCDC_VSPOL;
+
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ cfg |= ATMEL_HLCDC_HSPOL;
+
+ regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
+ ATMEL_HLCDC_HSPOL | ATMEL_HLCDC_VSPOL |
+ ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE |
+ ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY |
+ ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO |
+ ATMEL_HLCDC_GUARDTIME_MASK,
+ cfg);
+
+ fb = plane->fb;
+ plane->fb = old_fb;
+
+ return atmel_hlcdc_plane_update_with_mode(plane, c, fb, 0, 0,
+ adj->hdisplay, adj->vdisplay,
+ x << 16, y << 16,
+ adj->hdisplay << 16,
+ adj->vdisplay << 16,
+ adj);
+}
+
+int atmel_hlcdc_crtc_mode_set_base(struct drm_crtc *c, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ struct drm_plane *plane = c->primary;
+ struct drm_framebuffer *fb = plane->fb;
+ struct drm_display_mode *mode = &c->hwmode;
+
+ plane->fb = old_fb;
+
+ return plane->funcs->update_plane(plane, c, fb,
+ 0, 0,
+ mode->hdisplay,
+ mode->vdisplay,
+ x << 16, y << 16,
+ mode->hdisplay << 16,
+ mode->vdisplay << 16);
+}
+
+static void atmel_hlcdc_crtc_prepare(struct drm_crtc *crtc)
+{
+ atmel_hlcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void atmel_hlcdc_crtc_commit(struct drm_crtc *crtc)
+{
+ atmel_hlcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static bool atmel_hlcdc_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static void atmel_hlcdc_crtc_disable(struct drm_crtc *crtc)
+{
+ struct drm_plane *plane;
+
+ atmel_hlcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+ crtc->primary->funcs->disable_plane(crtc->primary);
+
+ drm_for_each_legacy_plane(plane, &crtc->dev->mode_config.plane_list) {
+ if (plane->crtc != crtc)
+ continue;
+
+ plane->funcs->disable_plane(crtc->primary);
+ plane->crtc = NULL;
+ }
+}
+
+static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = {
+ .mode_fixup = atmel_hlcdc_crtc_mode_fixup,
+ .dpms = atmel_hlcdc_crtc_dpms,
+ .mode_set = atmel_hlcdc_crtc_mode_set,
+ .mode_set_base = atmel_hlcdc_crtc_mode_set_base,
+ .prepare = atmel_hlcdc_crtc_prepare,
+ .commit = atmel_hlcdc_crtc_commit,
+ .disable = atmel_hlcdc_crtc_disable,
+};
+
+static void atmel_hlcdc_crtc_destroy(struct drm_crtc *c)
+{
+ struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
+
+ drm_crtc_cleanup(c);
+ kfree(crtc);
+}
+
+void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *c,
+ struct drm_file *file)
+{
+ struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
+ struct drm_pending_vblank_event *event;
+ struct drm_device *dev = c->dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ event = crtc->event;
+ if (event && event->base.file_priv == file) {
+ event->base.destroy(&event->base);
+ drm_vblank_put(dev, crtc->id);
+ crtc->event = NULL;
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static void atmel_hlcdc_crtc_finish_page_flip(struct atmel_hlcdc_crtc *crtc)
+{
+ struct drm_device *dev = crtc->base.dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (crtc->event) {
+ drm_send_vblank_event(dev, crtc->id, crtc->event);
+ drm_vblank_put(dev, crtc->id);
+ crtc->event = NULL;
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+void atmel_hlcdc_crtc_irq(struct drm_crtc *c)
+{
+ drm_handle_vblank(c->dev, 0);
+ atmel_hlcdc_crtc_finish_page_flip(drm_crtc_to_atmel_hlcdc_crtc(c));
+}
+
+static int atmel_hlcdc_crtc_page_flip(struct drm_crtc *c,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t page_flip_flags)
+{
+ struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
+ struct atmel_hlcdc_plane_update_req req;
+ struct drm_plane *plane = c->primary;
+ struct drm_device *dev = c->dev;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (crtc->event)
+ ret = -EBUSY;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ if (ret)
+ return ret;
+
+ memset(&req, 0, sizeof(req));
+ req.crtc_x = 0;
+ req.crtc_y = 0;
+ req.crtc_h = c->mode.crtc_vdisplay;
+ req.crtc_w = c->mode.crtc_hdisplay;
+ req.src_x = c->x << 16;
+ req.src_y = c->y << 16;
+ req.src_w = req.crtc_w << 16;
+ req.src_h = req.crtc_h << 16;
+ req.fb = fb;
+
+ ret = atmel_hlcdc_plane_prepare_update_req(plane, &req, &c->hwmode);
+ if (ret)
+ return ret;
+
+ if (event) {
+ drm_vblank_get(c->dev, crtc->id);
+ spin_lock_irqsave(&dev->event_lock, flags);
+ crtc->event = event;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
+
+ ret = atmel_hlcdc_plane_apply_update_req(plane, &req);
+ if (ret)
+ crtc->event = NULL;
+ else
+ plane->fb = fb;
+
+ return ret;
+}
+
+static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
+ .page_flip = atmel_hlcdc_crtc_page_flip,
+ .set_config = drm_crtc_helper_set_config,
+ .destroy = atmel_hlcdc_crtc_destroy,
+};
+
+int atmel_hlcdc_crtc_create(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ struct atmel_hlcdc_planes *planes = dc->planes;
+ struct atmel_hlcdc_crtc *crtc;
+ int ret;
+ int i;
+
+ crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
+ if (!crtc)
+ return -ENOMEM;
+
+ crtc->dpms = DRM_MODE_DPMS_OFF;
+ crtc->dc = dc;
+
+ ret = drm_crtc_init_with_planes(dev, &crtc->base,
+ &planes->primary->base,
+ planes->cursor ? &planes->cursor->base : NULL,
+ &atmel_hlcdc_crtc_funcs);
+ if (ret < 0)
+ goto fail;
+
+ crtc->id = drm_crtc_index(&crtc->base);
+
+ if (planes->cursor)
+ planes->cursor->base.possible_crtcs = 1 << crtc->id;
+
+ for (i = 0; i < planes->noverlays; i++)
+ planes->overlays[i]->base.possible_crtcs = 1 << crtc->id;
+
+ drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs);
+
+ dc->crtc = &crtc->base;
+
+ return 0;
+
+fail:
+ atmel_hlcdc_crtc_destroy(&crtc->base);
+ return ret;
+}
+
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
new file mode 100644
index 000000000000..7320a6c6613f
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 2014 Traphandler
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+
+#include "atmel_hlcdc_dc.h"
+
+#define ATMEL_HLCDC_LAYER_IRQS_OFFSET 8
+
+static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
+ {
+ .name = "base",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x40,
+ .id = 0,
+ .type = ATMEL_HLCDC_BASE_LAYER,
+ .nconfigs = 7,
+ .layout = {
+ .xstride = { 2 },
+ .default_color = 3,
+ .general_config = 4,
+ .disc_pos = 5,
+ .disc_size = 6,
+ },
+ },
+ {
+ .name = "overlay1",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x140,
+ .id = 1,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .nconfigs = 10,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .xstride = { 4 },
+ .pstride = { 5 },
+ .default_color = 6,
+ .chroma_key = 7,
+ .chroma_key_mask = 8,
+ .general_config = 9,
+ },
+ },
+ {
+ .name = "overlay2",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x240,
+ .id = 2,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .nconfigs = 10,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .xstride = { 4 },
+ .pstride = { 5 },
+ .default_color = 6,
+ .chroma_key = 7,
+ .chroma_key_mask = 8,
+ .general_config = 9,
+ },
+ },
+ {
+ .name = "high-end-overlay",
+ .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats,
+ .regs_offset = 0x340,
+ .id = 3,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .nconfigs = 42,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .memsize = 4,
+ .xstride = { 5, 7 },
+ .pstride = { 6, 8 },
+ .default_color = 9,
+ .chroma_key = 10,
+ .chroma_key_mask = 11,
+ .general_config = 12,
+ .csc = 14,
+ },
+ },
+ {
+ .name = "cursor",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x440,
+ .id = 4,
+ .type = ATMEL_HLCDC_CURSOR_LAYER,
+ .nconfigs = 10,
+ .max_width = 128,
+ .max_height = 128,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .xstride = { 4 },
+ .pstride = { 5 },
+ .default_color = 6,
+ .chroma_key = 7,
+ .chroma_key_mask = 8,
+ .general_config = 9,
+ },
+ },
+};
+
+static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = {
+ .min_width = 0,
+ .min_height = 0,
+ .max_width = 2048,
+ .max_height = 2048,
+ .nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers),
+ .layers = atmel_hlcdc_sama5d3_layers,
+};
+
+static const struct of_device_id atmel_hlcdc_of_match[] = {
+ {
+ .compatible = "atmel,sama5d3-hlcdc",
+ .data = &atmel_hlcdc_dc_sama5d3,
+ },
+ { /* sentinel */ },
+};
+
+int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc,
+ struct drm_display_mode *mode)
+{
+ int vfront_porch = mode->vsync_start - mode->vdisplay;
+ int vback_porch = mode->vtotal - mode->vsync_end;
+ int vsync_len = mode->vsync_end - mode->vsync_start;
+ int hfront_porch = mode->hsync_start - mode->hdisplay;
+ int hback_porch = mode->htotal - mode->hsync_end;
+ int hsync_len = mode->hsync_end - mode->hsync_start;
+
+ if (hsync_len > 0x40 || hsync_len < 1)
+ return MODE_HSYNC;
+
+ if (vsync_len > 0x40 || vsync_len < 1)
+ return MODE_VSYNC;
+
+ if (hfront_porch > 0x200 || hfront_porch < 1 ||
+ hback_porch > 0x200 || hback_porch < 1 ||
+ mode->hdisplay < 1)
+ return MODE_H_ILLEGAL;
+
+ if (vfront_porch > 0x40 || vfront_porch < 1 ||
+ vback_porch > 0x40 || vback_porch < 0 ||
+ mode->vdisplay < 1)
+ return MODE_V_ILLEGAL;
+
+ return MODE_OK;
+}
+
+static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data)
+{
+ struct drm_device *dev = data;
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ unsigned long status;
+ unsigned int imr, isr;
+ int i;
+
+ regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_IMR, &imr);
+ regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr);
+ status = imr & isr;
+ if (!status)
+ return IRQ_NONE;
+
+ if (status & ATMEL_HLCDC_SOF)
+ atmel_hlcdc_crtc_irq(dc->crtc);
+
+ for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
+ struct atmel_hlcdc_layer *layer = dc->layers[i];
+
+ if (!(ATMEL_HLCDC_LAYER_STATUS(i) & status) || !layer)
+ continue;
+
+ atmel_hlcdc_layer_irq(layer);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct drm_framebuffer *atmel_hlcdc_fb_create(struct drm_device *dev,
+ struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ return drm_fb_cma_create(dev, file_priv, mode_cmd);
+}
+
+static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+
+ if (dc->fbdev) {
+ drm_fbdev_cma_hotplug_event(dc->fbdev);
+ } else {
+ dc->fbdev = drm_fbdev_cma_init(dev, 24,
+ dev->mode_config.num_crtc,
+ dev->mode_config.num_connector);
+ if (IS_ERR(dc->fbdev))
+ dc->fbdev = NULL;
+ }
+}
+
+static const struct drm_mode_config_funcs mode_config_funcs = {
+ .fb_create = atmel_hlcdc_fb_create,
+ .output_poll_changed = atmel_hlcdc_fb_output_poll_changed,
+};
+
+static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ struct atmel_hlcdc_planes *planes;
+ int ret;
+ int i;
+
+ drm_mode_config_init(dev);
+
+ ret = atmel_hlcdc_create_outputs(dev);
+ if (ret) {
+ dev_err(dev->dev, "failed to create panel: %d\n", ret);
+ return ret;
+ }
+
+ planes = atmel_hlcdc_create_planes(dev);
+ if (IS_ERR(planes)) {
+ dev_err(dev->dev, "failed to create planes\n");
+ return PTR_ERR(planes);
+ }
+
+ dc->planes = planes;
+
+ dc->layers[planes->primary->layer.desc->id] =
+ &planes->primary->layer;
+
+ if (planes->cursor)
+ dc->layers[planes->cursor->layer.desc->id] =
+ &planes->cursor->layer;
+
+ for (i = 0; i < planes->noverlays; i++)
+ dc->layers[planes->overlays[i]->layer.desc->id] =
+ &planes->overlays[i]->layer;
+
+ ret = atmel_hlcdc_crtc_create(dev);
+ if (ret) {
+ dev_err(dev->dev, "failed to create crtc\n");
+ return ret;
+ }
+
+ dev->mode_config.min_width = dc->desc->min_width;
+ dev->mode_config.min_height = dc->desc->min_height;
+ dev->mode_config.max_width = dc->desc->max_width;
+ dev->mode_config.max_height = dc->desc->max_height;
+ dev->mode_config.funcs = &mode_config_funcs;
+
+ return 0;
+}
+
+static int atmel_hlcdc_dc_load(struct drm_device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev->dev);
+ const struct of_device_id *match;
+ struct atmel_hlcdc_dc *dc;
+ int ret;
+
+ match = of_match_node(atmel_hlcdc_of_match, dev->dev->parent->of_node);
+ if (!match) {
+ dev_err(&pdev->dev, "invalid compatible string\n");
+ return -ENODEV;
+ }
+
+ if (!match->data) {
+ dev_err(&pdev->dev, "invalid hlcdc description\n");
+ return -EINVAL;
+ }
+
+ dc = devm_kzalloc(dev->dev, sizeof(*dc), GFP_KERNEL);
+ if (!dc)
+ return -ENOMEM;
+
+ dc->wq = alloc_ordered_workqueue("atmel-hlcdc-dc", 0);
+ if (!dc->wq)
+ return -ENOMEM;
+
+ dc->desc = match->data;
+ dc->hlcdc = dev_get_drvdata(dev->dev->parent);
+ dev->dev_private = dc;
+
+ ret = clk_prepare_enable(dc->hlcdc->periph_clk);
+ if (ret) {
+ dev_err(dev->dev, "failed to enable periph_clk\n");
+ goto err_destroy_wq;
+ }
+
+ pm_runtime_enable(dev->dev);
+
+ pm_runtime_put_sync(dev->dev);
+
+ ret = atmel_hlcdc_dc_modeset_init(dev);
+ if (ret < 0) {
+ dev_err(dev->dev, "failed to initialize mode setting\n");
+ goto err_periph_clk_disable;
+ }
+
+ ret = drm_vblank_init(dev, 1);
+ if (ret < 0) {
+ dev_err(dev->dev, "failed to initialize vblank\n");
+ goto err_periph_clk_disable;
+ }
+
+ pm_runtime_get_sync(dev->dev);
+ ret = drm_irq_install(dev, dc->hlcdc->irq);
+ pm_runtime_put_sync(dev->dev);
+ if (ret < 0) {
+ dev_err(dev->dev, "failed to install IRQ handler\n");
+ goto err_periph_clk_disable;
+ }
+
+ platform_set_drvdata(pdev, dev);
+
+ drm_kms_helper_poll_init(dev);
+
+ /* force connectors detection */
+ drm_helper_hpd_irq_event(dev);
+
+ return 0;
+
+err_periph_clk_disable:
+ pm_runtime_disable(dev->dev);
+ clk_disable_unprepare(dc->hlcdc->periph_clk);
+
+err_destroy_wq:
+ destroy_workqueue(dc->wq);
+
+ return ret;
+}
+
+static void atmel_hlcdc_dc_unload(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+
+ if (dc->fbdev)
+ drm_fbdev_cma_fini(dc->fbdev);
+ flush_workqueue(dc->wq);
+ drm_kms_helper_poll_fini(dev);
+ drm_mode_config_cleanup(dev);
+ drm_vblank_cleanup(dev);
+
+ pm_runtime_get_sync(dev->dev);
+ drm_irq_uninstall(dev);
+ pm_runtime_put_sync(dev->dev);
+
+ dev->dev_private = NULL;
+
+ pm_runtime_disable(dev->dev);
+ clk_disable_unprepare(dc->hlcdc->periph_clk);
+ destroy_workqueue(dc->wq);
+}
+
+static int atmel_hlcdc_dc_connector_plug_all(struct drm_device *dev)
+{
+ struct drm_connector *connector, *failed;
+ int ret;
+
+ mutex_lock(&dev->mode_config.mutex);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ ret = drm_connector_register(connector);
+ if (ret) {
+ failed = connector;
+ goto err;
+ }
+ }
+ mutex_unlock(&dev->mode_config.mutex);
+ return 0;
+
+err:
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (failed == connector)
+ break;
+
+ drm_connector_unregister(connector);
+ }
+ mutex_unlock(&dev->mode_config.mutex);
+
+ return ret;
+}
+
+static void atmel_hlcdc_dc_connector_unplug_all(struct drm_device *dev)
+{
+ mutex_lock(&dev->mode_config.mutex);
+ drm_connector_unplug_all(dev);
+ mutex_unlock(&dev->mode_config.mutex);
+}
+
+static void atmel_hlcdc_dc_preclose(struct drm_device *dev,
+ struct drm_file *file)
+{
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ atmel_hlcdc_crtc_cancel_page_flip(crtc, file);
+}
+
+static void atmel_hlcdc_dc_lastclose(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+
+ drm_fbdev_cma_restore_mode(dc->fbdev);
+}
+
+static int atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ unsigned int cfg = 0;
+ int i;
+
+ /* Enable interrupts on activated layers */
+ for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
+ if (dc->layers[i])
+ cfg |= ATMEL_HLCDC_LAYER_STATUS(i);
+ }
+
+ regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg);
+
+ return 0;
+}
+
+static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ unsigned int isr;
+
+ regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0xffffffff);
+ regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr);
+}
+
+static int atmel_hlcdc_dc_enable_vblank(struct drm_device *dev, int crtc)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+
+ /* Enable SOF (Start Of Frame) interrupt for vblank counting */
+ regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, ATMEL_HLCDC_SOF);
+
+ return 0;
+}
+
+static void atmel_hlcdc_dc_disable_vblank(struct drm_device *dev, int crtc)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+
+ regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, ATMEL_HLCDC_SOF);
+}
+
+static const struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .poll = drm_poll,
+ .read = drm_read,
+ .llseek = no_llseek,
+ .mmap = drm_gem_cma_mmap,
+};
+
+static struct drm_driver atmel_hlcdc_dc_driver = {
+ .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
+ .preclose = atmel_hlcdc_dc_preclose,
+ .lastclose = atmel_hlcdc_dc_lastclose,
+ .irq_handler = atmel_hlcdc_dc_irq_handler,
+ .irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
+ .irq_postinstall = atmel_hlcdc_dc_irq_postinstall,
+ .irq_uninstall = atmel_hlcdc_dc_irq_uninstall,
+ .get_vblank_counter = drm_vblank_count,
+ .enable_vblank = atmel_hlcdc_dc_enable_vblank,
+ .disable_vblank = atmel_hlcdc_dc_disable_vblank,
+ .gem_free_object = drm_gem_cma_free_object,
+ .gem_vm_ops = &drm_gem_cma_vm_ops,
+ .dumb_create = drm_gem_cma_dumb_create,
+ .dumb_map_offset = drm_gem_cma_dumb_map_offset,
+ .dumb_destroy = drm_gem_dumb_destroy,
+ .fops = &fops,
+ .name = "atmel-hlcdc",
+ .desc = "Atmel HLCD Controller DRM",
+ .date = "20141504",
+ .major = 1,
+ .minor = 0,
+};
+
+static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev)
+{
+ struct drm_device *ddev;
+ int ret;
+
+ ddev = drm_dev_alloc(&atmel_hlcdc_dc_driver, &pdev->dev);
+ if (!ddev)
+ return -ENOMEM;
+
+ ret = drm_dev_set_unique(ddev, dev_name(ddev->dev));
+ if (ret)
+ goto err_unref;
+
+ ret = atmel_hlcdc_dc_load(ddev);
+ if (ret)
+ goto err_unref;
+
+ ret = drm_dev_register(ddev, 0);
+ if (ret)
+ goto err_unload;
+
+ ret = atmel_hlcdc_dc_connector_plug_all(ddev);
+ if (ret)
+ goto err_unregister;
+
+ return 0;
+
+err_unregister:
+ drm_dev_unregister(ddev);
+
+err_unload:
+ atmel_hlcdc_dc_unload(ddev);
+
+err_unref:
+ drm_dev_unref(ddev);
+
+ return ret;
+}
+
+static int atmel_hlcdc_dc_drm_remove(struct platform_device *pdev)
+{
+ struct drm_device *ddev = platform_get_drvdata(pdev);
+
+ atmel_hlcdc_dc_connector_unplug_all(ddev);
+ drm_dev_unregister(ddev);
+ atmel_hlcdc_dc_unload(ddev);
+ drm_dev_unref(ddev);
+
+ return 0;
+}
+
+static const struct of_device_id atmel_hlcdc_dc_of_match[] = {
+ { .compatible = "atmel,hlcdc-display-controller" },
+ { },
+};
+
+static struct platform_driver atmel_hlcdc_dc_platform_driver = {
+ .probe = atmel_hlcdc_dc_drm_probe,
+ .remove = atmel_hlcdc_dc_drm_remove,
+ .driver = {
+ .name = "atmel-hlcdc-display-controller",
+ .of_match_table = atmel_hlcdc_dc_of_match,
+ },
+};
+module_platform_driver(atmel_hlcdc_dc_platform_driver);
+
+MODULE_AUTHOR("Jean-Jacques Hiblot <jjhiblot@traphandler.com>");
+MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>");
+MODULE_DESCRIPTION("Atmel HLCDC Display Controller DRM Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:atmel-hlcdc-dc");
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
new file mode 100644
index 000000000000..7bc96af3397a
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2014 Traphandler
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DRM_ATMEL_HLCDC_H
+#define DRM_ATMEL_HLCDC_H
+
+#include <linux/clk.h>
+#include <linux/irqdomain.h>
+#include <linux/pwm.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drmP.h>
+
+#include "atmel_hlcdc_layer.h"
+
+#define ATMEL_HLCDC_MAX_LAYERS 5
+
+/**
+ * Atmel HLCDC Display Controller description structure.
+ *
+ * This structure describe the HLCDC IP capabilities and depends on the
+ * HLCDC IP version (or Atmel SoC family).
+ *
+ * @min_width: minimum width supported by the Display Controller
+ * @min_height: minimum height supported by the Display Controller
+ * @max_width: maximum width supported by the Display Controller
+ * @max_height: maximum height supported by the Display Controller
+ * @layers: a layer description table describing available layers
+ * @nlayers: layer description table size
+ */
+struct atmel_hlcdc_dc_desc {
+ int min_width;
+ int min_height;
+ int max_width;
+ int max_height;
+ const struct atmel_hlcdc_layer_desc *layers;
+ int nlayers;
+};
+
+/**
+ * Atmel HLCDC Plane properties.
+ *
+ * This structure stores plane property definitions.
+ *
+ * @alpha: alpha blending (or transparency) property
+ * @rotation: rotation property
+ */
+struct atmel_hlcdc_plane_properties {
+ struct drm_property *alpha;
+ struct drm_property *rotation;
+};
+
+/**
+ * Atmel HLCDC Plane.
+ *
+ * @base: base DRM plane structure
+ * @layer: HLCDC layer structure
+ * @properties: pointer to the property definitions structure
+ * @rotation: current rotation status
+ */
+struct atmel_hlcdc_plane {
+ struct drm_plane base;
+ struct atmel_hlcdc_layer layer;
+ struct atmel_hlcdc_plane_properties *properties;
+ unsigned int rotation;
+};
+
+static inline struct atmel_hlcdc_plane *
+drm_plane_to_atmel_hlcdc_plane(struct drm_plane *p)
+{
+ return container_of(p, struct atmel_hlcdc_plane, base);
+}
+
+static inline struct atmel_hlcdc_plane *
+atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *l)
+{
+ return container_of(l, struct atmel_hlcdc_plane, layer);
+}
+
+/**
+ * Atmel HLCDC Plane update request structure.
+ *
+ * @crtc_x: x position of the plane relative to the CRTC
+ * @crtc_y: y position of the plane relative to the CRTC
+ * @crtc_w: visible width of the plane
+ * @crtc_h: visible height of the plane
+ * @src_x: x buffer position
+ * @src_y: y buffer position
+ * @src_w: buffer width
+ * @src_h: buffer height
+ * @fb: framebuffer object object
+ * @bpp: bytes per pixel deduced from pixel_format
+ * @offsets: offsets to apply to the GEM buffers
+ * @xstride: value to add to the pixel pointer between each line
+ * @pstride: value to add to the pixel pointer between each pixel
+ * @nplanes: number of planes (deduced from pixel_format)
+ */
+struct atmel_hlcdc_plane_update_req {
+ int crtc_x;
+ int crtc_y;
+ unsigned int crtc_w;
+ unsigned int crtc_h;
+ uint32_t src_x;
+ uint32_t src_y;
+ uint32_t src_w;
+ uint32_t src_h;
+ struct drm_framebuffer *fb;
+
+ /* These fields are private and should not be touched */
+ int bpp[ATMEL_HLCDC_MAX_PLANES];
+ unsigned int offsets[ATMEL_HLCDC_MAX_PLANES];
+ int xstride[ATMEL_HLCDC_MAX_PLANES];
+ int pstride[ATMEL_HLCDC_MAX_PLANES];
+ int nplanes;
+};
+
+/**
+ * Atmel HLCDC Planes.
+ *
+ * This structure stores the instantiated HLCDC Planes and can be accessed by
+ * the HLCDC Display Controller or the HLCDC CRTC.
+ *
+ * @primary: primary plane
+ * @cursor: hardware cursor plane
+ * @overlays: overlay plane table
+ * @noverlays: number of overlay planes
+ */
+struct atmel_hlcdc_planes {
+ struct atmel_hlcdc_plane *primary;
+ struct atmel_hlcdc_plane *cursor;
+ struct atmel_hlcdc_plane **overlays;
+ int noverlays;
+};
+
+/**
+ * Atmel HLCDC Display Controller.
+ *
+ * @desc: HLCDC Display Controller description
+ * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
+ * @fbdev: framebuffer device attached to the Display Controller
+ * @crtc: CRTC provided by the display controller
+ * @planes: instantiated planes
+ * @layers: active HLCDC layer
+ * @wq: display controller workqueue
+ */
+struct atmel_hlcdc_dc {
+ const struct atmel_hlcdc_dc_desc *desc;
+ struct atmel_hlcdc *hlcdc;
+ struct drm_fbdev_cma *fbdev;
+ struct drm_crtc *crtc;
+ struct atmel_hlcdc_planes *planes;
+ struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
+ struct workqueue_struct *wq;
+};
+
+extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats;
+extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats;
+
+int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc,
+ struct drm_display_mode *mode);
+
+struct atmel_hlcdc_planes *
+atmel_hlcdc_create_planes(struct drm_device *dev);
+
+int atmel_hlcdc_plane_prepare_update_req(struct drm_plane *p,
+ struct atmel_hlcdc_plane_update_req *req,
+ const struct drm_display_mode *mode);
+
+int atmel_hlcdc_plane_apply_update_req(struct drm_plane *p,
+ struct atmel_hlcdc_plane_update_req *req);
+
+int atmel_hlcdc_plane_update_with_mode(struct drm_plane *p,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w,
+ unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h,
+ const struct drm_display_mode *mode);
+
+void atmel_hlcdc_crtc_irq(struct drm_crtc *c);
+
+void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *crtc,
+ struct drm_file *file);
+
+int atmel_hlcdc_crtc_create(struct drm_device *dev);
+
+int atmel_hlcdc_create_outputs(struct drm_device *dev);
+
+#endif /* DRM_ATMEL_HLCDC_H */
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.c
new file mode 100644
index 000000000000..063d2a7b941f
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.c
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+
+#include "atmel_hlcdc_dc.h"
+
+static void
+atmel_hlcdc_layer_fb_flip_release(struct drm_flip_work *work, void *val)
+{
+ struct atmel_hlcdc_layer_fb_flip *flip = val;
+
+ if (flip->fb)
+ drm_framebuffer_unreference(flip->fb);
+ kfree(flip);
+}
+
+static void
+atmel_hlcdc_layer_fb_flip_destroy(struct atmel_hlcdc_layer_fb_flip *flip)
+{
+ if (flip->fb)
+ drm_framebuffer_unreference(flip->fb);
+ kfree(flip->task);
+ kfree(flip);
+}
+
+static void
+atmel_hlcdc_layer_fb_flip_release_queue(struct atmel_hlcdc_layer *layer,
+ struct atmel_hlcdc_layer_fb_flip *flip)
+{
+ int i;
+
+ if (!flip)
+ return;
+
+ for (i = 0; i < layer->max_planes; i++) {
+ if (!flip->dscrs[i])
+ break;
+
+ flip->dscrs[i]->status = 0;
+ flip->dscrs[i] = NULL;
+ }
+
+ drm_flip_work_queue_task(&layer->gc, flip->task);
+ drm_flip_work_commit(&layer->gc, layer->wq);
+}
+
+static void atmel_hlcdc_layer_update_reset(struct atmel_hlcdc_layer *layer,
+ int id)
+{
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ struct atmel_hlcdc_layer_update_slot *slot;
+
+ if (id < 0 || id > 1)
+ return;
+
+ slot = &upd->slots[id];
+ bitmap_clear(slot->updated_configs, 0, layer->desc->nconfigs);
+ memset(slot->configs, 0,
+ sizeof(*slot->configs) * layer->desc->nconfigs);
+
+ if (slot->fb_flip) {
+ atmel_hlcdc_layer_fb_flip_release_queue(layer, slot->fb_flip);
+ slot->fb_flip = NULL;
+ }
+}
+
+static void atmel_hlcdc_layer_update_apply(struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
+ const struct atmel_hlcdc_layer_desc *desc = layer->desc;
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ struct regmap *regmap = layer->hlcdc->regmap;
+ struct atmel_hlcdc_layer_update_slot *slot;
+ struct atmel_hlcdc_layer_fb_flip *fb_flip;
+ struct atmel_hlcdc_dma_channel_dscr *dscr;
+ unsigned int cfg;
+ u32 action = 0;
+ int i = 0;
+
+ if (upd->pending < 0 || upd->pending > 1)
+ return;
+
+ slot = &upd->slots[upd->pending];
+
+ for_each_set_bit(cfg, slot->updated_configs, layer->desc->nconfigs) {
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_CFG(layer, cfg),
+ slot->configs[cfg]);
+ action |= ATMEL_HLCDC_LAYER_UPDATE;
+ }
+
+ fb_flip = slot->fb_flip;
+
+ if (!fb_flip->fb)
+ goto apply;
+
+ if (dma->status == ATMEL_HLCDC_LAYER_DISABLED) {
+ for (i = 0; i < fb_flip->ngems; i++) {
+ dscr = fb_flip->dscrs[i];
+ dscr->ctrl = ATMEL_HLCDC_LAYER_DFETCH |
+ ATMEL_HLCDC_LAYER_DMA_IRQ |
+ ATMEL_HLCDC_LAYER_ADD_IRQ |
+ ATMEL_HLCDC_LAYER_DONE_IRQ;
+
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
+ dscr->addr);
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
+ dscr->ctrl);
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
+ dscr->next);
+ }
+
+ action |= ATMEL_HLCDC_LAYER_DMA_CHAN;
+ dma->status = ATMEL_HLCDC_LAYER_ENABLED;
+ } else {
+ for (i = 0; i < fb_flip->ngems; i++) {
+ dscr = fb_flip->dscrs[i];
+ dscr->ctrl = ATMEL_HLCDC_LAYER_DFETCH |
+ ATMEL_HLCDC_LAYER_DMA_IRQ |
+ ATMEL_HLCDC_LAYER_DSCR_IRQ |
+ ATMEL_HLCDC_LAYER_DONE_IRQ;
+
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
+ dscr->next);
+ }
+
+ action |= ATMEL_HLCDC_LAYER_A2Q;
+ }
+
+ /* Release unneeded descriptors */
+ for (i = fb_flip->ngems; i < layer->max_planes; i++) {
+ fb_flip->dscrs[i]->status = 0;
+ fb_flip->dscrs[i] = NULL;
+ }
+
+ dma->queue = fb_flip;
+ slot->fb_flip = NULL;
+
+apply:
+ if (action)
+ regmap_write(regmap,
+ desc->regs_offset + ATMEL_HLCDC_LAYER_CHER,
+ action);
+
+ atmel_hlcdc_layer_update_reset(layer, upd->pending);
+
+ upd->pending = -1;
+}
+
+void atmel_hlcdc_layer_irq(struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
+ const struct atmel_hlcdc_layer_desc *desc = layer->desc;
+ struct regmap *regmap = layer->hlcdc->regmap;
+ struct atmel_hlcdc_layer_fb_flip *flip;
+ unsigned long flags;
+ unsigned int isr, imr;
+ unsigned int status;
+ unsigned int plane_status;
+ u32 flip_status;
+
+ int i;
+
+ regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IMR, &imr);
+ regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR, &isr);
+ status = imr & isr;
+ if (!status)
+ return;
+
+ spin_lock_irqsave(&layer->lock, flags);
+
+ flip = dma->queue ? dma->queue : dma->cur;
+
+ if (!flip) {
+ spin_unlock_irqrestore(&layer->lock, flags);
+ return;
+ }
+
+ /*
+ * Set LOADED and DONE flags: they'll be cleared if at least one
+ * memory plane is not LOADED or DONE.
+ */
+ flip_status = ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED |
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE;
+ for (i = 0; i < flip->ngems; i++) {
+ plane_status = (status >> (8 * i));
+
+ if (plane_status &
+ (ATMEL_HLCDC_LAYER_ADD_IRQ |
+ ATMEL_HLCDC_LAYER_DSCR_IRQ) &
+ ~flip->dscrs[i]->ctrl) {
+ flip->dscrs[i]->status |=
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED;
+ flip->dscrs[i]->ctrl |=
+ ATMEL_HLCDC_LAYER_ADD_IRQ |
+ ATMEL_HLCDC_LAYER_DSCR_IRQ;
+ }
+
+ if (plane_status &
+ ATMEL_HLCDC_LAYER_DONE_IRQ &
+ ~flip->dscrs[i]->ctrl) {
+ flip->dscrs[i]->status |=
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE;
+ flip->dscrs[i]->ctrl |=
+ ATMEL_HLCDC_LAYER_DONE_IRQ;
+ }
+
+ if (plane_status & ATMEL_HLCDC_LAYER_OVR_IRQ)
+ flip->dscrs[i]->status |=
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN;
+
+ /*
+ * Clear LOADED and DONE flags if the memory plane is either
+ * not LOADED or not DONE.
+ */
+ if (!(flip->dscrs[i]->status &
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED))
+ flip_status &= ~ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED;
+
+ if (!(flip->dscrs[i]->status &
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE))
+ flip_status &= ~ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE;
+
+ /*
+ * An overrun on one memory plane impact the whole framebuffer
+ * transfer, hence we set the OVERRUN flag as soon as there's
+ * one memory plane reporting such an overrun.
+ */
+ flip_status |= flip->dscrs[i]->status &
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN;
+ }
+
+ /* Get changed bits */
+ flip_status ^= flip->status;
+ flip->status |= flip_status;
+
+ if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED) {
+ atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur);
+ dma->cur = dma->queue;
+ dma->queue = NULL;
+ }
+
+ if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE) {
+ atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur);
+ dma->cur = NULL;
+ }
+
+ if (flip_status & ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN) {
+ regmap_write(regmap,
+ desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
+ ATMEL_HLCDC_LAYER_RST);
+ if (dma->queue)
+ atmel_hlcdc_layer_fb_flip_release_queue(layer,
+ dma->queue);
+
+ if (dma->cur)
+ atmel_hlcdc_layer_fb_flip_release_queue(layer,
+ dma->cur);
+
+ dma->cur = NULL;
+ dma->queue = NULL;
+ }
+
+ if (!dma->queue) {
+ atmel_hlcdc_layer_update_apply(layer);
+
+ if (!dma->cur)
+ dma->status = ATMEL_HLCDC_LAYER_DISABLED;
+ }
+
+ spin_unlock_irqrestore(&layer->lock, flags);
+}
+
+int atmel_hlcdc_layer_disable(struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ struct regmap *regmap = layer->hlcdc->regmap;
+ const struct atmel_hlcdc_layer_desc *desc = layer->desc;
+ unsigned long flags;
+ unsigned int isr;
+
+ spin_lock_irqsave(&layer->lock, flags);
+
+ /* Disable the layer */
+ regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
+ ATMEL_HLCDC_LAYER_RST);
+
+ /* Clear all pending interrupts */
+ regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR, &isr);
+
+ /* Discard current and queued framebuffer transfers. */
+ if (dma->cur) {
+ atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->cur);
+ dma->cur = NULL;
+ }
+
+ if (dma->queue) {
+ atmel_hlcdc_layer_fb_flip_release_queue(layer, dma->queue);
+ dma->queue = NULL;
+ }
+
+ /*
+ * Then discard the pending update request (if any) to prevent
+ * DMA irq handler from restarting the DMA channel after it has
+ * been disabled.
+ */
+ if (upd->pending >= 0) {
+ atmel_hlcdc_layer_update_reset(layer, upd->pending);
+ upd->pending = -1;
+ }
+
+ dma->status = ATMEL_HLCDC_LAYER_DISABLED;
+
+ spin_unlock_irqrestore(&layer->lock, flags);
+
+ return 0;
+}
+
+int atmel_hlcdc_layer_update_start(struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ struct regmap *regmap = layer->hlcdc->regmap;
+ struct atmel_hlcdc_layer_fb_flip *fb_flip;
+ struct atmel_hlcdc_layer_update_slot *slot;
+ unsigned long flags;
+ int i, j = 0;
+
+ fb_flip = kzalloc(sizeof(*fb_flip), GFP_KERNEL);
+ if (!fb_flip)
+ return -ENOMEM;
+
+ fb_flip->task = drm_flip_work_allocate_task(fb_flip, GFP_KERNEL);
+ if (!fb_flip->task) {
+ kfree(fb_flip);
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&layer->lock, flags);
+
+ upd->next = upd->pending ? 0 : 1;
+
+ slot = &upd->slots[upd->next];
+
+ for (i = 0; i < layer->max_planes * 4; i++) {
+ if (!dma->dscrs[i].status) {
+ fb_flip->dscrs[j++] = &dma->dscrs[i];
+ dma->dscrs[i].status =
+ ATMEL_HLCDC_DMA_CHANNEL_DSCR_RESERVED;
+ if (j == layer->max_planes)
+ break;
+ }
+ }
+
+ if (j < layer->max_planes) {
+ for (i = 0; i < j; i++)
+ fb_flip->dscrs[i]->status = 0;
+ }
+
+ if (j < layer->max_planes) {
+ spin_unlock_irqrestore(&layer->lock, flags);
+ atmel_hlcdc_layer_fb_flip_destroy(fb_flip);
+ return -EBUSY;
+ }
+
+ slot->fb_flip = fb_flip;
+
+ if (upd->pending >= 0) {
+ memcpy(slot->configs,
+ upd->slots[upd->pending].configs,
+ layer->desc->nconfigs * sizeof(u32));
+ memcpy(slot->updated_configs,
+ upd->slots[upd->pending].updated_configs,
+ DIV_ROUND_UP(layer->desc->nconfigs,
+ BITS_PER_BYTE * sizeof(unsigned long)) *
+ sizeof(unsigned long));
+ slot->fb_flip->fb = upd->slots[upd->pending].fb_flip->fb;
+ if (upd->slots[upd->pending].fb_flip->fb) {
+ slot->fb_flip->fb =
+ upd->slots[upd->pending].fb_flip->fb;
+ slot->fb_flip->ngems =
+ upd->slots[upd->pending].fb_flip->ngems;
+ drm_framebuffer_reference(slot->fb_flip->fb);
+ }
+ } else {
+ regmap_bulk_read(regmap,
+ layer->desc->regs_offset +
+ ATMEL_HLCDC_LAYER_CFG(layer, 0),
+ upd->slots[upd->next].configs,
+ layer->desc->nconfigs);
+ }
+
+ spin_unlock_irqrestore(&layer->lock, flags);
+
+ return 0;
+}
+
+void atmel_hlcdc_layer_update_rollback(struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+
+ atmel_hlcdc_layer_update_reset(layer, upd->next);
+ upd->next = -1;
+}
+
+void atmel_hlcdc_layer_update_set_fb(struct atmel_hlcdc_layer *layer,
+ struct drm_framebuffer *fb,
+ unsigned int *offsets)
+{
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ struct atmel_hlcdc_layer_fb_flip *fb_flip;
+ struct atmel_hlcdc_layer_update_slot *slot;
+ struct atmel_hlcdc_dma_channel_dscr *dscr;
+ struct drm_framebuffer *old_fb;
+ int nplanes = 0;
+ int i;
+
+ if (upd->next < 0 || upd->next > 1)
+ return;
+
+ if (fb)
+ nplanes = drm_format_num_planes(fb->pixel_format);
+
+ if (nplanes > layer->max_planes)
+ return;
+
+ slot = &upd->slots[upd->next];
+
+ fb_flip = slot->fb_flip;
+ old_fb = slot->fb_flip->fb;
+
+ for (i = 0; i < nplanes; i++) {
+ struct drm_gem_cma_object *gem;
+
+ dscr = slot->fb_flip->dscrs[i];
+ gem = drm_fb_cma_get_gem_obj(fb, i);
+ dscr->addr = gem->paddr + offsets[i];
+ }
+
+ fb_flip->ngems = nplanes;
+ fb_flip->fb = fb;
+
+ if (fb)
+ drm_framebuffer_reference(fb);
+
+ if (old_fb)
+ drm_framebuffer_unreference(old_fb);
+}
+
+void atmel_hlcdc_layer_update_cfg(struct atmel_hlcdc_layer *layer, int cfg,
+ u32 mask, u32 val)
+{
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ struct atmel_hlcdc_layer_update_slot *slot;
+
+ if (upd->next < 0 || upd->next > 1)
+ return;
+
+ if (cfg >= layer->desc->nconfigs)
+ return;
+
+ slot = &upd->slots[upd->next];
+ slot->configs[cfg] &= ~mask;
+ slot->configs[cfg] |= (val & mask);
+ set_bit(cfg, slot->updated_configs);
+}
+
+void atmel_hlcdc_layer_update_commit(struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ struct atmel_hlcdc_layer_update_slot *slot;
+ unsigned long flags;
+
+ if (upd->next < 0 || upd->next > 1)
+ return;
+
+ slot = &upd->slots[upd->next];
+
+ spin_lock_irqsave(&layer->lock, flags);
+
+ /*
+ * Release pending update request and replace it by the new one.
+ */
+ if (upd->pending >= 0)
+ atmel_hlcdc_layer_update_reset(layer, upd->pending);
+
+ upd->pending = upd->next;
+ upd->next = -1;
+
+ if (!dma->queue)
+ atmel_hlcdc_layer_update_apply(layer);
+
+ spin_unlock_irqrestore(&layer->lock, flags);
+
+
+ upd->next = -1;
+}
+
+static int atmel_hlcdc_layer_dma_init(struct drm_device *dev,
+ struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
+ dma_addr_t dma_addr;
+ int i;
+
+ dma->dscrs = dma_alloc_coherent(dev->dev,
+ layer->max_planes * 4 *
+ sizeof(*dma->dscrs),
+ &dma_addr, GFP_KERNEL);
+ if (!dma->dscrs)
+ return -ENOMEM;
+
+ for (i = 0; i < layer->max_planes * 4; i++) {
+ struct atmel_hlcdc_dma_channel_dscr *dscr = &dma->dscrs[i];
+
+ dscr->next = dma_addr + (i * sizeof(*dscr));
+ }
+
+ return 0;
+}
+
+static void atmel_hlcdc_layer_dma_cleanup(struct drm_device *dev,
+ struct atmel_hlcdc_layer *layer)
+{
+ struct atmel_hlcdc_layer_dma_channel *dma = &layer->dma;
+ int i;
+
+ for (i = 0; i < layer->max_planes * 4; i++) {
+ struct atmel_hlcdc_dma_channel_dscr *dscr = &dma->dscrs[i];
+
+ dscr->status = 0;
+ }
+
+ dma_free_coherent(dev->dev, layer->max_planes * 4 *
+ sizeof(*dma->dscrs), dma->dscrs,
+ dma->dscrs[0].next);
+}
+
+static int atmel_hlcdc_layer_update_init(struct drm_device *dev,
+ struct atmel_hlcdc_layer *layer,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ struct atmel_hlcdc_layer_update *upd = &layer->update;
+ int updated_size;
+ void *buffer;
+ int i;
+
+ updated_size = DIV_ROUND_UP(desc->nconfigs,
+ BITS_PER_BYTE *
+ sizeof(unsigned long));
+
+ buffer = devm_kzalloc(dev->dev,
+ ((desc->nconfigs * sizeof(u32)) +
+ (updated_size * sizeof(unsigned long))) * 2,
+ GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ for (i = 0; i < 2; i++) {
+ upd->slots[i].updated_configs = buffer;
+ buffer += updated_size * sizeof(unsigned long);
+ upd->slots[i].configs = buffer;
+ buffer += desc->nconfigs * sizeof(u32);
+ }
+
+ upd->pending = -1;
+ upd->next = -1;
+
+ return 0;
+}
+
+int atmel_hlcdc_layer_init(struct drm_device *dev,
+ struct atmel_hlcdc_layer *layer,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ struct regmap *regmap = dc->hlcdc->regmap;
+ unsigned int tmp;
+ int ret;
+ int i;
+
+ layer->hlcdc = dc->hlcdc;
+ layer->wq = dc->wq;
+ layer->desc = desc;
+
+ regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
+ ATMEL_HLCDC_LAYER_RST);
+ for (i = 0; i < desc->formats->nformats; i++) {
+ int nplanes = drm_format_num_planes(desc->formats->formats[i]);
+
+ if (nplanes > layer->max_planes)
+ layer->max_planes = nplanes;
+ }
+
+ spin_lock_init(&layer->lock);
+ drm_flip_work_init(&layer->gc, desc->name,
+ atmel_hlcdc_layer_fb_flip_release);
+ ret = atmel_hlcdc_layer_dma_init(dev, layer);
+ if (ret)
+ return ret;
+
+ ret = atmel_hlcdc_layer_update_init(dev, layer, desc);
+ if (ret)
+ return ret;
+
+ /* Flush Status Register */
+ regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IDR,
+ 0xffffffff);
+ regmap_read(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_ISR,
+ &tmp);
+
+ tmp = 0;
+ for (i = 0; i < layer->max_planes; i++)
+ tmp |= (ATMEL_HLCDC_LAYER_DMA_IRQ |
+ ATMEL_HLCDC_LAYER_DSCR_IRQ |
+ ATMEL_HLCDC_LAYER_ADD_IRQ |
+ ATMEL_HLCDC_LAYER_DONE_IRQ |
+ ATMEL_HLCDC_LAYER_OVR_IRQ) << (8 * i);
+
+ regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IER, tmp);
+
+ return 0;
+}
+
+void atmel_hlcdc_layer_cleanup(struct drm_device *dev,
+ struct atmel_hlcdc_layer *layer)
+{
+ const struct atmel_hlcdc_layer_desc *desc = layer->desc;
+ struct regmap *regmap = layer->hlcdc->regmap;
+
+ regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_IDR,
+ 0xffffffff);
+ regmap_write(regmap, desc->regs_offset + ATMEL_HLCDC_LAYER_CHDR,
+ ATMEL_HLCDC_LAYER_RST);
+
+ atmel_hlcdc_layer_dma_cleanup(dev, layer);
+ drm_flip_work_cleanup(&layer->gc);
+}
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.h
new file mode 100644
index 000000000000..27e56c0862ec
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_layer.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DRM_ATMEL_HLCDC_LAYER_H
+#define DRM_ATMEL_HLCDC_LAYER_H
+
+#include <linux/mfd/atmel-hlcdc.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_flip_work.h>
+#include <drm/drmP.h>
+
+#define ATMEL_HLCDC_LAYER_CHER 0x0
+#define ATMEL_HLCDC_LAYER_CHDR 0x4
+#define ATMEL_HLCDC_LAYER_CHSR 0x8
+#define ATMEL_HLCDC_LAYER_DMA_CHAN BIT(0)
+#define ATMEL_HLCDC_LAYER_UPDATE BIT(1)
+#define ATMEL_HLCDC_LAYER_A2Q BIT(2)
+#define ATMEL_HLCDC_LAYER_RST BIT(8)
+
+#define ATMEL_HLCDC_LAYER_IER 0xc
+#define ATMEL_HLCDC_LAYER_IDR 0x10
+#define ATMEL_HLCDC_LAYER_IMR 0x14
+#define ATMEL_HLCDC_LAYER_ISR 0x18
+#define ATMEL_HLCDC_LAYER_DFETCH BIT(0)
+#define ATMEL_HLCDC_LAYER_LFETCH BIT(1)
+#define ATMEL_HLCDC_LAYER_DMA_IRQ BIT(2)
+#define ATMEL_HLCDC_LAYER_DSCR_IRQ BIT(3)
+#define ATMEL_HLCDC_LAYER_ADD_IRQ BIT(4)
+#define ATMEL_HLCDC_LAYER_DONE_IRQ BIT(5)
+#define ATMEL_HLCDC_LAYER_OVR_IRQ BIT(6)
+
+#define ATMEL_HLCDC_LAYER_PLANE_HEAD(n) (((n) * 0x10) + 0x1c)
+#define ATMEL_HLCDC_LAYER_PLANE_ADDR(n) (((n) * 0x10) + 0x20)
+#define ATMEL_HLCDC_LAYER_PLANE_CTRL(n) (((n) * 0x10) + 0x24)
+#define ATMEL_HLCDC_LAYER_PLANE_NEXT(n) (((n) * 0x10) + 0x28)
+#define ATMEL_HLCDC_LAYER_CFG(p, c) (((c) * 4) + ((p)->max_planes * 0x10) + 0x1c)
+
+#define ATMEL_HLCDC_LAYER_DMA_CFG_ID 0
+#define ATMEL_HLCDC_LAYER_DMA_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, ATMEL_HLCDC_LAYER_DMA_CFG_ID)
+#define ATMEL_HLCDC_LAYER_DMA_SIF BIT(0)
+#define ATMEL_HLCDC_LAYER_DMA_BLEN_MASK GENMASK(5, 4)
+#define ATMEL_HLCDC_LAYER_DMA_BLEN_SINGLE (0 << 4)
+#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR4 (1 << 4)
+#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR8 (2 << 4)
+#define ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 (3 << 4)
+#define ATMEL_HLCDC_LAYER_DMA_DLBO BIT(8)
+#define ATMEL_HLCDC_LAYER_DMA_ROTDIS BIT(12)
+#define ATMEL_HLCDC_LAYER_DMA_LOCKDIS BIT(13)
+
+#define ATMEL_HLCDC_LAYER_FORMAT_CFG_ID 1
+#define ATMEL_HLCDC_LAYER_FORMAT_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, ATMEL_HLCDC_LAYER_FORMAT_CFG_ID)
+#define ATMEL_HLCDC_LAYER_RGB (0 << 0)
+#define ATMEL_HLCDC_LAYER_CLUT (1 << 0)
+#define ATMEL_HLCDC_LAYER_YUV (2 << 0)
+#define ATMEL_HLCDC_RGB_MODE(m) (((m) & 0xf) << 4)
+#define ATMEL_HLCDC_CLUT_MODE(m) (((m) & 0x3) << 8)
+#define ATMEL_HLCDC_YUV_MODE(m) (((m) & 0xf) << 12)
+#define ATMEL_HLCDC_YUV422ROT BIT(16)
+#define ATMEL_HLCDC_YUV422SWP BIT(17)
+#define ATMEL_HLCDC_DSCALEOPT BIT(20)
+
+#define ATMEL_HLCDC_XRGB4444_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(0))
+#define ATMEL_HLCDC_ARGB4444_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(1))
+#define ATMEL_HLCDC_RGBA4444_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(2))
+#define ATMEL_HLCDC_RGB565_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(3))
+#define ATMEL_HLCDC_ARGB1555_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(4))
+#define ATMEL_HLCDC_XRGB8888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(9))
+#define ATMEL_HLCDC_RGB888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(10))
+#define ATMEL_HLCDC_ARGB8888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(12))
+#define ATMEL_HLCDC_RGBA8888_MODE (ATMEL_HLCDC_LAYER_RGB | ATMEL_HLCDC_RGB_MODE(13))
+
+#define ATMEL_HLCDC_AYUV_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(0))
+#define ATMEL_HLCDC_YUYV_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(1))
+#define ATMEL_HLCDC_UYVY_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(2))
+#define ATMEL_HLCDC_YVYU_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(3))
+#define ATMEL_HLCDC_VYUY_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(4))
+#define ATMEL_HLCDC_NV61_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(5))
+#define ATMEL_HLCDC_YUV422_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(6))
+#define ATMEL_HLCDC_NV21_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(7))
+#define ATMEL_HLCDC_YUV420_MODE (ATMEL_HLCDC_LAYER_YUV | ATMEL_HLCDC_YUV_MODE(8))
+
+#define ATMEL_HLCDC_LAYER_POS_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.pos)
+#define ATMEL_HLCDC_LAYER_SIZE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.size)
+#define ATMEL_HLCDC_LAYER_MEMSIZE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.memsize)
+#define ATMEL_HLCDC_LAYER_XSTRIDE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.xstride)
+#define ATMEL_HLCDC_LAYER_PSTRIDE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.pstride)
+#define ATMEL_HLCDC_LAYER_DFLTCOLOR_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.default_color)
+#define ATMEL_HLCDC_LAYER_CRKEY_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.chroma_key)
+#define ATMEL_HLCDC_LAYER_CRKEY_MASK_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.chroma_key_mask)
+
+#define ATMEL_HLCDC_LAYER_GENERAL_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.general_config)
+#define ATMEL_HLCDC_LAYER_CRKEY BIT(0)
+#define ATMEL_HLCDC_LAYER_INV BIT(1)
+#define ATMEL_HLCDC_LAYER_ITER2BL BIT(2)
+#define ATMEL_HLCDC_LAYER_ITER BIT(3)
+#define ATMEL_HLCDC_LAYER_REVALPHA BIT(4)
+#define ATMEL_HLCDC_LAYER_GAEN BIT(5)
+#define ATMEL_HLCDC_LAYER_LAEN BIT(6)
+#define ATMEL_HLCDC_LAYER_OVR BIT(7)
+#define ATMEL_HLCDC_LAYER_DMA BIT(8)
+#define ATMEL_HLCDC_LAYER_REP BIT(9)
+#define ATMEL_HLCDC_LAYER_DSTKEY BIT(10)
+#define ATMEL_HLCDC_LAYER_DISCEN BIT(11)
+#define ATMEL_HLCDC_LAYER_GA_SHIFT 16
+#define ATMEL_HLCDC_LAYER_GA_MASK GENMASK(23, ATMEL_HLCDC_LAYER_GA_SHIFT)
+
+#define ATMEL_HLCDC_LAYER_CSC_CFG(p, o) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.csc + o)
+
+#define ATMEL_HLCDC_LAYER_DISC_POS_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.disc_pos)
+
+#define ATMEL_HLCDC_LAYER_DISC_SIZE_CFG(p) ATMEL_HLCDC_LAYER_CFG(p, (p)->desc->layout.disc_size)
+
+#define ATMEL_HLCDC_MAX_PLANES 3
+
+#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_RESERVED BIT(0)
+#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_LOADED BIT(1)
+#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE BIT(2)
+#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN BIT(3)
+
+/**
+ * Atmel HLCDC Layer registers layout structure
+ *
+ * Each HLCDC layer has its own register organization and a given register
+ * can be placed differently on 2 different layers depending on its
+ * capabilities.
+ * This structure stores common registers layout for a given layer and is
+ * used by HLCDC layer code to choose the appropriate register to write to
+ * or to read from.
+ *
+ * For all fields, a value of zero means "unsupported".
+ *
+ * See Atmel's datasheet for a detailled description of these registers.
+ *
+ * @xstride: xstride registers
+ * @pstride: pstride registers
+ * @pos: position register
+ * @size: displayed size register
+ * @memsize: memory size register
+ * @default_color: default color register
+ * @chroma_key: chroma key register
+ * @chroma_key_mask: chroma key mask register
+ * @general_config: general layer config register
+ * @disc_pos: discard area position register
+ * @disc_size: discard area size register
+ * @csc: color space conversion register
+ */
+struct atmel_hlcdc_layer_cfg_layout {
+ int xstride[ATMEL_HLCDC_MAX_PLANES];
+ int pstride[ATMEL_HLCDC_MAX_PLANES];
+ int pos;
+ int size;
+ int memsize;
+ int default_color;
+ int chroma_key;
+ int chroma_key_mask;
+ int general_config;
+ int disc_pos;
+ int disc_size;
+ int csc;
+};
+
+/**
+ * Atmel HLCDC framebuffer flip structure
+ *
+ * This structure is allocated when someone asked for a layer update (most
+ * likely a DRM plane update, either primary, overlay or cursor plane) and
+ * released when the layer do not need to reference the framebuffer object
+ * anymore (i.e. the layer was disabled or updated).
+ *
+ * @dscrs: DMA descriptors
+ * @fb: the referenced framebuffer object
+ * @ngems: number of GEM objects referenced by the fb element
+ * @status: fb flip operation status
+ */
+struct atmel_hlcdc_layer_fb_flip {
+ struct atmel_hlcdc_dma_channel_dscr *dscrs[ATMEL_HLCDC_MAX_PLANES];
+ struct drm_flip_task *task;
+ struct drm_framebuffer *fb;
+ int ngems;
+ u32 status;
+};
+
+/**
+ * Atmel HLCDC DMA descriptor structure
+ *
+ * This structure is used by the HLCDC DMA engine to schedule a DMA transfer.
+ *
+ * The structure fields must remain in this specific order, because they're
+ * used by the HLCDC DMA engine, which expect them in this order.
+ * HLCDC DMA descriptors must be aligned on 64 bits.
+ *
+ * @addr: buffer DMA address
+ * @ctrl: DMA transfer options
+ * @next: next DMA descriptor to fetch
+ * @gem_flip: the attached gem_flip operation
+ */
+struct atmel_hlcdc_dma_channel_dscr {
+ dma_addr_t addr;
+ u32 ctrl;
+ dma_addr_t next;
+ u32 status;
+} __aligned(sizeof(u64));
+
+/**
+ * Atmel HLCDC layer types
+ */
+enum atmel_hlcdc_layer_type {
+ ATMEL_HLCDC_BASE_LAYER,
+ ATMEL_HLCDC_OVERLAY_LAYER,
+ ATMEL_HLCDC_CURSOR_LAYER,
+ ATMEL_HLCDC_PP_LAYER,
+};
+
+/**
+ * Atmel HLCDC Supported formats structure
+ *
+ * This structure list all the formats supported by a given layer.
+ *
+ * @nformats: number of supported formats
+ * @formats: supported formats
+ */
+struct atmel_hlcdc_formats {
+ int nformats;
+ uint32_t *formats;
+};
+
+/**
+ * Atmel HLCDC Layer description structure
+ *
+ * This structure describe the capabilities provided by a given layer.
+ *
+ * @name: layer name
+ * @type: layer type
+ * @id: layer id
+ * @regs_offset: offset of the layer registers from the HLCDC registers base
+ * @nconfigs: number of config registers provided by this layer
+ * @formats: supported formats
+ * @layout: config registers layout
+ * @max_width: maximum width supported by this layer (0 means unlimited)
+ * @max_height: maximum height supported by this layer (0 means unlimited)
+ */
+struct atmel_hlcdc_layer_desc {
+ const char *name;
+ enum atmel_hlcdc_layer_type type;
+ int id;
+ int regs_offset;
+ int nconfigs;
+ struct atmel_hlcdc_formats *formats;
+ struct atmel_hlcdc_layer_cfg_layout layout;
+ int max_width;
+ int max_height;
+};
+
+/**
+ * Atmel HLCDC Layer Update Slot structure
+ *
+ * This structure stores layer update requests to be applied on next frame.
+ * This is the base structure behind the atomic layer update infrastructure.
+ *
+ * Atomic layer update provides a way to update all layer's parameters
+ * simultaneously. This is needed to avoid incompatible sequential updates
+ * like this one:
+ * 1) update layer format from RGB888 (1 plane/buffer) to YUV422
+ * (2 planes/buffers)
+ * 2) the format update is applied but the DMA channel for the second
+ * plane/buffer is not enabled
+ * 3) enable the DMA channel for the second plane
+ *
+ * @fb_flip: fb_flip object
+ * @updated_configs: bitmask used to record modified configs
+ * @configs: new config values
+ */
+struct atmel_hlcdc_layer_update_slot {
+ struct atmel_hlcdc_layer_fb_flip *fb_flip;
+ unsigned long *updated_configs;
+ u32 *configs;
+};
+
+/**
+ * Atmel HLCDC Layer Update structure
+ *
+ * This structure provides a way to queue layer update requests.
+ *
+ * At a given time there is at most:
+ * - one pending update request, which means the update request has been
+ * committed (or validated) and is waiting for the DMA channel(s) to be
+ * available
+ * - one request being prepared, which means someone started a layer update
+ * but has not committed it yet. There cannot be more than one started
+ * request, because the update lock is taken when starting a layer update
+ * and release when committing or rolling back the request.
+ *
+ * @slots: update slots. One is used for pending request and the other one
+ * for started update request
+ * @pending: the pending slot index or -1 if no request is pending
+ * @next: the started update slot index or -1 no update has been started
+ */
+struct atmel_hlcdc_layer_update {
+ struct atmel_hlcdc_layer_update_slot slots[2];
+ int pending;
+ int next;
+};
+
+enum atmel_hlcdc_layer_dma_channel_status {
+ ATMEL_HLCDC_LAYER_DISABLED,
+ ATMEL_HLCDC_LAYER_ENABLED,
+ ATMEL_HLCDC_LAYER_DISABLING,
+};
+
+/**
+ * Atmel HLCDC Layer DMA channel structure
+ *
+ * This structure stores information on the DMA channel associated to a
+ * given layer.
+ *
+ * @status: DMA channel status
+ * @cur: current framebuffer
+ * @queue: next framebuffer
+ * @dscrs: allocated DMA descriptors
+ */
+struct atmel_hlcdc_layer_dma_channel {
+ enum atmel_hlcdc_layer_dma_channel_status status;
+ struct atmel_hlcdc_layer_fb_flip *cur;
+ struct atmel_hlcdc_layer_fb_flip *queue;
+ struct atmel_hlcdc_dma_channel_dscr *dscrs;
+};
+
+/**
+ * Atmel HLCDC Layer structure
+ *
+ * This structure stores information on the layer instance.
+ *
+ * @desc: layer description
+ * @max_planes: maximum planes/buffers that can be associated with this layer.
+ * This depends on the supported formats.
+ * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
+ * @dma: dma channel
+ * @gc: fb flip garbage collector
+ * @update: update handler
+ * @lock: layer lock
+ */
+struct atmel_hlcdc_layer {
+ const struct atmel_hlcdc_layer_desc *desc;
+ int max_planes;
+ struct atmel_hlcdc *hlcdc;
+ struct workqueue_struct *wq;
+ struct drm_flip_work gc;
+ struct atmel_hlcdc_layer_dma_channel dma;
+ struct atmel_hlcdc_layer_update update;
+ spinlock_t lock;
+};
+
+void atmel_hlcdc_layer_irq(struct atmel_hlcdc_layer *layer);
+
+int atmel_hlcdc_layer_init(struct drm_device *dev,
+ struct atmel_hlcdc_layer *layer,
+ const struct atmel_hlcdc_layer_desc *desc);
+
+void atmel_hlcdc_layer_cleanup(struct drm_device *dev,
+ struct atmel_hlcdc_layer *layer);
+
+int atmel_hlcdc_layer_disable(struct atmel_hlcdc_layer *layer);
+
+int atmel_hlcdc_layer_update_start(struct atmel_hlcdc_layer *layer);
+
+void atmel_hlcdc_layer_update_cfg(struct atmel_hlcdc_layer *layer, int cfg,
+ u32 mask, u32 val);
+
+void atmel_hlcdc_layer_update_set_fb(struct atmel_hlcdc_layer *layer,
+ struct drm_framebuffer *fb,
+ unsigned int *offsets);
+
+void atmel_hlcdc_layer_update_set_finished(struct atmel_hlcdc_layer *layer,
+ void (*finished)(void *data),
+ void *finished_data);
+
+void atmel_hlcdc_layer_update_rollback(struct atmel_hlcdc_layer *layer);
+
+void atmel_hlcdc_layer_update_commit(struct atmel_hlcdc_layer *layer);
+
+#endif /* DRM_ATMEL_HLCDC_LAYER_H */
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
new file mode 100644
index 000000000000..c402192362c5
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2014 Traphandler
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/of_graph.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_panel.h>
+
+#include "atmel_hlcdc_dc.h"
+
+/**
+ * Atmel HLCDC RGB output mode
+ */
+enum atmel_hlcdc_connector_rgb_mode {
+ ATMEL_HLCDC_CONNECTOR_RGB444,
+ ATMEL_HLCDC_CONNECTOR_RGB565,
+ ATMEL_HLCDC_CONNECTOR_RGB666,
+ ATMEL_HLCDC_CONNECTOR_RGB888,
+};
+
+/**
+ * Atmel HLCDC RGB connector structure
+ *
+ * This structure stores RGB slave device information.
+ *
+ * @connector: DRM connector
+ * @encoder: DRM encoder
+ * @dc: pointer to the atmel_hlcdc_dc structure
+ * @dpms: current DPMS mode
+ */
+struct atmel_hlcdc_rgb_output {
+ struct drm_connector connector;
+ struct drm_encoder encoder;
+ struct atmel_hlcdc_dc *dc;
+ int dpms;
+};
+
+static inline struct atmel_hlcdc_rgb_output *
+drm_connector_to_atmel_hlcdc_rgb_output(struct drm_connector *connector)
+{
+ return container_of(connector, struct atmel_hlcdc_rgb_output,
+ connector);
+}
+
+static inline struct atmel_hlcdc_rgb_output *
+drm_encoder_to_atmel_hlcdc_rgb_output(struct drm_encoder *encoder)
+{
+ return container_of(encoder, struct atmel_hlcdc_rgb_output, encoder);
+}
+
+/**
+ * Atmel HLCDC Panel device structure
+ *
+ * This structure is specialization of the slave device structure to
+ * interface with drm panels.
+ *
+ * @base: base slave device fields
+ * @panel: drm panel attached to this slave device
+ */
+struct atmel_hlcdc_panel {
+ struct atmel_hlcdc_rgb_output base;
+ struct drm_panel *panel;
+};
+
+static inline struct atmel_hlcdc_panel *
+atmel_hlcdc_rgb_output_to_panel(struct atmel_hlcdc_rgb_output *output)
+{
+ return container_of(output, struct atmel_hlcdc_panel, base);
+}
+
+static void atmel_hlcdc_panel_encoder_dpms(struct drm_encoder *encoder,
+ int mode)
+{
+ struct atmel_hlcdc_rgb_output *rgb =
+ drm_encoder_to_atmel_hlcdc_rgb_output(encoder);
+ struct atmel_hlcdc_panel *panel = atmel_hlcdc_rgb_output_to_panel(rgb);
+
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
+ if (mode == rgb->dpms)
+ return;
+
+ if (mode != DRM_MODE_DPMS_ON)
+ drm_panel_disable(panel->panel);
+ else
+ drm_panel_enable(panel->panel);
+
+ rgb->dpms = mode;
+}
+
+static bool
+atmel_hlcdc_panel_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ return true;
+}
+
+static void atmel_hlcdc_panel_encoder_prepare(struct drm_encoder *encoder)
+{
+ atmel_hlcdc_panel_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
+static void atmel_hlcdc_panel_encoder_commit(struct drm_encoder *encoder)
+{
+ atmel_hlcdc_panel_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
+}
+
+static void
+atmel_hlcdc_rgb_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct atmel_hlcdc_rgb_output *rgb =
+ drm_encoder_to_atmel_hlcdc_rgb_output(encoder);
+ struct drm_display_info *info = &rgb->connector.display_info;
+ unsigned int cfg;
+
+ cfg = 0;
+
+ if (info->num_bus_formats) {
+ switch (info->bus_formats[0]) {
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ cfg |= ATMEL_HLCDC_CONNECTOR_RGB666 << 8;
+ break;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ cfg |= ATMEL_HLCDC_CONNECTOR_RGB888 << 8;
+ break;
+ default:
+ break;
+ }
+ }
+
+ regmap_update_bits(rgb->dc->hlcdc->regmap, ATMEL_HLCDC_CFG(5),
+ ATMEL_HLCDC_MODE_MASK,
+ cfg);
+}
+
+static struct drm_encoder_helper_funcs atmel_hlcdc_panel_encoder_helper_funcs = {
+ .dpms = atmel_hlcdc_panel_encoder_dpms,
+ .mode_fixup = atmel_hlcdc_panel_encoder_mode_fixup,
+ .prepare = atmel_hlcdc_panel_encoder_prepare,
+ .commit = atmel_hlcdc_panel_encoder_commit,
+ .mode_set = atmel_hlcdc_rgb_encoder_mode_set,
+};
+
+static void atmel_hlcdc_rgb_encoder_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+ memset(encoder, 0, sizeof(*encoder));
+}
+
+static const struct drm_encoder_funcs atmel_hlcdc_panel_encoder_funcs = {
+ .destroy = atmel_hlcdc_rgb_encoder_destroy,
+};
+
+static int atmel_hlcdc_panel_get_modes(struct drm_connector *connector)
+{
+ struct atmel_hlcdc_rgb_output *rgb =
+ drm_connector_to_atmel_hlcdc_rgb_output(connector);
+ struct atmel_hlcdc_panel *panel = atmel_hlcdc_rgb_output_to_panel(rgb);
+
+ return panel->panel->funcs->get_modes(panel->panel);
+}
+
+static int atmel_hlcdc_rgb_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct atmel_hlcdc_rgb_output *rgb =
+ drm_connector_to_atmel_hlcdc_rgb_output(connector);
+
+ return atmel_hlcdc_dc_mode_valid(rgb->dc, mode);
+}
+
+
+
+static struct drm_encoder *
+atmel_hlcdc_rgb_best_encoder(struct drm_connector *connector)
+{
+ struct atmel_hlcdc_rgb_output *rgb =
+ drm_connector_to_atmel_hlcdc_rgb_output(connector);
+
+ return &rgb->encoder;
+}
+
+static struct drm_connector_helper_funcs atmel_hlcdc_panel_connector_helper_funcs = {
+ .get_modes = atmel_hlcdc_panel_get_modes,
+ .mode_valid = atmel_hlcdc_rgb_mode_valid,
+ .best_encoder = atmel_hlcdc_rgb_best_encoder,
+};
+
+static enum drm_connector_status
+atmel_hlcdc_panel_connector_detect(struct drm_connector *connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static void
+atmel_hlcdc_panel_connector_destroy(struct drm_connector *connector)
+{
+ struct atmel_hlcdc_rgb_output *rgb =
+ drm_connector_to_atmel_hlcdc_rgb_output(connector);
+ struct atmel_hlcdc_panel *panel = atmel_hlcdc_rgb_output_to_panel(rgb);
+
+ drm_panel_detach(panel->panel);
+ drm_connector_cleanup(connector);
+}
+
+static const struct drm_connector_funcs atmel_hlcdc_panel_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .detect = atmel_hlcdc_panel_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = atmel_hlcdc_panel_connector_destroy,
+};
+
+static int atmel_hlcdc_create_panel_output(struct drm_device *dev,
+ struct of_endpoint *ep)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ struct device_node *np;
+ struct drm_panel *p = NULL;
+ struct atmel_hlcdc_panel *panel;
+ int ret;
+
+ np = of_graph_get_remote_port_parent(ep->local_node);
+ if (!np)
+ return -EINVAL;
+
+ p = of_drm_find_panel(np);
+ of_node_put(np);
+
+ if (!p)
+ return -EPROBE_DEFER;
+
+ panel = devm_kzalloc(dev->dev, sizeof(*panel), GFP_KERNEL);
+ if (!panel)
+ return -EINVAL;
+
+ panel->base.dpms = DRM_MODE_DPMS_OFF;
+
+ panel->base.dc = dc;
+
+ drm_encoder_helper_add(&panel->base.encoder,
+ &atmel_hlcdc_panel_encoder_helper_funcs);
+ ret = drm_encoder_init(dev, &panel->base.encoder,
+ &atmel_hlcdc_panel_encoder_funcs,
+ DRM_MODE_ENCODER_LVDS);
+ if (ret)
+ return ret;
+
+ panel->base.connector.dpms = DRM_MODE_DPMS_OFF;
+ panel->base.connector.polled = DRM_CONNECTOR_POLL_CONNECT;
+ drm_connector_helper_add(&panel->base.connector,
+ &atmel_hlcdc_panel_connector_helper_funcs);
+ ret = drm_connector_init(dev, &panel->base.connector,
+ &atmel_hlcdc_panel_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+ if (ret)
+ goto err_encoder_cleanup;
+
+ drm_mode_connector_attach_encoder(&panel->base.connector,
+ &panel->base.encoder);
+ panel->base.encoder.possible_crtcs = 0x1;
+
+ drm_panel_attach(p, &panel->base.connector);
+ panel->panel = p;
+
+ return 0;
+
+err_encoder_cleanup:
+ drm_encoder_cleanup(&panel->base.encoder);
+
+ return ret;
+}
+
+int atmel_hlcdc_create_outputs(struct drm_device *dev)
+{
+ struct device_node *port_np, *np;
+ struct of_endpoint ep;
+ int ret;
+
+ port_np = of_get_child_by_name(dev->dev->of_node, "port");
+ if (!port_np)
+ return -EINVAL;
+
+ np = of_get_child_by_name(port_np, "endpoint");
+ of_node_put(port_np);
+
+ if (!np)
+ return -EINVAL;
+
+ ret = of_graph_parse_endpoint(np, &ep);
+ of_node_put(port_np);
+
+ if (ret)
+ return ret;
+
+ /* We currently only support panel output */
+ return atmel_hlcdc_create_panel_output(dev, &ep);
+}
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
new file mode 100644
index 000000000000..c5892dcfd745
--- /dev/null
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -0,0 +1,856 @@
+/*
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "atmel_hlcdc_dc.h"
+
+#define SUBPIXEL_MASK 0xffff
+
+static uint32_t rgb_formats[] = {
+ DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGBA4444,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888,
+};
+
+struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = {
+ .formats = rgb_formats,
+ .nformats = ARRAY_SIZE(rgb_formats),
+};
+
+static uint32_t rgb_and_yuv_formats[] = {
+ DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGBA4444,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_AYUV,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY,
+ DRM_FORMAT_YVYU,
+ DRM_FORMAT_VYUY,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_YUV422,
+ DRM_FORMAT_YUV420,
+};
+
+struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats = {
+ .formats = rgb_and_yuv_formats,
+ .nformats = ARRAY_SIZE(rgb_and_yuv_formats),
+};
+
+static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode)
+{
+ switch (format) {
+ case DRM_FORMAT_XRGB4444:
+ *mode = ATMEL_HLCDC_XRGB4444_MODE;
+ break;
+ case DRM_FORMAT_ARGB4444:
+ *mode = ATMEL_HLCDC_ARGB4444_MODE;
+ break;
+ case DRM_FORMAT_RGBA4444:
+ *mode = ATMEL_HLCDC_RGBA4444_MODE;
+ break;
+ case DRM_FORMAT_RGB565:
+ *mode = ATMEL_HLCDC_RGB565_MODE;
+ break;
+ case DRM_FORMAT_RGB888:
+ *mode = ATMEL_HLCDC_RGB888_MODE;
+ break;
+ case DRM_FORMAT_ARGB1555:
+ *mode = ATMEL_HLCDC_ARGB1555_MODE;
+ break;
+ case DRM_FORMAT_XRGB8888:
+ *mode = ATMEL_HLCDC_XRGB8888_MODE;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ *mode = ATMEL_HLCDC_ARGB8888_MODE;
+ break;
+ case DRM_FORMAT_RGBA8888:
+ *mode = ATMEL_HLCDC_RGBA8888_MODE;
+ break;
+ case DRM_FORMAT_AYUV:
+ *mode = ATMEL_HLCDC_AYUV_MODE;
+ break;
+ case DRM_FORMAT_YUYV:
+ *mode = ATMEL_HLCDC_YUYV_MODE;
+ break;
+ case DRM_FORMAT_UYVY:
+ *mode = ATMEL_HLCDC_UYVY_MODE;
+ break;
+ case DRM_FORMAT_YVYU:
+ *mode = ATMEL_HLCDC_YVYU_MODE;
+ break;
+ case DRM_FORMAT_VYUY:
+ *mode = ATMEL_HLCDC_VYUY_MODE;
+ break;
+ case DRM_FORMAT_NV21:
+ *mode = ATMEL_HLCDC_NV21_MODE;
+ break;
+ case DRM_FORMAT_NV61:
+ *mode = ATMEL_HLCDC_NV61_MODE;
+ break;
+ case DRM_FORMAT_YUV420:
+ *mode = ATMEL_HLCDC_YUV420_MODE;
+ break;
+ case DRM_FORMAT_YUV422:
+ *mode = ATMEL_HLCDC_YUV422_MODE;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static bool atmel_hlcdc_format_embedds_alpha(u32 format)
+{
+ int i;
+
+ for (i = 0; i < sizeof(format); i++) {
+ char tmp = (format >> (8 * i)) & 0xff;
+
+ if (tmp == 'A')
+ return true;
+ }
+
+ return false;
+}
+
+static u32 heo_downscaling_xcoef[] = {
+ 0x11343311,
+ 0x000000f7,
+ 0x1635300c,
+ 0x000000f9,
+ 0x1b362c08,
+ 0x000000fb,
+ 0x1f372804,
+ 0x000000fe,
+ 0x24382400,
+ 0x00000000,
+ 0x28371ffe,
+ 0x00000004,
+ 0x2c361bfb,
+ 0x00000008,
+ 0x303516f9,
+ 0x0000000c,
+};
+
+static u32 heo_downscaling_ycoef[] = {
+ 0x00123737,
+ 0x00173732,
+ 0x001b382d,
+ 0x001f3928,
+ 0x00243824,
+ 0x0028391f,
+ 0x002d381b,
+ 0x00323717,
+};
+
+static u32 heo_upscaling_xcoef[] = {
+ 0xf74949f7,
+ 0x00000000,
+ 0xf55f33fb,
+ 0x000000fe,
+ 0xf5701efe,
+ 0x000000ff,
+ 0xf87c0dff,
+ 0x00000000,
+ 0x00800000,
+ 0x00000000,
+ 0x0d7cf800,
+ 0x000000ff,
+ 0x1e70f5ff,
+ 0x000000fe,
+ 0x335ff5fe,
+ 0x000000fb,
+};
+
+static u32 heo_upscaling_ycoef[] = {
+ 0x00004040,
+ 0x00075920,
+ 0x00056f0c,
+ 0x00027b03,
+ 0x00008000,
+ 0x00037b02,
+ 0x000c6f05,
+ 0x00205907,
+};
+
+static void
+atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_update_req *req)
+{
+ const struct atmel_hlcdc_layer_cfg_layout *layout =
+ &plane->layer.desc->layout;
+
+ if (layout->size)
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ layout->size,
+ 0xffffffff,
+ (req->crtc_w - 1) |
+ ((req->crtc_h - 1) << 16));
+
+ if (layout->memsize)
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ layout->memsize,
+ 0xffffffff,
+ (req->src_w - 1) |
+ ((req->src_h - 1) << 16));
+
+ if (layout->pos)
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ layout->pos,
+ 0xffffffff,
+ req->crtc_x |
+ (req->crtc_y << 16));
+
+ /* TODO: rework the rescaling part */
+ if (req->crtc_w != req->src_w || req->crtc_h != req->src_h) {
+ u32 factor_reg = 0;
+
+ if (req->crtc_w != req->src_w) {
+ int i;
+ u32 factor;
+ u32 *coeff_tab = heo_upscaling_xcoef;
+ u32 max_memsize;
+
+ if (req->crtc_w < req->src_w)
+ coeff_tab = heo_downscaling_xcoef;
+ for (i = 0; i < ARRAY_SIZE(heo_upscaling_xcoef); i++)
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ 17 + i,
+ 0xffffffff,
+ coeff_tab[i]);
+ factor = ((8 * 256 * req->src_w) - (256 * 4)) /
+ req->crtc_w;
+ factor++;
+ max_memsize = ((factor * req->crtc_w) + (256 * 4)) /
+ 2048;
+ if (max_memsize > req->src_w)
+ factor--;
+ factor_reg |= factor | 0x80000000;
+ }
+
+ if (req->crtc_h != req->src_h) {
+ int i;
+ u32 factor;
+ u32 *coeff_tab = heo_upscaling_ycoef;
+ u32 max_memsize;
+
+ if (req->crtc_w < req->src_w)
+ coeff_tab = heo_downscaling_ycoef;
+ for (i = 0; i < ARRAY_SIZE(heo_upscaling_ycoef); i++)
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ 33 + i,
+ 0xffffffff,
+ coeff_tab[i]);
+ factor = ((8 * 256 * req->src_w) - (256 * 4)) /
+ req->crtc_w;
+ factor++;
+ max_memsize = ((factor * req->crtc_w) + (256 * 4)) /
+ 2048;
+ if (max_memsize > req->src_w)
+ factor--;
+ factor_reg |= (factor << 16) | 0x80000000;
+ }
+
+ atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
+ factor_reg);
+ }
+}
+
+static void
+atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_update_req *req)
+{
+ const struct atmel_hlcdc_layer_cfg_layout *layout =
+ &plane->layer.desc->layout;
+ unsigned int cfg = ATMEL_HLCDC_LAYER_DMA;
+
+ if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
+ cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL |
+ ATMEL_HLCDC_LAYER_ITER;
+
+ if (atmel_hlcdc_format_embedds_alpha(req->fb->pixel_format))
+ cfg |= ATMEL_HLCDC_LAYER_LAEN;
+ else
+ cfg |= ATMEL_HLCDC_LAYER_GAEN;
+ }
+
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ ATMEL_HLCDC_LAYER_DMA_CFG_ID,
+ ATMEL_HLCDC_LAYER_DMA_BLEN_MASK,
+ ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16);
+
+ atmel_hlcdc_layer_update_cfg(&plane->layer, layout->general_config,
+ ATMEL_HLCDC_LAYER_ITER2BL |
+ ATMEL_HLCDC_LAYER_ITER |
+ ATMEL_HLCDC_LAYER_GAEN |
+ ATMEL_HLCDC_LAYER_LAEN |
+ ATMEL_HLCDC_LAYER_OVR |
+ ATMEL_HLCDC_LAYER_DMA, cfg);
+}
+
+static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_update_req *req)
+{
+ u32 cfg;
+ int ret;
+
+ ret = atmel_hlcdc_format_to_plane_mode(req->fb->pixel_format, &cfg);
+ if (ret)
+ return;
+
+ if ((req->fb->pixel_format == DRM_FORMAT_YUV422 ||
+ req->fb->pixel_format == DRM_FORMAT_NV61) &&
+ (plane->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))))
+ cfg |= ATMEL_HLCDC_YUV422ROT;
+
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ ATMEL_HLCDC_LAYER_FORMAT_CFG_ID,
+ 0xffffffff,
+ cfg);
+
+ /*
+ * Rotation optimization is not working on RGB888 (rotation is still
+ * working but without any optimization).
+ */
+ if (req->fb->pixel_format == DRM_FORMAT_RGB888)
+ cfg = ATMEL_HLCDC_LAYER_DMA_ROTDIS;
+ else
+ cfg = 0;
+
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ ATMEL_HLCDC_LAYER_DMA_CFG_ID,
+ ATMEL_HLCDC_LAYER_DMA_ROTDIS, cfg);
+}
+
+static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_update_req *req)
+{
+ struct atmel_hlcdc_layer *layer = &plane->layer;
+ const struct atmel_hlcdc_layer_cfg_layout *layout =
+ &layer->desc->layout;
+ int i;
+
+ atmel_hlcdc_layer_update_set_fb(&plane->layer, req->fb, req->offsets);
+
+ for (i = 0; i < req->nplanes; i++) {
+ if (layout->xstride[i]) {
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ layout->xstride[i],
+ 0xffffffff,
+ req->xstride[i]);
+ }
+
+ if (layout->pstride[i]) {
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ layout->pstride[i],
+ 0xffffffff,
+ req->pstride[i]);
+ }
+ }
+}
+
+static int atmel_hlcdc_plane_check_update_req(struct drm_plane *p,
+ struct atmel_hlcdc_plane_update_req *req,
+ const struct drm_display_mode *mode)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+ const struct atmel_hlcdc_layer_cfg_layout *layout =
+ &plane->layer.desc->layout;
+
+ if (!layout->size &&
+ (mode->hdisplay != req->crtc_w ||
+ mode->vdisplay != req->crtc_h))
+ return -EINVAL;
+
+ if (plane->layer.desc->max_height &&
+ req->crtc_h > plane->layer.desc->max_height)
+ return -EINVAL;
+
+ if (plane->layer.desc->max_width &&
+ req->crtc_w > plane->layer.desc->max_width)
+ return -EINVAL;
+
+ if ((req->crtc_h != req->src_h || req->crtc_w != req->src_w) &&
+ (!layout->memsize ||
+ atmel_hlcdc_format_embedds_alpha(req->fb->pixel_format)))
+ return -EINVAL;
+
+ if (req->crtc_x < 0 || req->crtc_y < 0)
+ return -EINVAL;
+
+ if (req->crtc_w + req->crtc_x > mode->hdisplay ||
+ req->crtc_h + req->crtc_y > mode->vdisplay)
+ return -EINVAL;
+
+ return 0;
+}
+
+int atmel_hlcdc_plane_prepare_update_req(struct drm_plane *p,
+ struct atmel_hlcdc_plane_update_req *req,
+ const struct drm_display_mode *mode)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+ unsigned int patched_crtc_w;
+ unsigned int patched_crtc_h;
+ unsigned int patched_src_w;
+ unsigned int patched_src_h;
+ unsigned int tmp;
+ int x_offset = 0;
+ int y_offset = 0;
+ int hsub = 1;
+ int vsub = 1;
+ int i;
+
+ if ((req->src_x | req->src_y | req->src_w | req->src_h) &
+ SUBPIXEL_MASK)
+ return -EINVAL;
+
+ req->src_x >>= 16;
+ req->src_y >>= 16;
+ req->src_w >>= 16;
+ req->src_h >>= 16;
+
+ req->nplanes = drm_format_num_planes(req->fb->pixel_format);
+ if (req->nplanes > ATMEL_HLCDC_MAX_PLANES)
+ return -EINVAL;
+
+ /*
+ * Swap width and size in case of 90 or 270 degrees rotation
+ */
+ if (plane->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))) {
+ tmp = req->crtc_w;
+ req->crtc_w = req->crtc_h;
+ req->crtc_h = tmp;
+ tmp = req->src_w;
+ req->src_w = req->src_h;
+ req->src_h = tmp;
+ }
+
+ if (req->crtc_x + req->crtc_w > mode->hdisplay)
+ patched_crtc_w = mode->hdisplay - req->crtc_x;
+ else
+ patched_crtc_w = req->crtc_w;
+
+ if (req->crtc_x < 0) {
+ patched_crtc_w += req->crtc_x;
+ x_offset = -req->crtc_x;
+ req->crtc_x = 0;
+ }
+
+ if (req->crtc_y + req->crtc_h > mode->vdisplay)
+ patched_crtc_h = mode->vdisplay - req->crtc_y;
+ else
+ patched_crtc_h = req->crtc_h;
+
+ if (req->crtc_y < 0) {
+ patched_crtc_h += req->crtc_y;
+ y_offset = -req->crtc_y;
+ req->crtc_y = 0;
+ }
+
+ patched_src_w = DIV_ROUND_CLOSEST(patched_crtc_w * req->src_w,
+ req->crtc_w);
+ patched_src_h = DIV_ROUND_CLOSEST(patched_crtc_h * req->src_h,
+ req->crtc_h);
+
+ hsub = drm_format_horz_chroma_subsampling(req->fb->pixel_format);
+ vsub = drm_format_vert_chroma_subsampling(req->fb->pixel_format);
+
+ for (i = 0; i < req->nplanes; i++) {
+ unsigned int offset = 0;
+ int xdiv = i ? hsub : 1;
+ int ydiv = i ? vsub : 1;
+
+ req->bpp[i] = drm_format_plane_cpp(req->fb->pixel_format, i);
+ if (!req->bpp[i])
+ return -EINVAL;
+
+ switch (plane->rotation & 0xf) {
+ case BIT(DRM_ROTATE_90):
+ offset = ((y_offset + req->src_y + patched_src_w - 1) /
+ ydiv) * req->fb->pitches[i];
+ offset += ((x_offset + req->src_x) / xdiv) *
+ req->bpp[i];
+ req->xstride[i] = ((patched_src_w - 1) / ydiv) *
+ req->fb->pitches[i];
+ req->pstride[i] = -req->fb->pitches[i] - req->bpp[i];
+ break;
+ case BIT(DRM_ROTATE_180):
+ offset = ((y_offset + req->src_y + patched_src_h - 1) /
+ ydiv) * req->fb->pitches[i];
+ offset += ((x_offset + req->src_x + patched_src_w - 1) /
+ xdiv) * req->bpp[i];
+ req->xstride[i] = ((((patched_src_w - 1) / xdiv) - 1) *
+ req->bpp[i]) - req->fb->pitches[i];
+ req->pstride[i] = -2 * req->bpp[i];
+ break;
+ case BIT(DRM_ROTATE_270):
+ offset = ((y_offset + req->src_y) / ydiv) *
+ req->fb->pitches[i];
+ offset += ((x_offset + req->src_x + patched_src_h - 1) /
+ xdiv) * req->bpp[i];
+ req->xstride[i] = -(((patched_src_w - 1) / ydiv) *
+ req->fb->pitches[i]) -
+ (2 * req->bpp[i]);
+ req->pstride[i] = req->fb->pitches[i] - req->bpp[i];
+ break;
+ case BIT(DRM_ROTATE_0):
+ default:
+ offset = ((y_offset + req->src_y) / ydiv) *
+ req->fb->pitches[i];
+ offset += ((x_offset + req->src_x) / xdiv) *
+ req->bpp[i];
+ req->xstride[i] = req->fb->pitches[i] -
+ ((patched_src_w / xdiv) *
+ req->bpp[i]);
+ req->pstride[i] = 0;
+ break;
+ }
+
+ req->offsets[i] = offset + req->fb->offsets[i];
+ }
+
+ req->src_w = patched_src_w;
+ req->src_h = patched_src_h;
+ req->crtc_w = patched_crtc_w;
+ req->crtc_h = patched_crtc_h;
+
+ return atmel_hlcdc_plane_check_update_req(p, req, mode);
+}
+
+int atmel_hlcdc_plane_apply_update_req(struct drm_plane *p,
+ struct atmel_hlcdc_plane_update_req *req)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+ int ret;
+
+ ret = atmel_hlcdc_layer_update_start(&plane->layer);
+ if (ret)
+ return ret;
+
+ atmel_hlcdc_plane_update_pos_and_size(plane, req);
+ atmel_hlcdc_plane_update_general_settings(plane, req);
+ atmel_hlcdc_plane_update_format(plane, req);
+ atmel_hlcdc_plane_update_buffers(plane, req);
+
+ atmel_hlcdc_layer_update_commit(&plane->layer);
+
+ return 0;
+}
+
+int atmel_hlcdc_plane_update_with_mode(struct drm_plane *p,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w,
+ unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h,
+ const struct drm_display_mode *mode)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+ struct atmel_hlcdc_plane_update_req req;
+ int ret = 0;
+
+ memset(&req, 0, sizeof(req));
+ req.crtc_x = crtc_x;
+ req.crtc_y = crtc_y;
+ req.crtc_w = crtc_w;
+ req.crtc_h = crtc_h;
+ req.src_x = src_x;
+ req.src_y = src_y;
+ req.src_w = src_w;
+ req.src_h = src_h;
+ req.fb = fb;
+
+ ret = atmel_hlcdc_plane_prepare_update_req(&plane->base, &req, mode);
+ if (ret)
+ return ret;
+
+ if (!req.crtc_h || !req.crtc_w)
+ return atmel_hlcdc_layer_disable(&plane->layer);
+
+ return atmel_hlcdc_plane_apply_update_req(&plane->base, &req);
+}
+
+static int atmel_hlcdc_plane_update(struct drm_plane *p,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ return atmel_hlcdc_plane_update_with_mode(p, crtc, fb, crtc_x, crtc_y,
+ crtc_w, crtc_h, src_x, src_y,
+ src_w, src_h, &crtc->hwmode);
+}
+
+static int atmel_hlcdc_plane_disable(struct drm_plane *p)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+
+ return atmel_hlcdc_layer_disable(&plane->layer);
+}
+
+static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+
+ if (plane->base.fb)
+ drm_framebuffer_unreference(plane->base.fb);
+
+ atmel_hlcdc_layer_cleanup(p->dev, &plane->layer);
+
+ drm_plane_cleanup(p);
+ devm_kfree(p->dev->dev, plane);
+}
+
+static int atmel_hlcdc_plane_set_alpha(struct atmel_hlcdc_plane *plane,
+ u8 alpha)
+{
+ atmel_hlcdc_layer_update_start(&plane->layer);
+ atmel_hlcdc_layer_update_cfg(&plane->layer,
+ plane->layer.desc->layout.general_config,
+ ATMEL_HLCDC_LAYER_GA_MASK,
+ alpha << ATMEL_HLCDC_LAYER_GA_SHIFT);
+ atmel_hlcdc_layer_update_commit(&plane->layer);
+
+ return 0;
+}
+
+static int atmel_hlcdc_plane_set_rotation(struct atmel_hlcdc_plane *plane,
+ unsigned int rotation)
+{
+ plane->rotation = rotation;
+
+ return 0;
+}
+
+static int atmel_hlcdc_plane_set_property(struct drm_plane *p,
+ struct drm_property *property,
+ uint64_t value)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+ struct atmel_hlcdc_plane_properties *props = plane->properties;
+
+ if (property == props->alpha)
+ atmel_hlcdc_plane_set_alpha(plane, value);
+ else if (property == props->rotation)
+ atmel_hlcdc_plane_set_rotation(plane, value);
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static void atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc,
+ struct atmel_hlcdc_plane_properties *props)
+{
+ struct regmap *regmap = plane->layer.hlcdc->regmap;
+
+ if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
+ desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
+ drm_object_attach_property(&plane->base.base,
+ props->alpha, 255);
+
+ /* Set default alpha value */
+ regmap_update_bits(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_GENERAL_CFG(&plane->layer),
+ ATMEL_HLCDC_LAYER_GA_MASK,
+ ATMEL_HLCDC_LAYER_GA_MASK);
+ }
+
+ if (desc->layout.xstride && desc->layout.pstride)
+ drm_object_attach_property(&plane->base.base,
+ props->rotation,
+ BIT(DRM_ROTATE_0));
+
+ if (desc->layout.csc) {
+ /*
+ * TODO: decare a "yuv-to-rgb-conv-factors" property to let
+ * userspace modify these factors (using a BLOB property ?).
+ */
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 0),
+ 0x4c900091);
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 1),
+ 0x7a5f5090);
+ regmap_write(regmap,
+ desc->regs_offset +
+ ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 2),
+ 0x40040890);
+ }
+}
+
+static struct drm_plane_funcs layer_plane_funcs = {
+ .update_plane = atmel_hlcdc_plane_update,
+ .disable_plane = atmel_hlcdc_plane_disable,
+ .set_property = atmel_hlcdc_plane_set_property,
+ .destroy = atmel_hlcdc_plane_destroy,
+};
+
+static struct atmel_hlcdc_plane *
+atmel_hlcdc_plane_create(struct drm_device *dev,
+ const struct atmel_hlcdc_layer_desc *desc,
+ struct atmel_hlcdc_plane_properties *props)
+{
+ struct atmel_hlcdc_plane *plane;
+ enum drm_plane_type type;
+ int ret;
+
+ plane = devm_kzalloc(dev->dev, sizeof(*plane), GFP_KERNEL);
+ if (!plane)
+ return ERR_PTR(-ENOMEM);
+
+ ret = atmel_hlcdc_layer_init(dev, &plane->layer, desc);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (desc->type == ATMEL_HLCDC_BASE_LAYER)
+ type = DRM_PLANE_TYPE_PRIMARY;
+ else if (desc->type == ATMEL_HLCDC_CURSOR_LAYER)
+ type = DRM_PLANE_TYPE_CURSOR;
+ else
+ type = DRM_PLANE_TYPE_OVERLAY;
+
+ ret = drm_universal_plane_init(dev, &plane->base, 0,
+ &layer_plane_funcs,
+ desc->formats->formats,
+ desc->formats->nformats, type);
+ if (ret)
+ return ERR_PTR(ret);
+
+ /* Set default property values*/
+ atmel_hlcdc_plane_init_properties(plane, desc, props);
+
+ return plane;
+}
+
+static struct atmel_hlcdc_plane_properties *
+atmel_hlcdc_plane_create_properties(struct drm_device *dev)
+{
+ struct atmel_hlcdc_plane_properties *props;
+
+ props = devm_kzalloc(dev->dev, sizeof(*props), GFP_KERNEL);
+ if (!props)
+ return ERR_PTR(-ENOMEM);
+
+ props->alpha = drm_property_create_range(dev, 0, "alpha", 0, 255);
+ if (!props->alpha)
+ return ERR_PTR(-ENOMEM);
+
+ props->rotation = drm_mode_create_rotation_property(dev,
+ BIT(DRM_ROTATE_0) |
+ BIT(DRM_ROTATE_90) |
+ BIT(DRM_ROTATE_180) |
+ BIT(DRM_ROTATE_270));
+ if (!props->rotation)
+ return ERR_PTR(-ENOMEM);
+
+ return props;
+}
+
+struct atmel_hlcdc_planes *
+atmel_hlcdc_create_planes(struct drm_device *dev)
+{
+ struct atmel_hlcdc_dc *dc = dev->dev_private;
+ struct atmel_hlcdc_plane_properties *props;
+ struct atmel_hlcdc_planes *planes;
+ const struct atmel_hlcdc_layer_desc *descs = dc->desc->layers;
+ int nlayers = dc->desc->nlayers;
+ int i;
+
+ planes = devm_kzalloc(dev->dev, sizeof(*planes), GFP_KERNEL);
+ if (!planes)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < nlayers; i++) {
+ if (descs[i].type == ATMEL_HLCDC_OVERLAY_LAYER)
+ planes->noverlays++;
+ }
+
+ if (planes->noverlays) {
+ planes->overlays = devm_kzalloc(dev->dev,
+ planes->noverlays *
+ sizeof(*planes->overlays),
+ GFP_KERNEL);
+ if (!planes->overlays)
+ return ERR_PTR(-ENOMEM);
+ }
+
+ props = atmel_hlcdc_plane_create_properties(dev);
+ if (IS_ERR(props))
+ return ERR_CAST(props);
+
+ planes->noverlays = 0;
+ for (i = 0; i < nlayers; i++) {
+ struct atmel_hlcdc_plane *plane;
+
+ if (descs[i].type == ATMEL_HLCDC_PP_LAYER)
+ continue;
+
+ plane = atmel_hlcdc_plane_create(dev, &descs[i], props);
+ if (IS_ERR(plane))
+ return ERR_CAST(plane);
+
+ plane->properties = props;
+
+ switch (descs[i].type) {
+ case ATMEL_HLCDC_BASE_LAYER:
+ if (planes->primary)
+ return ERR_PTR(-EINVAL);
+ planes->primary = plane;
+ break;
+
+ case ATMEL_HLCDC_OVERLAY_LAYER:
+ planes->overlays[planes->noverlays++] = plane;
+ break;
+
+ case ATMEL_HLCDC_CURSOR_LAYER:
+ if (planes->cursor)
+ return ERR_PTR(-EINVAL);
+ planes->cursor = plane;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return planes;
+}
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
index 61dbf09dff5d..976d9798dc99 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -207,12 +207,22 @@ int bochs_fbdev_init(struct bochs_device *bochs)
if (ret)
return ret;
- drm_fb_helper_single_add_all_connectors(&bochs->fb.helper);
+ ret = drm_fb_helper_single_add_all_connectors(&bochs->fb.helper);
+ if (ret)
+ goto fini;
+
drm_helper_disable_unused_functions(bochs->dev);
- drm_fb_helper_initial_config(&bochs->fb.helper, 32);
+
+ ret = drm_fb_helper_initial_config(&bochs->fb.helper, 32);
+ if (ret)
+ goto fini;
bochs->fb.initialized = true;
return 0;
+
+fini:
+ drm_fb_helper_fini(&bochs->fb.helper);
+ return ret;
}
void bochs_fbdev_fini(struct bochs_device *bochs)
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 85f0f8cf1fb8..26bcd03a8cb6 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -18,10 +18,6 @@ MODULE_PARM_DESC(defy, "default y resolution");
/* ---------------------------------------------------------------------- */
-static void bochs_crtc_load_lut(struct drm_crtc *crtc)
-{
-}
-
static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode)
{
switch (mode) {
@@ -144,7 +140,6 @@ static const struct drm_crtc_helper_funcs bochs_helper_funcs = {
.mode_set_base = bochs_crtc_mode_set_base,
.prepare = bochs_crtc_prepare,
.commit = bochs_crtc_commit,
- .load_lut = bochs_crtc_load_lut,
};
static void bochs_crtc_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 884923f982d9..f38bbcdf929b 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -1,5 +1,13 @@
+config DRM_DW_HDMI
+ tristate
+ depends on DRM
+ select DRM_KMS_HELPER
+
config DRM_PTN3460
tristate "PTN3460 DP/LVDS bridge"
depends on DRM
+ depends on OF
select DRM_KMS_HELPER
+ select DRM_PANEL
---help---
+ ptn3460 eDP-LVDS bridge chip driver.
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index b4733e1fbd2e..d8a8cfd12fbb 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,3 +1,4 @@
ccflags-y := -Iinclude/drm
obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
+obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index ddc53e039530..cd6a70647e32 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -6,31 +6,26 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
- * for SLISHDMI13T and SLIPHDMIT IP cores
+ * Designware High-Definition Multimedia Interface (HDMI) driver
*
* Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
*/
-
-#include <linux/component.h>
+#include <linux/module.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/hdmi.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/of_device.h>
+#include <drm/drm_of.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder_slave.h>
-#include <video/imx-ipu-v3.h>
+#include <drm/bridge/dw_hdmi.h>
-#include "imx-hdmi.h"
-#include "imx-drm.h"
+#include "dw_hdmi.h"
#define HDMI_EDID_LEN 512
@@ -54,11 +49,6 @@ enum hdmi_datamap {
YCbCr422_12B = 0x12,
};
-enum imx_hdmi_devtype {
- IMX6Q_HDMI,
- IMX6DL_HDMI,
-};
-
static const u16 csc_coeff_default[3][4] = {
{ 0x2000, 0x0000, 0x0000, 0x0000 },
{ 0x0000, 0x2000, 0x0000, 0x0000 },
@@ -111,16 +101,19 @@ struct hdmi_data_info {
struct hdmi_vmode video_mode;
};
-struct imx_hdmi {
+struct dw_hdmi {
struct drm_connector connector;
- struct drm_encoder encoder;
+ struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
- enum imx_hdmi_devtype dev_type;
+ enum dw_hdmi_devtype dev_type;
struct device *dev;
struct clk *isfr_clk;
struct clk *iahb_clk;
struct hdmi_data_info hdmi_data;
+ const struct dw_hdmi_plat_data *plat_data;
+
int vic;
u8 edid[HDMI_EDID_LEN];
@@ -135,26 +128,42 @@ struct imx_hdmi {
unsigned int sample_rate;
int ratio;
+
+ void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
+ u8 (*read)(struct dw_hdmi *hdmi, int offset);
};
-static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
+static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset)
{
- regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
- IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
- ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
+ writel(val, hdmi->regs + (offset << 2));
}
-static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
+static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset)
+{
+ return readl(hdmi->regs + (offset << 2));
+}
+
+static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
{
writeb(val, hdmi->regs + offset);
}
-static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
+static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset)
{
return readb(hdmi->regs + offset);
}
-static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
+static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
+{
+ hdmi->write(hdmi, val, offset);
+}
+
+static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
+{
+ return hdmi->read(hdmi, offset);
+}
+
+static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
{
u8 val = hdmi_readb(hdmi, reg) & ~mask;
@@ -162,13 +171,13 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
hdmi_writeb(hdmi, val, reg);
}
-static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
- u8 shift, u8 mask)
+static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
+ u8 shift, u8 mask)
{
hdmi_modb(hdmi, data << shift, mask, reg);
}
-static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
+static void hdmi_set_clock_regenerator_n(struct dw_hdmi *hdmi,
unsigned int value)
{
hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
@@ -179,7 +188,7 @@ static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
}
-static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
+static void hdmi_regenerate_cts(struct dw_hdmi *hdmi, unsigned int cts)
{
/* Must be set/cleared first */
hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
@@ -326,8 +335,8 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
return (cts * ratio) / 100;
}
-static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
- unsigned long pixel_clk)
+static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
+ unsigned long pixel_clk)
{
unsigned int clk_n, clk_cts;
@@ -338,7 +347,7 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
if (!clk_cts) {
dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
- __func__, pixel_clk);
+ __func__, pixel_clk);
return;
}
@@ -350,12 +359,12 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
hdmi_regenerate_cts(hdmi, clk_cts);
}
-static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
+static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
{
hdmi_set_clk_regenerator(hdmi, 74250000);
}
-static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
+static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
{
hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock);
}
@@ -367,7 +376,7 @@ static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
* pin{31~24} <==> G[7:0]
* pin{15~8} <==> B[7:0]
*/
-static void hdmi_video_sample(struct imx_hdmi *hdmi)
+static void hdmi_video_sample(struct dw_hdmi *hdmi)
{
int color_format = 0;
u8 val;
@@ -423,12 +432,12 @@ static void hdmi_video_sample(struct imx_hdmi *hdmi)
hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
}
-static int is_color_space_conversion(struct imx_hdmi *hdmi)
+static int is_color_space_conversion(struct dw_hdmi *hdmi)
{
return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
}
-static int is_color_space_decimation(struct imx_hdmi *hdmi)
+static int is_color_space_decimation(struct dw_hdmi *hdmi)
{
if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
return 0;
@@ -438,7 +447,7 @@ static int is_color_space_decimation(struct imx_hdmi *hdmi)
return 0;
}
-static int is_color_space_interpolation(struct imx_hdmi *hdmi)
+static int is_color_space_interpolation(struct dw_hdmi *hdmi)
{
if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
return 0;
@@ -448,7 +457,7 @@ static int is_color_space_interpolation(struct imx_hdmi *hdmi)
return 0;
}
-static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
+static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
{
const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
unsigned i;
@@ -477,13 +486,11 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
u16 coeff_b = (*csc_coeff)[1][i];
u16 coeff_c = (*csc_coeff)[2][i];
- hdmi_writeb(hdmi, coeff_a & 0xff,
- HDMI_CSC_COEF_A1_LSB + i * 2);
+ hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2);
hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
- hdmi_writeb(hdmi, coeff_c & 0xff,
- HDMI_CSC_COEF_C1_LSB + i * 2);
+ hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2);
hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
}
@@ -491,7 +498,7 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
HDMI_CSC_SCALE);
}
-static void hdmi_video_csc(struct imx_hdmi *hdmi)
+static void hdmi_video_csc(struct dw_hdmi *hdmi)
{
int color_depth = 0;
int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
@@ -519,7 +526,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
HDMI_CSC_SCALE);
- imx_hdmi_update_csc_coeffs(hdmi);
+ dw_hdmi_update_csc_coeffs(hdmi);
}
/*
@@ -527,7 +534,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
* for example, if input is YCC422 mode or repeater is used,
* data should be repacked this module can be bypassed.
*/
-static void hdmi_video_packetize(struct imx_hdmi *hdmi)
+static void hdmi_video_packetize(struct dw_hdmi *hdmi)
{
unsigned int color_depth = 0;
unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
@@ -535,21 +542,22 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
u8 val, vp_conf;
- if (hdmi_data->enc_out_format == RGB
- || hdmi_data->enc_out_format == YCBCR444) {
- if (!hdmi_data->enc_color_depth)
+ if (hdmi_data->enc_out_format == RGB ||
+ hdmi_data->enc_out_format == YCBCR444) {
+ if (!hdmi_data->enc_color_depth) {
output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
- else if (hdmi_data->enc_color_depth == 8) {
+ } else if (hdmi_data->enc_color_depth == 8) {
color_depth = 4;
output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
- } else if (hdmi_data->enc_color_depth == 10)
+ } else if (hdmi_data->enc_color_depth == 10) {
color_depth = 5;
- else if (hdmi_data->enc_color_depth == 12)
+ } else if (hdmi_data->enc_color_depth == 12) {
color_depth = 6;
- else if (hdmi_data->enc_color_depth == 16)
+ } else if (hdmi_data->enc_color_depth == 16) {
color_depth = 7;
- else
+ } else {
return;
+ }
} else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
if (!hdmi_data->enc_color_depth ||
hdmi_data->enc_color_depth == 8)
@@ -561,8 +569,9 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
else
return;
output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
- } else
+ } else {
return;
+ }
/* set the packetizer registers */
val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
@@ -622,182 +631,132 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
HDMI_VP_CONF);
}
-static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
}
-static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
}
-static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
}
-static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
}
-static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
}
-static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
+static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
{
- while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
+ u32 val;
+
+ while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
if (msec-- == 0)
return false;
udelay(1000);
}
+ hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
+
return true;
}
-static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
- unsigned char addr)
+static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
+ unsigned char addr)
{
hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
hdmi_writeb(hdmi, (unsigned char)(data >> 8),
- HDMI_PHY_I2CM_DATAO_1_ADDR);
+ HDMI_PHY_I2CM_DATAO_1_ADDR);
hdmi_writeb(hdmi, (unsigned char)(data >> 0),
- HDMI_PHY_I2CM_DATAO_0_ADDR);
+ HDMI_PHY_I2CM_DATAO_0_ADDR);
hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
- HDMI_PHY_I2CM_OPERATION_ADDR);
+ HDMI_PHY_I2CM_OPERATION_ADDR);
hdmi_phy_wait_i2c_done(hdmi, 1000);
}
-static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
- unsigned char addr)
+static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
+ unsigned char addr)
{
__hdmi_phy_i2c_write(hdmi, data, addr);
return 0;
}
-static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_power(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_PDZ_OFFSET,
HDMI_PHY_CONF0_PDZ_MASK);
}
-static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_ENTMDS_OFFSET,
HDMI_PHY_CONF0_ENTMDS_MASK);
}
-static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable)
+{
+ hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+ HDMI_PHY_CONF0_SPARECTRL_OFFSET,
+ HDMI_PHY_CONF0_SPARECTRL_MASK);
+}
+
+static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
}
-static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
}
-static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
HDMI_PHY_CONF0_SELDATAENPOL_MASK);
}
-static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_SELDIPIF_OFFSET,
HDMI_PHY_CONF0_SELDIPIF_MASK);
}
-enum {
- RES_8,
- RES_10,
- RES_12,
- RES_MAX,
-};
-
-struct mpll_config {
- unsigned long mpixelclock;
- struct {
- u16 cpce;
- u16 gmp;
- } res[RES_MAX];
-};
-
-static const struct mpll_config mpll_config[] = {
- {
- 45250000, {
- { 0x01e0, 0x0000 },
- { 0x21e1, 0x0000 },
- { 0x41e2, 0x0000 }
- },
- }, {
- 92500000, {
- { 0x0140, 0x0005 },
- { 0x2141, 0x0005 },
- { 0x4142, 0x0005 },
- },
- }, {
- 148500000, {
- { 0x00a0, 0x000a },
- { 0x20a1, 0x000a },
- { 0x40a2, 0x000a },
- },
- }, {
- ~0UL, {
- { 0x00a0, 0x000a },
- { 0x2001, 0x000f },
- { 0x4002, 0x000f },
- },
- }
-};
-
-struct curr_ctrl {
- unsigned long mpixelclock;
- u16 curr[RES_MAX];
-};
-
-static const struct curr_ctrl curr_ctrl[] = {
- /* pixelclk bpp8 bpp10 bpp12 */
- {
- 54000000, { 0x091c, 0x091c, 0x06dc },
- }, {
- 58400000, { 0x091c, 0x06dc, 0x06dc },
- }, {
- 72000000, { 0x06dc, 0x06dc, 0x091c },
- }, {
- 74250000, { 0x06dc, 0x0b5c, 0x091c },
- }, {
- 118800000, { 0x091c, 0x091c, 0x06dc },
- }, {
- 216000000, { 0x06dc, 0x0b5c, 0x091c },
- }
-};
-
-static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
+static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
unsigned char res, int cscon)
{
unsigned res_idx, i;
u8 val, msec;
+ const struct dw_hdmi_mpll_config *mpll_config =
+ hdmi->plat_data->mpll_cfg;
+ const struct dw_hdmi_curr_ctrl *curr_ctrl = hdmi->plat_data->cur_ctr;
+ const struct dw_hdmi_sym_term *sym_term = hdmi->plat_data->sym_term;
if (prep)
return -EINVAL;
@@ -805,13 +764,13 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
switch (res) {
case 0: /* color resolution 0 is 8 bit colour depth */
case 8:
- res_idx = RES_8;
+ res_idx = DW_HDMI_RES_8;
break;
case 10:
- res_idx = RES_10;
+ res_idx = DW_HDMI_RES_10;
break;
case 12:
- res_idx = RES_12;
+ res_idx = DW_HDMI_RES_12;
break;
default:
return -EINVAL;
@@ -826,10 +785,10 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
/* gen2 tx power off */
- imx_hdmi_phy_gen2_txpwron(hdmi, 0);
+ dw_hdmi_phy_gen2_txpwron(hdmi, 0);
/* gen2 pddq */
- imx_hdmi_phy_gen2_pddq(hdmi, 1);
+ dw_hdmi_phy_gen2_pddq(hdmi, 1);
/* PHY reset */
hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
@@ -839,11 +798,11 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
hdmi_phy_test_clear(hdmi, 1);
hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
- HDMI_PHY_I2CM_SLAVE_ADDR);
+ HDMI_PHY_I2CM_SLAVE_ADDR);
hdmi_phy_test_clear(hdmi, 0);
/* PLL/MPLL Cfg - always match on final entry */
- for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
+ for (i = 0; mpll_config[i].mpixelclock != (~0UL); i++)
if (hdmi->hdmi_data.video_mode.mpixelclock <=
mpll_config[i].mpixelclock)
break;
@@ -851,15 +810,14 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
- for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
+ for (i = 0; curr_ctrl[i].mpixelclock != (~0UL); i++)
if (hdmi->hdmi_data.video_mode.mpixelclock <=
curr_ctrl[i].mpixelclock)
break;
- if (i >= ARRAY_SIZE(curr_ctrl)) {
- dev_err(hdmi->dev,
- "Pixel clock %d - unsupported by HDMI\n",
- hdmi->hdmi_data.video_mode.mpixelclock);
+ if (curr_ctrl[i].mpixelclock == (~0UL)) {
+ dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n",
+ hdmi->hdmi_data.video_mode.mpixelclock);
return -EINVAL;
}
@@ -868,24 +826,34 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
+
+ for (i = 0; sym_term[i].mpixelclock != (~0UL); i++)
+ if (hdmi->hdmi_data.video_mode.mpixelclock <=
+ sym_term[i].mpixelclock)
+ break;
+
/* RESISTANCE TERM 133Ohm Cfg */
- hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
+ hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19); /* TXTERM */
/* PREEMP Cgf 0.00 */
- hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */
+ hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09); /* CKSYMTXCTRL */
+
/* TX/CK LVL 10 */
hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */
/* REMOVE CLK TERM */
hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
- imx_hdmi_phy_enable_power(hdmi, 1);
+ dw_hdmi_phy_enable_power(hdmi, 1);
/* toggle TMDS enable */
- imx_hdmi_phy_enable_tmds(hdmi, 0);
- imx_hdmi_phy_enable_tmds(hdmi, 1);
+ dw_hdmi_phy_enable_tmds(hdmi, 0);
+ dw_hdmi_phy_enable_tmds(hdmi, 1);
/* gen2 tx power on */
- imx_hdmi_phy_gen2_txpwron(hdmi, 1);
- imx_hdmi_phy_gen2_pddq(hdmi, 0);
+ dw_hdmi_phy_gen2_txpwron(hdmi, 1);
+ dw_hdmi_phy_gen2_pddq(hdmi, 0);
+
+ if (hdmi->dev_type == RK3288_HDMI)
+ dw_hdmi_phy_enable_spare(hdmi, 1);
/*Wait for PHY PLL lock */
msec = 5;
@@ -906,7 +874,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
return 0;
}
-static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
{
int i, ret;
bool cscon = false;
@@ -917,10 +885,10 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
/* HDMI Phy spec says to do the phy initialization sequence twice */
for (i = 0; i < 2; i++) {
- imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
- imx_hdmi_phy_sel_interface_control(hdmi, 0);
- imx_hdmi_phy_enable_tmds(hdmi, 0);
- imx_hdmi_phy_enable_power(hdmi, 0);
+ dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
+ dw_hdmi_phy_sel_interface_control(hdmi, 0);
+ dw_hdmi_phy_enable_tmds(hdmi, 0);
+ dw_hdmi_phy_enable_power(hdmi, 0);
/* Enable CSC */
ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
@@ -932,7 +900,7 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
return 0;
}
-static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
+static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
{
u8 de;
@@ -951,7 +919,7 @@ static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
}
-static void hdmi_config_AVI(struct imx_hdmi *hdmi)
+static void hdmi_config_AVI(struct dw_hdmi *hdmi)
{
u8 val, pix_fmt, under_scan;
u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
@@ -1045,7 +1013,7 @@ static void hdmi_config_AVI(struct imx_hdmi *hdmi)
hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
}
-static void hdmi_av_composer(struct imx_hdmi *hdmi,
+static void hdmi_av_composer(struct dw_hdmi *hdmi,
const struct drm_display_mode *mode)
{
u8 inv_val;
@@ -1129,19 +1097,19 @@ static void hdmi_av_composer(struct imx_hdmi *hdmi,
hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
}
-static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
{
if (!hdmi->phy_enabled)
return;
- imx_hdmi_phy_enable_tmds(hdmi, 0);
- imx_hdmi_phy_enable_power(hdmi, 0);
+ dw_hdmi_phy_enable_tmds(hdmi, 0);
+ dw_hdmi_phy_enable_power(hdmi, 0);
hdmi->phy_enabled = false;
}
/* HDMI Initialization Step B.4 */
-static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
+static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
{
u8 clkdis;
@@ -1170,13 +1138,13 @@ static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
}
}
-static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
+static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
{
hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
}
/* Workaround to clear the overflow condition */
-static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
+static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
{
int count;
u8 val;
@@ -1194,19 +1162,19 @@ static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
}
-static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
+static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi)
{
hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
}
-static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
+static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
{
hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
HDMI_IH_MUTE_FC_STAT2);
}
-static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
+static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
{
int ret;
@@ -1223,21 +1191,21 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
}
if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
- (hdmi->vic == 21) || (hdmi->vic == 22) ||
- (hdmi->vic == 2) || (hdmi->vic == 3) ||
- (hdmi->vic == 17) || (hdmi->vic == 18))
+ (hdmi->vic == 21) || (hdmi->vic == 22) ||
+ (hdmi->vic == 2) || (hdmi->vic == 3) ||
+ (hdmi->vic == 17) || (hdmi->vic == 18))
hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
else
hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
- (hdmi->vic == 12) || (hdmi->vic == 13) ||
- (hdmi->vic == 14) || (hdmi->vic == 15) ||
- (hdmi->vic == 25) || (hdmi->vic == 26) ||
- (hdmi->vic == 27) || (hdmi->vic == 28) ||
- (hdmi->vic == 29) || (hdmi->vic == 30) ||
- (hdmi->vic == 35) || (hdmi->vic == 36) ||
- (hdmi->vic == 37) || (hdmi->vic == 38))
+ (hdmi->vic == 12) || (hdmi->vic == 13) ||
+ (hdmi->vic == 14) || (hdmi->vic == 15) ||
+ (hdmi->vic == 25) || (hdmi->vic == 26) ||
+ (hdmi->vic == 27) || (hdmi->vic == 28) ||
+ (hdmi->vic == 29) || (hdmi->vic == 30) ||
+ (hdmi->vic == 35) || (hdmi->vic == 36) ||
+ (hdmi->vic == 37) || (hdmi->vic == 38))
hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
else
hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
@@ -1258,17 +1226,17 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
hdmi_av_composer(hdmi, mode);
/* HDMI Initializateion Step B.2 */
- ret = imx_hdmi_phy_init(hdmi);
+ ret = dw_hdmi_phy_init(hdmi);
if (ret)
return ret;
/* HDMI Initialization Step B.3 */
- imx_hdmi_enable_video_path(hdmi);
+ dw_hdmi_enable_video_path(hdmi);
/* not for DVI mode */
- if (hdmi->hdmi_data.video_mode.mdvi)
+ if (hdmi->hdmi_data.video_mode.mdvi) {
dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
- else {
+ } else {
dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
/* HDMI Initialization Step E - Configure audio */
@@ -1284,7 +1252,7 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
hdmi_video_sample(hdmi);
hdmi_tx_hdcp_config(hdmi);
- imx_hdmi_clear_overflow(hdmi);
+ dw_hdmi_clear_overflow(hdmi);
if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
hdmi_enable_overflow_interrupts(hdmi);
@@ -1292,7 +1260,7 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
}
/* Wait until we are registered to enable interrupts */
-static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
+static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi)
{
hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
HDMI_PHY_I2CM_INT_ADDR);
@@ -1310,7 +1278,7 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
return 0;
}
-static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
+static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
{
u8 ih_mute;
@@ -1362,29 +1330,67 @@ static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
}
-static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
+static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
+{
+ dw_hdmi_setup(hdmi, &hdmi->previous_mode);
+}
+
+static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
{
- imx_hdmi_setup(hdmi, &hdmi->previous_mode);
+ dw_hdmi_phy_disable(hdmi);
}
-static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
+static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *orig_mode,
+ struct drm_display_mode *mode)
{
- imx_hdmi_phy_disable(hdmi);
+ struct dw_hdmi *hdmi = bridge->driver_private;
+
+ dw_hdmi_setup(hdmi, mode);
+
+ /* Store the display mode for plugin/DKMS poweron events */
+ memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
}
-static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
- *connector, bool force)
+static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
- struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+ return true;
+}
+
+static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
+{
+ struct dw_hdmi *hdmi = bridge->driver_private;
+
+ dw_hdmi_poweroff(hdmi);
+}
+
+static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
+{
+ struct dw_hdmi *hdmi = bridge->driver_private;
+
+ dw_hdmi_poweron(hdmi);
+}
+
+static void dw_hdmi_bridge_nop(struct drm_bridge *bridge)
+{
+ /* do nothing */
+}
+
+static enum drm_connector_status
+dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
connector);
return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
connector_status_connected : connector_status_disconnected;
}
-static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
+static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
{
- struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
connector);
struct edid *edid;
int ret;
@@ -1407,94 +1413,60 @@ static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
return 0;
}
-static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
- *connector)
-{
- struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
- connector);
-
- return &hdmi->encoder;
-}
-
-static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
- imx_hdmi_setup(hdmi, mode);
-
- /* Store the display mode for plugin/DKMS poweron events */
- memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
-}
-
-static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status
+dw_hdmi_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
{
- return true;
-}
+ struct dw_hdmi *hdmi = container_of(connector,
+ struct dw_hdmi, connector);
+ enum drm_mode_status mode_status = MODE_OK;
-static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
-{
-}
-
-static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
+ if (hdmi->plat_data->mode_valid)
+ mode_status = hdmi->plat_data->mode_valid(connector, mode);
- if (mode)
- imx_hdmi_poweroff(hdmi);
- else
- imx_hdmi_poweron(hdmi);
+ return mode_status;
}
-static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
+static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector
+ *connector)
{
- struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
+ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+ connector);
- imx_hdmi_poweroff(hdmi);
- imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
+ return hdmi->encoder;
}
-static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_connector_destroy(struct drm_connector *connector)
{
- struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
- int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
-
- imx_hdmi_set_ipu_di_mux(hdmi, mux);
-
- imx_hdmi_poweron(hdmi);
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
}
-static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
- .destroy = imx_drm_encoder_destroy,
-};
-
-static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
- .dpms = imx_hdmi_encoder_dpms,
- .prepare = imx_hdmi_encoder_prepare,
- .commit = imx_hdmi_encoder_commit,
- .mode_set = imx_hdmi_encoder_mode_set,
- .mode_fixup = imx_hdmi_encoder_mode_fixup,
- .disable = imx_hdmi_encoder_disable,
-};
-
-static struct drm_connector_funcs imx_hdmi_connector_funcs = {
+static struct drm_connector_funcs dw_hdmi_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
- .detect = imx_hdmi_connector_detect,
- .destroy = imx_drm_connector_destroy,
+ .detect = dw_hdmi_connector_detect,
+ .destroy = dw_hdmi_connector_destroy,
+};
+
+static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
+ .get_modes = dw_hdmi_connector_get_modes,
+ .mode_valid = dw_hdmi_connector_mode_valid,
+ .best_encoder = dw_hdmi_connector_best_encoder,
};
-static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
- .get_modes = imx_hdmi_connector_get_modes,
- .best_encoder = imx_hdmi_connector_best_encoder,
+struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
+ .enable = dw_hdmi_bridge_enable,
+ .disable = dw_hdmi_bridge_disable,
+ .pre_enable = dw_hdmi_bridge_nop,
+ .post_disable = dw_hdmi_bridge_nop,
+ .mode_set = dw_hdmi_bridge_mode_set,
+ .mode_fixup = dw_hdmi_bridge_mode_fixup,
};
-static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
+static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
{
- struct imx_hdmi *hdmi = dev_id;
+ struct dw_hdmi *hdmi = dev_id;
u8 intr_stat;
intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
@@ -1504,9 +1476,9 @@ static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
}
-static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
+static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
{
- struct imx_hdmi *hdmi = dev_id;
+ struct dw_hdmi *hdmi = dev_id;
u8 intr_stat;
u8 phy_int_pol;
@@ -1520,14 +1492,14 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
- imx_hdmi_poweron(hdmi);
+ dw_hdmi_poweron(hdmi);
} else {
dev_dbg(hdmi->dev, "EVENT=plugout\n");
hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
- HDMI_PHY_POL0);
+ HDMI_PHY_POL0);
- imx_hdmi_poweroff(hdmi);
+ dw_hdmi_poweroff(hdmi);
}
drm_helper_hpd_irq_event(hdmi->connector.dev);
}
@@ -1538,147 +1510,140 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
+static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
{
+ struct drm_encoder *encoder = hdmi->encoder;
+ struct drm_bridge *bridge;
int ret;
- ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
- hdmi->dev->of_node);
- if (ret)
- return ret;
+ bridge = devm_kzalloc(drm->dev, sizeof(*bridge), GFP_KERNEL);
+ if (!bridge) {
+ DRM_ERROR("Failed to allocate drm bridge\n");
+ return -ENOMEM;
+ }
- hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
+ hdmi->bridge = bridge;
+ bridge->driver_private = hdmi;
+ bridge->funcs = &dw_hdmi_bridge_funcs;
+ ret = drm_bridge_attach(drm, bridge);
+ if (ret) {
+ DRM_ERROR("Failed to initialize bridge with drm\n");
+ return -EINVAL;
+ }
- drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
- drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
- DRM_MODE_ENCODER_TMDS);
+ encoder->bridge = bridge;
+ hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_helper_add(&hdmi->connector,
- &imx_hdmi_connector_helper_funcs);
- drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
+ &dw_hdmi_connector_helper_funcs);
+ drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);
- hdmi->connector.encoder = &hdmi->encoder;
+ hdmi->connector.encoder = encoder;
- drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
+ drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
return 0;
}
-static struct platform_device_id imx_hdmi_devtype[] = {
- {
- .name = "imx6q-hdmi",
- .driver_data = IMX6Q_HDMI,
- }, {
- .name = "imx6dl-hdmi",
- .driver_data = IMX6DL_HDMI,
- }, { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
-
-static const struct of_device_id imx_hdmi_dt_ids[] = {
-{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
-{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
-{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
-
-static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
+int dw_hdmi_bind(struct device *dev, struct device *master,
+ void *data, struct drm_encoder *encoder,
+ struct resource *iores, int irq,
+ const struct dw_hdmi_plat_data *plat_data)
{
- struct platform_device *pdev = to_platform_device(dev);
- const struct of_device_id *of_id =
- of_match_device(imx_hdmi_dt_ids, dev);
struct drm_device *drm = data;
struct device_node *np = dev->of_node;
struct device_node *ddc_node;
- struct imx_hdmi *hdmi;
- struct resource *iores;
- int ret, irq;
+ struct dw_hdmi *hdmi;
+ int ret;
+ u32 val = 1;
hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
+ hdmi->plat_data = plat_data;
hdmi->dev = dev;
+ hdmi->dev_type = plat_data->dev_type;
hdmi->sample_rate = 48000;
hdmi->ratio = 100;
+ hdmi->encoder = encoder;
- if (of_id) {
- const struct platform_device_id *device_id = of_id->data;
+ of_property_read_u32(np, "reg-io-width", &val);
- hdmi->dev_type = device_id->driver_data;
+ switch (val) {
+ case 4:
+ hdmi->write = dw_hdmi_writel;
+ hdmi->read = dw_hdmi_readl;
+ break;
+ case 1:
+ hdmi->write = dw_hdmi_writeb;
+ hdmi->read = dw_hdmi_readb;
+ break;
+ default:
+ dev_err(dev, "reg-io-width must be 1 or 4\n");
+ return -EINVAL;
}
ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
if (ddc_node) {
hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
- if (!hdmi->ddc)
+ of_node_put(ddc_node);
+ if (!hdmi->ddc) {
dev_dbg(hdmi->dev, "failed to read ddc node\n");
+ return -EPROBE_DEFER;
+ }
- of_node_put(ddc_node);
} else {
dev_dbg(hdmi->dev, "no ddc property found\n");
}
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
- imx_hdmi_irq, IRQF_SHARED,
- dev_name(dev), hdmi);
- if (ret)
- return ret;
-
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hdmi->regs = devm_ioremap_resource(dev, iores);
if (IS_ERR(hdmi->regs))
return PTR_ERR(hdmi->regs);
- hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
- if (IS_ERR(hdmi->regmap))
- return PTR_ERR(hdmi->regmap);
-
hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
if (IS_ERR(hdmi->isfr_clk)) {
ret = PTR_ERR(hdmi->isfr_clk);
- dev_err(hdmi->dev,
- "Unable to get HDMI isfr clk: %d\n", ret);
+ dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret);
return ret;
}
ret = clk_prepare_enable(hdmi->isfr_clk);
if (ret) {
- dev_err(hdmi->dev,
- "Cannot enable HDMI isfr clock: %d\n", ret);
+ dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret);
return ret;
}
hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
if (IS_ERR(hdmi->iahb_clk)) {
ret = PTR_ERR(hdmi->iahb_clk);
- dev_err(hdmi->dev,
- "Unable to get HDMI iahb clk: %d\n", ret);
+ dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret);
goto err_isfr;
}
ret = clk_prepare_enable(hdmi->iahb_clk);
if (ret) {
- dev_err(hdmi->dev,
- "Cannot enable HDMI iahb clock: %d\n", ret);
+ dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret);
goto err_isfr;
}
/* Product and revision IDs */
dev_info(dev,
- "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
- hdmi_readb(hdmi, HDMI_DESIGN_ID),
- hdmi_readb(hdmi, HDMI_REVISION_ID),
- hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
- hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
+ "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
+ hdmi_readb(hdmi, HDMI_DESIGN_ID),
+ hdmi_readb(hdmi, HDMI_REVISION_ID),
+ hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
+ hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
initialize_hdmi_ih_mutes(hdmi);
+ ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
+ dw_hdmi_irq, IRQF_SHARED,
+ dev_name(dev), hdmi);
+ if (ret)
+ goto err_iahb;
+
/*
* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
* N and cts values before enabling phy
@@ -1694,11 +1659,11 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
/* Clear Hotplug interrupts */
hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
- ret = imx_hdmi_fb_registered(hdmi);
+ ret = dw_hdmi_fb_registered(hdmi);
if (ret)
goto err_iahb;
- ret = imx_hdmi_register(drm, hdmi);
+ ret = dw_hdmi_register(drm, hdmi);
if (ret)
goto err_iahb;
@@ -1716,51 +1681,27 @@ err_isfr:
return ret;
}
+EXPORT_SYMBOL_GPL(dw_hdmi_bind);
-static void imx_hdmi_unbind(struct device *dev, struct device *master,
- void *data)
+void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
{
- struct imx_hdmi *hdmi = dev_get_drvdata(dev);
+ struct dw_hdmi *hdmi = dev_get_drvdata(dev);
/* Disable all interrupts */
hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
hdmi->connector.funcs->destroy(&hdmi->connector);
- hdmi->encoder.funcs->destroy(&hdmi->encoder);
+ hdmi->encoder->funcs->destroy(hdmi->encoder);
clk_disable_unprepare(hdmi->iahb_clk);
clk_disable_unprepare(hdmi->isfr_clk);
i2c_put_adapter(hdmi->ddc);
}
-
-static const struct component_ops hdmi_ops = {
- .bind = imx_hdmi_bind,
- .unbind = imx_hdmi_unbind,
-};
-
-static int imx_hdmi_platform_probe(struct platform_device *pdev)
-{
- return component_add(&pdev->dev, &hdmi_ops);
-}
-
-static int imx_hdmi_platform_remove(struct platform_device *pdev)
-{
- component_del(&pdev->dev, &hdmi_ops);
- return 0;
-}
-
-static struct platform_driver imx_hdmi_driver = {
- .probe = imx_hdmi_platform_probe,
- .remove = imx_hdmi_platform_remove,
- .driver = {
- .name = "imx-hdmi",
- .of_match_table = imx_hdmi_dt_ids,
- },
-};
-
-module_platform_driver(imx_hdmi_driver);
+EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_DESCRIPTION("DW HDMI transmitter driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-hdmi");
+MODULE_ALIAS("platform:dw-hdmi");
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index 39b677689db6..175dbc89a824 100644
--- a/drivers/gpu/drm/imx/imx-hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -837,7 +837,8 @@ enum {
HDMI_PHY_CONF0_PDZ_OFFSET = 7,
HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
- HDMI_PHY_CONF0_SPARECTRL = 0x20,
+ HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
+ HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
@@ -1029,4 +1030,5 @@ enum {
HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
};
+
#endif /* __IMX_HDMI_H__ */
diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
index d466696ed5e8..826833e396f0 100644
--- a/drivers/gpu/drm/bridge/ptn3460.c
+++ b/drivers/gpu/drm/bridge/ptn3460.c
@@ -13,20 +13,23 @@
* GNU General Public License for more details.
*/
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
+#include <linux/of_graph.h>
-#include "drmP.h"
-#include "drm_edid.h"
-#include "drm_crtc.h"
-#include "drm_crtc_helper.h"
+#include <drm/drm_panel.h>
#include "bridge/ptn3460.h"
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+#include "drm_edid.h"
+#include "drmP.h"
+
#define PTN3460_EDID_ADDR 0x0
#define PTN3460_EDID_EMULATION_ADDR 0x84
#define PTN3460_EDID_ENABLE_EMULATION 0
@@ -36,15 +39,27 @@
struct ptn3460_bridge {
struct drm_connector connector;
struct i2c_client *client;
- struct drm_encoder *encoder;
- struct drm_bridge *bridge;
+ struct drm_bridge bridge;
struct edid *edid;
- int gpio_pd_n;
- int gpio_rst_n;
+ struct drm_panel *panel;
+ struct gpio_desc *gpio_pd_n;
+ struct gpio_desc *gpio_rst_n;
u32 edid_emulation;
bool enabled;
};
+static inline struct ptn3460_bridge *
+ bridge_to_ptn3460(struct drm_bridge *bridge)
+{
+ return container_of(bridge, struct ptn3460_bridge, bridge);
+}
+
+static inline struct ptn3460_bridge *
+ connector_to_ptn3460(struct drm_connector *connector)
+{
+ return container_of(connector, struct ptn3460_bridge, connector);
+}
+
static int ptn3460_read_bytes(struct ptn3460_bridge *ptn_bridge, char addr,
u8 *buf, int len)
{
@@ -92,7 +107,7 @@ static int ptn3460_select_edid(struct ptn3460_bridge *ptn_bridge)
ret = ptn3460_write_byte(ptn_bridge, PTN3460_EDID_SRAM_LOAD_ADDR,
ptn_bridge->edid_emulation);
if (ret) {
- DRM_ERROR("Failed to transfer edid to sram, ret=%d\n", ret);
+ DRM_ERROR("Failed to transfer EDID to sram, ret=%d\n", ret);
return ret;
}
@@ -102,7 +117,7 @@ static int ptn3460_select_edid(struct ptn3460_bridge *ptn_bridge)
ret = ptn3460_write_byte(ptn_bridge, PTN3460_EDID_EMULATION_ADDR, val);
if (ret) {
- DRM_ERROR("Failed to write edid value, ret=%d\n", ret);
+ DRM_ERROR("Failed to write EDID value, ret=%d\n", ret);
return ret;
}
@@ -111,19 +126,21 @@ static int ptn3460_select_edid(struct ptn3460_bridge *ptn_bridge)
static void ptn3460_pre_enable(struct drm_bridge *bridge)
{
- struct ptn3460_bridge *ptn_bridge = bridge->driver_private;
+ struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
int ret;
if (ptn_bridge->enabled)
return;
- if (gpio_is_valid(ptn_bridge->gpio_pd_n))
- gpio_set_value(ptn_bridge->gpio_pd_n, 1);
+ gpiod_set_value(ptn_bridge->gpio_pd_n, 1);
+
+ gpiod_set_value(ptn_bridge->gpio_rst_n, 0);
+ usleep_range(10, 20);
+ gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
- if (gpio_is_valid(ptn_bridge->gpio_rst_n)) {
- gpio_set_value(ptn_bridge->gpio_rst_n, 0);
- udelay(10);
- gpio_set_value(ptn_bridge->gpio_rst_n, 1);
+ if (drm_panel_prepare(ptn_bridge->panel)) {
+ DRM_ERROR("failed to prepare panel\n");
+ return;
}
/*
@@ -135,73 +152,67 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)
ret = ptn3460_select_edid(ptn_bridge);
if (ret)
- DRM_ERROR("Select edid failed ret=%d\n", ret);
+ DRM_ERROR("Select EDID failed ret=%d\n", ret);
ptn_bridge->enabled = true;
}
static void ptn3460_enable(struct drm_bridge *bridge)
{
+ struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
+
+ if (drm_panel_enable(ptn_bridge->panel)) {
+ DRM_ERROR("failed to enable panel\n");
+ return;
+ }
}
static void ptn3460_disable(struct drm_bridge *bridge)
{
- struct ptn3460_bridge *ptn_bridge = bridge->driver_private;
+ struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
if (!ptn_bridge->enabled)
return;
ptn_bridge->enabled = false;
- if (gpio_is_valid(ptn_bridge->gpio_rst_n))
- gpio_set_value(ptn_bridge->gpio_rst_n, 1);
+ if (drm_panel_disable(ptn_bridge->panel)) {
+ DRM_ERROR("failed to disable panel\n");
+ return;
+ }
- if (gpio_is_valid(ptn_bridge->gpio_pd_n))
- gpio_set_value(ptn_bridge->gpio_pd_n, 0);
+ gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
+ gpiod_set_value(ptn_bridge->gpio_pd_n, 0);
}
static void ptn3460_post_disable(struct drm_bridge *bridge)
{
-}
+ struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
-void ptn3460_bridge_destroy(struct drm_bridge *bridge)
-{
- struct ptn3460_bridge *ptn_bridge = bridge->driver_private;
-
- drm_bridge_cleanup(bridge);
- if (gpio_is_valid(ptn_bridge->gpio_pd_n))
- gpio_free(ptn_bridge->gpio_pd_n);
- if (gpio_is_valid(ptn_bridge->gpio_rst_n))
- gpio_free(ptn_bridge->gpio_rst_n);
- /* Nothing else to free, we've got devm allocated memory */
+ if (drm_panel_unprepare(ptn_bridge->panel)) {
+ DRM_ERROR("failed to unprepare panel\n");
+ return;
+ }
}
-struct drm_bridge_funcs ptn3460_bridge_funcs = {
- .pre_enable = ptn3460_pre_enable,
- .enable = ptn3460_enable,
- .disable = ptn3460_disable,
- .post_disable = ptn3460_post_disable,
- .destroy = ptn3460_bridge_destroy,
-};
-
-int ptn3460_get_modes(struct drm_connector *connector)
+static int ptn3460_get_modes(struct drm_connector *connector)
{
struct ptn3460_bridge *ptn_bridge;
u8 *edid;
- int ret, num_modes;
+ int ret, num_modes = 0;
bool power_off;
- ptn_bridge = container_of(connector, struct ptn3460_bridge, connector);
+ ptn_bridge = connector_to_ptn3460(connector);
if (ptn_bridge->edid)
return drm_add_edid_modes(connector, ptn_bridge->edid);
power_off = !ptn_bridge->enabled;
- ptn3460_pre_enable(ptn_bridge->bridge);
+ ptn3460_pre_enable(&ptn_bridge->bridge);
edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
if (!edid) {
- DRM_ERROR("Failed to allocate edid\n");
+ DRM_ERROR("Failed to allocate EDID\n");
return 0;
}
@@ -209,7 +220,6 @@ int ptn3460_get_modes(struct drm_connector *connector)
EDID_LENGTH);
if (ret) {
kfree(edid);
- num_modes = 0;
goto out;
}
@@ -220,124 +230,188 @@ int ptn3460_get_modes(struct drm_connector *connector)
out:
if (power_off)
- ptn3460_disable(ptn_bridge->bridge);
+ ptn3460_disable(&ptn_bridge->bridge);
return num_modes;
}
-struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
+static struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
{
- struct ptn3460_bridge *ptn_bridge;
-
- ptn_bridge = container_of(connector, struct ptn3460_bridge, connector);
+ struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector);
- return ptn_bridge->encoder;
+ return ptn_bridge->bridge.encoder;
}
-struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
+static struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
.get_modes = ptn3460_get_modes,
.best_encoder = ptn3460_best_encoder,
};
-enum drm_connector_status ptn3460_detect(struct drm_connector *connector,
+static enum drm_connector_status ptn3460_detect(struct drm_connector *connector,
bool force)
{
return connector_status_connected;
}
-void ptn3460_connector_destroy(struct drm_connector *connector)
+static void ptn3460_connector_destroy(struct drm_connector *connector)
{
drm_connector_cleanup(connector);
}
-struct drm_connector_funcs ptn3460_connector_funcs = {
+static struct drm_connector_funcs ptn3460_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = ptn3460_detect,
.destroy = ptn3460_connector_destroy,
};
-int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
- struct i2c_client *client, struct device_node *node)
+int ptn3460_bridge_attach(struct drm_bridge *bridge)
{
+ struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
int ret;
- struct drm_bridge *bridge;
- struct ptn3460_bridge *ptn_bridge;
- bridge = devm_kzalloc(dev->dev, sizeof(*bridge), GFP_KERNEL);
- if (!bridge) {
- DRM_ERROR("Failed to allocate drm bridge\n");
- return -ENOMEM;
+ if (!bridge->encoder) {
+ DRM_ERROR("Parent encoder object not found");
+ return -ENODEV;
+ }
+
+ ptn_bridge->connector.polled = DRM_CONNECTOR_POLL_HPD;
+ ret = drm_connector_init(bridge->dev, &ptn_bridge->connector,
+ &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
+ if (ret) {
+ DRM_ERROR("Failed to initialize connector with drm\n");
+ return ret;
}
+ drm_connector_helper_add(&ptn_bridge->connector,
+ &ptn3460_connector_helper_funcs);
+ drm_connector_register(&ptn_bridge->connector);
+ drm_mode_connector_attach_encoder(&ptn_bridge->connector,
+ bridge->encoder);
- ptn_bridge = devm_kzalloc(dev->dev, sizeof(*ptn_bridge), GFP_KERNEL);
+ if (ptn_bridge->panel)
+ drm_panel_attach(ptn_bridge->panel, &ptn_bridge->connector);
+
+ drm_helper_hpd_irq_event(ptn_bridge->connector.dev);
+
+ return ret;
+}
+
+static struct drm_bridge_funcs ptn3460_bridge_funcs = {
+ .pre_enable = ptn3460_pre_enable,
+ .enable = ptn3460_enable,
+ .disable = ptn3460_disable,
+ .post_disable = ptn3460_post_disable,
+ .attach = ptn3460_bridge_attach,
+};
+
+static int ptn3460_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct ptn3460_bridge *ptn_bridge;
+ struct device_node *endpoint, *panel_node;
+ int ret;
+
+ ptn_bridge = devm_kzalloc(dev, sizeof(*ptn_bridge), GFP_KERNEL);
if (!ptn_bridge) {
- DRM_ERROR("Failed to allocate ptn bridge\n");
return -ENOMEM;
}
- ptn_bridge->client = client;
- ptn_bridge->encoder = encoder;
- ptn_bridge->bridge = bridge;
- ptn_bridge->gpio_pd_n = of_get_named_gpio(node, "powerdown-gpio", 0);
- if (gpio_is_valid(ptn_bridge->gpio_pd_n)) {
- ret = gpio_request_one(ptn_bridge->gpio_pd_n,
- GPIOF_OUT_INIT_HIGH, "PTN3460_PD_N");
- if (ret) {
- DRM_ERROR("Request powerdown-gpio failed (%d)\n", ret);
- return ret;
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (endpoint) {
+ panel_node = of_graph_get_remote_port_parent(endpoint);
+ if (panel_node) {
+ ptn_bridge->panel = of_drm_find_panel(panel_node);
+ of_node_put(panel_node);
+ if (!ptn_bridge->panel)
+ return -EPROBE_DEFER;
}
}
- ptn_bridge->gpio_rst_n = of_get_named_gpio(node, "reset-gpio", 0);
- if (gpio_is_valid(ptn_bridge->gpio_rst_n)) {
- /*
- * Request the reset pin low to avoid the bridge being
- * initialized prematurely
- */
- ret = gpio_request_one(ptn_bridge->gpio_rst_n,
- GPIOF_OUT_INIT_LOW, "PTN3460_RST_N");
- if (ret) {
- DRM_ERROR("Request reset-gpio failed (%d)\n", ret);
- gpio_free(ptn_bridge->gpio_pd_n);
- return ret;
- }
+ ptn_bridge->client = client;
+
+ ptn_bridge->gpio_pd_n = devm_gpiod_get(&client->dev, "powerdown");
+ if (IS_ERR(ptn_bridge->gpio_pd_n)) {
+ ret = PTR_ERR(ptn_bridge->gpio_pd_n);
+ dev_err(dev, "cannot get gpio_pd_n %d\n", ret);
+ return ret;
}
- ret = of_property_read_u32(node, "edid-emulation",
- &ptn_bridge->edid_emulation);
+ ret = gpiod_direction_output(ptn_bridge->gpio_pd_n, 1);
if (ret) {
- DRM_ERROR("Can't read edid emulation value\n");
- goto err;
+ DRM_ERROR("cannot configure gpio_pd_n\n");
+ return ret;
}
- ret = drm_bridge_init(dev, bridge, &ptn3460_bridge_funcs);
+ ptn_bridge->gpio_rst_n = devm_gpiod_get(&client->dev, "reset");
+ if (IS_ERR(ptn_bridge->gpio_rst_n)) {
+ ret = PTR_ERR(ptn_bridge->gpio_rst_n);
+ DRM_ERROR("cannot get gpio_rst_n %d\n", ret);
+ return ret;
+ }
+ /*
+ * Request the reset pin low to avoid the bridge being
+ * initialized prematurely
+ */
+ ret = gpiod_direction_output(ptn_bridge->gpio_rst_n, 0);
if (ret) {
- DRM_ERROR("Failed to initialize bridge with drm\n");
- goto err;
+ DRM_ERROR("cannot configure gpio_rst_n\n");
+ return ret;
}
- bridge->driver_private = ptn_bridge;
- encoder->bridge = bridge;
+ ret = of_property_read_u32(dev->of_node, "edid-emulation",
+ &ptn_bridge->edid_emulation);
+ if (ret) {
+ dev_err(dev, "Can't read EDID emulation value\n");
+ return ret;
+ }
- ret = drm_connector_init(dev, &ptn_bridge->connector,
- &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
+ ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
+ ptn_bridge->bridge.of_node = dev->of_node;
+ ret = drm_bridge_add(&ptn_bridge->bridge);
if (ret) {
- DRM_ERROR("Failed to initialize connector with drm\n");
- goto err;
+ DRM_ERROR("Failed to add bridge\n");
+ return ret;
}
- drm_connector_helper_add(&ptn_bridge->connector,
- &ptn3460_connector_helper_funcs);
- drm_connector_register(&ptn_bridge->connector);
- drm_mode_connector_attach_encoder(&ptn_bridge->connector, encoder);
+
+ i2c_set_clientdata(client, ptn_bridge);
return 0;
+}
-err:
- if (gpio_is_valid(ptn_bridge->gpio_pd_n))
- gpio_free(ptn_bridge->gpio_pd_n);
- if (gpio_is_valid(ptn_bridge->gpio_rst_n))
- gpio_free(ptn_bridge->gpio_rst_n);
- return ret;
+static int ptn3460_remove(struct i2c_client *client)
+{
+ struct ptn3460_bridge *ptn_bridge = i2c_get_clientdata(client);
+
+ drm_bridge_remove(&ptn_bridge->bridge);
+
+ return 0;
}
-EXPORT_SYMBOL(ptn3460_init);
+
+static const struct i2c_device_id ptn3460_i2c_table[] = {
+ {"nxp,ptn3460", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, ptn3460_i2c_table);
+
+static const struct of_device_id ptn3460_match[] = {
+ { .compatible = "nxp,ptn3460" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ptn3460_match);
+
+static struct i2c_driver ptn3460_driver = {
+ .id_table = ptn3460_i2c_table,
+ .probe = ptn3460_probe,
+ .remove = ptn3460_remove,
+ .driver = {
+ .name = "nxp,ptn3460",
+ .owner = THIS_MODULE,
+ .of_match_table = ptn3460_match,
+ },
+};
+module_i2c_driver(ptn3460_driver);
+
+MODULE_AUTHOR("Sean Paul <seanpaul@chromium.org>");
+MODULE_DESCRIPTION("NXP ptn3460 eDP-LVDS converter driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 502a89eb54b5..13ddf1c4bb8e 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -317,17 +317,17 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
cdev->num_crtc, CIRRUSFB_CONN_LIMIT);
- if (ret) {
- kfree(gfbdev);
+ if (ret)
+ return ret;
+
+ ret = drm_fb_helper_single_add_all_connectors(&gfbdev->helper);
+ if (ret)
return ret;
- }
- drm_fb_helper_single_add_all_connectors(&gfbdev->helper);
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(cdev->dev);
- drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
- return 0;
+ return drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
}
void cirrus_fbdev_fini(struct cirrus_device *cdev)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index ff5f034cc405..c2e9c5283136 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -56,6 +56,11 @@ drm_atomic_state_alloc(struct drm_device *dev)
if (!state)
return NULL;
+ /* TODO legacy paths should maybe do a better job about
+ * setting this appropriately?
+ */
+ state->allow_modeset = true;
+
state->num_connector = ACCESS_ONCE(dev->mode_config.num_connector);
state->crtcs = kcalloc(dev->mode_config.num_crtc,
@@ -129,6 +134,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
connector->funcs->atomic_destroy_state(connector,
state->connector_states[i]);
+ state->connector_states[i] = NULL;
}
for (i = 0; i < config->num_crtc; i++) {
@@ -139,6 +145,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
crtc->funcs->atomic_destroy_state(crtc,
state->crtc_states[i]);
+ state->crtc_states[i] = NULL;
}
for (i = 0; i < config->num_total_plane; i++) {
@@ -149,6 +156,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
plane->funcs->atomic_destroy_state(plane,
state->plane_states[i]);
+ state->plane_states[i] = NULL;
}
}
EXPORT_SYMBOL(drm_atomic_state_clear);
@@ -217,6 +225,83 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
EXPORT_SYMBOL(drm_atomic_get_crtc_state);
/**
+ * drm_atomic_crtc_set_property - set property on CRTC
+ * @crtc: the drm CRTC to set a property on
+ * @state: the state object to update with the new property value
+ * @property: the property to set
+ * @val: the new property value
+ *
+ * Use this instead of calling crtc->atomic_set_property directly.
+ * This function handles generic/core properties and calls out to
+ * driver's ->atomic_set_property() for driver properties. To ensure
+ * consistent behavior you must call this function rather than the
+ * driver hook directly.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
+ struct drm_crtc_state *state, struct drm_property *property,
+ uint64_t val)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_mode_config *config = &dev->mode_config;
+
+ /* FIXME: Mode prop is missing, which also controls ->enable. */
+ if (property == config->prop_active) {
+ state->active = val;
+ } else if (crtc->funcs->atomic_set_property)
+ return crtc->funcs->atomic_set_property(crtc, state, property, val);
+ return -EINVAL;
+}
+EXPORT_SYMBOL(drm_atomic_crtc_set_property);
+
+/*
+ * This function handles generic/core properties and calls out to
+ * driver's ->atomic_get_property() for driver properties. To ensure
+ * consistent behavior you must call this function rather than the
+ * driver hook directly.
+ */
+int drm_atomic_crtc_get_property(struct drm_crtc *crtc,
+ const struct drm_crtc_state *state,
+ struct drm_property *property, uint64_t *val)
+{
+ if (crtc->funcs->atomic_get_property)
+ return crtc->funcs->atomic_get_property(crtc, state, property, val);
+ return -EINVAL;
+}
+
+/**
+ * drm_atomic_crtc_check - check crtc state
+ * @crtc: crtc to check
+ * @state: crtc state to check
+ *
+ * Provides core sanity checks for crtc state.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+static int drm_atomic_crtc_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ /* NOTE: we explicitly don't enforce constraints such as primary
+ * layer covering entire screen, since that is something we want
+ * to allow (on hw that supports it). For hw that does not, it
+ * should be checked in driver's crtc->atomic_check() vfunc.
+ *
+ * TODO: Add generic modeset state checks once we support those.
+ */
+
+ if (state->active && !state->enable) {
+ DRM_DEBUG_KMS("[CRTC:%d] active without enabled\n",
+ crtc->base.id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
* drm_atomic_get_plane_state - get plane state
* @state: global atomic state object
* @plane: plane to get state object for
@@ -272,6 +357,185 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
EXPORT_SYMBOL(drm_atomic_get_plane_state);
/**
+ * drm_atomic_plane_set_property - set property on plane
+ * @plane: the drm plane to set a property on
+ * @state: the state object to update with the new property value
+ * @property: the property to set
+ * @val: the new property value
+ *
+ * Use this instead of calling plane->atomic_set_property directly.
+ * This function handles generic/core properties and calls out to
+ * driver's ->atomic_set_property() for driver properties. To ensure
+ * consistent behavior you must call this function rather than the
+ * driver hook directly.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+int drm_atomic_plane_set_property(struct drm_plane *plane,
+ struct drm_plane_state *state, struct drm_property *property,
+ uint64_t val)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_mode_config *config = &dev->mode_config;
+
+ if (property == config->prop_fb_id) {
+ struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
+ drm_atomic_set_fb_for_plane(state, fb);
+ if (fb)
+ drm_framebuffer_unreference(fb);
+ } else if (property == config->prop_crtc_id) {
+ struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ return drm_atomic_set_crtc_for_plane(state, crtc);
+ } else if (property == config->prop_crtc_x) {
+ state->crtc_x = U642I64(val);
+ } else if (property == config->prop_crtc_y) {
+ state->crtc_y = U642I64(val);
+ } else if (property == config->prop_crtc_w) {
+ state->crtc_w = val;
+ } else if (property == config->prop_crtc_h) {
+ state->crtc_h = val;
+ } else if (property == config->prop_src_x) {
+ state->src_x = val;
+ } else if (property == config->prop_src_y) {
+ state->src_y = val;
+ } else if (property == config->prop_src_w) {
+ state->src_w = val;
+ } else if (property == config->prop_src_h) {
+ state->src_h = val;
+ } else if (property == config->rotation_property) {
+ state->rotation = val;
+ } else if (plane->funcs->atomic_set_property) {
+ return plane->funcs->atomic_set_property(plane, state,
+ property, val);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_atomic_plane_set_property);
+
+/*
+ * This function handles generic/core properties and calls out to
+ * driver's ->atomic_get_property() for driver properties. To ensure
+ * consistent behavior you must call this function rather than the
+ * driver hook directly.
+ */
+static int
+drm_atomic_plane_get_property(struct drm_plane *plane,
+ const struct drm_plane_state *state,
+ struct drm_property *property, uint64_t *val)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_mode_config *config = &dev->mode_config;
+
+ if (property == config->prop_fb_id) {
+ *val = (state->fb) ? state->fb->base.id : 0;
+ } else if (property == config->prop_crtc_id) {
+ *val = (state->crtc) ? state->crtc->base.id : 0;
+ } else if (property == config->prop_crtc_x) {
+ *val = I642U64(state->crtc_x);
+ } else if (property == config->prop_crtc_y) {
+ *val = I642U64(state->crtc_y);
+ } else if (property == config->prop_crtc_w) {
+ *val = state->crtc_w;
+ } else if (property == config->prop_crtc_h) {
+ *val = state->crtc_h;
+ } else if (property == config->prop_src_x) {
+ *val = state->src_x;
+ } else if (property == config->prop_src_y) {
+ *val = state->src_y;
+ } else if (property == config->prop_src_w) {
+ *val = state->src_w;
+ } else if (property == config->prop_src_h) {
+ *val = state->src_h;
+ } else if (plane->funcs->atomic_get_property) {
+ return plane->funcs->atomic_get_property(plane, state, property, val);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * drm_atomic_plane_check - check plane state
+ * @plane: plane to check
+ * @state: plane state to check
+ *
+ * Provides core sanity checks for plane state.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+static int drm_atomic_plane_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ unsigned int fb_width, fb_height;
+ unsigned int i;
+
+ /* either *both* CRTC and FB must be set, or neither */
+ if (WARN_ON(state->crtc && !state->fb)) {
+ DRM_DEBUG_KMS("CRTC set but no FB\n");
+ return -EINVAL;
+ } else if (WARN_ON(state->fb && !state->crtc)) {
+ DRM_DEBUG_KMS("FB set but no CRTC\n");
+ return -EINVAL;
+ }
+
+ /* if disabled, we don't care about the rest of the state: */
+ if (!state->crtc)
+ return 0;
+
+ /* Check whether this plane is usable on this CRTC */
+ if (!(plane->possible_crtcs & drm_crtc_mask(state->crtc))) {
+ DRM_DEBUG_KMS("Invalid crtc for plane\n");
+ return -EINVAL;
+ }
+
+ /* Check whether this plane supports the fb pixel format. */
+ for (i = 0; i < plane->format_count; i++)
+ if (state->fb->pixel_format == plane->format_types[i])
+ break;
+ if (i == plane->format_count) {
+ DRM_DEBUG_KMS("Invalid pixel format %s\n",
+ drm_get_format_name(state->fb->pixel_format));
+ return -EINVAL;
+ }
+
+ /* Give drivers some help against integer overflows */
+ if (state->crtc_w > INT_MAX ||
+ state->crtc_x > INT_MAX - (int32_t) state->crtc_w ||
+ state->crtc_h > INT_MAX ||
+ state->crtc_y > INT_MAX - (int32_t) state->crtc_h) {
+ DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
+ state->crtc_w, state->crtc_h,
+ state->crtc_x, state->crtc_y);
+ return -ERANGE;
+ }
+
+ fb_width = state->fb->width << 16;
+ fb_height = state->fb->height << 16;
+
+ /* Make sure source coordinates are inside the fb. */
+ if (state->src_w > fb_width ||
+ state->src_x > fb_width - state->src_w ||
+ state->src_h > fb_height ||
+ state->src_y > fb_height - state->src_h) {
+ DRM_DEBUG_KMS("Invalid source coordinates "
+ "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
+ state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10,
+ state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10,
+ state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10,
+ state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10);
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+/**
* drm_atomic_get_connector_state - get connector state
* @state: global atomic state object
* @connector: connector to get state object for
@@ -343,9 +607,113 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
EXPORT_SYMBOL(drm_atomic_get_connector_state);
/**
+ * drm_atomic_connector_set_property - set property on connector.
+ * @connector: the drm connector to set a property on
+ * @state: the state object to update with the new property value
+ * @property: the property to set
+ * @val: the new property value
+ *
+ * Use this instead of calling connector->atomic_set_property directly.
+ * This function handles generic/core properties and calls out to
+ * driver's ->atomic_set_property() for driver properties. To ensure
+ * consistent behavior you must call this function rather than the
+ * driver hook directly.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+int drm_atomic_connector_set_property(struct drm_connector *connector,
+ struct drm_connector_state *state, struct drm_property *property,
+ uint64_t val)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_mode_config *config = &dev->mode_config;
+
+ if (property == config->prop_crtc_id) {
+ struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ return drm_atomic_set_crtc_for_connector(state, crtc);
+ } else if (property == config->dpms_property) {
+ /* setting DPMS property requires special handling, which
+ * is done in legacy setprop path for us. Disallow (for
+ * now?) atomic writes to DPMS property:
+ */
+ return -EINVAL;
+ } else if (connector->funcs->atomic_set_property) {
+ return connector->funcs->atomic_set_property(connector,
+ state, property, val);
+ } else {
+ return -EINVAL;
+ }
+}
+EXPORT_SYMBOL(drm_atomic_connector_set_property);
+
+/*
+ * This function handles generic/core properties and calls out to
+ * driver's ->atomic_get_property() for driver properties. To ensure
+ * consistent behavior you must call this function rather than the
+ * driver hook directly.
+ */
+static int
+drm_atomic_connector_get_property(struct drm_connector *connector,
+ const struct drm_connector_state *state,
+ struct drm_property *property, uint64_t *val)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_mode_config *config = &dev->mode_config;
+
+ if (property == config->prop_crtc_id) {
+ *val = (state->crtc) ? state->crtc->base.id : 0;
+ } else if (property == config->dpms_property) {
+ *val = connector->dpms;
+ } else if (connector->funcs->atomic_get_property) {
+ return connector->funcs->atomic_get_property(connector,
+ state, property, val);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int drm_atomic_get_property(struct drm_mode_object *obj,
+ struct drm_property *property, uint64_t *val)
+{
+ struct drm_device *dev = property->dev;
+ int ret;
+
+ switch (obj->type) {
+ case DRM_MODE_OBJECT_CONNECTOR: {
+ struct drm_connector *connector = obj_to_connector(obj);
+ WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+ ret = drm_atomic_connector_get_property(connector,
+ connector->state, property, val);
+ break;
+ }
+ case DRM_MODE_OBJECT_CRTC: {
+ struct drm_crtc *crtc = obj_to_crtc(obj);
+ WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
+ ret = drm_atomic_crtc_get_property(crtc,
+ crtc->state, property, val);
+ break;
+ }
+ case DRM_MODE_OBJECT_PLANE: {
+ struct drm_plane *plane = obj_to_plane(obj);
+ WARN_ON(!drm_modeset_is_locked(&plane->mutex));
+ ret = drm_atomic_plane_get_property(plane,
+ plane->state, property, val);
+ break;
+ }
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
* drm_atomic_set_crtc_for_plane - set crtc for plane
- * @state: the incoming atomic state
- * @plane: the plane whose incoming state to update
+ * @plane_state: the plane whose incoming state to update
* @crtc: crtc to use for the plane
*
* Changing the assigned crtc for a plane requires us to grab the lock and state
@@ -358,16 +726,12 @@ EXPORT_SYMBOL(drm_atomic_get_connector_state);
* sequence must be restarted. All other errors are fatal.
*/
int
-drm_atomic_set_crtc_for_plane(struct drm_atomic_state *state,
- struct drm_plane *plane, struct drm_crtc *crtc)
+drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
+ struct drm_crtc *crtc)
{
- struct drm_plane_state *plane_state =
- drm_atomic_get_plane_state(state, plane);
+ struct drm_plane *plane = plane_state->plane;
struct drm_crtc_state *crtc_state;
- if (WARN_ON(IS_ERR(plane_state)))
- return PTR_ERR(plane_state);
-
if (plane_state->crtc) {
crtc_state = drm_atomic_get_crtc_state(plane_state->state,
plane_state->crtc);
@@ -583,14 +947,63 @@ EXPORT_SYMBOL(drm_atomic_legacy_backoff);
*/
int drm_atomic_check_only(struct drm_atomic_state *state)
{
- struct drm_mode_config *config = &state->dev->mode_config;
+ struct drm_device *dev = state->dev;
+ struct drm_mode_config *config = &dev->mode_config;
+ int nplanes = config->num_total_plane;
+ int ncrtcs = config->num_crtc;
+ int i, ret = 0;
DRM_DEBUG_KMS("checking %p\n", state);
+ for (i = 0; i < nplanes; i++) {
+ struct drm_plane *plane = state->planes[i];
+
+ if (!plane)
+ continue;
+
+ ret = drm_atomic_plane_check(plane, state->plane_states[i]);
+ if (ret) {
+ DRM_DEBUG_KMS("[PLANE:%d] atomic core check failed\n",
+ plane->base.id);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < ncrtcs; i++) {
+ struct drm_crtc *crtc = state->crtcs[i];
+
+ if (!crtc)
+ continue;
+
+ ret = drm_atomic_crtc_check(crtc, state->crtc_states[i]);
+ if (ret) {
+ DRM_DEBUG_KMS("[CRTC:%d] atomic core check failed\n",
+ crtc->base.id);
+ return ret;
+ }
+ }
+
if (config->funcs->atomic_check)
- return config->funcs->atomic_check(state->dev, state);
- else
- return 0;
+ ret = config->funcs->atomic_check(state->dev, state);
+
+ if (!state->allow_modeset) {
+ for (i = 0; i < ncrtcs; i++) {
+ struct drm_crtc *crtc = state->crtcs[i];
+ struct drm_crtc_state *crtc_state = state->crtc_states[i];
+
+ if (!crtc)
+ continue;
+
+ if (crtc_state->mode_changed ||
+ crtc_state->active_changed) {
+ DRM_DEBUG_KMS("[CRTC:%d] requires full modeset\n",
+ crtc->base.id);
+ return -EINVAL;
+ }
+ }
+ }
+
+ return ret;
}
EXPORT_SYMBOL(drm_atomic_check_only);
@@ -655,3 +1068,315 @@ int drm_atomic_async_commit(struct drm_atomic_state *state)
return config->funcs->atomic_commit(state->dev, state, true);
}
EXPORT_SYMBOL(drm_atomic_async_commit);
+
+/*
+ * The big monstor ioctl
+ */
+
+static struct drm_pending_vblank_event *create_vblank_event(
+ struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
+{
+ struct drm_pending_vblank_event *e = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (file_priv->event_space < sizeof e->event) {
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ goto out;
+ }
+ file_priv->event_space -= sizeof e->event;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ e = kzalloc(sizeof *e, GFP_KERNEL);
+ if (e == NULL) {
+ spin_lock_irqsave(&dev->event_lock, flags);
+ file_priv->event_space += sizeof e->event;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ goto out;
+ }
+
+ e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
+ e->event.base.length = sizeof e->event;
+ e->event.user_data = user_data;
+ e->base.event = &e->event.base;
+ e->base.file_priv = file_priv;
+ e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+
+out:
+ return e;
+}
+
+static void destroy_vblank_event(struct drm_device *dev,
+ struct drm_file *file_priv, struct drm_pending_vblank_event *e)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ file_priv->event_space += sizeof e->event;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ kfree(e);
+}
+
+static int atomic_set_prop(struct drm_atomic_state *state,
+ struct drm_mode_object *obj, struct drm_property *prop,
+ uint64_t prop_value)
+{
+ struct drm_mode_object *ref;
+ int ret;
+
+ if (!drm_property_change_valid_get(prop, prop_value, &ref))
+ return -EINVAL;
+
+ switch (obj->type) {
+ case DRM_MODE_OBJECT_CONNECTOR: {
+ struct drm_connector *connector = obj_to_connector(obj);
+ struct drm_connector_state *connector_state;
+
+ connector_state = drm_atomic_get_connector_state(state, connector);
+ if (IS_ERR(connector_state)) {
+ ret = PTR_ERR(connector_state);
+ break;
+ }
+
+ ret = drm_atomic_connector_set_property(connector,
+ connector_state, prop, prop_value);
+ break;
+ }
+ case DRM_MODE_OBJECT_CRTC: {
+ struct drm_crtc *crtc = obj_to_crtc(obj);
+ struct drm_crtc_state *crtc_state;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ break;
+ }
+
+ ret = drm_atomic_crtc_set_property(crtc,
+ crtc_state, prop, prop_value);
+ break;
+ }
+ case DRM_MODE_OBJECT_PLANE: {
+ struct drm_plane *plane = obj_to_plane(obj);
+ struct drm_plane_state *plane_state;
+
+ plane_state = drm_atomic_get_plane_state(state, plane);
+ if (IS_ERR(plane_state)) {
+ ret = PTR_ERR(plane_state);
+ break;
+ }
+
+ ret = drm_atomic_plane_set_property(plane,
+ plane_state, prop, prop_value);
+ break;
+ }
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ drm_property_change_valid_put(prop, ref);
+ return ret;
+}
+
+int drm_mode_atomic_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_mode_atomic *arg = data;
+ uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr);
+ uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr);
+ uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
+ uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr);
+ unsigned int copied_objs, copied_props;
+ struct drm_atomic_state *state;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_plane *plane;
+ unsigned plane_mask = 0;
+ int ret = 0;
+ unsigned int i, j;
+
+ /* disallow for drivers not supporting atomic: */
+ if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
+ return -EINVAL;
+
+ /* disallow for userspace that has not enabled atomic cap (even
+ * though this may be a bit overkill, since legacy userspace
+ * wouldn't know how to call this ioctl)
+ */
+ if (!file_priv->atomic)
+ return -EINVAL;
+
+ if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS)
+ return -EINVAL;
+
+ if (arg->reserved)
+ return -EINVAL;
+
+ if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) &&
+ !dev->mode_config.async_page_flip)
+ return -EINVAL;
+
+ /* can't test and expect an event at the same time. */
+ if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
+ (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
+ return -EINVAL;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_atomic_state_alloc(dev);
+ if (!state)
+ return -ENOMEM;
+
+ state->acquire_ctx = &ctx;
+ state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
+
+retry:
+ copied_objs = 0;
+ copied_props = 0;
+
+ for (i = 0; i < arg->count_objs; i++) {
+ uint32_t obj_id, count_props;
+ struct drm_mode_object *obj;
+
+ if (get_user(obj_id, objs_ptr + copied_objs)) {
+ ret = -EFAULT;
+ goto fail;
+ }
+
+ obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
+ if (!obj || !obj->properties) {
+ ret = -ENOENT;
+ goto fail;
+ }
+
+ if (obj->type == DRM_MODE_OBJECT_PLANE) {
+ plane = obj_to_plane(obj);
+ plane_mask |= (1 << drm_plane_index(plane));
+ plane->old_fb = plane->fb;
+ }
+
+ if (get_user(count_props, count_props_ptr + copied_objs)) {
+ ret = -EFAULT;
+ goto fail;
+ }
+
+ copied_objs++;
+
+ for (j = 0; j < count_props; j++) {
+ uint32_t prop_id;
+ uint64_t prop_value;
+ struct drm_property *prop;
+
+ if (get_user(prop_id, props_ptr + copied_props)) {
+ ret = -EFAULT;
+ goto fail;
+ }
+
+ prop = drm_property_find(dev, prop_id);
+ if (!prop) {
+ ret = -ENOENT;
+ goto fail;
+ }
+
+ if (copy_from_user(&prop_value,
+ prop_values_ptr + copied_props,
+ sizeof(prop_value))) {
+ ret = -EFAULT;
+ goto fail;
+ }
+
+ ret = atomic_set_prop(state, obj, prop, prop_value);
+ if (ret)
+ goto fail;
+
+ copied_props++;
+ }
+ }
+
+ if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+ int ncrtcs = dev->mode_config.num_crtc;
+
+ for (i = 0; i < ncrtcs; i++) {
+ struct drm_crtc_state *crtc_state = state->crtc_states[i];
+ struct drm_pending_vblank_event *e;
+
+ if (!crtc_state)
+ continue;
+
+ e = create_vblank_event(dev, file_priv, arg->user_data);
+ if (!e) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ crtc_state->event = e;
+ }
+ }
+
+ if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
+ ret = drm_atomic_check_only(state);
+ /* _check_only() does not free state, unlike _commit() */
+ drm_atomic_state_free(state);
+ } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
+ ret = drm_atomic_async_commit(state);
+ } else {
+ ret = drm_atomic_commit(state);
+ }
+
+ /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping
+ * locks (ie. while it is still safe to deref plane->state). We
+ * need to do this here because the driver entry points cannot
+ * distinguish between legacy and atomic ioctls.
+ */
+ drm_for_each_plane_mask(plane, dev, plane_mask) {
+ if (ret == 0) {
+ struct drm_framebuffer *new_fb = plane->state->fb;
+ if (new_fb)
+ drm_framebuffer_reference(new_fb);
+ plane->fb = new_fb;
+ plane->crtc = plane->state->crtc;
+ } else {
+ plane->old_fb = NULL;
+ }
+ if (plane->old_fb) {
+ drm_framebuffer_unreference(plane->old_fb);
+ plane->old_fb = NULL;
+ }
+ }
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ return ret;
+
+fail:
+ if (ret == -EDEADLK)
+ goto backoff;
+
+ if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+ int ncrtcs = dev->mode_config.num_crtc;
+
+ for (i = 0; i < ncrtcs; i++) {
+ struct drm_crtc_state *crtc_state = state->crtc_states[i];
+
+ if (!crtc_state)
+ continue;
+
+ destroy_vblank_event(dev, file_priv, crtc_state->event);
+ crtc_state->event = NULL;
+ }
+ }
+
+ drm_atomic_state_free(state);
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ return ret;
+
+backoff:
+ drm_atomic_state_clear(state);
+ drm_modeset_backoff(&ctx);
+
+ goto retry;
+}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index bbdbe4721573..7e3a52b97c7d 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -297,13 +297,22 @@ mode_fixup(struct drm_atomic_state *state)
}
}
-
- ret = funcs->mode_fixup(encoder, &crtc_state->mode,
- &crtc_state->adjusted_mode);
- if (!ret) {
- DRM_DEBUG_KMS("[ENCODER:%d:%s] fixup failed\n",
- encoder->base.id, encoder->name);
- return -EINVAL;
+ if (funcs->atomic_check) {
+ ret = funcs->atomic_check(encoder, crtc_state,
+ conn_state);
+ if (ret) {
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] check failed\n",
+ encoder->base.id, encoder->name);
+ return ret;
+ }
+ } else {
+ ret = funcs->mode_fixup(encoder, &crtc_state->mode,
+ &crtc_state->adjusted_mode);
+ if (!ret) {
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] fixup failed\n",
+ encoder->base.id, encoder->name);
+ return -EINVAL;
+ }
}
}
@@ -330,7 +339,35 @@ mode_fixup(struct drm_atomic_state *state)
return 0;
}
-static int
+static bool
+needs_modeset(struct drm_crtc_state *state)
+{
+ return state->mode_changed || state->active_changed;
+}
+
+/**
+ * drm_atomic_helper_check - validate state object for modeset changes
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * Check the state object to see if the requested state is physically possible.
+ * This does all the crtc and connector related computations for an atomic
+ * update. It computes and updates crtc_state->mode_changed, adds any additional
+ * connectors needed for full modesets and calls down into ->mode_fixup
+ * functions of the driver backend.
+ *
+ * IMPORTANT:
+ *
+ * Drivers which update ->mode_changed (e.g. in their ->atomic_check hooks if a
+ * plane update can't be done without a full modeset) _must_ call this function
+ * afterwards after that change. It is permitted to call this function multiple
+ * times for the same update, e.g. when the ->atomic_check functions depend upon
+ * the adjusted dotclock for fifo space allocation and watermark computation.
+ *
+ * RETURNS
+ * Zero for success or -errno
+ */
+int
drm_atomic_helper_check_modeset(struct drm_device *dev,
struct drm_atomic_state *state)
{
@@ -382,12 +419,27 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
crtc = state->crtcs[i];
crtc_state = state->crtc_states[i];
- if (!crtc || !crtc_state->mode_changed)
+ if (!crtc)
continue;
- DRM_DEBUG_KMS("[CRTC:%d] needs full modeset, enable: %c\n",
+ /*
+ * We must set ->active_changed after walking connectors for
+ * otherwise an update that only changes active would result in
+ * a full modeset because update_connector_routing force that.
+ */
+ if (crtc->state->active != crtc_state->active) {
+ DRM_DEBUG_KMS("[CRTC:%d] active changed\n",
+ crtc->base.id);
+ crtc_state->active_changed = true;
+ }
+
+ if (!needs_modeset(crtc_state))
+ continue;
+
+ DRM_DEBUG_KMS("[CRTC:%d] needs all connectors, enable: %c, active: %c\n",
crtc->base.id,
- crtc_state->enable ? 'y' : 'n');
+ crtc_state->enable ? 'y' : 'n',
+ crtc_state->active ? 'y' : 'n');
ret = drm_atomic_add_affected_connectors(state, crtc);
if (ret != 0)
@@ -406,23 +458,23 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
return mode_fixup(state);
}
+EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
/**
- * drm_atomic_helper_check - validate state object
+ * drm_atomic_helper_check - validate state object for modeset changes
* @dev: DRM device
* @state: the driver state object
*
* Check the state object to see if the requested state is physically possible.
- * Only crtcs and planes have check callbacks, so for any additional (global)
- * checking that a driver needs it can simply wrap that around this function.
- * Drivers without such needs can directly use this as their ->atomic_check()
- * callback.
+ * This does all the plane update related checks using by calling into the
+ * ->atomic_check hooks provided by the driver.
*
* RETURNS
* Zero for success or -errno
*/
-int drm_atomic_helper_check(struct drm_device *dev,
- struct drm_atomic_state *state)
+int
+drm_atomic_helper_check_planes(struct drm_device *dev,
+ struct drm_atomic_state *state)
{
int nplanes = dev->mode_config.num_total_plane;
int ncrtcs = dev->mode_config.num_crtc;
@@ -445,7 +497,7 @@ int drm_atomic_helper_check(struct drm_device *dev,
ret = funcs->atomic_check(plane, plane_state);
if (ret) {
- DRM_DEBUG_KMS("[PLANE:%d] atomic check failed\n",
+ DRM_DEBUG_KMS("[PLANE:%d] atomic driver check failed\n",
plane->base.id);
return ret;
}
@@ -465,16 +517,49 @@ int drm_atomic_helper_check(struct drm_device *dev,
ret = funcs->atomic_check(crtc, state->crtc_states[i]);
if (ret) {
- DRM_DEBUG_KMS("[CRTC:%d] atomic check failed\n",
+ DRM_DEBUG_KMS("[CRTC:%d] atomic driver check failed\n",
crtc->base.id);
return ret;
}
}
+ return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_check_planes);
+
+/**
+ * drm_atomic_helper_check - validate state object
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * Check the state object to see if the requested state is physically possible.
+ * Only crtcs and planes have check callbacks, so for any additional (global)
+ * checking that a driver needs it can simply wrap that around this function.
+ * Drivers without such needs can directly use this as their ->atomic_check()
+ * callback.
+ *
+ * This just wraps the two parts of the state checking for planes and modeset
+ * state in the default order: First it calls drm_atomic_helper_check_modeset()
+ * and then drm_atomic_helper_check_planes(). The assumption is that the
+ * ->atomic_check functions depend upon an updated adjusted_mode.clock to
+ * e.g. properly compute watermarks.
+ *
+ * RETURNS
+ * Zero for success or -errno
+ */
+int drm_atomic_helper_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ int ret;
+
ret = drm_atomic_helper_check_modeset(dev, state);
if (ret)
return ret;
+ ret = drm_atomic_helper_check_planes(dev, state);
+ if (ret)
+ return ret;
+
return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_check);
@@ -490,6 +575,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
struct drm_connector *connector;
struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder;
+ struct drm_crtc_state *old_crtc_state;
old_conn_state = old_state->connector_states[i];
connector = old_state->connectors[i];
@@ -499,6 +585,11 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
if (!old_conn_state || !old_conn_state->crtc)
continue;
+ old_crtc_state = old_state->crtc_states[drm_crtc_index(old_conn_state->crtc)];
+
+ if (!old_crtc_state->active)
+ continue;
+
encoder = old_conn_state->best_encoder;
/* We shouldn't get this far if we didn't previously have
@@ -509,6 +600,9 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
funcs = encoder->helper_private;
+ DRM_DEBUG_KMS("disabling [ENCODER:%d:%s]\n",
+ encoder->base.id, encoder->name);
+
/*
* Each encoder has at most one connector (since we always steal
* it away), so we won't call call disable hooks twice.
@@ -517,7 +611,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
encoder->bridge->funcs->disable(encoder->bridge);
/* Right function depends upon target state. */
- if (connector->state->crtc)
+ if (connector->state->crtc && funcs->prepare)
funcs->prepare(encoder);
else if (funcs->disable)
funcs->disable(encoder);
@@ -531,17 +625,26 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc;
+ struct drm_crtc_state *old_crtc_state;
crtc = old_state->crtcs[i];
+ old_crtc_state = old_state->crtc_states[i];
/* Shut down everything that needs a full modeset. */
- if (!crtc || !crtc->state->mode_changed)
+ if (!crtc || !needs_modeset(crtc->state))
+ continue;
+
+ if (!old_crtc_state->active)
continue;
funcs = crtc->helper_private;
+ DRM_DEBUG_KMS("disabling [CRTC:%d]\n",
+ crtc->base.id);
+
+
/* Right function depends upon target state. */
- if (crtc->state->enable)
+ if (crtc->state->enable && funcs->prepare)
funcs->prepare(crtc);
else if (funcs->disable)
funcs->disable(crtc);
@@ -620,8 +723,12 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
funcs = crtc->helper_private;
- if (crtc->state->enable)
+ if (crtc->state->enable) {
+ DRM_DEBUG_KMS("modeset on [CRTC:%d]\n",
+ crtc->base.id);
+
funcs->mode_set_nofb(crtc);
+ }
}
for (i = 0; i < old_state->num_connector; i++) {
@@ -642,6 +749,12 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
mode = &new_crtc_state->mode;
adjusted_mode = &new_crtc_state->adjusted_mode;
+ if (!new_crtc_state->mode_changed)
+ continue;
+
+ DRM_DEBUG_KMS("modeset on [ENCODER:%d:%s]\n",
+ encoder->base.id, encoder->name);
+
/*
* Each encoder has at most one connector (since we always steal
* it away), so we won't call call mode_set hooks twice.
@@ -694,13 +807,23 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev,
crtc = old_state->crtcs[i];
/* Need to filter out CRTCs where only planes change. */
- if (!crtc || !crtc->state->mode_changed)
+ if (!crtc || !needs_modeset(crtc->state))
+ continue;
+
+ if (!crtc->state->active)
continue;
funcs = crtc->helper_private;
- if (crtc->state->enable)
- funcs->commit(crtc);
+ if (crtc->state->enable) {
+ DRM_DEBUG_KMS("enabling [CRTC:%d]\n",
+ crtc->base.id);
+
+ if (funcs->enable)
+ funcs->enable(crtc);
+ else
+ funcs->commit(crtc);
+ }
}
for (i = 0; i < old_state->num_connector; i++) {
@@ -713,9 +836,15 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev,
if (!connector || !connector->state->best_encoder)
continue;
+ if (!connector->state->crtc->state->active)
+ continue;
+
encoder = connector->state->best_encoder;
funcs = encoder->helper_private;
+ DRM_DEBUG_KMS("enabling [ENCODER:%d:%s]\n",
+ encoder->base.id, encoder->name);
+
/*
* Each encoder has at most one connector (since we always steal
* it away), so we won't call call enable hooks twice.
@@ -723,7 +852,10 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev,
if (encoder->bridge)
encoder->bridge->funcs->pre_enable(encoder->bridge);
- funcs->commit(encoder);
+ if (funcs->enable)
+ funcs->enable(encoder);
+ else
+ funcs->commit(encoder);
if (encoder->bridge)
encoder->bridge->funcs->enable(encoder->bridge);
@@ -813,6 +945,11 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
if (!crtc->state->enable)
continue;
+ /* Legacy cursor ioctls are completely unsynced, and userspace
+ * relies on that (by doing tons of cursor updates). */
+ if (old_state->legacy_cursor_update)
+ continue;
+
if (!framebuffer_changed(dev, old_state, crtc))
continue;
@@ -1053,12 +1190,19 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
funcs = plane->helper_private;
- if (!funcs || !funcs->atomic_update)
+ if (!funcs)
continue;
old_plane_state = old_state->plane_states[i];
- funcs->atomic_update(plane, old_plane_state);
+ /*
+ * Special-case disabling the plane if drivers support it.
+ */
+ if (drm_atomic_plane_disabling(plane, old_plane_state) &&
+ funcs->atomic_disable)
+ funcs->atomic_disable(plane, old_plane_state);
+ else
+ funcs->atomic_update(plane, old_plane_state);
}
for (i = 0; i < ncrtcs; i++) {
@@ -1222,7 +1366,7 @@ retry:
goto fail;
}
- ret = drm_atomic_set_crtc_for_plane(state, plane, crtc);
+ ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
if (ret != 0)
goto fail;
drm_atomic_set_fb_for_plane(plane_state, fb);
@@ -1239,6 +1383,9 @@ retry:
if (ret != 0)
goto fail;
+ if (plane == crtc->cursor)
+ state->legacy_cursor_update = true;
+
/* Driver takes ownership of state on successful commit. */
return 0;
fail:
@@ -1301,7 +1448,7 @@ retry:
goto fail;
}
- ret = drm_atomic_set_crtc_for_plane(state, plane, NULL);
+ ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
if (ret != 0)
goto fail;
drm_atomic_set_fb_for_plane(plane_state, NULL);
@@ -1314,6 +1461,9 @@ retry:
plane_state->src_h = 0;
plane_state->src_w = 0;
+ if (plane == plane->crtc->cursor)
+ state->legacy_cursor_update = true;
+
ret = drm_atomic_commit(state);
if (ret != 0)
goto fail;
@@ -1463,8 +1613,9 @@ retry:
WARN_ON(set->num_connectors);
crtc_state->enable = false;
+ crtc_state->active = false;
- ret = drm_atomic_set_crtc_for_plane(state, crtc->primary, NULL);
+ ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
if (ret != 0)
goto fail;
@@ -1477,9 +1628,10 @@ retry:
WARN_ON(!set->num_connectors);
crtc_state->enable = true;
+ crtc_state->active = true;
drm_mode_copy(&crtc_state->mode, set->mode);
- ret = drm_atomic_set_crtc_for_plane(state, crtc->primary, crtc);
+ ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
if (ret != 0)
goto fail;
drm_atomic_set_fb_for_plane(primary_state, set->fb);
@@ -1558,8 +1710,8 @@ retry:
goto fail;
}
- ret = crtc->funcs->atomic_set_property(crtc, crtc_state,
- property, val);
+ ret = drm_atomic_crtc_set_property(crtc, crtc_state,
+ property, val);
if (ret)
goto fail;
@@ -1617,8 +1769,8 @@ retry:
goto fail;
}
- ret = plane->funcs->atomic_set_property(plane, plane_state,
- property, val);
+ ret = drm_atomic_plane_set_property(plane, plane_state,
+ property, val);
if (ret)
goto fail;
@@ -1676,8 +1828,8 @@ retry:
goto fail;
}
- ret = connector->funcs->atomic_set_property(connector, connector_state,
- property, val);
+ ret = drm_atomic_connector_set_property(connector, connector_state,
+ property, val);
if (ret)
goto fail;
@@ -1751,7 +1903,7 @@ retry:
goto fail;
}
- ret = drm_atomic_set_crtc_for_plane(state, plane, crtc);
+ ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
if (ret != 0)
goto fail;
drm_atomic_set_fb_for_plane(plane_state, fb);
@@ -1789,6 +1941,83 @@ backoff:
EXPORT_SYMBOL(drm_atomic_helper_page_flip);
/**
+ * drm_atomic_helper_connector_dpms() - connector dpms helper implementation
+ * @connector: affected connector
+ * @mode: DPMS mode
+ *
+ * This is the main helper function provided by the atomic helper framework for
+ * implementing the legacy DPMS connector interface. It computes the new desired
+ * ->active state for the corresponding CRTC (if the connector is enabled) and
+ * updates it.
+ */
+void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
+ int mode)
+{
+ struct drm_mode_config *config = &connector->dev->mode_config;
+ struct drm_atomic_state *state;
+ struct drm_crtc_state *crtc_state;
+ struct drm_crtc *crtc;
+ struct drm_connector *tmp_connector;
+ int ret;
+ bool active = false;
+
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
+ connector->dpms = mode;
+ crtc = connector->state->crtc;
+
+ if (!crtc)
+ return;
+
+ /* FIXME: ->dpms has no return value so can't forward the -ENOMEM. */
+ state = drm_atomic_state_alloc(connector->dev);
+ if (!state)
+ return;
+
+ state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
+retry:
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state))
+ return;
+
+ WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
+
+ list_for_each_entry(tmp_connector, &config->connector_list, head) {
+ if (connector->state->crtc != crtc)
+ continue;
+
+ if (connector->dpms == DRM_MODE_DPMS_ON) {
+ active = true;
+ break;
+ }
+ }
+ crtc_state->active = active;
+
+ ret = drm_atomic_commit(state);
+ if (ret != 0)
+ goto fail;
+
+ /* Driver takes ownership of state on successful async commit. */
+ return;
+fail:
+ if (ret == -EDEADLK)
+ goto backoff;
+
+ drm_atomic_state_free(state);
+
+ WARN(1, "Driver bug: Changing ->active failed with ret=%i\n", ret);
+
+ return;
+backoff:
+ drm_atomic_state_clear(state);
+ drm_atomic_legacy_backoff(state);
+
+ goto retry;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
+
+/**
* DOC: atomic state reset and initialization
*
* Both the drm core and the atomic helpers assume that there is always the full
@@ -1814,6 +2043,9 @@ void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
{
kfree(crtc->state);
crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
+
+ if (crtc->state)
+ crtc->state->crtc = crtc;
}
EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
@@ -1836,6 +2068,7 @@ drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
if (state) {
state->mode_changed = false;
+ state->active_changed = false;
state->planes_changed = false;
state->event = NULL;
}
@@ -1873,6 +2106,9 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
kfree(plane->state);
plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
+
+ if (plane->state)
+ plane->state->plane = plane;
}
EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
@@ -1930,6 +2166,9 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector)
{
kfree(connector->state);
connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL);
+
+ if (connector->state)
+ connector->state->connector = connector;
}
EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
new file mode 100644
index 000000000000..d1187e571c6d
--- /dev/null
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <drm/drm_crtc.h>
+
+#include "drm/drmP.h"
+
+static DEFINE_MUTEX(bridge_lock);
+static LIST_HEAD(bridge_list);
+
+int drm_bridge_add(struct drm_bridge *bridge)
+{
+ mutex_lock(&bridge_lock);
+ list_add_tail(&bridge->list, &bridge_list);
+ mutex_unlock(&bridge_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_bridge_add);
+
+void drm_bridge_remove(struct drm_bridge *bridge)
+{
+ mutex_lock(&bridge_lock);
+ list_del_init(&bridge->list);
+ mutex_unlock(&bridge_lock);
+}
+EXPORT_SYMBOL(drm_bridge_remove);
+
+extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
+{
+ if (!dev || !bridge)
+ return -EINVAL;
+
+ if (bridge->dev)
+ return -EBUSY;
+
+ bridge->dev = dev;
+
+ if (bridge->funcs->attach)
+ return bridge->funcs->attach(bridge);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_bridge_attach);
+
+#ifdef CONFIG_OF
+struct drm_bridge *of_drm_find_bridge(struct device_node *np)
+{
+ struct drm_bridge *bridge;
+
+ mutex_lock(&bridge_lock);
+
+ list_for_each_entry(bridge, &bridge_list, list) {
+ if (bridge->of_node == np) {
+ mutex_unlock(&bridge_lock);
+ return bridge;
+ }
+ }
+
+ mutex_unlock(&bridge_lock);
+ return NULL;
+}
+EXPORT_SYMBOL(of_drm_find_bridge);
+#endif
+
+MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
+MODULE_DESCRIPTION("DRM bridge infrastructure");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index a6b690626a6b..9a62d7a53553 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -32,6 +32,7 @@
#include <drm/drmP.h>
#if defined(CONFIG_X86)
+#include <asm/smp.h>
/*
* clflushopt is an unordered instruction which needs fencing with mfence or
@@ -64,12 +65,6 @@ static void drm_cache_flush_clflush(struct page *pages[],
drm_clflush_page(*pages++);
mb();
}
-
-static void
-drm_clflush_ipi_handler(void *null)
-{
- wbinvd();
-}
#endif
void
@@ -82,7 +77,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
return;
}
- if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
+ if (wbinvd_on_all_cpus())
printk(KERN_ERR "Timed out waiting for cache flush.\n");
#elif defined(__powerpc__)
@@ -121,7 +116,7 @@ drm_clflush_sg(struct sg_table *st)
return;
}
- if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
+ if (wbinvd_on_all_cpus())
printk(KERN_ERR "Timed out waiting for cache flush.\n");
#else
printk(KERN_ERR "Architecture has no drm_cache.c support\n");
@@ -144,7 +139,7 @@ drm_clflush_virt_range(void *addr, unsigned long length)
return;
}
- if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
+ if (wbinvd_on_all_cpus())
printk(KERN_ERR "Timed out waiting for cache flush.\n");
#else
printk(KERN_ERR "Architecture has no drm_cache.c support\n");
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5213da499d39..6b00173d1be4 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,6 +38,7 @@
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_modeset_lock.h>
+#include <drm/drm_atomic.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
@@ -61,8 +62,8 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
/*
* Global properties
*/
-static const struct drm_prop_enum_list drm_dpms_enum_list[] =
-{ { DRM_MODE_DPMS_ON, "On" },
+static const struct drm_prop_enum_list drm_dpms_enum_list[] = {
+ { DRM_MODE_DPMS_ON, "On" },
{ DRM_MODE_DPMS_STANDBY, "Standby" },
{ DRM_MODE_DPMS_SUSPEND, "Suspend" },
{ DRM_MODE_DPMS_OFF, "Off" }
@@ -70,8 +71,7 @@ static const struct drm_prop_enum_list drm_dpms_enum_list[] =
DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
-static const struct drm_prop_enum_list drm_plane_type_enum_list[] =
-{
+static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
{ DRM_PLANE_TYPE_OVERLAY, "Overlay" },
{ DRM_PLANE_TYPE_PRIMARY, "Primary" },
{ DRM_PLANE_TYPE_CURSOR, "Cursor" },
@@ -80,8 +80,7 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] =
/*
* Optional properties
*/
-static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
-{
+static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = {
{ DRM_MODE_SCALE_NONE, "None" },
{ DRM_MODE_SCALE_FULLSCREEN, "Full" },
{ DRM_MODE_SCALE_CENTER, "Center" },
@@ -97,8 +96,7 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
/*
* Non-global properties, but "required" for certain connectors.
*/
-static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
-{
+static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {
{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
{ DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
{ DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
@@ -106,8 +104,7 @@ static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
-static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
-{
+static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {
{ DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
{ DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
{ DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
@@ -116,8 +113,7 @@ static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
drm_dvi_i_subconnector_enum_list)
-static const struct drm_prop_enum_list drm_tv_select_enum_list[] =
-{
+static const struct drm_prop_enum_list drm_tv_select_enum_list[] = {
{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
@@ -127,8 +123,7 @@ static const struct drm_prop_enum_list drm_tv_select_enum_list[] =
DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
-static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
-{
+static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
{ DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
@@ -154,8 +149,8 @@ struct drm_conn_prop_enum_list {
/*
* Connector and encoder types.
*/
-static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
-{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
+static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {
+ { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
{ DRM_MODE_CONNECTOR_VGA, "VGA" },
{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
@@ -174,8 +169,8 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
{ DRM_MODE_CONNECTOR_DSI, "DSI" },
};
-static const struct drm_prop_enum_list drm_encoder_enum_list[] =
-{ { DRM_MODE_ENCODER_NONE, "None" },
+static const struct drm_prop_enum_list drm_encoder_enum_list[] = {
+ { DRM_MODE_ENCODER_NONE, "None" },
{ DRM_MODE_ENCODER_DAC, "DAC" },
{ DRM_MODE_ENCODER_TMDS, "TMDS" },
{ DRM_MODE_ENCODER_LVDS, "LVDS" },
@@ -185,8 +180,7 @@ static const struct drm_prop_enum_list drm_encoder_enum_list[] =
{ DRM_MODE_ENCODER_DPMST, "DP MST" },
};
-static const struct drm_prop_enum_list drm_subpixel_enum_list[] =
-{
+static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {
{ SubPixelUnknown, "Unknown" },
{ SubPixelHorizontalRGB, "Horizontal RGB" },
{ SubPixelHorizontalBGR, "Horizontal BGR" },
@@ -697,6 +691,10 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
if (cursor)
cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
+ if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
+ drm_object_attach_property(&crtc->base, config->prop_active, 0);
+ }
+
return 0;
}
EXPORT_SYMBOL(drm_crtc_init_with_planes);
@@ -768,6 +766,40 @@ static void drm_mode_remove(struct drm_connector *connector,
}
/**
+ * drm_display_info_set_bus_formats - set the supported bus formats
+ * @info: display info to store bus formats in
+ * @formats: array containing the supported bus formats
+ * @num_formats: the number of entries in the fmts array
+ *
+ * Store the supported bus formats in display info structure.
+ * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for
+ * a full list of available formats.
+ */
+int drm_display_info_set_bus_formats(struct drm_display_info *info,
+ const u32 *formats,
+ unsigned int num_formats)
+{
+ u32 *fmts = NULL;
+
+ if (!formats && num_formats)
+ return -EINVAL;
+
+ if (formats && num_formats) {
+ fmts = kmemdup(formats, sizeof(*formats) * num_formats,
+ GFP_KERNEL);
+ if (!fmts)
+ return -ENOMEM;
+ }
+
+ kfree(info->bus_formats);
+ info->bus_formats = fmts;
+ info->num_bus_formats = num_formats;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_display_info_set_bus_formats);
+
+/**
* drm_connector_get_cmdline_mode - reads the user's cmdline mode
* @connector: connector to quwery
*
@@ -837,6 +869,7 @@ int drm_connector_init(struct drm_device *dev,
const struct drm_connector_funcs *funcs,
int connector_type)
{
+ struct drm_mode_config *config = &dev->mode_config;
int ret;
struct ida *connector_ida =
&drm_connector_enum_list[connector_type].ida;
@@ -875,16 +908,20 @@ int drm_connector_init(struct drm_device *dev,
/* We should add connectors at the end to avoid upsetting the connector
* index too much. */
- list_add_tail(&connector->head, &dev->mode_config.connector_list);
- dev->mode_config.num_connector++;
+ list_add_tail(&connector->head, &config->connector_list);
+ config->num_connector++;
if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
drm_object_attach_property(&connector->base,
- dev->mode_config.edid_property,
+ config->edid_property,
0);
drm_object_attach_property(&connector->base,
- dev->mode_config.dpms_property, 0);
+ config->dpms_property, 0);
+
+ if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
+ drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
+ }
connector->debugfs_entry = NULL;
@@ -924,6 +961,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
ida_remove(&drm_connector_enum_list[connector->connector_type].ida,
connector->connector_type_id);
+ kfree(connector->display_info.bus_formats);
drm_mode_object_put(dev, &connector->base);
kfree(connector->name);
connector->name = NULL;
@@ -1028,61 +1066,6 @@ void drm_connector_unplug_all(struct drm_device *dev)
EXPORT_SYMBOL(drm_connector_unplug_all);
/**
- * drm_bridge_init - initialize a drm transcoder/bridge
- * @dev: drm device
- * @bridge: transcoder/bridge to set up
- * @funcs: bridge function table
- *
- * Initialises a preallocated bridge. Bridges should be
- * subclassed as part of driver connector objects.
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge,
- const struct drm_bridge_funcs *funcs)
-{
- int ret;
-
- drm_modeset_lock_all(dev);
-
- ret = drm_mode_object_get(dev, &bridge->base, DRM_MODE_OBJECT_BRIDGE);
- if (ret)
- goto out;
-
- bridge->dev = dev;
- bridge->funcs = funcs;
-
- list_add_tail(&bridge->head, &dev->mode_config.bridge_list);
- dev->mode_config.num_bridge++;
-
- out:
- drm_modeset_unlock_all(dev);
- return ret;
-}
-EXPORT_SYMBOL(drm_bridge_init);
-
-/**
- * drm_bridge_cleanup - cleans up an initialised bridge
- * @bridge: bridge to cleanup
- *
- * Cleans up the bridge but doesn't free the object.
- */
-void drm_bridge_cleanup(struct drm_bridge *bridge)
-{
- struct drm_device *dev = bridge->dev;
-
- drm_modeset_lock_all(dev);
- drm_mode_object_put(dev, &bridge->base);
- list_del(&bridge->head);
- dev->mode_config.num_bridge--;
- drm_modeset_unlock_all(dev);
-
- memset(bridge, 0, sizeof(*bridge));
-}
-EXPORT_SYMBOL(drm_bridge_cleanup);
-
-/**
* drm_encoder_init - Init a preallocated encoder
* @dev: drm device
* @encoder: the encoder to init
@@ -1142,6 +1125,7 @@ EXPORT_SYMBOL(drm_encoder_init);
void drm_encoder_cleanup(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
+
drm_modeset_lock_all(dev);
drm_mode_object_put(dev, &encoder->base);
kfree(encoder->name);
@@ -1174,6 +1158,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
const uint32_t *formats, uint32_t format_count,
enum drm_plane_type type)
{
+ struct drm_mode_config *config = &dev->mode_config;
int ret;
ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
@@ -1185,8 +1170,8 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
plane->base.properties = &plane->properties;
plane->dev = dev;
plane->funcs = funcs;
- plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
- GFP_KERNEL);
+ plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
+ GFP_KERNEL);
if (!plane->format_types) {
DRM_DEBUG_KMS("out of memory when allocating plane\n");
drm_mode_object_put(dev, &plane->base);
@@ -1198,15 +1183,28 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
plane->possible_crtcs = possible_crtcs;
plane->type = type;
- list_add_tail(&plane->head, &dev->mode_config.plane_list);
- dev->mode_config.num_total_plane++;
+ list_add_tail(&plane->head, &config->plane_list);
+ config->num_total_plane++;
if (plane->type == DRM_PLANE_TYPE_OVERLAY)
- dev->mode_config.num_overlay_plane++;
+ config->num_overlay_plane++;
drm_object_attach_property(&plane->base,
- dev->mode_config.plane_type_property,
+ config->plane_type_property,
plane->type);
+ if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
+ drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
+ drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
+ drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
+ drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
+ drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
+ drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
+ drm_object_attach_property(&plane->base, config->prop_src_x, 0);
+ drm_object_attach_property(&plane->base, config->prop_src_y, 0);
+ drm_object_attach_property(&plane->base, config->prop_src_w, 0);
+ drm_object_attach_property(&plane->base, config->prop_src_h, 0);
+ }
+
return 0;
}
EXPORT_SYMBOL(drm_universal_plane_init);
@@ -1328,50 +1326,115 @@ void drm_plane_force_disable(struct drm_plane *plane)
}
EXPORT_SYMBOL(drm_plane_force_disable);
-static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
+static int drm_mode_create_standard_properties(struct drm_device *dev)
{
- struct drm_property *edid;
- struct drm_property *dpms;
- struct drm_property *dev_path;
+ struct drm_property *prop;
/*
* Standard properties (apply to all connectors)
*/
- edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
+ prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
DRM_MODE_PROP_IMMUTABLE,
"EDID", 0);
- dev->mode_config.edid_property = edid;
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.edid_property = prop;
- dpms = drm_property_create_enum(dev, 0,
+ prop = drm_property_create_enum(dev, 0,
"DPMS", drm_dpms_enum_list,
ARRAY_SIZE(drm_dpms_enum_list));
- dev->mode_config.dpms_property = dpms;
-
- dev_path = drm_property_create(dev,
- DRM_MODE_PROP_BLOB |
- DRM_MODE_PROP_IMMUTABLE,
- "PATH", 0);
- dev->mode_config.path_property = dev_path;
-
- dev->mode_config.tile_property = drm_property_create(dev,
- DRM_MODE_PROP_BLOB |
- DRM_MODE_PROP_IMMUTABLE,
- "TILE", 0);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.dpms_property = prop;
- return 0;
-}
+ prop = drm_property_create(dev,
+ DRM_MODE_PROP_BLOB |
+ DRM_MODE_PROP_IMMUTABLE,
+ "PATH", 0);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.path_property = prop;
-static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
-{
- struct drm_property *type;
+ prop = drm_property_create(dev,
+ DRM_MODE_PROP_BLOB |
+ DRM_MODE_PROP_IMMUTABLE,
+ "TILE", 0);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.tile_property = prop;
- /*
- * Standard properties (apply to all planes)
- */
- type = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"type", drm_plane_type_enum_list,
ARRAY_SIZE(drm_plane_type_enum_list));
- dev->mode_config.plane_type_property = type;
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.plane_type_property = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "SRC_X", 0, UINT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_src_x = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "SRC_Y", 0, UINT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_src_y = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "SRC_W", 0, UINT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_src_w = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "SRC_H", 0, UINT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_src_h = prop;
+
+ prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CRTC_X", INT_MIN, INT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_crtc_x = prop;
+
+ prop = drm_property_create_signed_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CRTC_Y", INT_MIN, INT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_crtc_y = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CRTC_W", 0, INT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_crtc_w = prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "CRTC_H", 0, INT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_crtc_h = prop;
+
+ prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
+ "FB_ID", DRM_MODE_OBJECT_FB);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_fb_id = prop;
+
+ prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
+ "CRTC_ID", DRM_MODE_OBJECT_CRTC);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_crtc_id = prop;
+
+ prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
+ "ACTIVE");
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_active = prop;
return 0;
}
@@ -1597,16 +1660,14 @@ static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *gr
total_objects += dev->mode_config.num_crtc;
total_objects += dev->mode_config.num_connector;
total_objects += dev->mode_config.num_encoder;
- total_objects += dev->mode_config.num_bridge;
- group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
+ group->id_list = kcalloc(total_objects, sizeof(uint32_t), GFP_KERNEL);
if (!group->id_list)
return -ENOMEM;
group->num_crtcs = 0;
group->num_connectors = 0;
group->num_encoders = 0;
- group->num_bridges = 0;
return 0;
}
@@ -1626,10 +1687,10 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
struct drm_crtc *crtc;
struct drm_encoder *encoder;
struct drm_connector *connector;
- struct drm_bridge *bridge;
int ret;
- if ((ret = drm_mode_group_init(dev, group)))
+ ret = drm_mode_group_init(dev, group);
+ if (ret)
return ret;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
@@ -1643,11 +1704,6 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
group->id_list[group->num_crtcs + group->num_encoders +
group->num_connectors++] = connector->base.id;
- list_for_each_entry(bridge, &dev->mode_config.bridge_list, head)
- group->id_list[group->num_crtcs + group->num_encoders +
- group->num_connectors + group->num_bridges++] =
- bridge->base.id;
-
return 0;
}
EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
@@ -1996,6 +2052,44 @@ static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *conne
return connector->encoder;
}
+/* helper for getconnector and getproperties ioctls */
+static int get_properties(struct drm_mode_object *obj, bool atomic,
+ uint32_t __user *prop_ptr, uint64_t __user *prop_values,
+ uint32_t *arg_count_props)
+{
+ int props_count;
+ int i, ret, copied;
+
+ props_count = obj->properties->count;
+ if (!atomic)
+ props_count -= obj->properties->atomic_count;
+
+ if ((*arg_count_props >= props_count) && props_count) {
+ for (i = 0, copied = 0; copied < props_count; i++) {
+ struct drm_property *prop = obj->properties->properties[i];
+ uint64_t val;
+
+ if ((prop->flags & DRM_MODE_PROP_ATOMIC) && !atomic)
+ continue;
+
+ ret = drm_object_property_get_value(obj, prop, &val);
+ if (ret)
+ return ret;
+
+ if (put_user(prop->base.id, prop_ptr + copied))
+ return -EFAULT;
+
+ if (put_user(val, prop_values + copied))
+ return -EFAULT;
+
+ copied++;
+ }
+ }
+ *arg_count_props = props_count;
+
+ return 0;
+}
+
/**
* drm_mode_getconnector - get connector configuration
* @dev: drm device for the ioctl
@@ -2017,15 +2111,12 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
struct drm_encoder *encoder;
struct drm_display_mode *mode;
int mode_count = 0;
- int props_count = 0;
int encoders_count = 0;
int ret = 0;
int copied = 0;
int i;
struct drm_mode_modeinfo u_mode;
struct drm_mode_modeinfo __user *mode_ptr;
- uint32_t __user *prop_ptr;
- uint64_t __user *prop_values;
uint32_t __user *encoder_ptr;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
@@ -2036,6 +2127,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
mutex_lock(&dev->mode_config.mutex);
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
connector = drm_connector_find(dev, out_resp->connector_id);
if (!connector) {
@@ -2043,13 +2135,9 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
goto out;
}
- props_count = connector->properties.count;
-
- for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
- if (connector->encoder_ids[i] != 0) {
+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
+ if (connector->encoder_ids[i] != 0)
encoders_count++;
- }
- }
if (out_resp->count_modes == 0) {
connector->funcs->fill_modes(connector,
@@ -2069,14 +2157,11 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
out_resp->mm_height = connector->display_info.height_mm;
out_resp->subpixel = connector->display_info.subpixel_order;
out_resp->connection = connector->status;
- drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
-
encoder = drm_connector_get_encoder(connector);
if (encoder)
out_resp->encoder_id = encoder->base.id;
else
out_resp->encoder_id = 0;
- drm_modeset_unlock(&dev->mode_config.connection_mutex);
/*
* This ioctl is called twice, once to determine how much space is
@@ -2100,26 +2185,12 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
}
out_resp->count_modes = mode_count;
- if ((out_resp->count_props >= props_count) && props_count) {
- copied = 0;
- 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->properties.values[i],
- prop_values + copied)) {
- ret = -EFAULT;
- goto out;
- }
- copied++;
- }
- }
- out_resp->count_props = props_count;
+ ret = get_properties(&connector->base, file_priv->atomic,
+ (uint32_t __user *)(unsigned long)(out_resp->props_ptr),
+ (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),
+ &out_resp->count_props);
+ if (ret)
+ goto out;
if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
copied = 0;
@@ -2138,6 +2209,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
out_resp->count_encoders = encoders_count;
out:
+ drm_modeset_unlock(&dev->mode_config.connection_mutex);
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -2529,7 +2601,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
*
* This is a little helper to wrap internal calls to the ->set_config driver
* interface. The only thing it adds is correct refcounting dance.
- *
+ *
* Returns:
* Zero on success, negative errno on failure.
*/
@@ -2569,6 +2641,27 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
EXPORT_SYMBOL(drm_mode_set_config_internal);
/**
+ * drm_crtc_get_hv_timing - Fetches hdisplay/vdisplay for given mode
+ * @mode: mode to query
+ * @hdisplay: hdisplay value to fill in
+ * @vdisplay: vdisplay value to fill in
+ *
+ * The vdisplay value will be doubled if the specified mode is a stereo mode of
+ * the appropriate layout.
+ */
+void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
+ int *hdisplay, int *vdisplay)
+{
+ struct drm_display_mode adjusted;
+
+ drm_mode_copy(&adjusted, mode);
+ drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE_ONLY);
+ *hdisplay = adjusted.crtc_hdisplay;
+ *vdisplay = adjusted.crtc_vdisplay;
+}
+EXPORT_SYMBOL(drm_crtc_get_hv_timing);
+
+/**
* drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
* CRTC viewport
* @crtc: CRTC that framebuffer will be displayed on
@@ -2585,16 +2678,7 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
{
int hdisplay, vdisplay;
- hdisplay = mode->hdisplay;
- vdisplay = mode->vdisplay;
-
- if (drm_mode_is_stereo(mode)) {
- struct drm_display_mode adjusted = *mode;
-
- drm_mode_set_crtcinfo(&adjusted, CRTC_STEREO_DOUBLE);
- hdisplay = adjusted.crtc_hdisplay;
- vdisplay = adjusted.crtc_vdisplay;
- }
+ drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
if (crtc->invert_dimensions)
swap(hdisplay, vdisplay);
@@ -2690,6 +2774,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
goto out;
}
+ mode->status = drm_mode_validate_basic(mode);
+ if (mode->status != MODE_OK) {
+ ret = -EINVAL;
+ goto out;
+ }
+
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
@@ -2721,9 +2811,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
goto out;
}
- connector_set = kmalloc(crtc_req->count_connectors *
- sizeof(struct drm_connector *),
- GFP_KERNEL);
+ connector_set = kmalloc_array(crtc_req->count_connectors,
+ sizeof(struct drm_connector *),
+ GFP_KERNEL);
if (!connector_set) {
ret = -ENOMEM;
goto out;
@@ -2968,6 +3058,7 @@ int drm_mode_cursor2_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_mode_cursor2 *req = data;
+
return drm_mode_cursor_common(dev, req, file_priv);
}
@@ -3415,7 +3506,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
ret = -EINVAL;
goto out_err1;
}
- clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
+ clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
if (!clips) {
ret = -ENOMEM;
goto out_err1;
@@ -3516,7 +3607,8 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
property->dev = dev;
if (num_values) {
- property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
+ property->values = kcalloc(num_values, sizeof(uint64_t),
+ GFP_KERNEL);
if (!property->values)
goto fail;
}
@@ -3665,7 +3757,7 @@ static struct drm_property *property_create_range(struct drm_device *dev,
}
/**
- * drm_property_create_range - create a new ranged property type
+ * drm_property_create_range - create a new unsigned ranged property type
* @dev: drm device
* @flags: flags specifying the property type
* @name: name of the property
@@ -3676,8 +3768,8 @@ static struct drm_property *property_create_range(struct drm_device *dev,
* object with drm_object_attach_property. The returned property object must be
* freed with drm_property_destroy.
*
- * Userspace is allowed to set any integer value in the (min, max) range
- * inclusive.
+ * Userspace is allowed to set any unsigned integer value in the (min, max)
+ * range inclusive.
*
* Returns:
* A pointer to the newly created property on success, NULL on failure.
@@ -3691,6 +3783,24 @@ struct drm_property *drm_property_create_range(struct drm_device *dev, int flags
}
EXPORT_SYMBOL(drm_property_create_range);
+/**
+ * drm_property_create_signed_range - create a new signed ranged property type
+ * @dev: drm device
+ * @flags: flags specifying the property type
+ * @name: name of the property
+ * @min: minimum value of the property
+ * @max: maximum value of the property
+ *
+ * This creates a new generic drm property which can then be attached to a drm
+ * object with drm_object_attach_property. The returned property object must be
+ * freed with drm_property_destroy.
+ *
+ * Userspace is allowed to set any signed integer value in the (min, max)
+ * range inclusive.
+ *
+ * Returns:
+ * A pointer to the newly created property on success, NULL on failure.
+ */
struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
int flags, const char *name,
int64_t min, int64_t max)
@@ -3700,6 +3810,23 @@ struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_property_create_signed_range);
+/**
+ * drm_property_create_object - create a new object property type
+ * @dev: drm device
+ * @flags: flags specifying the property type
+ * @name: name of the property
+ * @type: object type from DRM_MODE_OBJECT_* defines
+ *
+ * This creates a new generic drm property which can then be attached to a drm
+ * object with drm_object_attach_property. The returned property object must be
+ * freed with drm_property_destroy.
+ *
+ * Userspace is only allowed to set this to any property value of the given
+ * @type. Only useful for atomic properties, which is enforced.
+ *
+ * Returns:
+ * A pointer to the newly created property on success, NULL on failure.
+ */
struct drm_property *drm_property_create_object(struct drm_device *dev,
int flags, const char *name, uint32_t type)
{
@@ -3707,6 +3834,9 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
flags |= DRM_MODE_PROP_OBJECT;
+ if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC)))
+ return NULL;
+
property = drm_property_create(dev, flags, name, 1);
if (!property)
return NULL;
@@ -3718,6 +3848,28 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
EXPORT_SYMBOL(drm_property_create_object);
/**
+ * drm_property_create_bool - create a new boolean property type
+ * @dev: drm device
+ * @flags: flags specifying the property type
+ * @name: name of the property
+ *
+ * This creates a new generic drm property which can then be attached to a drm
+ * object with drm_object_attach_property. The returned property object must be
+ * freed with drm_property_destroy.
+ *
+ * This is implemented as a ranged property with only {0, 1} as valid values.
+ *
+ * Returns:
+ * A pointer to the newly created property on success, NULL on failure.
+ */
+struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
+ const char *name)
+{
+ return drm_property_create_range(dev, flags, name, 0, 1);
+}
+EXPORT_SYMBOL(drm_property_create_bool);
+
+/**
* drm_property_add_enum - add a possible value to an enumeration property
* @property: enumeration property to change
* @index: index of the new enumeration
@@ -3822,9 +3974,11 @@ void drm_object_attach_property(struct drm_mode_object *obj,
return;
}
- obj->properties->ids[count] = property->base.id;
+ obj->properties->properties[count] = property;
obj->properties->values[count] = init_val;
obj->properties->count++;
+ if (property->flags & DRM_MODE_PROP_ATOMIC)
+ obj->properties->atomic_count++;
}
EXPORT_SYMBOL(drm_object_attach_property);
@@ -3847,7 +4001,7 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
int i;
for (i = 0; i < obj->properties->count; i++) {
- if (obj->properties->ids[i] == property->base.id) {
+ if (obj->properties->properties[i] == property) {
obj->properties->values[i] = val;
return 0;
}
@@ -3876,8 +4030,16 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
{
int i;
+ /* read-only properties bypass atomic mechanism and still store
+ * their value in obj->properties->values[].. mostly to avoid
+ * having to deal w/ EDID and similar props in atomic paths:
+ */
+ if (drm_core_check_feature(property->dev, DRIVER_ATOMIC) &&
+ !(property->flags & DRM_MODE_PROP_IMMUTABLE))
+ return drm_atomic_get_property(obj, property, val);
+
for (i = 0; i < obj->properties->count; i++) {
- if (obj->properties->ids[i] == property->base.id) {
+ if (obj->properties->properties[i] == property) {
*val = obj->properties->values[i];
return 0;
}
@@ -4057,7 +4219,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
if (out_resp->length == blob->length) {
blob_ptr = (void __user *)(unsigned long)out_resp->data;
- if (copy_to_user(blob_ptr, blob->data, blob->length)){
+ if (copy_to_user(blob_ptr, blob->data, blob->length)) {
ret = -EFAULT;
goto done;
}
@@ -4193,25 +4355,38 @@ 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,
- uint64_t value)
+/* Some properties could refer to dynamic refcnt'd objects, or things that
+ * need special locking to handle lifetime issues (ie. to ensure the prop
+ * value doesn't become invalid part way through the property update due to
+ * race). The value returned by reference via 'obj' should be passed back
+ * to drm_property_change_valid_put() after the property is set (and the
+ * object to which the property is attached has a chance to take it's own
+ * reference).
+ */
+bool drm_property_change_valid_get(struct drm_property *property,
+ uint64_t value, struct drm_mode_object **ref)
{
+ int i;
+
if (property->flags & DRM_MODE_PROP_IMMUTABLE)
return false;
+ *ref = NULL;
+
if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) {
if (value < property->values[0] || value > property->values[1])
return false;
return true;
} else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) {
int64_t svalue = U642I64(value);
+
if (svalue < U642I64(property->values[0]) ||
svalue > U642I64(property->values[1]))
return false;
return true;
} else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
- int i;
uint64_t valid_mask = 0;
+
for (i = 0; i < property->num_values; i++)
valid_mask |= (1ULL << property->values[i]);
return !(value & ~valid_mask);
@@ -4219,25 +4394,40 @@ static bool drm_property_change_is_valid(struct drm_property *property,
/* Only the driver knows */
return true;
} else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
- struct drm_mode_object *obj;
/* a zero value for an object property translates to null: */
if (value == 0)
return true;
- /*
- * NOTE: use _object_find() directly to bypass restriction on
- * looking up refcnt'd objects (ie. fb's). For a refcnt'd
- * object this could race against object finalization, so it
- * simply tells us that the object *was* valid. Which is good
- * enough.
- */
- obj = _object_find(property->dev, value, property->values[0]);
- return obj != NULL;
- } else {
- int i;
- for (i = 0; i < property->num_values; i++)
- if (property->values[i] == value)
+
+ /* handle refcnt'd objects specially: */
+ if (property->values[0] == DRM_MODE_OBJECT_FB) {
+ struct drm_framebuffer *fb;
+ fb = drm_framebuffer_lookup(property->dev, value);
+ if (fb) {
+ *ref = &fb->base;
return true;
- return false;
+ } else {
+ return false;
+ }
+ } else {
+ return _object_find(property->dev, value, property->values[0]) != NULL;
+ }
+ }
+
+ for (i = 0; i < property->num_values; i++)
+ if (property->values[i] == value)
+ return true;
+ return false;
+}
+
+void drm_property_change_valid_put(struct drm_property *property,
+ struct drm_mode_object *ref)
+{
+ if (!ref)
+ return;
+
+ if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) {
+ if (property->values[0] == DRM_MODE_OBJECT_FB)
+ drm_framebuffer_unreference(obj_to_fb(ref));
}
}
@@ -4356,11 +4546,6 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
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;
@@ -4377,30 +4562,11 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
goto out;
}
- props_count = obj->properties->count;
+ ret = get_properties(obj, file_priv->atomic,
+ (uint32_t __user *)(unsigned long)(arg->props_ptr),
+ (uint64_t __user *)(unsigned long)(arg->prop_values_ptr),
+ &arg->count_props);
- /* 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:
drm_modeset_unlock_all(dev);
return ret;
@@ -4429,8 +4595,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
struct drm_mode_object *arg_obj;
struct drm_mode_object *prop_obj;
struct drm_property *property;
- int ret = -EINVAL;
- int i;
+ int i, ret = -EINVAL;
+ struct drm_mode_object *ref;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
@@ -4446,7 +4612,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
goto out;
for (i = 0; i < arg_obj->properties->count; i++)
- if (arg_obj->properties->ids[i] == arg->prop_id)
+ if (arg_obj->properties->properties[i]->base.id == arg->prop_id)
break;
if (i == arg_obj->properties->count)
@@ -4460,7 +4626,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
}
property = obj_to_property(prop_obj);
- if (!drm_property_change_is_valid(property, arg->value))
+ if (!drm_property_change_valid_get(property, arg->value, &ref))
goto out;
switch (arg_obj->type) {
@@ -4477,6 +4643,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
break;
}
+ drm_property_change_valid_put(property, ref);
+
out:
drm_modeset_unlock_all(dev);
return ret;
@@ -4526,7 +4694,8 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
{
crtc->gamma_size = gamma_size;
- crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
+ crtc->gamma_store = kcalloc(gamma_size, sizeof(uint16_t) * 3,
+ GFP_KERNEL);
if (!crtc->gamma_store) {
crtc->gamma_size = 0;
return -ENOMEM;
@@ -4741,23 +4910,23 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
ret = -ENOMEM;
spin_lock_irqsave(&dev->event_lock, flags);
- if (file_priv->event_space < sizeof e->event) {
+ if (file_priv->event_space < sizeof(e->event)) {
spin_unlock_irqrestore(&dev->event_lock, flags);
goto out;
}
- file_priv->event_space -= sizeof e->event;
+ file_priv->event_space -= sizeof(e->event);
spin_unlock_irqrestore(&dev->event_lock, flags);
- e = kzalloc(sizeof *e, GFP_KERNEL);
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
if (e == NULL) {
spin_lock_irqsave(&dev->event_lock, flags);
- file_priv->event_space += sizeof e->event;
+ file_priv->event_space += sizeof(e->event);
spin_unlock_irqrestore(&dev->event_lock, flags);
goto out;
}
e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
- e->event.base.length = sizeof e->event;
+ e->event.base.length = sizeof(e->event);
e->event.user_data = page_flip->user_data;
e->base.event = &e->event.base;
e->base.file_priv = file_priv;
@@ -4770,7 +4939,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if (ret) {
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
spin_lock_irqsave(&dev->event_lock, flags);
- file_priv->event_space += sizeof e->event;
+ file_priv->event_space += sizeof(e->event);
spin_unlock_irqrestore(&dev->event_lock, flags);
kfree(e);
}
@@ -5211,7 +5380,6 @@ void drm_mode_config_init(struct drm_device *dev)
INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list);
INIT_LIST_HEAD(&dev->mode_config.connector_list);
- INIT_LIST_HEAD(&dev->mode_config.bridge_list);
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);
@@ -5220,8 +5388,7 @@ void drm_mode_config_init(struct drm_device *dev)
idr_init(&dev->mode_config.tile_idr);
drm_modeset_lock_all(dev);
- drm_mode_create_standard_connector_properties(dev);
- drm_mode_create_standard_plane_properties(dev);
+ drm_mode_create_standard_properties(dev);
drm_modeset_unlock_all(dev);
/* Just to be sure */
@@ -5252,7 +5419,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_connector *connector, *ot;
struct drm_crtc *crtc, *ct;
struct drm_encoder *encoder, *enct;
- struct drm_bridge *bridge, *brt;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
struct drm_property_blob *blob, *bt;
@@ -5263,11 +5429,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
encoder->funcs->destroy(encoder);
}
- list_for_each_entry_safe(bridge, brt,
- &dev->mode_config.bridge_list, head) {
- bridge->funcs->destroy(bridge);
- }
-
list_for_each_entry_safe(connector, ot,
&dev->mode_config.connector_list, head) {
connector->funcs->destroy(connector);
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index d552708409de..b1979e7bdc88 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -946,6 +946,7 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod
crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
if (!crtc_state)
return -ENOMEM;
+ crtc_state->crtc = crtc;
crtc_state->enable = true;
crtc_state->planes_changed = true;
@@ -1005,6 +1006,7 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
if (!plane_state)
return -ENOMEM;
+ plane_state->plane = plane;
plane_state->crtc = crtc;
drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index a2945ee6d675..247dc8b62564 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -36,3 +36,9 @@ int drm_mode_object_get(struct drm_device *dev,
void drm_mode_object_put(struct drm_device *dev,
struct drm_mode_object *object);
+/* drm_atomic.c */
+int drm_atomic_get_property(struct drm_mode_object *obj,
+ struct drm_property *property, uint64_t *val);
+int drm_mode_atomic_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 79968e39c8d0..f1283878ff6d 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -354,6 +354,37 @@ int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link)
EXPORT_SYMBOL(drm_dp_link_power_up);
/**
+ * drm_dp_link_power_down() - power down a DisplayPort link
+ * @aux: DisplayPort AUX channel
+ * @link: pointer to a structure containing the link configuration
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link)
+{
+ u8 value;
+ int err;
+
+ /* DP_SET_POWER register is only available on DPCD v1.1 and later */
+ if (link->revision < 0x11)
+ return 0;
+
+ err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
+ if (err < 0)
+ return err;
+
+ value &= ~DP_SET_POWER_MASK;
+ value |= DP_SET_POWER_D3;
+
+ err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_dp_link_power_down);
+
+/**
* drm_dp_link_configure() - configure a DisplayPort link
* @aux: DisplayPort AUX channel
* @link: pointer to a structure containing the link configuration
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 4f41377b0b80..d51213464672 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -40,15 +40,19 @@
unsigned int drm_debug = 0; /* 1 to enable debug output */
EXPORT_SYMBOL(drm_debug);
+bool drm_atomic = 0;
+
MODULE_AUTHOR(CORE_AUTHOR);
MODULE_DESCRIPTION(CORE_DESC);
MODULE_LICENSE("GPL and additional rights");
MODULE_PARM_DESC(debug, "Enable debug output");
+MODULE_PARM_DESC(atomic, "Enable experimental atomic KMS API");
MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)");
MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
module_param_named(debug, drm_debug, int, 0600);
+module_param_named_unsafe(atomic, drm_atomic, bool, 0600);
static DEFINE_SPINLOCK(drm_minor_lock);
static struct idr drm_minors_idr;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index dc386ebe5193..1e6a0c760c5d 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1722,7 +1722,7 @@ out:
* RETURNS:
* Zero if everything went ok, nonzero otherwise.
*/
-bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
+int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
{
struct drm_device *dev = fb_helper->dev;
int count = 0;
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 0b9514b6cd64..076dd606b580 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -478,64 +478,59 @@ int drm_release(struct inode *inode, struct file *filp)
}
EXPORT_SYMBOL(drm_release);
-static bool
-drm_dequeue_event(struct drm_file *file_priv,
- size_t total, size_t max, struct drm_pending_event **out)
+ssize_t drm_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *offset)
{
+ struct drm_file *file_priv = filp->private_data;
struct drm_device *dev = file_priv->minor->dev;
- struct drm_pending_event *e;
- unsigned long flags;
- bool ret = false;
-
- spin_lock_irqsave(&dev->event_lock, flags);
+ ssize_t ret = 0;
- *out = NULL;
- if (list_empty(&file_priv->event_list))
- goto out;
- e = list_first_entry(&file_priv->event_list,
- struct drm_pending_event, link);
- if (e->event->length + total > max)
- goto out;
+ if (!access_ok(VERIFY_WRITE, buffer, count))
+ return -EFAULT;
- file_priv->event_space += e->event->length;
- list_del(&e->link);
- *out = e;
- ret = true;
+ spin_lock_irq(&dev->event_lock);
+ for (;;) {
+ if (list_empty(&file_priv->event_list)) {
+ if (ret)
+ break;
-out:
- spin_unlock_irqrestore(&dev->event_lock, flags);
- return ret;
-}
-
-ssize_t drm_read(struct file *filp, char __user *buffer,
- size_t count, loff_t *offset)
-{
- struct drm_file *file_priv = filp->private_data;
- struct drm_pending_event *e;
- size_t total;
- ssize_t ret;
+ if (filp->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ break;
+ }
- if ((filp->f_flags & O_NONBLOCK) == 0) {
- ret = wait_event_interruptible(file_priv->event_wait,
- !list_empty(&file_priv->event_list));
- if (ret < 0)
- return ret;
- }
+ spin_unlock_irq(&dev->event_lock);
+ ret = wait_event_interruptible(file_priv->event_wait,
+ !list_empty(&file_priv->event_list));
+ spin_lock_irq(&dev->event_lock);
+ if (ret < 0)
+ break;
+
+ ret = 0;
+ } else {
+ struct drm_pending_event *e;
+
+ e = list_first_entry(&file_priv->event_list,
+ struct drm_pending_event, link);
+ if (e->event->length + ret > count)
+ break;
+
+ if (__copy_to_user_inatomic(buffer + ret,
+ e->event, e->event->length)) {
+ if (ret == 0)
+ ret = -EFAULT;
+ break;
+ }
- total = 0;
- while (drm_dequeue_event(file_priv, total, count, &e)) {
- if (copy_to_user(buffer + total,
- e->event, e->event->length)) {
- total = -EFAULT;
+ file_priv->event_space += e->event->length;
+ ret += e->event->length;
+ list_del(&e->link);
e->destroy(e);
- break;
}
-
- total += e->event->length;
- e->destroy(e);
}
+ spin_unlock_irq(&dev->event_lock);
- return total ?: -EAGAIN;
+ return ret;
}
EXPORT_SYMBOL(drm_read);
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 51efebd434f3..f1b32f91d941 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -153,30 +153,6 @@ int drm_bufs_info(struct seq_file *m, void *data)
}
/**
- * Called when "/proc/dri/.../vblank" is read.
- */
-int drm_vblank_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;
- int crtc;
-
- mutex_lock(&dev->struct_mutex);
- for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
- seq_printf(m, "CRTC %d enable: %d\n",
- crtc, atomic_read(&dev->vblank[crtc].refcount));
- seq_printf(m, "CRTC %d counter: %d\n",
- crtc, drm_vblank_count(dev, crtc));
- seq_printf(m, "CRTC %d last wait: %d\n",
- crtc, dev->vblank[crtc].last_wait);
- seq_printf(m, "CRTC %d in modeset: %d\n",
- crtc, dev->vblank[crtc].inmodeset);
- }
- mutex_unlock(&dev->struct_mutex);
- return 0;
-}
-
-/**
* Called when "/proc/dri/.../clients" is read.
*
*/
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 7cc0a3516871..12a61d706827 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -55,7 +55,6 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr
int drm_name_info(struct seq_file *m, void *data);
int drm_vm_info(struct seq_file *m, void *data);
int drm_bufs_info(struct seq_file *m, void *data);
-int drm_vblank_info(struct seq_file *m, void *data);
int drm_clients_info(struct seq_file *m, void* data);
int drm_gem_name_info(struct seq_file *m, void *data);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 00587a1e3c83..3785d66721f2 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -32,6 +32,7 @@
#include <drm/drm_core.h>
#include "drm_legacy.h"
#include "drm_internal.h"
+#include "drm_crtc_internal.h"
#include <linux/pci.h>
#include <linux/export.h>
@@ -345,6 +346,17 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
return -EINVAL;
file_priv->universal_planes = req->value;
break;
+ case DRM_CLIENT_CAP_ATOMIC:
+ /* for now, hide behind experimental drm.atomic moduleparam */
+ if (!drm_atomic)
+ return -EINVAL;
+ if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
+ return -EINVAL;
+ if (req->value > 1)
+ return -EINVAL;
+ file_priv->atomic = req->value;
+ file_priv->universal_planes = req->value;
+ break;
default:
return -EINVAL;
}
@@ -620,6 +632,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, 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),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 4d79dad9d44f..10574a0c3a55 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -185,8 +185,15 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
return;
}
- dev->driver->disable_vblank(dev, crtc);
- vblank->enabled = false;
+ /*
+ * Only disable vblank interrupts if they're enabled. This avoids
+ * calling the ->disable_vblank() operation in atomic context with the
+ * hardware potentially runtime suspended.
+ */
+ if (vblank->enabled) {
+ dev->driver->disable_vblank(dev, crtc);
+ vblank->enabled = false;
+ }
/* No further vblank irq's will be processed after
* this point. Get current hardware vblank count and
@@ -778,7 +785,7 @@ static struct timeval get_drm_timestamp(void)
/**
* drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent
- * vblank interval
+ * vblank interval
* @dev: DRM device
* @crtc: which CRTC's vblank timestamp to retrieve
* @tvblank: Pointer to target struct timeval which should receive the timestamp
@@ -933,6 +940,7 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
{
struct timeval now;
unsigned int seq;
+
if (crtc >= 0) {
seq = drm_vblank_count_and_time(dev, crtc, &now);
} else {
@@ -1422,7 +1430,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
unsigned int seq;
int ret;
- e = kzalloc(sizeof *e, GFP_KERNEL);
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
if (e == NULL) {
ret = -ENOMEM;
goto err_put;
@@ -1431,7 +1439,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
e->pipe = pipe;
e->base.pid = current->pid;
e->event.base.type = DRM_EVENT_VBLANK;
- e->event.base.length = sizeof e->event;
+ e->event.base.length = sizeof(e->event);
e->event.user_data = vblwait->request.signal;
e->base.event = &e->event.base;
e->base.file_priv = file_priv;
@@ -1451,12 +1459,12 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
goto err_unlock;
}
- if (file_priv->event_space < sizeof e->event) {
+ if (file_priv->event_space < sizeof(e->event)) {
ret = -EBUSY;
goto err_unlock;
}
- file_priv->event_space -= sizeof e->event;
+ file_priv->event_space -= sizeof(e->event);
seq = drm_vblank_count_and_time(dev, pipe, &now);
if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index c0644bb865f2..2d5ca8eec13a 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -323,8 +323,6 @@ EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
const struct mipi_dsi_msg *msg)
{
- const u8 *tx = msg->tx_buf;
-
if (!packet || !msg)
return -EINVAL;
@@ -353,8 +351,10 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
packet->header[2] = (msg->tx_len >> 8) & 0xff;
packet->payload_length = msg->tx_len;
- packet->payload = tx;
+ packet->payload = msg->tx_buf;
} else {
+ const u8 *tx = msg->tx_buf;
+
packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
}
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 6d8b941c8200..487d0e35c134 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -615,6 +615,46 @@ void drm_display_mode_from_videomode(const struct videomode *vm,
}
EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
+/**
+ * drm_display_mode_to_videomode - fill in @vm using @dmode,
+ * @dmode: drm_display_mode structure to use as source
+ * @vm: videomode structure to use as destination
+ *
+ * Fills out @vm using the display mode specified in @dmode.
+ */
+void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
+ struct videomode *vm)
+{
+ vm->hactive = dmode->hdisplay;
+ vm->hfront_porch = dmode->hsync_start - dmode->hdisplay;
+ vm->hsync_len = dmode->hsync_end - dmode->hsync_start;
+ vm->hback_porch = dmode->htotal - dmode->hsync_end;
+
+ vm->vactive = dmode->vdisplay;
+ vm->vfront_porch = dmode->vsync_start - dmode->vdisplay;
+ vm->vsync_len = dmode->vsync_end - dmode->vsync_start;
+ vm->vback_porch = dmode->vtotal - dmode->vsync_end;
+
+ vm->pixelclock = dmode->clock * 1000;
+
+ vm->flags = 0;
+ if (dmode->flags & DRM_MODE_FLAG_PHSYNC)
+ vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
+ else if (dmode->flags & DRM_MODE_FLAG_NHSYNC)
+ vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
+ if (dmode->flags & DRM_MODE_FLAG_PVSYNC)
+ vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
+ else if (dmode->flags & DRM_MODE_FLAG_NVSYNC)
+ vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
+ if (dmode->flags & DRM_MODE_FLAG_INTERLACE)
+ vm->flags |= DISPLAY_FLAGS_INTERLACED;
+ if (dmode->flags & DRM_MODE_FLAG_DBLSCAN)
+ vm->flags |= DISPLAY_FLAGS_DOUBLESCAN;
+ if (dmode->flags & DRM_MODE_FLAG_DBLCLK)
+ vm->flags |= DISPLAY_FLAGS_DOUBLECLK;
+}
+EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
+
#ifdef CONFIG_OF
/**
* of_get_drm_display_mode - get a drm_display_mode from devicetree
@@ -739,6 +779,8 @@ EXPORT_SYMBOL(drm_mode_vrefresh);
* - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for
* buffers containing two eyes (only adjust the timings when needed, eg. for
* "frame packing" or "side by side full").
+ * - The CRTC_NO_DBLSCAN and CRTC_NO_VSCAN flags request that adjustment *not*
+ * be performed for doublescan and vscan > 1 modes respectively.
*/
void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
{
@@ -765,18 +807,22 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
}
}
- if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
- p->crtc_vdisplay *= 2;
- p->crtc_vsync_start *= 2;
- p->crtc_vsync_end *= 2;
- p->crtc_vtotal *= 2;
+ if (!(adjust_flags & CRTC_NO_DBLSCAN)) {
+ if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
+ p->crtc_vdisplay *= 2;
+ p->crtc_vsync_start *= 2;
+ p->crtc_vsync_end *= 2;
+ p->crtc_vtotal *= 2;
+ }
}
- if (p->vscan > 1) {
- p->crtc_vdisplay *= p->vscan;
- p->crtc_vsync_start *= p->vscan;
- p->crtc_vsync_end *= p->vscan;
- p->crtc_vtotal *= p->vscan;
+ if (!(adjust_flags & CRTC_NO_VSCAN)) {
+ if (p->vscan > 1) {
+ p->crtc_vdisplay *= p->vscan;
+ p->crtc_vsync_start *= p->vscan;
+ p->crtc_vsync_end *= p->vscan;
+ p->crtc_vtotal *= p->vscan;
+ }
}
if (adjust_flags & CRTC_STEREO_DOUBLE) {
@@ -906,9 +952,40 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
/**
+ * drm_mode_validate_basic - make sure the mode is somewhat sane
+ * @mode: mode to check
+ *
+ * Check that the mode timings are at least somewhat reasonable.
+ * Any hardware specific limits are left up for each driver to check.
+ *
+ * Returns:
+ * The mode status
+ */
+enum drm_mode_status
+drm_mode_validate_basic(const struct drm_display_mode *mode)
+{
+ if (mode->clock == 0)
+ return MODE_CLOCK_LOW;
+
+ if (mode->hdisplay == 0 ||
+ mode->hsync_start < mode->hdisplay ||
+ mode->hsync_end < mode->hsync_start ||
+ mode->htotal < mode->hsync_end)
+ return MODE_H_ILLEGAL;
+
+ if (mode->vdisplay == 0 ||
+ mode->vsync_start < mode->vdisplay ||
+ mode->vsync_end < mode->vsync_start ||
+ mode->vtotal < mode->vsync_end)
+ return MODE_V_ILLEGAL;
+
+ return MODE_OK;
+}
+EXPORT_SYMBOL(drm_mode_validate_basic);
+
+/**
* drm_mode_validate_size - make sure modes adhere to size constraints
- * @dev: DRM device
- * @mode_list: list of modes to check
+ * @mode: mode to check
* @maxX: maximum width
* @maxY: maximum height
*
@@ -916,23 +993,80 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
* limitations of the DRM device/connector. If a mode is too big its status
* member is updated with the appropriate validation failure code. The list
* itself is not changed.
+ *
+ * Returns:
+ * The mode status
*/
-void drm_mode_validate_size(struct drm_device *dev,
- struct list_head *mode_list,
- int maxX, int maxY)
+enum drm_mode_status
+drm_mode_validate_size(const struct drm_display_mode *mode,
+ int maxX, int maxY)
{
- struct drm_display_mode *mode;
+ if (maxX > 0 && mode->hdisplay > maxX)
+ return MODE_VIRTUAL_X;
- list_for_each_entry(mode, mode_list, head) {
- if (maxX > 0 && mode->hdisplay > maxX)
- mode->status = MODE_VIRTUAL_X;
+ if (maxY > 0 && mode->vdisplay > maxY)
+ return MODE_VIRTUAL_Y;
- if (maxY > 0 && mode->vdisplay > maxY)
- mode->status = MODE_VIRTUAL_Y;
- }
+ return MODE_OK;
}
EXPORT_SYMBOL(drm_mode_validate_size);
+#define MODE_STATUS(status) [MODE_ ## status + 3] = #status
+
+static const char * const drm_mode_status_names[] = {
+ MODE_STATUS(OK),
+ MODE_STATUS(HSYNC),
+ MODE_STATUS(VSYNC),
+ MODE_STATUS(H_ILLEGAL),
+ MODE_STATUS(V_ILLEGAL),
+ MODE_STATUS(BAD_WIDTH),
+ MODE_STATUS(NOMODE),
+ MODE_STATUS(NO_INTERLACE),
+ MODE_STATUS(NO_DBLESCAN),
+ MODE_STATUS(NO_VSCAN),
+ MODE_STATUS(MEM),
+ MODE_STATUS(VIRTUAL_X),
+ MODE_STATUS(VIRTUAL_Y),
+ MODE_STATUS(MEM_VIRT),
+ MODE_STATUS(NOCLOCK),
+ MODE_STATUS(CLOCK_HIGH),
+ MODE_STATUS(CLOCK_LOW),
+ MODE_STATUS(CLOCK_RANGE),
+ MODE_STATUS(BAD_HVALUE),
+ MODE_STATUS(BAD_VVALUE),
+ MODE_STATUS(BAD_VSCAN),
+ MODE_STATUS(HSYNC_NARROW),
+ MODE_STATUS(HSYNC_WIDE),
+ MODE_STATUS(HBLANK_NARROW),
+ MODE_STATUS(HBLANK_WIDE),
+ MODE_STATUS(VSYNC_NARROW),
+ MODE_STATUS(VSYNC_WIDE),
+ MODE_STATUS(VBLANK_NARROW),
+ MODE_STATUS(VBLANK_WIDE),
+ MODE_STATUS(PANEL),
+ MODE_STATUS(INTERLACE_WIDTH),
+ MODE_STATUS(ONE_WIDTH),
+ MODE_STATUS(ONE_HEIGHT),
+ MODE_STATUS(ONE_SIZE),
+ MODE_STATUS(NO_REDUCED),
+ MODE_STATUS(NO_STEREO),
+ MODE_STATUS(UNVERIFIED),
+ MODE_STATUS(BAD),
+ MODE_STATUS(ERROR),
+};
+
+#undef MODE_STATUS
+
+static const char *drm_get_mode_status_name(enum drm_mode_status status)
+{
+ int index = status + 3;
+
+ if (WARN_ON(index < 0 || index >= ARRAY_SIZE(drm_mode_status_names)))
+ return "";
+
+ return drm_mode_status_names[index];
+}
+
/**
* drm_mode_prune_invalid - remove invalid modes from mode list
* @dev: DRM device
@@ -954,8 +1088,9 @@ void drm_mode_prune_invalid(struct drm_device *dev,
list_del(&mode->head);
if (verbose) {
drm_mode_debug_printmodeline(mode);
- DRM_DEBUG_KMS("Not using %s mode %d\n",
- mode->name, mode->status);
+ DRM_DEBUG_KMS("Not using %s mode: %s\n",
+ mode->name,
+ drm_get_mode_status_name(mode->status));
}
drm_mode_destroy(dev, mode);
}
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 18a1ac6ac22f..5ba5792bfdba 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -142,6 +142,17 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
{
int hscale, vscale;
+ if (!fb) {
+ *visible = false;
+ return 0;
+ }
+
+ /* crtc should only be NULL when disabling (i.e., !fb) */
+ if (WARN_ON(!crtc)) {
+ *visible = false;
+ return 0;
+ }
+
if (!crtc->enabled && !can_update_disabled) {
DRM_DEBUG_KMS("Cannot update plane of a disabled CRTC.\n");
return -EINVAL;
@@ -155,11 +166,6 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
return -ERANGE;
}
- if (!fb) {
- *visible = false;
- return 0;
- }
-
*visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);
if (!*visible)
/*
@@ -429,7 +435,8 @@ int drm_plane_helper_commit(struct drm_plane *plane,
goto out;
}
- if (plane_funcs->prepare_fb && plane_state->fb) {
+ if (plane_funcs->prepare_fb && plane_state->fb &&
+ plane_state->fb != old_fb) {
ret = plane_funcs->prepare_fb(plane, plane_state->fb);
if (ret)
goto out;
@@ -443,13 +450,28 @@ int drm_plane_helper_commit(struct drm_plane *plane,
crtc_funcs[i]->atomic_begin(crtc[i]);
}
- plane_funcs->atomic_update(plane, plane_state);
+ /*
+ * Drivers may optionally implement the ->atomic_disable callback, so
+ * special-case that here.
+ */
+ if (drm_atomic_plane_disabling(plane, plane_state) &&
+ plane_funcs->atomic_disable)
+ plane_funcs->atomic_disable(plane, plane_state);
+ else
+ plane_funcs->atomic_update(plane, plane_state);
for (i = 0; i < 2; i++) {
if (crtc_funcs[i] && crtc_funcs[i]->atomic_flush)
crtc_funcs[i]->atomic_flush(crtc[i]);
}
+ /*
+ * If we only moved the plane and didn't change fb's, there's no need to
+ * wait for vblank.
+ */
+ if (plane->state->fb == old_fb)
+ goto out;
+
for (i = 0; i < 2; i++) {
if (!crtc[i])
continue;
@@ -478,7 +500,7 @@ out:
}
/**
- * drm_plane_helper_update() - Helper for primary plane update
+ * drm_plane_helper_update() - Transitional helper for plane update
* @plane: plane object to update
* @crtc: owning CRTC of owning plane
* @fb: framebuffer to flip onto plane
@@ -517,6 +539,7 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
if (!plane_state)
return -ENOMEM;
+ plane_state->plane = plane;
plane_state->crtc = crtc;
drm_atomic_set_fb_for_plane(plane_state, fb);
@@ -534,7 +557,7 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
EXPORT_SYMBOL(drm_plane_helper_update);
/**
- * drm_plane_helper_disable() - Helper for primary plane disable
+ * drm_plane_helper_disable() - Transitional helper for plane disable
* @plane: plane to disable
*
* Provides a default plane disable handler using the atomic plane update
@@ -563,6 +586,7 @@ int drm_plane_helper_disable(struct drm_plane *plane)
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
if (!plane_state)
return -ENOMEM;
+ plane_state->plane = plane;
plane_state->crtc = NULL;
drm_atomic_set_fb_for_plane(plane_state, NULL);
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 7483a47de8e4..6591d48c1b9d 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -58,28 +58,23 @@
static bool drm_kms_helper_poll = true;
module_param_named(poll, drm_kms_helper_poll, bool, 0600);
-static void drm_mode_validate_flag(struct drm_connector *connector,
- int flags)
+static enum drm_mode_status
+drm_mode_validate_flag(const struct drm_display_mode *mode,
+ int flags)
{
- struct drm_display_mode *mode;
+ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+ !(flags & DRM_MODE_FLAG_INTERLACE))
+ return MODE_NO_INTERLACE;
- if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
- DRM_MODE_FLAG_3D_MASK))
- return;
+ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+ !(flags & DRM_MODE_FLAG_DBLSCAN))
+ return MODE_NO_DBLESCAN;
- 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;
- if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
- !(flags & DRM_MODE_FLAG_DBLSCAN))
- mode->status = MODE_NO_DBLESCAN;
- if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
- !(flags & DRM_MODE_FLAG_3D_MASK))
- mode->status = MODE_NO_STEREO;
- }
+ if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
+ !(flags & DRM_MODE_FLAG_3D_MASK))
+ return MODE_NO_STEREO;
- return;
+ return MODE_OK;
}
static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
@@ -108,6 +103,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
int count = 0;
int mode_flags = 0;
bool verbose_prune = true;
+ enum drm_connector_status old_status;
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
@@ -126,7 +122,33 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
if (connector->funcs->force)
connector->funcs->force(connector);
} else {
+ old_status = connector->status;
+
connector->status = connector->funcs->detect(connector, true);
+
+ /*
+ * Normally either the driver's hpd code or the poll loop should
+ * pick up any changes and fire the hotplug event. But if
+ * userspace sneaks in a probe, we might miss a change. Hence
+ * check here, and if anything changed start the hotplug code.
+ */
+ if (old_status != connector->status) {
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+ connector->base.id,
+ connector->name,
+ old_status, connector->status);
+
+ /*
+ * The hotplug event code might call into the fb
+ * helpers, and so expects that we do not hold any
+ * locks. Fire up the poll struct instead, it will
+ * disable itself again.
+ */
+ dev->mode_config.delayed_event = true;
+ if (dev->mode_config.poll_enabled)
+ schedule_delayed_work(&dev->mode_config.output_poll_work,
+ 0);
+ }
}
/* Re-enable polling in case the global poll config changed. */
@@ -164,18 +186,22 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
drm_mode_connector_list_update(connector, merge_type_bits);
- if (maxX && maxY)
- drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
-
if (connector->interlace_allowed)
mode_flags |= DRM_MODE_FLAG_INTERLACE;
if (connector->doublescan_allowed)
mode_flags |= DRM_MODE_FLAG_DBLSCAN;
if (connector->stereo_allowed)
mode_flags |= DRM_MODE_FLAG_3D_MASK;
- drm_mode_validate_flag(connector, mode_flags);
list_for_each_entry(mode, &connector->modes, head) {
+ mode->status = drm_mode_validate_basic(mode);
+
+ if (mode->status == MODE_OK)
+ mode->status = drm_mode_validate_size(mode, maxX, maxY);
+
+ if (mode->status == MODE_OK)
+ mode->status = drm_mode_validate_flag(mode, mode_flags);
+
if (mode->status == MODE_OK && connector_funcs->mode_valid)
mode->status = connector_funcs->mode_valid(connector,
mode);
@@ -275,10 +301,14 @@ static void output_poll_execute(struct work_struct *work)
struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
struct drm_connector *connector;
enum drm_connector_status old_status;
- bool repoll = false, changed = false;
+ bool repoll = false, changed;
+
+ /* Pick up any changes detected by the probe functions. */
+ changed = dev->mode_config.delayed_event;
+ dev->mode_config.delayed_event = false;
if (!drm_kms_helper_poll)
- return;
+ goto out;
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -305,6 +335,24 @@ static void output_poll_execute(struct work_struct *work)
if (old_status != connector->status) {
const char *old, *new;
+ /*
+ * The poll work sets force=false when calling detect so
+ * that drivers can avoid to do disruptive tests (e.g.
+ * when load detect cycles could cause flickering on
+ * other, running displays). This bears the risk that we
+ * flip-flop between unknown here in the poll work and
+ * the real state when userspace forces a full detect
+ * call after receiving a hotplug event due to this
+ * change.
+ *
+ * Hence clamp an unknown detect status to the old
+ * value.
+ */
+ if (connector->status == connector_status_unknown) {
+ connector->status = old_status;
+ continue;
+ }
+
old = drm_get_connector_status_name(old_status);
new = drm_get_connector_status_name(connector->status);
@@ -320,6 +368,7 @@ static void output_poll_execute(struct work_struct *work)
mutex_unlock(&dev->mode_config.mutex);
+out:
if (changed)
drm_kms_helper_hotplug_event(dev);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index cc3d6d6d67e0..5c99d3773212 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -339,19 +339,51 @@ static ssize_t select_subconnector_show(struct device *device,
drm_get_dvi_i_select_name((int)subconnector));
}
-static struct device_attribute connector_attrs[] = {
- __ATTR_RO(status),
- __ATTR_RO(enabled),
- __ATTR_RO(dpms),
- __ATTR_RO(modes),
+static DEVICE_ATTR_RO(status);
+static DEVICE_ATTR_RO(enabled);
+static DEVICE_ATTR_RO(dpms);
+static DEVICE_ATTR_RO(modes);
+
+static struct attribute *connector_dev_attrs[] = {
+ &dev_attr_status.attr,
+ &dev_attr_enabled.attr,
+ &dev_attr_dpms.attr,
+ &dev_attr_modes.attr,
+ NULL
};
/* These attributes are for both DVI-I connectors and all types of tv-out. */
-static struct device_attribute connector_attrs_opt1[] = {
- __ATTR_RO(subconnector),
- __ATTR_RO(select_subconnector),
+static DEVICE_ATTR_RO(subconnector);
+static DEVICE_ATTR_RO(select_subconnector);
+
+static struct attribute *connector_opt_dev_attrs[] = {
+ &dev_attr_subconnector.attr,
+ &dev_attr_select_subconnector.attr,
+ NULL
};
+static umode_t connector_opt_dev_is_visible(struct kobject *kobj,
+ struct attribute *attr, int idx)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct drm_connector *connector = to_drm_connector(dev);
+
+ /*
+ * In the long run it maybe a good idea to make one set of
+ * optionals per connector type.
+ */
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_Composite:
+ case DRM_MODE_CONNECTOR_SVIDEO:
+ case DRM_MODE_CONNECTOR_Component:
+ case DRM_MODE_CONNECTOR_TV:
+ return attr->mode;
+ }
+
+ return 0;
+}
+
static struct bin_attribute edid_attr = {
.attr.name = "edid",
.attr.mode = 0444,
@@ -359,6 +391,27 @@ static struct bin_attribute edid_attr = {
.read = edid_show,
};
+static struct bin_attribute *connector_bin_attrs[] = {
+ &edid_attr,
+ NULL
+};
+
+static const struct attribute_group connector_dev_group = {
+ .attrs = connector_dev_attrs,
+ .bin_attrs = connector_bin_attrs,
+};
+
+static const struct attribute_group connector_opt_dev_group = {
+ .attrs = connector_opt_dev_attrs,
+ .is_visible = connector_opt_dev_is_visible,
+};
+
+static const struct attribute_group *connector_dev_groups[] = {
+ &connector_dev_group,
+ &connector_opt_dev_group,
+ NULL
+};
+
/**
* drm_sysfs_connector_add - add a connector to sysfs
* @connector: connector to add
@@ -371,73 +424,27 @@ static struct bin_attribute edid_attr = {
int drm_sysfs_connector_add(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- int attr_cnt = 0;
- int opt_cnt = 0;
- int i;
- int ret;
if (connector->kdev)
return 0;
- connector->kdev = device_create(drm_class, dev->primary->kdev,
- 0, connector, "card%d-%s",
- dev->primary->index, connector->name);
+ connector->kdev =
+ device_create_with_groups(drm_class, dev->primary->kdev, 0,
+ connector, connector_dev_groups,
+ "card%d-%s", dev->primary->index,
+ connector->name);
DRM_DEBUG("adding \"%s\" to sysfs\n",
connector->name);
if (IS_ERR(connector->kdev)) {
DRM_ERROR("failed to register connector device: %ld\n", PTR_ERR(connector->kdev));
- ret = PTR_ERR(connector->kdev);
- goto out;
- }
-
- /* Standard attributes */
-
- for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) {
- ret = device_create_file(connector->kdev, &connector_attrs[attr_cnt]);
- if (ret)
- goto err_out_files;
+ return PTR_ERR(connector->kdev);
}
- /* Optional attributes */
- /*
- * In the long run it maybe a good idea to make one set of
- * optionals per connector type.
- */
- switch (connector->connector_type) {
- case DRM_MODE_CONNECTOR_DVII:
- case DRM_MODE_CONNECTOR_Composite:
- case DRM_MODE_CONNECTOR_SVIDEO:
- case DRM_MODE_CONNECTOR_Component:
- case DRM_MODE_CONNECTOR_TV:
- for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) {
- ret = device_create_file(connector->kdev, &connector_attrs_opt1[opt_cnt]);
- if (ret)
- goto err_out_files;
- }
- break;
- default:
- break;
- }
-
- ret = sysfs_create_bin_file(&connector->kdev->kobj, &edid_attr);
- if (ret)
- goto err_out_files;
-
/* Let userspace know we have a new connector */
drm_sysfs_hotplug_event(dev);
return 0;
-
-err_out_files:
- for (i = 0; i < opt_cnt; i++)
- device_remove_file(connector->kdev, &connector_attrs_opt1[i]);
- for (i = 0; i < attr_cnt; i++)
- device_remove_file(connector->kdev, &connector_attrs[i]);
- device_unregister(connector->kdev);
-
-out:
- return ret;
}
/**
@@ -455,16 +462,11 @@ out:
*/
void drm_sysfs_connector_remove(struct drm_connector *connector)
{
- int i;
-
if (!connector->kdev)
return;
DRM_DEBUG("removing \"%s\" from sysfs\n",
connector->name);
- for (i = 0; i < ARRAY_SIZE(connector_attrs); i++)
- device_remove_file(connector->kdev, &connector_attrs[i]);
- sysfs_remove_bin_file(&connector->kdev->kobj, &edid_attr);
device_unregister(connector->kdev);
connector->kdev = NULL;
}
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 7f9f6f9e9b7e..a5e74612100e 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -6,23 +6,15 @@ config DRM_EXYNOS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
select VIDEOMODE_HELPERS
help
Choose this option if you have a Samsung SoC EXYNOS chipset.
If M is selected the module will be called exynosdrm.
config DRM_EXYNOS_IOMMU
- bool "EXYNOS DRM IOMMU Support"
+ bool
depends on DRM_EXYNOS && EXYNOS_IOMMU && ARM_DMA_USE_IOMMU
- help
- Choose this option if you want to use IOMMU feature for DRM.
-
-config DRM_EXYNOS_DMABUF
- bool "EXYNOS DRM DMABUF"
- depends on DRM_EXYNOS
- help
- Choose this option if you want to use DMABUF feature for DRM.
+ default y
config DRM_EXYNOS_FIMD
bool "Exynos DRM FIMD"
@@ -32,9 +24,16 @@ config DRM_EXYNOS_FIMD
help
Choose this option if you want to use Exynos FIMD for DRM.
+config DRM_EXYNOS7_DECON
+ bool "Exynos DRM DECON"
+ depends on DRM_EXYNOS
+ select FB_MODE_HELPERS
+ help
+ Choose this option if you want to use Exynos DECON for DRM.
+
config DRM_EXYNOS_DPI
bool "EXYNOS DRM parallel output support"
- depends on DRM_EXYNOS_FIMD
+ depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
select DRM_PANEL
default n
help
@@ -42,7 +41,7 @@ config DRM_EXYNOS_DPI
config DRM_EXYNOS_DSI
bool "EXYNOS DRM MIPI-DSI driver support"
- depends on DRM_EXYNOS_FIMD
+ depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
select DRM_MIPI_DSI
select DRM_PANEL
default n
@@ -51,7 +50,7 @@ config DRM_EXYNOS_DSI
config DRM_EXYNOS_DP
bool "EXYNOS DRM DP driver support"
- depends on DRM_EXYNOS_FIMD && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
+ depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
default DRM_EXYNOS
select DRM_PANEL
help
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 33ae3652b8da..cc90679cfc06 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -6,11 +6,11 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
- exynos_drm_plane.o
+ exynos_drm_plane.o exynos_drm_dmabuf.o
exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
-exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
+exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o
exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
new file mode 100644
index 000000000000..63f02e2380ae
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -0,0 +1,990 @@
+/* drivers/gpu/drm/exynos/exynos7_drm_decon.c
+ *
+ * Copyright (C) 2014 Samsung Electronics Co.Ltd
+ * Authors:
+ * Akshu Agarwal <akshua@gmail.com>
+ * Ajay Kumar <ajaykumar.rs@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#include <drm/drmP.h>
+#include <drm/exynos_drm.h>
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <video/of_display_timing.h>
+#include <video/of_videomode.h>
+#include <video/exynos7_decon.h>
+
+#include "exynos_drm_crtc.h"
+#include "exynos_drm_drv.h"
+#include "exynos_drm_fbdev.h"
+#include "exynos_drm_iommu.h"
+
+/*
+ * DECON stands for Display and Enhancement controller.
+ */
+
+#define DECON_DEFAULT_FRAMERATE 60
+#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
+
+#define WINDOWS_NR 2
+
+struct decon_win_data {
+ unsigned int ovl_x;
+ unsigned int ovl_y;
+ unsigned int offset_x;
+ unsigned int offset_y;
+ unsigned int ovl_width;
+ unsigned int ovl_height;
+ unsigned int fb_width;
+ unsigned int fb_height;
+ unsigned int bpp;
+ unsigned int pixel_format;
+ dma_addr_t dma_addr;
+ bool enabled;
+ bool resume;
+};
+
+struct decon_context {
+ struct device *dev;
+ struct drm_device *drm_dev;
+ struct exynos_drm_crtc *crtc;
+ struct clk *pclk;
+ struct clk *aclk;
+ struct clk *eclk;
+ struct clk *vclk;
+ void __iomem *regs;
+ struct decon_win_data win_data[WINDOWS_NR];
+ unsigned int default_win;
+ unsigned long irq_flags;
+ bool i80_if;
+ bool suspended;
+ int pipe;
+ wait_queue_head_t wait_vsync_queue;
+ atomic_t wait_vsync_event;
+
+ struct exynos_drm_panel_info panel;
+ struct exynos_drm_display *display;
+};
+
+static const struct of_device_id decon_driver_dt_match[] = {
+ {.compatible = "samsung,exynos7-decon"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, decon_driver_dt_match);
+
+static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
+{
+ struct decon_context *ctx = crtc->ctx;
+
+ if (ctx->suspended)
+ return;
+
+ atomic_set(&ctx->wait_vsync_event, 1);
+
+ /*
+ * wait for DECON to signal VSYNC interrupt or return after
+ * timeout which is set to 50ms (refresh rate of 20).
+ */
+ if (!wait_event_timeout(ctx->wait_vsync_queue,
+ !atomic_read(&ctx->wait_vsync_event),
+ HZ/20))
+ DRM_DEBUG_KMS("vblank wait timed out.\n");
+}
+
+static void decon_clear_channel(struct decon_context *ctx)
+{
+ int win, ch_enabled = 0;
+
+ DRM_DEBUG_KMS("%s\n", __FILE__);
+
+ /* Check if any channel is enabled. */
+ for (win = 0; win < WINDOWS_NR; win++) {
+ u32 val = readl(ctx->regs + WINCON(win));
+
+ if (val & WINCONx_ENWIN) {
+ val &= ~WINCONx_ENWIN;
+ writel(val, ctx->regs + WINCON(win));
+ ch_enabled = 1;
+ }
+ }
+
+ /* Wait for vsync, as disable channel takes effect at next vsync */
+ if (ch_enabled) {
+ unsigned int state = ctx->suspended;
+
+ ctx->suspended = 0;
+ decon_wait_for_vblank(ctx->crtc);
+ ctx->suspended = state;
+ }
+}
+
+static int decon_ctx_initialize(struct decon_context *ctx,
+ struct drm_device *drm_dev)
+{
+ struct exynos_drm_private *priv = drm_dev->dev_private;
+
+ ctx->drm_dev = drm_dev;
+ ctx->pipe = priv->pipe++;
+
+ /* attach this sub driver to iommu mapping if supported. */
+ if (is_drm_iommu_supported(ctx->drm_dev)) {
+ int ret;
+
+ /*
+ * If any channel is already active, iommu will throw
+ * a PAGE FAULT when enabled. So clear any channel if enabled.
+ */
+ decon_clear_channel(ctx);
+ ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
+ if (ret) {
+ DRM_ERROR("drm_iommu_attach failed.\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void decon_ctx_remove(struct decon_context *ctx)
+{
+ /* detach this sub driver from iommu mapping if supported. */
+ if (is_drm_iommu_supported(ctx->drm_dev))
+ drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+}
+
+static u32 decon_calc_clkdiv(struct decon_context *ctx,
+ const struct drm_display_mode *mode)
+{
+ unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
+ u32 clkdiv;
+
+ /* Find the clock divider value that gets us closest to ideal_clk */
+ clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->vclk), ideal_clk);
+
+ return (clkdiv < 0x100) ? clkdiv : 0xff;
+}
+
+static bool decon_mode_fixup(struct exynos_drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ if (adjusted_mode->vrefresh == 0)
+ adjusted_mode->vrefresh = DECON_DEFAULT_FRAMERATE;
+
+ return true;
+}
+
+static void decon_commit(struct exynos_drm_crtc *crtc)
+{
+ struct decon_context *ctx = crtc->ctx;
+ struct drm_display_mode *mode = &crtc->base.mode;
+ u32 val, clkdiv;
+
+ if (ctx->suspended)
+ return;
+
+ /* nothing to do if we haven't set the mode yet */
+ if (mode->htotal == 0 || mode->vtotal == 0)
+ return;
+
+ if (!ctx->i80_if) {
+ int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
+ /* setup vertical timing values. */
+ vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
+ vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
+ vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
+
+ val = VIDTCON0_VBPD(vbpd - 1) | VIDTCON0_VFPD(vfpd - 1);
+ writel(val, ctx->regs + VIDTCON0);
+
+ val = VIDTCON1_VSPW(vsync_len - 1);
+ writel(val, ctx->regs + VIDTCON1);
+
+ /* setup horizontal timing values. */
+ hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+ hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
+ hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
+
+ /* setup horizontal timing values. */
+ val = VIDTCON2_HBPD(hbpd - 1) | VIDTCON2_HFPD(hfpd - 1);
+ writel(val, ctx->regs + VIDTCON2);
+
+ val = VIDTCON3_HSPW(hsync_len - 1);
+ writel(val, ctx->regs + VIDTCON3);
+ }
+
+ /* setup horizontal and vertical display size. */
+ val = VIDTCON4_LINEVAL(mode->vdisplay - 1) |
+ VIDTCON4_HOZVAL(mode->hdisplay - 1);
+ writel(val, ctx->regs + VIDTCON4);
+
+ writel(mode->vdisplay - 1, ctx->regs + LINECNT_OP_THRESHOLD);
+
+ /*
+ * fields of register with prefix '_F' would be updated
+ * at vsync(same as dma start)
+ */
+ val = VIDCON0_ENVID | VIDCON0_ENVID_F;
+ writel(val, ctx->regs + VIDCON0);
+
+ clkdiv = decon_calc_clkdiv(ctx, mode);
+ if (clkdiv > 1) {
+ val = VCLKCON1_CLKVAL_NUM_VCLK(clkdiv - 1);
+ writel(val, ctx->regs + VCLKCON1);
+ writel(val, ctx->regs + VCLKCON2);
+ }
+
+ val = readl(ctx->regs + DECON_UPDATE);
+ val |= DECON_UPDATE_STANDALONE_F;
+ writel(val, ctx->regs + DECON_UPDATE);
+}
+
+static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
+{
+ struct decon_context *ctx = crtc->ctx;
+ u32 val;
+
+ if (ctx->suspended)
+ return -EPERM;
+
+ if (!test_and_set_bit(0, &ctx->irq_flags)) {
+ val = readl(ctx->regs + VIDINTCON0);
+
+ val |= VIDINTCON0_INT_ENABLE;
+
+ if (!ctx->i80_if) {
+ val |= VIDINTCON0_INT_FRAME;
+ val &= ~VIDINTCON0_FRAMESEL0_MASK;
+ val |= VIDINTCON0_FRAMESEL0_VSYNC;
+ }
+
+ writel(val, ctx->regs + VIDINTCON0);
+ }
+
+ return 0;
+}
+
+static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
+{
+ struct decon_context *ctx = crtc->ctx;
+ u32 val;
+
+ if (ctx->suspended)
+ return;
+
+ if (test_and_clear_bit(0, &ctx->irq_flags)) {
+ val = readl(ctx->regs + VIDINTCON0);
+
+ val &= ~VIDINTCON0_INT_ENABLE;
+ if (!ctx->i80_if)
+ val &= ~VIDINTCON0_INT_FRAME;
+
+ writel(val, ctx->regs + VIDINTCON0);
+ }
+}
+
+static void decon_win_mode_set(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
+{
+ struct decon_context *ctx = crtc->ctx;
+ struct decon_win_data *win_data;
+ int win, padding;
+
+ if (!plane) {
+ DRM_ERROR("plane is NULL\n");
+ return;
+ }
+
+ win = plane->zpos;
+ if (win == DEFAULT_ZPOS)
+ win = ctx->default_win;
+
+ if (win < 0 || win >= WINDOWS_NR)
+ return;
+
+
+ win_data = &ctx->win_data[win];
+
+ padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width;
+ win_data->offset_x = plane->fb_x;
+ win_data->offset_y = plane->fb_y;
+ win_data->fb_width = plane->fb_width + padding;
+ win_data->fb_height = plane->fb_height;
+ win_data->ovl_x = plane->crtc_x;
+ win_data->ovl_y = plane->crtc_y;
+ win_data->ovl_width = plane->crtc_width;
+ win_data->ovl_height = plane->crtc_height;
+ win_data->dma_addr = plane->dma_addr[0];
+ win_data->bpp = plane->bpp;
+ win_data->pixel_format = plane->pixel_format;
+
+ DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
+ win_data->offset_x, win_data->offset_y);
+ DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
+ win_data->ovl_width, win_data->ovl_height);
+ DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
+ DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
+ plane->fb_width, plane->crtc_width);
+}
+
+static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
+{
+ struct decon_win_data *win_data = &ctx->win_data[win];
+ unsigned long val;
+
+ val = readl(ctx->regs + WINCON(win));
+ val &= ~WINCONx_BPPMODE_MASK;
+
+ switch (win_data->pixel_format) {
+ case DRM_FORMAT_RGB565:
+ val |= WINCONx_BPPMODE_16BPP_565;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_XRGB8888:
+ val |= WINCONx_BPPMODE_24BPP_xRGB;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_XBGR8888:
+ val |= WINCONx_BPPMODE_24BPP_xBGR;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_RGBX8888:
+ val |= WINCONx_BPPMODE_24BPP_RGBx;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_BGRX8888:
+ val |= WINCONx_BPPMODE_24BPP_BGRx;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ val |= WINCONx_BPPMODE_32BPP_ARGB | WINCONx_BLD_PIX |
+ WINCONx_ALPHA_SEL;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_ABGR8888:
+ val |= WINCONx_BPPMODE_32BPP_ABGR | WINCONx_BLD_PIX |
+ WINCONx_ALPHA_SEL;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_RGBA8888:
+ val |= WINCONx_BPPMODE_32BPP_RGBA | WINCONx_BLD_PIX |
+ WINCONx_ALPHA_SEL;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case DRM_FORMAT_BGRA8888:
+ val |= WINCONx_BPPMODE_32BPP_BGRA | WINCONx_BLD_PIX |
+ WINCONx_ALPHA_SEL;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ default:
+ DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n");
+
+ val |= WINCONx_BPPMODE_24BPP_xRGB;
+ val |= WINCONx_BURSTLEN_16WORD;
+ break;
+ }
+
+ DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp);
+
+ /*
+ * In case of exynos, setting dma-burst to 16Word causes permanent
+ * tearing for very small buffers, e.g. cursor buffer. Burst Mode
+ * switching which is based on plane size is not recommended as
+ * plane size varies a lot towards the end of the screen and rapid
+ * movement causes unstable DMA which results into iommu crash/tear.
+ */
+
+ if (win_data->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
+ val &= ~WINCONx_BURSTLEN_MASK;
+ val |= WINCONx_BURSTLEN_8WORD;
+ }
+
+ writel(val, ctx->regs + WINCON(win));
+}
+
+static void decon_win_set_colkey(struct decon_context *ctx, unsigned int win)
+{
+ unsigned int keycon0 = 0, keycon1 = 0;
+
+ keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F |
+ WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0);
+
+ keycon1 = WxKEYCON1_COLVAL(0xffffffff);
+
+ writel(keycon0, ctx->regs + WKEYCON0_BASE(win));
+ writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
+}
+
+/**
+ * shadow_protect_win() - disable updating values from shadow registers at vsync
+ *
+ * @win: window to protect registers for
+ * @protect: 1 to protect (disable updates)
+ */
+static void decon_shadow_protect_win(struct decon_context *ctx,
+ int win, bool protect)
+{
+ u32 bits, val;
+
+ bits = SHADOWCON_WINx_PROTECT(win);
+
+ val = readl(ctx->regs + SHADOWCON);
+ if (protect)
+ val |= bits;
+ else
+ val &= ~bits;
+ writel(val, ctx->regs + SHADOWCON);
+}
+
+static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
+{
+ struct decon_context *ctx = crtc->ctx;
+ struct drm_display_mode *mode = &crtc->base.mode;
+ struct decon_win_data *win_data;
+ int win = zpos;
+ unsigned long val, alpha;
+ unsigned int last_x;
+ unsigned int last_y;
+
+ if (ctx->suspended)
+ return;
+
+ if (win == DEFAULT_ZPOS)
+ win = ctx->default_win;
+
+ if (win < 0 || win >= WINDOWS_NR)
+ return;
+
+ win_data = &ctx->win_data[win];
+
+ /* If suspended, enable this on resume */
+ if (ctx->suspended) {
+ win_data->resume = true;
+ return;
+ }
+
+ /*
+ * SHADOWCON/PRTCON register is used for enabling timing.
+ *
+ * for example, once only width value of a register is set,
+ * if the dma is started then decon hardware could malfunction so
+ * with protect window setting, the register fields with prefix '_F'
+ * wouldn't be updated at vsync also but updated once unprotect window
+ * is set.
+ */
+
+ /* protect windows */
+ decon_shadow_protect_win(ctx, win, true);
+
+ /* buffer start address */
+ val = (unsigned long)win_data->dma_addr;
+ writel(val, ctx->regs + VIDW_BUF_START(win));
+
+ /* buffer size */
+ writel(win_data->fb_width, ctx->regs + VIDW_WHOLE_X(win));
+ writel(win_data->fb_height, ctx->regs + VIDW_WHOLE_Y(win));
+
+ /* offset from the start of the buffer to read */
+ writel(win_data->offset_x, ctx->regs + VIDW_OFFSET_X(win));
+ writel(win_data->offset_y, ctx->regs + VIDW_OFFSET_Y(win));
+
+ DRM_DEBUG_KMS("start addr = 0x%lx\n",
+ (unsigned long)win_data->dma_addr);
+ DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
+ win_data->ovl_width, win_data->ovl_height);
+
+ /*
+ * OSD position.
+ * In case the window layout goes of LCD layout, DECON fails.
+ */
+ if ((win_data->ovl_x + win_data->ovl_width) > mode->hdisplay)
+ win_data->ovl_x = mode->hdisplay - win_data->ovl_width;
+ if ((win_data->ovl_y + win_data->ovl_height) > mode->vdisplay)
+ win_data->ovl_y = mode->vdisplay - win_data->ovl_height;
+
+ val = VIDOSDxA_TOPLEFT_X(win_data->ovl_x) |
+ VIDOSDxA_TOPLEFT_Y(win_data->ovl_y);
+ writel(val, ctx->regs + VIDOSD_A(win));
+
+ last_x = win_data->ovl_x + win_data->ovl_width;
+ if (last_x)
+ last_x--;
+ last_y = win_data->ovl_y + win_data->ovl_height;
+ if (last_y)
+ last_y--;
+
+ val = VIDOSDxB_BOTRIGHT_X(last_x) | VIDOSDxB_BOTRIGHT_Y(last_y);
+
+ writel(val, ctx->regs + VIDOSD_B(win));
+
+ DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
+ win_data->ovl_x, win_data->ovl_y, last_x, last_y);
+
+ /* OSD alpha */
+ alpha = VIDOSDxC_ALPHA0_R_F(0x0) |
+ VIDOSDxC_ALPHA0_G_F(0x0) |
+ VIDOSDxC_ALPHA0_B_F(0x0);
+
+ writel(alpha, ctx->regs + VIDOSD_C(win));
+
+ alpha = VIDOSDxD_ALPHA1_R_F(0xff) |
+ VIDOSDxD_ALPHA1_G_F(0xff) |
+ VIDOSDxD_ALPHA1_B_F(0xff);
+
+ writel(alpha, ctx->regs + VIDOSD_D(win));
+
+ decon_win_set_pixfmt(ctx, win);
+
+ /* hardware window 0 doesn't support color key. */
+ if (win != 0)
+ decon_win_set_colkey(ctx, win);
+
+ /* wincon */
+ val = readl(ctx->regs + WINCON(win));
+ val |= WINCONx_TRIPLE_BUF_MODE;
+ val |= WINCONx_ENWIN;
+ writel(val, ctx->regs + WINCON(win));
+
+ /* Enable DMA channel and unprotect windows */
+ decon_shadow_protect_win(ctx, win, false);
+
+ val = readl(ctx->regs + DECON_UPDATE);
+ val |= DECON_UPDATE_STANDALONE_F;
+ writel(val, ctx->regs + DECON_UPDATE);
+
+ win_data->enabled = true;
+}
+
+static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos)
+{
+ struct decon_context *ctx = crtc->ctx;
+ struct decon_win_data *win_data;
+ int win = zpos;
+ u32 val;
+
+ if (win == DEFAULT_ZPOS)
+ win = ctx->default_win;
+
+ if (win < 0 || win >= WINDOWS_NR)
+ return;
+
+ win_data = &ctx->win_data[win];
+
+ if (ctx->suspended) {
+ /* do not resume this window*/
+ win_data->resume = false;
+ return;
+ }
+
+ /* protect windows */
+ decon_shadow_protect_win(ctx, win, true);
+
+ /* wincon */
+ val = readl(ctx->regs + WINCON(win));
+ val &= ~WINCONx_ENWIN;
+ writel(val, ctx->regs + WINCON(win));
+
+ /* unprotect windows */
+ decon_shadow_protect_win(ctx, win, false);
+
+ val = readl(ctx->regs + DECON_UPDATE);
+ val |= DECON_UPDATE_STANDALONE_F;
+ writel(val, ctx->regs + DECON_UPDATE);
+
+ win_data->enabled = false;
+}
+
+static void decon_window_suspend(struct decon_context *ctx)
+{
+ struct decon_win_data *win_data;
+ int i;
+
+ for (i = 0; i < WINDOWS_NR; i++) {
+ win_data = &ctx->win_data[i];
+ win_data->resume = win_data->enabled;
+ if (win_data->enabled)
+ decon_win_disable(ctx->crtc, i);
+ }
+}
+
+static void decon_window_resume(struct decon_context *ctx)
+{
+ struct decon_win_data *win_data;
+ int i;
+
+ for (i = 0; i < WINDOWS_NR; i++) {
+ win_data = &ctx->win_data[i];
+ win_data->enabled = win_data->resume;
+ win_data->resume = false;
+ }
+}
+
+static void decon_apply(struct decon_context *ctx)
+{
+ struct decon_win_data *win_data;
+ int i;
+
+ for (i = 0; i < WINDOWS_NR; i++) {
+ win_data = &ctx->win_data[i];
+ if (win_data->enabled)
+ decon_win_commit(ctx->crtc, i);
+ else
+ decon_win_disable(ctx->crtc, i);
+ }
+
+ decon_commit(ctx->crtc);
+}
+
+static void decon_init(struct decon_context *ctx)
+{
+ u32 val;
+
+ writel(VIDCON0_SWRESET, ctx->regs + VIDCON0);
+
+ val = VIDOUTCON0_DISP_IF_0_ON;
+ if (!ctx->i80_if)
+ val |= VIDOUTCON0_RGBIF;
+ writel(val, ctx->regs + VIDOUTCON0);
+
+ writel(VCLKCON0_CLKVALUP | VCLKCON0_VCLKFREE, ctx->regs + VCLKCON0);
+
+ if (!ctx->i80_if)
+ writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0));
+}
+
+static int decon_poweron(struct decon_context *ctx)
+{
+ int ret;
+
+ if (!ctx->suspended)
+ return 0;
+
+ ctx->suspended = false;
+
+ pm_runtime_get_sync(ctx->dev);
+
+ ret = clk_prepare_enable(ctx->pclk);
+ if (ret < 0) {
+ DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret);
+ goto pclk_err;
+ }
+
+ ret = clk_prepare_enable(ctx->aclk);
+ if (ret < 0) {
+ DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret);
+ goto aclk_err;
+ }
+
+ ret = clk_prepare_enable(ctx->eclk);
+ if (ret < 0) {
+ DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret);
+ goto eclk_err;
+ }
+
+ ret = clk_prepare_enable(ctx->vclk);
+ if (ret < 0) {
+ DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret);
+ goto vclk_err;
+ }
+
+ decon_init(ctx);
+
+ /* if vblank was enabled status, enable it again. */
+ if (test_and_clear_bit(0, &ctx->irq_flags)) {
+ ret = decon_enable_vblank(ctx->crtc);
+ if (ret) {
+ DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
+ goto err;
+ }
+ }
+
+ decon_window_resume(ctx);
+
+ decon_apply(ctx);
+
+ return 0;
+
+err:
+ clk_disable_unprepare(ctx->vclk);
+vclk_err:
+ clk_disable_unprepare(ctx->eclk);
+eclk_err:
+ clk_disable_unprepare(ctx->aclk);
+aclk_err:
+ clk_disable_unprepare(ctx->pclk);
+pclk_err:
+ ctx->suspended = true;
+ return ret;
+}
+
+static int decon_poweroff(struct decon_context *ctx)
+{
+ if (ctx->suspended)
+ return 0;
+
+ /*
+ * We need to make sure that all windows are disabled before we
+ * suspend that connector. Otherwise we might try to scan from
+ * a destroyed buffer later.
+ */
+ decon_window_suspend(ctx);
+
+ clk_disable_unprepare(ctx->vclk);
+ clk_disable_unprepare(ctx->eclk);
+ clk_disable_unprepare(ctx->aclk);
+ clk_disable_unprepare(ctx->pclk);
+
+ pm_runtime_put_sync(ctx->dev);
+
+ ctx->suspended = true;
+ return 0;
+}
+
+static void decon_dpms(struct exynos_drm_crtc *crtc, int mode)
+{
+ DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
+
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ decon_poweron(crtc->ctx);
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ decon_poweroff(crtc->ctx);
+ break;
+ default:
+ DRM_DEBUG_KMS("unspecified mode %d\n", mode);
+ break;
+ }
+}
+
+static struct exynos_drm_crtc_ops decon_crtc_ops = {
+ .dpms = decon_dpms,
+ .mode_fixup = decon_mode_fixup,
+ .commit = decon_commit,
+ .enable_vblank = decon_enable_vblank,
+ .disable_vblank = decon_disable_vblank,
+ .wait_for_vblank = decon_wait_for_vblank,
+ .win_mode_set = decon_win_mode_set,
+ .win_commit = decon_win_commit,
+ .win_disable = decon_win_disable,
+};
+
+
+static irqreturn_t decon_irq_handler(int irq, void *dev_id)
+{
+ struct decon_context *ctx = (struct decon_context *)dev_id;
+ u32 val, clear_bit;
+
+ val = readl(ctx->regs + VIDINTCON1);
+
+ clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME;
+ if (val & clear_bit)
+ writel(clear_bit, ctx->regs + VIDINTCON1);
+
+ /* check the crtc is detached already from encoder */
+ if (ctx->pipe < 0 || !ctx->drm_dev)
+ goto out;
+
+ if (!ctx->i80_if) {
+ drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+ exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+
+ /* set wait vsync event to zero and wake up queue. */
+ if (atomic_read(&ctx->wait_vsync_event)) {
+ atomic_set(&ctx->wait_vsync_event, 0);
+ wake_up(&ctx->wait_vsync_queue);
+ }
+ }
+out:
+ return IRQ_HANDLED;
+}
+
+static int decon_bind(struct device *dev, struct device *master, void *data)
+{
+ struct decon_context *ctx = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ int ret;
+
+ ret = decon_ctx_initialize(ctx, drm_dev);
+ if (ret) {
+ DRM_ERROR("decon_ctx_initialize failed.\n");
+ return ret;
+ }
+
+ ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
+ EXYNOS_DISPLAY_TYPE_LCD,
+ &decon_crtc_ops, ctx);
+ if (IS_ERR(ctx->crtc)) {
+ decon_ctx_remove(ctx);
+ return PTR_ERR(ctx->crtc);
+ }
+
+ if (ctx->display)
+ exynos_drm_create_enc_conn(drm_dev, ctx->display);
+
+ return 0;
+
+}
+
+static void decon_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct decon_context *ctx = dev_get_drvdata(dev);
+
+ decon_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
+
+ if (ctx->display)
+ exynos_dpi_remove(ctx->display);
+
+ decon_ctx_remove(ctx);
+}
+
+static const struct component_ops decon_component_ops = {
+ .bind = decon_bind,
+ .unbind = decon_unbind,
+};
+
+static int decon_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct decon_context *ctx;
+ struct device_node *i80_if_timings;
+ struct resource *res;
+ int ret;
+
+ if (!dev->of_node)
+ return -ENODEV;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
+ EXYNOS_DISPLAY_TYPE_LCD);
+ if (ret)
+ return ret;
+
+ ctx->dev = dev;
+ ctx->suspended = true;
+
+ i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings");
+ if (i80_if_timings)
+ ctx->i80_if = true;
+ of_node_put(i80_if_timings);
+
+ ctx->regs = of_iomap(dev->of_node, 0);
+ if (IS_ERR(ctx->regs)) {
+ ret = PTR_ERR(ctx->regs);
+ goto err_del_component;
+ }
+
+ ctx->pclk = devm_clk_get(dev, "pclk_decon0");
+ if (IS_ERR(ctx->pclk)) {
+ dev_err(dev, "failed to get bus clock pclk\n");
+ ret = PTR_ERR(ctx->pclk);
+ goto err_iounmap;
+ }
+
+ ctx->aclk = devm_clk_get(dev, "aclk_decon0");
+ if (IS_ERR(ctx->aclk)) {
+ dev_err(dev, "failed to get bus clock aclk\n");
+ ret = PTR_ERR(ctx->aclk);
+ goto err_iounmap;
+ }
+
+ ctx->eclk = devm_clk_get(dev, "decon0_eclk");
+ if (IS_ERR(ctx->eclk)) {
+ dev_err(dev, "failed to get eclock\n");
+ ret = PTR_ERR(ctx->eclk);
+ goto err_iounmap;
+ }
+
+ ctx->vclk = devm_clk_get(dev, "decon0_vclk");
+ if (IS_ERR(ctx->vclk)) {
+ dev_err(dev, "failed to get vclock\n");
+ ret = PTR_ERR(ctx->vclk);
+ goto err_iounmap;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+ ctx->i80_if ? "lcd_sys" : "vsync");
+ if (!res) {
+ dev_err(dev, "irq request failed.\n");
+ ret = -ENXIO;
+ goto err_iounmap;
+ }
+
+ ret = devm_request_irq(dev, res->start, decon_irq_handler,
+ 0, "drm_decon", ctx);
+ if (ret) {
+ dev_err(dev, "irq request failed.\n");
+ goto err_iounmap;
+ }
+
+ init_waitqueue_head(&ctx->wait_vsync_queue);
+ atomic_set(&ctx->wait_vsync_event, 0);
+
+ platform_set_drvdata(pdev, ctx);
+
+ ctx->display = exynos_dpi_probe(dev);
+ if (IS_ERR(ctx->display)) {
+ ret = PTR_ERR(ctx->display);
+ goto err_iounmap;
+ }
+
+ pm_runtime_enable(dev);
+
+ ret = component_add(dev, &decon_component_ops);
+ if (ret)
+ goto err_disable_pm_runtime;
+
+ return ret;
+
+err_disable_pm_runtime:
+ pm_runtime_disable(dev);
+
+err_iounmap:
+ iounmap(ctx->regs);
+
+err_del_component:
+ exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
+ return ret;
+}
+
+static int decon_remove(struct platform_device *pdev)
+{
+ struct decon_context *ctx = dev_get_drvdata(&pdev->dev);
+
+ pm_runtime_disable(&pdev->dev);
+
+ iounmap(ctx->regs);
+
+ component_del(&pdev->dev, &decon_component_ops);
+ exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
+
+ return 0;
+}
+
+struct platform_driver decon_driver = {
+ .probe = decon_probe,
+ .remove = decon_remove,
+ .driver = {
+ .name = "exynos-decon",
+ .of_match_table = decon_driver_dt_match,
+ },
+};
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 34d46aa75416..bf17a60b40ed 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/of_graph.h>
#include <linux/gpio.h>
#include <linux/component.h>
#include <linux/phy/phy.h>
@@ -993,32 +994,20 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
.best_encoder = exynos_dp_best_encoder,
};
-static bool find_bridge(const char *compat, struct bridge_init *bridge)
-{
- bridge->client = NULL;
- bridge->node = of_find_compatible_node(NULL, NULL, compat);
- if (!bridge->node)
- return false;
-
- bridge->client = of_find_i2c_device_by_node(bridge->node);
- if (!bridge->client)
- return false;
-
- return true;
-}
-
/* returns the number of bridges attached */
-static int exynos_drm_attach_lcd_bridge(struct drm_device *dev,
+static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
struct drm_encoder *encoder)
{
- struct bridge_init bridge;
int ret;
- if (find_bridge("nxp,ptn3460", &bridge)) {
- ret = ptn3460_init(dev, encoder, bridge.client, bridge.node);
- if (!ret)
- return 1;
+ encoder->bridge = dp->bridge;
+ dp->bridge->encoder = encoder;
+ ret = drm_bridge_attach(encoder->dev, dp->bridge);
+ if (ret) {
+ DRM_ERROR("Failed to attach bridge to drm\n");
+ return ret;
}
+
return 0;
}
@@ -1032,9 +1021,11 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
dp->encoder = encoder;
/* Pre-empt DP connector creation if there's a bridge */
- ret = exynos_drm_attach_lcd_bridge(dp->drm_dev, encoder);
- if (ret)
- return 0;
+ if (dp->bridge) {
+ ret = exynos_drm_attach_lcd_bridge(dp, encoder);
+ if (!ret)
+ return 0;
+ }
connector->polled = DRM_CONNECTOR_POLL_HPD;
@@ -1067,10 +1058,8 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
phy_power_off(dp->phy);
}
-static void exynos_dp_poweron(struct exynos_drm_display *display)
+static void exynos_dp_poweron(struct exynos_dp_device *dp)
{
- struct exynos_dp_device *dp = display_to_dp(display);
-
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
return;
@@ -1085,13 +1074,11 @@ static void exynos_dp_poweron(struct exynos_drm_display *display)
exynos_dp_phy_init(dp);
exynos_dp_init_dp(dp);
enable_irq(dp->irq);
- exynos_dp_commit(display);
+ exynos_dp_commit(&dp->display);
}
-static void exynos_dp_poweroff(struct exynos_drm_display *display)
+static void exynos_dp_poweroff(struct exynos_dp_device *dp)
{
- struct exynos_dp_device *dp = display_to_dp(display);
-
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
return;
@@ -1119,12 +1106,12 @@ static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
- exynos_dp_poweron(display);
+ exynos_dp_poweron(dp);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- exynos_dp_poweroff(display);
+ exynos_dp_poweroff(dp);
break;
default:
break;
@@ -1241,7 +1228,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
}
}
- if (!dp->panel) {
+ if (!dp->panel && !dp->bridge) {
ret = exynos_dp_dt_parse_panel(dp);
if (ret)
return ret;
@@ -1325,7 +1312,7 @@ static const struct component_ops exynos_dp_ops = {
static int exynos_dp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct device_node *panel_node;
+ struct device_node *panel_node, *bridge_node, *endpoint;
struct exynos_dp_device *dp;
int ret;
@@ -1351,6 +1338,18 @@ static int exynos_dp_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (endpoint) {
+ bridge_node = of_graph_get_remote_port_parent(endpoint);
+ if (bridge_node) {
+ dp->bridge = of_drm_find_bridge(bridge_node);
+ of_node_put(bridge_node);
+ if (!dp->bridge)
+ return -EPROBE_DEFER;
+ } else
+ return -EPROBE_DEFER;
+ }
+
ret = component_add(&pdev->dev, &exynos_dp_ops);
if (ret)
exynos_drm_component_del(&pdev->dev,
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index 164f171168e7..a4e799679669 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -153,6 +153,7 @@ struct exynos_dp_device {
struct drm_connector connector;
struct drm_encoder *encoder;
struct drm_panel *panel;
+ struct drm_bridge *bridge;
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 9c8088462c26..24994ba10e28 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -63,11 +63,11 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
return -ENOMEM;
}
- buf->kvaddr = (void __iomem *)dma_alloc_attrs(dev->dev,
+ buf->cookie = dma_alloc_attrs(dev->dev,
buf->size,
&buf->dma_addr, GFP_KERNEL,
&buf->dma_attrs);
- if (!buf->kvaddr) {
+ if (!buf->cookie) {
DRM_ERROR("failed to allocate buffer.\n");
ret = -ENOMEM;
goto err_free;
@@ -132,7 +132,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
buf->sgt = NULL;
if (!is_drm_iommu_supported(dev)) {
- dma_free_attrs(dev->dev, buf->size, buf->kvaddr,
+ dma_free_attrs(dev->dev, buf->size, buf->cookie,
(dma_addr_t)buf->dma_addr, &buf->dma_attrs);
drm_free_large(buf->pages);
} else
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 45026e693225..48ccab7fdf63 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -20,43 +20,9 @@
#include "exynos_drm_encoder.h"
#include "exynos_drm_plane.h"
-#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc,\
- drm_crtc)
-
-enum exynos_crtc_mode {
- CRTC_MODE_NORMAL, /* normal mode */
- CRTC_MODE_BLANK, /* The private plane of crtc is blank */
-};
-
-/*
- * Exynos specific crtc structure.
- *
- * @drm_crtc: crtc object.
- * @manager: the manager associated with this crtc
- * @pipe: a crtc index created at load() with a new crtc object creation
- * and the crtc object would be set to private->crtc array
- * to get a crtc object corresponding to this pipe from private->crtc
- * array when irq interrupt occurred. the reason of using this pipe is that
- * drm framework doesn't support multiple irq yet.
- * we can refer to the crtc to current hardware interrupt occurred through
- * this pipe value.
- * @dpms: store the crtc dpms value
- * @mode: store the crtc mode value
- */
-struct exynos_drm_crtc {
- struct drm_crtc drm_crtc;
- struct exynos_drm_manager *manager;
- unsigned int pipe;
- unsigned int dpms;
- enum exynos_crtc_mode mode;
- wait_queue_head_t pending_flip_queue;
- atomic_t pending_flip;
-};
-
static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- struct exynos_drm_manager *manager = exynos_crtc->manager;
DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
@@ -74,8 +40,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
drm_crtc_vblank_off(crtc);
}
- if (manager->ops->dpms)
- manager->ops->dpms(manager, mode);
+ if (exynos_crtc->ops->dpms)
+ exynos_crtc->ops->dpms(exynos_crtc, mode);
exynos_crtc->dpms = mode;
@@ -91,16 +57,15 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- struct exynos_drm_manager *manager = exynos_crtc->manager;
+ struct exynos_drm_plane *exynos_plane = to_exynos_plane(crtc->primary);
exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
- exynos_plane_commit(crtc->primary);
-
- if (manager->ops->commit)
- manager->ops->commit(manager);
+ if (exynos_crtc->ops->win_commit)
+ exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos);
- exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON);
+ if (exynos_crtc->ops->commit)
+ exynos_crtc->ops->commit(exynos_crtc);
}
static bool
@@ -109,10 +74,10 @@ exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc,
struct drm_display_mode *adjusted_mode)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- struct exynos_drm_manager *manager = exynos_crtc->manager;
- if (manager->ops->mode_fixup)
- return manager->ops->mode_fixup(manager, mode, adjusted_mode);
+ if (exynos_crtc->ops->mode_fixup)
+ return exynos_crtc->ops->mode_fixup(exynos_crtc, mode,
+ adjusted_mode);
return true;
}
@@ -122,11 +87,10 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode, int x, int y,
struct drm_framebuffer *old_fb)
{
- struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- struct exynos_drm_manager *manager = exynos_crtc->manager;
struct drm_framebuffer *fb = crtc->primary->fb;
unsigned int crtc_w;
unsigned int crtc_h;
+ int ret;
/*
* copy the mode data adjusted by mode_fixup() into crtc->mode
@@ -134,24 +98,25 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
*/
memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
+ ret = exynos_check_plane(crtc->primary, fb);
+ if (ret < 0)
+ return ret;
+
crtc_w = fb->width - x;
crtc_h = fb->height - y;
+ exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
+ crtc_w, crtc_h, x, y, crtc_w, crtc_h);
- if (manager->ops->mode_set)
- manager->ops->mode_set(manager, &crtc->mode);
-
- return exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
- crtc_w, crtc_h, x, y, crtc_w, crtc_h);
+ return 0;
}
-static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
+static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_framebuffer *fb = crtc->primary->fb;
unsigned int crtc_w;
unsigned int crtc_h;
- int ret;
/* when framebuffer changing is requested, crtc's dpms should be on */
if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
@@ -162,20 +127,8 @@ static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
crtc_w = fb->width - x;
crtc_h = fb->height - y;
- ret = exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
- crtc_w, crtc_h, x, y, crtc_w, crtc_h);
- if (ret)
- return ret;
-
- exynos_drm_crtc_commit(crtc);
-
- return 0;
-}
-
-static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
-{
- return exynos_drm_crtc_mode_set_commit(crtc, x, y, old_fb);
+ return exynos_update_plane(crtc->primary, crtc, fb, 0, 0,
+ crtc_w, crtc_h, x, y, crtc_w, crtc_h);
}
static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
@@ -214,6 +167,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
struct exynos_drm_private *dev_priv = dev->dev_private;
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_framebuffer *old_fb = crtc->primary->fb;
+ unsigned int crtc_w, crtc_h;
int ret = -EINVAL;
/* when the page flip is requested, crtc's dpms should be on */
@@ -245,8 +199,11 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
spin_unlock_irq(&dev->event_lock);
crtc->primary->fb = fb;
- ret = exynos_drm_crtc_mode_set_commit(crtc, crtc->x, crtc->y,
- NULL);
+ crtc_w = fb->width - crtc->x;
+ crtc_h = fb->height - crtc->y;
+ ret = exynos_update_plane(crtc->primary, crtc, fb, 0, 0,
+ crtc_w, crtc_h, crtc->x, crtc->y,
+ crtc_w, crtc_h);
if (ret) {
crtc->primary->fb = old_fb;
@@ -275,116 +232,61 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
kfree(exynos_crtc);
}
-static int exynos_drm_crtc_set_property(struct drm_crtc *crtc,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_device *dev = crtc->dev;
- struct exynos_drm_private *dev_priv = dev->dev_private;
- struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
-
- if (property == dev_priv->crtc_mode_property) {
- enum exynos_crtc_mode mode = val;
-
- if (mode == exynos_crtc->mode)
- return 0;
-
- exynos_crtc->mode = mode;
-
- switch (mode) {
- case CRTC_MODE_NORMAL:
- exynos_drm_crtc_commit(crtc);
- break;
- case CRTC_MODE_BLANK:
- exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_OFF);
- break;
- default:
- break;
- }
-
- return 0;
- }
-
- return -EINVAL;
-}
-
static struct drm_crtc_funcs exynos_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
.page_flip = exynos_drm_crtc_page_flip,
.destroy = exynos_drm_crtc_destroy,
- .set_property = exynos_drm_crtc_set_property,
-};
-
-static const struct drm_prop_enum_list mode_names[] = {
- { CRTC_MODE_NORMAL, "normal" },
- { CRTC_MODE_BLANK, "blank" },
};
-static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct exynos_drm_private *dev_priv = dev->dev_private;
- struct drm_property *prop;
-
- prop = dev_priv->crtc_mode_property;
- if (!prop) {
- prop = drm_property_create_enum(dev, 0, "mode", mode_names,
- ARRAY_SIZE(mode_names));
- if (!prop)
- return;
-
- dev_priv->crtc_mode_property = prop;
- }
-
- drm_object_attach_property(&crtc->base, prop, 0);
-}
-
-int exynos_drm_crtc_create(struct exynos_drm_manager *manager)
+struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
+ int pipe,
+ enum exynos_drm_output_type type,
+ struct exynos_drm_crtc_ops *ops,
+ void *ctx)
{
struct exynos_drm_crtc *exynos_crtc;
struct drm_plane *plane;
- struct exynos_drm_private *private = manager->drm_dev->dev_private;
+ struct exynos_drm_private *private = drm_dev->dev_private;
struct drm_crtc *crtc;
int ret;
exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
if (!exynos_crtc)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
init_waitqueue_head(&exynos_crtc->pending_flip_queue);
atomic_set(&exynos_crtc->pending_flip, 0);
exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
- exynos_crtc->manager = manager;
- exynos_crtc->pipe = manager->pipe;
- plane = exynos_plane_init(manager->drm_dev, 1 << manager->pipe,
+ exynos_crtc->pipe = pipe;
+ exynos_crtc->type = type;
+ exynos_crtc->ops = ops;
+ exynos_crtc->ctx = ctx;
+ plane = exynos_plane_init(drm_dev, 1 << pipe,
DRM_PLANE_TYPE_PRIMARY);
if (IS_ERR(plane)) {
ret = PTR_ERR(plane);
goto err_plane;
}
- manager->crtc = &exynos_crtc->drm_crtc;
- crtc = &exynos_crtc->drm_crtc;
+ crtc = &exynos_crtc->base;
- private->crtc[manager->pipe] = crtc;
+ private->crtc[pipe] = crtc;
- ret = drm_crtc_init_with_planes(manager->drm_dev, crtc, plane, NULL,
+ ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL,
&exynos_crtc_funcs);
if (ret < 0)
goto err_crtc;
drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs);
- exynos_drm_crtc_attach_mode_property(crtc);
-
- return 0;
+ return exynos_crtc;
err_crtc:
plane->funcs->destroy(plane);
err_plane:
kfree(exynos_crtc);
- return ret;
+ return ERR_PTR(ret);
}
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe)
@@ -392,13 +294,12 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe)
struct exynos_drm_private *private = dev->dev_private;
struct exynos_drm_crtc *exynos_crtc =
to_exynos_crtc(private->crtc[pipe]);
- struct exynos_drm_manager *manager = exynos_crtc->manager;
if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
return -EPERM;
- if (manager->ops->enable_vblank)
- manager->ops->enable_vblank(manager);
+ if (exynos_crtc->ops->enable_vblank)
+ exynos_crtc->ops->enable_vblank(exynos_crtc);
return 0;
}
@@ -408,13 +309,12 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe)
struct exynos_drm_private *private = dev->dev_private;
struct exynos_drm_crtc *exynos_crtc =
to_exynos_crtc(private->crtc[pipe]);
- struct exynos_drm_manager *manager = exynos_crtc->manager;
if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
return;
- if (manager->ops->disable_vblank)
- manager->ops->disable_vblank(manager);
+ if (exynos_crtc->ops->disable_vblank)
+ exynos_crtc->ops->disable_vblank(exynos_crtc);
}
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe)
@@ -443,42 +343,9 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe)
spin_unlock_irqrestore(&dev->event_lock, flags);
}
-void exynos_drm_crtc_plane_mode_set(struct drm_crtc *crtc,
- struct exynos_drm_overlay *overlay)
-{
- struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
-
- if (manager->ops->win_mode_set)
- manager->ops->win_mode_set(manager, overlay);
-}
-
-void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos)
-{
- struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
-
- if (manager->ops->win_commit)
- manager->ops->win_commit(manager, zpos);
-}
-
-void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos)
-{
- struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
-
- if (manager->ops->win_enable)
- manager->ops->win_enable(manager, zpos);
-}
-
-void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos)
-{
- struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
-
- if (manager->ops->win_disable)
- manager->ops->win_disable(manager, zpos);
-}
-
void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
{
- struct exynos_drm_manager *manager;
+ struct exynos_drm_crtc *exynos_crtc;
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
@@ -487,15 +354,15 @@ void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
* for all encoders.
*/
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- manager = to_exynos_crtc(crtc)->manager;
+ exynos_crtc = to_exynos_crtc(crtc);
/*
* wait for vblank interrupt
* - this makes sure that overlay data are updated to
* real hardware.
*/
- if (manager->ops->wait_for_vblank)
- manager->ops->wait_for_vblank(manager);
+ if (exynos_crtc->ops->wait_for_vblank)
+ exynos_crtc->ops->wait_for_vblank(exynos_crtc);
}
}
@@ -508,8 +375,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
struct exynos_drm_crtc *exynos_crtc;
exynos_crtc = to_exynos_crtc(crtc);
- if (exynos_crtc->manager->type == out_type)
- return exynos_crtc->manager->pipe;
+ if (exynos_crtc->type == out_type)
+ return exynos_crtc->pipe;
}
return -EPERM;
@@ -517,8 +384,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
{
- struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
+ struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- if (manager->ops->te_handler)
- manager->ops->te_handler(manager);
+ if (exynos_crtc->ops->te_handler)
+ exynos_crtc->ops->te_handler(exynos_crtc);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index e353d353836f..6258b800aab8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -17,14 +17,18 @@
#include "exynos_drm_drv.h"
-int exynos_drm_crtc_create(struct exynos_drm_manager *manager);
+struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
+ int pipe,
+ enum exynos_drm_output_type type,
+ struct exynos_drm_crtc_ops *ops,
+ void *context);
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
void exynos_drm_crtc_plane_mode_set(struct drm_crtc *crtc,
- struct exynos_drm_overlay *overlay);
+ struct exynos_drm_plane *plane);
void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos);
void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos);
void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index 60192ed544f0..3833bf8ca025 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -279,7 +279,3 @@ err_buf_detach:
return ERR_PTR(ret);
}
-
-MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
-MODULE_DESCRIPTION("Samsung SoC DRM DMABUF Module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
index 49acfafb4fdb..886de9ff484d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
@@ -12,14 +12,9 @@
#ifndef _EXYNOS_DRM_DMABUF_H_
#define _EXYNOS_DRM_DMABUF_H_
-#ifdef CONFIG_DRM_EXYNOS_DMABUF
struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev,
struct drm_gem_object *obj, int flags);
struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
struct dma_buf *dma_buf);
-#else
-#define exynos_dmabuf_prime_export NULL
-#define exynos_dmabuf_prime_import NULL
-#endif
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 1bcbe07cecfc..90168d7cf66a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -556,6 +556,9 @@ static struct platform_driver *const exynos_drm_kms_drivers[] = {
#ifdef CONFIG_DRM_EXYNOS_FIMD
&fimd_driver,
#endif
+#ifdef CONFIG_DRM_EXYNOS7_DECON
+ &decon_driver,
+#endif
#ifdef CONFIG_DRM_EXYNOS_DP
&dp_driver,
#endif
@@ -612,6 +615,7 @@ static const char * const strings[] = {
"samsung,exynos3",
"samsung,exynos4",
"samsung,exynos5",
+ "samsung,exynos7",
};
static struct platform_driver exynos_drm_platform_driver = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 2e5063488c50..9afd390d4674 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -23,6 +23,9 @@
#define MAX_FB_BUFFER 4
#define DEFAULT_ZPOS -1
+#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc, base)
+#define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base)
+
/* This enumerates device type. */
enum exynos_drm_device_type {
EXYNOS_DEVICE_TYPE_NONE,
@@ -44,6 +47,7 @@ enum exynos_drm_output_type {
/*
* Exynos drm common overlay structure.
*
+ * @base: plane object
* @fb_x: offset x on a framebuffer to be displayed.
* - the unit is screen coordinates.
* @fb_y: offset y on a framebuffer to be displayed.
@@ -73,11 +77,14 @@ enum exynos_drm_output_type {
* @local_path: in case of lcd type, local path mode on or off.
* @transparency: transparency on or off.
* @activated: activated or not.
+ * @enabled: enabled or not.
*
* this structure is common to exynos SoC and its contents would be copied
* to hardware specific overlay info.
*/
-struct exynos_drm_overlay {
+
+struct exynos_drm_plane {
+ struct drm_plane base;
unsigned int fb_x;
unsigned int fb_y;
unsigned int fb_width;
@@ -104,6 +111,7 @@ struct exynos_drm_overlay {
bool local_path:1;
bool transparency:1;
bool activated:1;
+ bool enabled:1;
};
/*
@@ -155,11 +163,10 @@ struct exynos_drm_display {
};
/*
- * Exynos drm manager ops
+ * Exynos drm crtc ops
*
* @dpms: control device power.
* @mode_fixup: fix mode data before applying it
- * @mode_set: set the given mode to the manager
* @commit: set current hw specific display mode to hw.
* @enable_vblank: specific driver callback for enabling vblank interrupt.
* @disable_vblank: specific driver callback for disabling vblank interrupt.
@@ -172,44 +179,49 @@ struct exynos_drm_display {
* @te_handler: trigger to transfer video image at the tearing effect
* synchronization signal if there is a page flip request.
*/
-struct exynos_drm_manager;
-struct exynos_drm_manager_ops {
- void (*dpms)(struct exynos_drm_manager *mgr, int mode);
- bool (*mode_fixup)(struct exynos_drm_manager *mgr,
+struct exynos_drm_crtc;
+struct exynos_drm_crtc_ops {
+ void (*dpms)(struct exynos_drm_crtc *crtc, int mode);
+ bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
- void (*mode_set)(struct exynos_drm_manager *mgr,
- const struct drm_display_mode *mode);
- void (*commit)(struct exynos_drm_manager *mgr);
- int (*enable_vblank)(struct exynos_drm_manager *mgr);
- void (*disable_vblank)(struct exynos_drm_manager *mgr);
- void (*wait_for_vblank)(struct exynos_drm_manager *mgr);
- void (*win_mode_set)(struct exynos_drm_manager *mgr,
- struct exynos_drm_overlay *overlay);
- void (*win_commit)(struct exynos_drm_manager *mgr, int zpos);
- void (*win_enable)(struct exynos_drm_manager *mgr, int zpos);
- void (*win_disable)(struct exynos_drm_manager *mgr, int zpos);
- void (*te_handler)(struct exynos_drm_manager *mgr);
+ void (*commit)(struct exynos_drm_crtc *crtc);
+ int (*enable_vblank)(struct exynos_drm_crtc *crtc);
+ void (*disable_vblank)(struct exynos_drm_crtc *crtc);
+ void (*wait_for_vblank)(struct exynos_drm_crtc *crtc);
+ void (*win_mode_set)(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane);
+ void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos);
+ void (*win_enable)(struct exynos_drm_crtc *crtc, int zpos);
+ void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos);
+ void (*te_handler)(struct exynos_drm_crtc *crtc);
};
/*
- * Exynos drm common manager structure, maps 1:1 with a crtc
+ * Exynos specific crtc structure.
*
- * @list: the list entry for this manager
+ * @base: crtc object.
* @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
- * @drm_dev: pointer to the drm device
- * @crtc: crtc object.
- * @pipe: the pipe number for this crtc/manager
+ * @pipe: a crtc index created at load() with a new crtc object creation
+ * and the crtc object would be set to private->crtc array
+ * to get a crtc object corresponding to this pipe from private->crtc
+ * array when irq interrupt occurred. the reason of using this pipe is that
+ * drm framework doesn't support multiple irq yet.
+ * we can refer to the crtc to current hardware interrupt occurred through
+ * this pipe value.
+ * @dpms: store the crtc dpms value
* @ops: pointer to callbacks for exynos drm specific functionality
- * @ctx: A pointer to the manager's implementation specific context
+ * @ctx: A pointer to the crtc's implementation specific context
*/
-struct exynos_drm_manager {
- struct list_head list;
- enum exynos_drm_output_type type;
- struct drm_device *drm_dev;
- struct drm_crtc *crtc;
- int pipe;
- struct exynos_drm_manager_ops *ops;
+struct exynos_drm_crtc {
+ struct drm_crtc base;
+ enum exynos_drm_output_type type;
+ unsigned int pipe;
+ unsigned int dpms;
+ wait_queue_head_t pending_flip_queue;
+ atomic_t pending_flip;
+ struct exynos_drm_crtc_ops *ops;
+ void *ctx;
};
struct exynos_drm_g2d_private {
@@ -246,7 +258,6 @@ struct exynos_drm_private {
*/
struct drm_crtc *crtc[MAX_CRTC];
struct drm_property *plane_zpos_property;
- struct drm_property *crtc_mode_property;
unsigned long da_start;
unsigned long da_space_size;
@@ -333,6 +344,7 @@ void exynos_drm_component_del(struct device *dev,
enum exynos_drm_device_type dev_type);
extern struct platform_driver fimd_driver;
+extern struct platform_driver decon_driver;
extern struct platform_driver dp_driver;
extern struct platform_driver dsi_driver;
extern struct platform_driver mixer_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 7e282e3d6038..57de0bdc5a3b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -102,7 +102,7 @@ static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
/* all planes connected to this encoder should be also disabled. */
drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
- if (plane->crtc == encoder->crtc)
+ if (plane->crtc && (plane->crtc == encoder->crtc))
plane->funcs->disable_plane(plane);
}
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index e12ea90c6237..84f8dfe1c5ec 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -79,9 +79,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
struct drm_framebuffer *fb)
{
struct fb_info *fbi = helper->fbdev;
- struct drm_device *dev = helper->dev;
struct exynos_drm_gem_buf *buffer;
unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
+ unsigned int nr_pages;
unsigned long offset;
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
@@ -94,25 +94,14 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
return -EFAULT;
}
- /* map pages with kernel virtual space. */
+ nr_pages = buffer->size >> PAGE_SHIFT;
+
+ buffer->kvaddr = (void __iomem *) vmap(buffer->pages,
+ nr_pages, VM_MAP,
+ pgprot_writecombine(PAGE_KERNEL));
if (!buffer->kvaddr) {
- if (is_drm_iommu_supported(dev)) {
- unsigned int nr_pages = buffer->size >> PAGE_SHIFT;
-
- buffer->kvaddr = (void __iomem *) vmap(buffer->pages,
- nr_pages, VM_MAP,
- pgprot_writecombine(PAGE_KERNEL));
- } else {
- phys_addr_t dma_addr = buffer->dma_addr;
- if (dma_addr)
- buffer->kvaddr = (void __iomem *)phys_to_virt(dma_addr);
- else
- buffer->kvaddr = (void __iomem *)NULL;
- }
- if (!buffer->kvaddr) {
- DRM_ERROR("failed to map pages to kernel space.\n");
- return -EIO;
- }
+ DRM_ERROR("failed to map pages to kernel space.\n");
+ return -EIO;
}
/* buffer count to framebuffer always is 1 at booting time. */
@@ -313,7 +302,7 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev,
struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj;
struct drm_framebuffer *fb;
- if (is_drm_iommu_supported(dev) && exynos_gem_obj->buffer->kvaddr)
+ if (exynos_gem_obj->buffer->kvaddr)
vunmap(exynos_gem_obj->buffer->kvaddr);
/* release drm framebuffer and real buffer */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 835b6af00970..842d6b8dc3c4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -461,7 +461,6 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
cfg |= EXYNOS_MSCTRL_C_INT_IN_3PLANE;
break;
case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV12MT:
case DRM_FORMAT_NV16:
cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR |
EXYNOS_MSCTRL_C_INT_IN_2PLANE);
@@ -511,7 +510,6 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
case DRM_FORMAT_YVU420:
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
- case DRM_FORMAT_NV12MT:
cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420;
break;
default:
@@ -524,10 +522,7 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK;
- if (fmt == DRM_FORMAT_NV12MT)
- cfg |= EXYNOS_CIDMAPARAM_R_MODE_64X32;
- else
- cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR;
+ cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR;
fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
@@ -812,7 +807,6 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
cfg |= EXYNOS_CIOCTRL_YCBCR_3PLANE;
break;
case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV12MT:
case DRM_FORMAT_NV16:
cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR;
cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE;
@@ -867,7 +861,6 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV12MT:
case DRM_FORMAT_NV21:
cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420;
break;
@@ -883,10 +876,7 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK;
- if (fmt == DRM_FORMAT_NV12MT)
- cfg |= EXYNOS_CIDMAPARAM_W_MODE_64X32;
- else
- cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR;
+ cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR;
fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index e5810d13bf9c..925fc69af1a0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -157,14 +157,13 @@ struct fimd_win_data {
};
struct fimd_context {
- struct exynos_drm_manager manager;
struct device *dev;
struct drm_device *drm_dev;
+ struct exynos_drm_crtc *crtc;
struct clk *bus_clk;
struct clk *lcd_clk;
void __iomem *regs;
struct regmap *sysreg;
- struct drm_display_mode mode;
struct fimd_win_data win_data[WINDOWS_NR];
unsigned int default_win;
unsigned long irq_flags;
@@ -185,11 +184,6 @@ struct fimd_context {
struct exynos_drm_display *display;
};
-static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr)
-{
- return container_of(mgr, struct fimd_context, manager);
-}
-
static const struct of_device_id fimd_driver_dt_match[] = {
{ .compatible = "samsung,s3c6400-fimd",
.data = &s3c64xx_fimd_driver_data },
@@ -214,9 +208,9 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
return (struct fimd_driver_data *)of_id->data;
}
-static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
+static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
+ struct fimd_context *ctx = crtc->ctx;
if (ctx->suspended)
return;
@@ -259,9 +253,8 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
writel(val, ctx->regs + SHADOWCON);
}
-static void fimd_clear_channel(struct exynos_drm_manager *mgr)
+static void fimd_clear_channel(struct fimd_context *ctx)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
int win, ch_enabled = 0;
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -286,38 +279,42 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr)
unsigned int state = ctx->suspended;
ctx->suspended = 0;
- fimd_wait_for_vblank(mgr);
+ fimd_wait_for_vblank(ctx->crtc);
ctx->suspended = state;
}
}
-static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
+static int fimd_ctx_initialize(struct fimd_context *ctx,
struct drm_device *drm_dev)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
struct exynos_drm_private *priv;
priv = drm_dev->dev_private;
- mgr->drm_dev = ctx->drm_dev = drm_dev;
- mgr->pipe = ctx->pipe = priv->pipe++;
+ ctx->drm_dev = drm_dev;
+ ctx->pipe = priv->pipe++;
/* attach this sub driver to iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev)) {
+ int ret;
+
/*
* If any channel is already active, iommu will throw
* a PAGE FAULT when enabled. So clear any channel if enabled.
*/
- fimd_clear_channel(mgr);
- drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
+ fimd_clear_channel(ctx);
+ ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
+ if (ret) {
+ DRM_ERROR("drm_iommu_attach failed.\n");
+ return ret;
+ }
+
}
return 0;
}
-static void fimd_mgr_remove(struct exynos_drm_manager *mgr)
+static void fimd_ctx_remove(struct fimd_context *ctx)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
-
/* detach this sub driver from iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev))
drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
@@ -343,7 +340,7 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
return (clkdiv < 0x100) ? clkdiv : 0xff;
}
-static bool fimd_mode_fixup(struct exynos_drm_manager *mgr,
+static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
@@ -353,18 +350,10 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr,
return true;
}
-static void fimd_mode_set(struct exynos_drm_manager *mgr,
- const struct drm_display_mode *in_mode)
-{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
-
- drm_mode_copy(&ctx->mode, in_mode);
-}
-
-static void fimd_commit(struct exynos_drm_manager *mgr)
+static void fimd_commit(struct exynos_drm_crtc *crtc)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
- struct drm_display_mode *mode = &ctx->mode;
+ struct fimd_context *ctx = crtc->ctx;
+ struct drm_display_mode *mode = &crtc->base.mode;
struct fimd_driver_data *driver_data = ctx->driver_data;
void *timing_base = ctx->regs + driver_data->timing_base;
u32 val, clkdiv;
@@ -461,9 +450,9 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
writel(val, ctx->regs + VIDCON0);
}
-static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
+static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
+ struct fimd_context *ctx = crtc->ctx;
u32 val;
if (ctx->suspended)
@@ -493,9 +482,9 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
return 0;
}
-static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
+static void fimd_disable_vblank(struct exynos_drm_crtc *crtc)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
+ struct fimd_context *ctx = crtc->ctx;
u32 val;
if (ctx->suspended)
@@ -517,45 +506,45 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
}
}
-static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
- struct exynos_drm_overlay *overlay)
+static void fimd_win_mode_set(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
+ struct fimd_context *ctx = crtc->ctx;
struct fimd_win_data *win_data;
int win;
unsigned long offset;
- if (!overlay) {
- DRM_ERROR("overlay is NULL\n");
+ if (!plane) {
+ DRM_ERROR("plane is NULL\n");
return;
}
- win = overlay->zpos;
+ win = plane->zpos;
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
if (win < 0 || win >= WINDOWS_NR)
return;
- offset = overlay->fb_x * (overlay->bpp >> 3);
- offset += overlay->fb_y * overlay->pitch;
+ offset = plane->fb_x * (plane->bpp >> 3);
+ offset += plane->fb_y * plane->pitch;
- DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch);
+ DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch);
win_data = &ctx->win_data[win];
- win_data->offset_x = overlay->crtc_x;
- win_data->offset_y = overlay->crtc_y;
- win_data->ovl_width = overlay->crtc_width;
- win_data->ovl_height = overlay->crtc_height;
- win_data->fb_width = overlay->fb_width;
- win_data->fb_height = overlay->fb_height;
- win_data->dma_addr = overlay->dma_addr[0] + offset;
- win_data->bpp = overlay->bpp;
- win_data->pixel_format = overlay->pixel_format;
- win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
- (overlay->bpp >> 3);
- win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3);
+ win_data->offset_x = plane->crtc_x;
+ win_data->offset_y = plane->crtc_y;
+ win_data->ovl_width = plane->crtc_width;
+ win_data->ovl_height = plane->crtc_height;
+ win_data->fb_width = plane->fb_width;
+ win_data->fb_height = plane->fb_height;
+ win_data->dma_addr = plane->dma_addr[0] + offset;
+ win_data->bpp = plane->bpp;
+ win_data->pixel_format = plane->pixel_format;
+ win_data->buf_offsize = (plane->fb_width - plane->crtc_width) *
+ (plane->bpp >> 3);
+ win_data->line_size = plane->crtc_width * (plane->bpp >> 3);
DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
win_data->offset_x, win_data->offset_y);
@@ -563,7 +552,7 @@ static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
win_data->ovl_width, win_data->ovl_height);
DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
- overlay->fb_width, overlay->crtc_width);
+ plane->fb_width, plane->crtc_width);
}
static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win)
@@ -623,8 +612,8 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win)
/*
* In case of exynos, setting dma-burst to 16Word causes permanent
* tearing for very small buffers, e.g. cursor buffer. Burst Mode
- * switching which is based on overlay size is not recommended as
- * overlay size varies alot towards the end of the screen and rapid
+ * switching which is based on plane size is not recommended as
+ * plane size varies alot towards the end of the screen and rapid
* movement causes unstable DMA which results into iommu crash/tear.
*/
@@ -676,9 +665,9 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx,
writel(val, ctx->regs + reg);
}
-static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
+static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
+ struct fimd_context *ctx = crtc->ctx;
struct fimd_win_data *win_data;
int win = zpos;
unsigned long val, alpha, size;
@@ -799,9 +788,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
atomic_set(&ctx->win_updated, 1);
}
-static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
+static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
+ struct fimd_context *ctx = crtc->ctx;
struct fimd_win_data *win_data;
int win = zpos;
@@ -833,9 +822,8 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
win_data->enabled = false;
}
-static void fimd_window_suspend(struct exynos_drm_manager *mgr)
+static void fimd_window_suspend(struct fimd_context *ctx)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
struct fimd_win_data *win_data;
int i;
@@ -843,13 +831,12 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr)
win_data = &ctx->win_data[i];
win_data->resume = win_data->enabled;
if (win_data->enabled)
- fimd_win_disable(mgr, i);
+ fimd_win_disable(ctx->crtc, i);
}
}
-static void fimd_window_resume(struct exynos_drm_manager *mgr)
+static void fimd_window_resume(struct fimd_context *ctx)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
struct fimd_win_data *win_data;
int i;
@@ -860,26 +847,24 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr)
}
}
-static void fimd_apply(struct exynos_drm_manager *mgr)
+static void fimd_apply(struct fimd_context *ctx)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
struct fimd_win_data *win_data;
int i;
for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
if (win_data->enabled)
- fimd_win_commit(mgr, i);
+ fimd_win_commit(ctx->crtc, i);
else
- fimd_win_disable(mgr, i);
+ fimd_win_disable(ctx->crtc, i);
}
- fimd_commit(mgr);
+ fimd_commit(ctx->crtc);
}
-static int fimd_poweron(struct exynos_drm_manager *mgr)
+static int fimd_poweron(struct fimd_context *ctx)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
int ret;
if (!ctx->suspended)
@@ -903,16 +888,16 @@ static int fimd_poweron(struct exynos_drm_manager *mgr)
/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags)) {
- ret = fimd_enable_vblank(mgr);
+ ret = fimd_enable_vblank(ctx->crtc);
if (ret) {
DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
goto enable_vblank_err;
}
}
- fimd_window_resume(mgr);
+ fimd_window_resume(ctx);
- fimd_apply(mgr);
+ fimd_apply(ctx);
return 0;
@@ -925,10 +910,8 @@ bus_clk_err:
return ret;
}
-static int fimd_poweroff(struct exynos_drm_manager *mgr)
+static int fimd_poweroff(struct fimd_context *ctx)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
-
if (ctx->suspended)
return 0;
@@ -937,7 +920,7 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
* suspend that connector. Otherwise we might try to scan from
* a destroyed buffer later.
*/
- fimd_window_suspend(mgr);
+ fimd_window_suspend(ctx);
clk_disable_unprepare(ctx->lcd_clk);
clk_disable_unprepare(ctx->bus_clk);
@@ -948,18 +931,18 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
return 0;
}
-static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
+static void fimd_dpms(struct exynos_drm_crtc *crtc, int mode)
{
DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
switch (mode) {
case DRM_MODE_DPMS_ON:
- fimd_poweron(mgr);
+ fimd_poweron(crtc->ctx);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- fimd_poweroff(mgr);
+ fimd_poweroff(crtc->ctx);
break;
default:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -996,9 +979,9 @@ static void fimd_trigger(struct device *dev)
atomic_set(&ctx->triggering, 0);
}
-static void fimd_te_handler(struct exynos_drm_manager *mgr)
+static void fimd_te_handler(struct exynos_drm_crtc *crtc)
{
- struct fimd_context *ctx = mgr_to_fimd(mgr);
+ struct fimd_context *ctx = crtc->ctx;
/* Checks the crtc is detached already from encoder */
if (ctx->pipe < 0 || !ctx->drm_dev)
@@ -1021,10 +1004,9 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr)
drm_handle_vblank(ctx->drm_dev, ctx->pipe);
}
-static struct exynos_drm_manager_ops fimd_manager_ops = {
+static struct exynos_drm_crtc_ops fimd_crtc_ops = {
.dpms = fimd_dpms,
.mode_fixup = fimd_mode_fixup,
- .mode_set = fimd_mode_set,
.commit = fimd_commit,
.enable_vblank = fimd_enable_vblank,
.disable_vblank = fimd_disable_vblank,
@@ -1074,9 +1056,22 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
{
struct fimd_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
+ int ret;
+
+ ret = fimd_ctx_initialize(ctx, drm_dev);
+ if (ret) {
+ DRM_ERROR("fimd_ctx_initialize failed.\n");
+ return ret;
+ }
+
+ ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
+ EXYNOS_DISPLAY_TYPE_LCD,
+ &fimd_crtc_ops, ctx);
+ if (IS_ERR(ctx->crtc)) {
+ fimd_ctx_remove(ctx);
+ return PTR_ERR(ctx->crtc);
+ }
- fimd_mgr_initialize(&ctx->manager, drm_dev);
- exynos_drm_crtc_create(&ctx->manager);
if (ctx->display)
exynos_drm_create_enc_conn(drm_dev, ctx->display);
@@ -1089,12 +1084,12 @@ static void fimd_unbind(struct device *dev, struct device *master,
{
struct fimd_context *ctx = dev_get_drvdata(dev);
- fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF);
+ fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
if (ctx->display)
exynos_dpi_remove(ctx->display);
- fimd_mgr_remove(&ctx->manager);
+ fimd_ctx_remove(ctx);
}
static const struct component_ops fimd_component_ops = {
@@ -1108,7 +1103,7 @@ static int fimd_probe(struct platform_device *pdev)
struct fimd_context *ctx;
struct device_node *i80_if_timings;
struct resource *res;
- int ret = -EINVAL;
+ int ret;
if (!dev->of_node)
return -ENODEV;
@@ -1117,11 +1112,8 @@ static int fimd_probe(struct platform_device *pdev)
if (!ctx)
return -ENOMEM;
- ctx->manager.type = EXYNOS_DISPLAY_TYPE_LCD;
- ctx->manager.ops = &fimd_manager_ops;
-
ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
- ctx->manager.type);
+ EXYNOS_DISPLAY_TYPE_LCD);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index ec58fe9c40df..308173cb4f0a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -22,6 +22,7 @@
/*
* exynos drm gem buffer structure.
*
+ * @cookie: cookie returned by dma_alloc_attrs
* @kvaddr: kernel virtual address to allocated memory region.
* *userptr: user space address.
* @dma_addr: bus address(accessed by dma) to allocated memory region.
@@ -35,6 +36,7 @@
* VM_PFNMAP or not.
*/
struct exynos_drm_gem_buf {
+ void *cookie;
void __iomem *kvaddr;
unsigned long userptr;
dma_addr_t dma_addr;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 0261468c8019..8040ed2a831f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -542,9 +542,6 @@ static int gsc_src_set_fmt(struct device *dev, u32 fmt)
cfg |= (GSC_IN_CHROMA_ORDER_CBCR |
GSC_IN_YUV420_2P);
break;
- case DRM_FORMAT_NV12MT:
- cfg |= (GSC_IN_TILE_C_16x8 | GSC_IN_TILE_MODE);
- break;
default:
dev_err(ippdrv->dev, "inavlid target yuv order 0x%x.\n", fmt);
return -EINVAL;
@@ -809,9 +806,6 @@ static int gsc_dst_set_fmt(struct device *dev, u32 fmt)
cfg |= (GSC_OUT_CHROMA_ORDER_CBCR |
GSC_OUT_YUV420_2P);
break;
- case DRM_FORMAT_NV12MT:
- cfg |= (GSC_OUT_TILE_C_16x8 | GSC_OUT_TILE_MODE);
- break;
default:
dev_err(ippdrv->dev, "inavlid target yuv order 0x%x.\n", fmt);
return -EINVAL;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index c7045a663763..a5616872eee7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -12,25 +12,17 @@
#include <drm/drmP.h>
#include <drm/exynos_drm.h>
+#include <drm/drm_plane_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
#include "exynos_drm_fb.h"
#include "exynos_drm_gem.h"
#include "exynos_drm_plane.h"
-#define to_exynos_plane(x) container_of(x, struct exynos_plane, base)
-
-struct exynos_plane {
- struct drm_plane base;
- struct exynos_drm_overlay overlay;
- bool enabled;
-};
-
static const uint32_t formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_NV12,
- DRM_FORMAT_NV12MT,
};
/*
@@ -69,16 +61,9 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
return size;
}
-int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h)
+int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb)
{
- struct exynos_plane *exynos_plane = to_exynos_plane(plane);
- struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
- unsigned int actual_w;
- unsigned int actual_h;
+ struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
int nr;
int i;
@@ -91,12 +76,26 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
return -EFAULT;
}
- overlay->dma_addr[i] = buffer->dma_addr;
+ exynos_plane->dma_addr[i] = buffer->dma_addr;
DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
- i, (unsigned long)overlay->dma_addr[i]);
+ i, (unsigned long)exynos_plane->dma_addr[i]);
}
+ return 0;
+}
+
+void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
+ struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+ unsigned int actual_w;
+ unsigned int actual_h;
+
actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
@@ -113,98 +112,79 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
}
/* set drm framebuffer data. */
- overlay->fb_x = src_x;
- overlay->fb_y = src_y;
- overlay->fb_width = fb->width;
- overlay->fb_height = fb->height;
- overlay->src_width = src_w;
- overlay->src_height = src_h;
- overlay->bpp = fb->bits_per_pixel;
- overlay->pitch = fb->pitches[0];
- overlay->pixel_format = fb->pixel_format;
-
- /* set overlay range to be displayed. */
- overlay->crtc_x = crtc_x;
- overlay->crtc_y = crtc_y;
- overlay->crtc_width = actual_w;
- overlay->crtc_height = actual_h;
+ exynos_plane->fb_x = src_x;
+ exynos_plane->fb_y = src_y;
+ exynos_plane->fb_width = fb->width;
+ exynos_plane->fb_height = fb->height;
+ exynos_plane->src_width = src_w;
+ exynos_plane->src_height = src_h;
+ exynos_plane->bpp = fb->bits_per_pixel;
+ exynos_plane->pitch = fb->pitches[0];
+ exynos_plane->pixel_format = fb->pixel_format;
+
+ /* set plane range to be displayed. */
+ exynos_plane->crtc_x = crtc_x;
+ exynos_plane->crtc_y = crtc_y;
+ exynos_plane->crtc_width = actual_w;
+ exynos_plane->crtc_height = actual_h;
/* set drm mode data. */
- overlay->mode_width = crtc->mode.hdisplay;
- overlay->mode_height = crtc->mode.vdisplay;
- overlay->refresh = crtc->mode.vrefresh;
- overlay->scan_flag = crtc->mode.flags;
+ exynos_plane->mode_width = crtc->mode.hdisplay;
+ exynos_plane->mode_height = crtc->mode.vdisplay;
+ exynos_plane->refresh = crtc->mode.vrefresh;
+ exynos_plane->scan_flag = crtc->mode.flags;
- DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)",
- overlay->crtc_x, overlay->crtc_y,
- overlay->crtc_width, overlay->crtc_height);
+ DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)",
+ exynos_plane->crtc_x, exynos_plane->crtc_y,
+ exynos_plane->crtc_width, exynos_plane->crtc_height);
plane->crtc = crtc;
- exynos_drm_crtc_plane_mode_set(crtc, overlay);
-
- return 0;
-}
-
-void exynos_plane_commit(struct drm_plane *plane)
-{
- struct exynos_plane *exynos_plane = to_exynos_plane(plane);
- struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
-
- exynos_drm_crtc_plane_commit(plane->crtc, overlay->zpos);
+ if (exynos_crtc->ops->win_mode_set)
+ exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane);
}
-void exynos_plane_dpms(struct drm_plane *plane, int mode)
-{
- struct exynos_plane *exynos_plane = to_exynos_plane(plane);
- struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
-
- if (mode == DRM_MODE_DPMS_ON) {
- if (exynos_plane->enabled)
- return;
-
- exynos_drm_crtc_plane_enable(plane->crtc, overlay->zpos);
- exynos_plane->enabled = true;
- } else {
- if (!exynos_plane->enabled)
- return;
-
- exynos_drm_crtc_plane_disable(plane->crtc, overlay->zpos);
- exynos_plane->enabled = false;
- }
-}
-
-static int
+int
exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
{
+
+ struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+ struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
int ret;
- ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
- crtc_w, crtc_h, src_x >> 16, src_y >> 16,
- src_w >> 16, src_h >> 16);
+ ret = exynos_check_plane(plane, fb);
if (ret < 0)
return ret;
- exynos_plane_commit(plane);
- exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
+ exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
+ crtc_w, crtc_h, src_x >> 16, src_y >> 16,
+ src_w >> 16, src_h >> 16);
+
+ if (exynos_crtc->ops->win_commit)
+ exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos);
return 0;
}
static int exynos_disable_plane(struct drm_plane *plane)
{
- exynos_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+ struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
+ struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);
+
+ if (exynos_crtc->ops->win_disable)
+ exynos_crtc->ops->win_disable(exynos_crtc,
+ exynos_plane->zpos);
return 0;
}
static void exynos_plane_destroy(struct drm_plane *plane)
{
- struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+ struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
exynos_disable_plane(plane);
drm_plane_cleanup(plane);
@@ -216,11 +196,11 @@ static int exynos_plane_set_property(struct drm_plane *plane,
uint64_t val)
{
struct drm_device *dev = plane->dev;
- struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+ struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_private *dev_priv = dev->dev_private;
if (property == dev_priv->plane_zpos_property) {
- exynos_plane->overlay.zpos = val;
+ exynos_plane->zpos = val;
return 0;
}
@@ -257,10 +237,10 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
unsigned long possible_crtcs,
enum drm_plane_type type)
{
- struct exynos_plane *exynos_plane;
+ struct exynos_drm_plane *exynos_plane;
int err;
- exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
+ exynos_plane = kzalloc(sizeof(struct exynos_drm_plane), GFP_KERNEL);
if (!exynos_plane)
return ERR_PTR(-ENOMEM);
@@ -274,7 +254,7 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
}
if (type == DRM_PLANE_TYPE_PRIMARY)
- exynos_plane->overlay.zpos = DEFAULT_ZPOS;
+ exynos_plane->zpos = DEFAULT_ZPOS;
else
exynos_plane_attach_zpos_property(&exynos_plane->base);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h
index 0d1986b115f8..9d3c374e7b3e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h
@@ -9,13 +9,17 @@
*
*/
-int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h);
-void exynos_plane_commit(struct drm_plane *plane);
-void exynos_plane_dpms(struct drm_plane *plane, int mode);
+int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb);
+void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h);
+int exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h);
struct drm_plane *exynos_plane_init(struct drm_device *dev,
unsigned long possible_crtcs,
enum drm_plane_type type);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 45899fb63272..b886972b5888 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -47,11 +47,10 @@ struct vidi_win_data {
};
struct vidi_context {
- struct exynos_drm_manager manager;
struct exynos_drm_display display;
struct platform_device *pdev;
struct drm_device *drm_dev;
- struct drm_crtc *crtc;
+ struct exynos_drm_crtc *crtc;
struct drm_encoder *encoder;
struct drm_connector connector;
struct vidi_win_data win_data[WINDOWS_NR];
@@ -68,11 +67,6 @@ struct vidi_context {
int pipe;
};
-static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m)
-{
- return container_of(m, struct vidi_context, manager);
-}
-
static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
{
return container_of(d, struct vidi_context, display);
@@ -103,34 +97,22 @@ static const char fake_edid_info[] = {
0x00, 0x00, 0x00, 0x06
};
-static void vidi_apply(struct exynos_drm_manager *mgr)
+static void vidi_apply(struct vidi_context *ctx)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
- struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
+ struct exynos_drm_crtc_ops *crtc_ops = ctx->crtc->ops;
struct vidi_win_data *win_data;
int i;
for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
- if (win_data->enabled && (mgr_ops && mgr_ops->win_commit))
- mgr_ops->win_commit(mgr, i);
+ if (win_data->enabled && (crtc_ops && crtc_ops->win_commit))
+ crtc_ops->win_commit(ctx->crtc, i);
}
-
- if (mgr_ops && mgr_ops->commit)
- mgr_ops->commit(mgr);
}
-static void vidi_commit(struct exynos_drm_manager *mgr)
+static int vidi_enable_vblank(struct exynos_drm_crtc *crtc)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
-
- if (ctx->suspended)
- return;
-}
-
-static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
-{
- struct vidi_context *ctx = manager_to_vidi(mgr);
+ struct vidi_context *ctx = crtc->ctx;
if (ctx->suspended)
return -EPERM;
@@ -143,16 +125,16 @@ static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
/*
* in case of page flip request, vidi_finish_pageflip function
* will not be called because direct_vblank is true and then
- * that function will be called by manager_ops->win_commit callback
+ * that function will be called by crtc_ops->win_commit callback
*/
schedule_work(&ctx->work);
return 0;
}
-static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
+static void vidi_disable_vblank(struct exynos_drm_crtc *crtc)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
+ struct vidi_context *ctx = crtc->ctx;
if (ctx->suspended)
return;
@@ -161,44 +143,44 @@ static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
ctx->vblank_on = false;
}
-static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
- struct exynos_drm_overlay *overlay)
+static void vidi_win_mode_set(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
+ struct vidi_context *ctx = crtc->ctx;
struct vidi_win_data *win_data;
int win;
unsigned long offset;
- if (!overlay) {
- DRM_ERROR("overlay is NULL\n");
+ if (!plane) {
+ DRM_ERROR("plane is NULL\n");
return;
}
- win = overlay->zpos;
+ win = plane->zpos;
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
if (win < 0 || win >= WINDOWS_NR)
return;
- offset = overlay->fb_x * (overlay->bpp >> 3);
- offset += overlay->fb_y * overlay->pitch;
+ offset = plane->fb_x * (plane->bpp >> 3);
+ offset += plane->fb_y * plane->pitch;
- DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch);
+ DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch);
win_data = &ctx->win_data[win];
- win_data->offset_x = overlay->crtc_x;
- win_data->offset_y = overlay->crtc_y;
- win_data->ovl_width = overlay->crtc_width;
- win_data->ovl_height = overlay->crtc_height;
- win_data->fb_width = overlay->fb_width;
- win_data->fb_height = overlay->fb_height;
- win_data->dma_addr = overlay->dma_addr[0] + offset;
- win_data->bpp = overlay->bpp;
- win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
- (overlay->bpp >> 3);
- win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3);
+ win_data->offset_x = plane->crtc_x;
+ win_data->offset_y = plane->crtc_y;
+ win_data->ovl_width = plane->crtc_width;
+ win_data->ovl_height = plane->crtc_height;
+ win_data->fb_width = plane->fb_width;
+ win_data->fb_height = plane->fb_height;
+ win_data->dma_addr = plane->dma_addr[0] + offset;
+ win_data->bpp = plane->bpp;
+ win_data->buf_offsize = (plane->fb_width - plane->crtc_width) *
+ (plane->bpp >> 3);
+ win_data->line_size = plane->crtc_width * (plane->bpp >> 3);
/*
* some parts of win_data should be transferred to user side
@@ -211,12 +193,12 @@ static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
win_data->ovl_width, win_data->ovl_height);
DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
- overlay->fb_width, overlay->crtc_width);
+ plane->fb_width, plane->crtc_width);
}
-static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
+static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
+ struct vidi_context *ctx = crtc->ctx;
struct vidi_win_data *win_data;
int win = zpos;
@@ -239,9 +221,9 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
schedule_work(&ctx->work);
}
-static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
+static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
+ struct vidi_context *ctx = crtc->ctx;
struct vidi_win_data *win_data;
int win = zpos;
@@ -257,10 +239,8 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
/* TODO. */
}
-static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
+static int vidi_power_on(struct vidi_context *ctx, bool enable)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
-
DRM_DEBUG_KMS("%s\n", __FILE__);
if (enable != false && enable != true)
@@ -271,9 +251,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags))
- vidi_enable_vblank(mgr);
+ vidi_enable_vblank(ctx->crtc);
- vidi_apply(mgr);
+ vidi_apply(ctx);
} else {
ctx->suspended = true;
}
@@ -281,9 +261,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
return 0;
}
-static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
+static void vidi_dpms(struct exynos_drm_crtc *crtc, int mode)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
+ struct vidi_context *ctx = crtc->ctx;
DRM_DEBUG_KMS("%d\n", mode);
@@ -291,12 +271,12 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
- vidi_power_on(mgr, true);
+ vidi_power_on(ctx, true);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- vidi_power_on(mgr, false);
+ vidi_power_on(ctx, false);
break;
default:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -306,21 +286,19 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
mutex_unlock(&ctx->lock);
}
-static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
+static int vidi_ctx_initialize(struct vidi_context *ctx,
struct drm_device *drm_dev)
{
- struct vidi_context *ctx = manager_to_vidi(mgr);
struct exynos_drm_private *priv = drm_dev->dev_private;
- mgr->drm_dev = ctx->drm_dev = drm_dev;
- mgr->pipe = ctx->pipe = priv->pipe++;
+ ctx->drm_dev = drm_dev;
+ ctx->pipe = priv->pipe++;
return 0;
}
-static struct exynos_drm_manager_ops vidi_manager_ops = {
+static struct exynos_drm_crtc_ops vidi_crtc_ops = {
.dpms = vidi_dpms,
- .commit = vidi_commit,
.enable_vblank = vidi_enable_vblank,
.disable_vblank = vidi_disable_vblank,
.win_mode_set = vidi_win_mode_set,
@@ -565,21 +543,21 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
{
struct vidi_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
- struct drm_crtc *crtc = ctx->crtc;
int ret;
- vidi_mgr_initialize(&ctx->manager, drm_dev);
+ vidi_ctx_initialize(ctx, drm_dev);
- ret = exynos_drm_crtc_create(&ctx->manager);
- if (ret) {
+ ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
+ EXYNOS_DISPLAY_TYPE_VIDI,
+ &vidi_crtc_ops, ctx);
+ if (IS_ERR(ctx->crtc)) {
DRM_ERROR("failed to create crtc.\n");
- return ret;
+ return PTR_ERR(ctx->crtc);
}
ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
if (ret) {
- crtc->funcs->destroy(crtc);
- DRM_ERROR("failed to create encoder and connector.\n");
+ ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
return ret;
}
@@ -605,15 +583,13 @@ static int vidi_probe(struct platform_device *pdev)
if (!ctx)
return -ENOMEM;
- ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI;
- ctx->manager.ops = &vidi_manager_ops;
ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
ctx->display.ops = &vidi_display_ops;
ctx->default_win = 0;
ctx->pdev = pdev;
ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
- ctx->manager.type);
+ EXYNOS_DISPLAY_TYPE_VIDI);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 98051e8e855a..229b3613c60b 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2032,9 +2032,8 @@ static void hdmi_commit(struct exynos_drm_display *display)
hdmi_conf_apply(hdata);
}
-static void hdmi_poweron(struct exynos_drm_display *display)
+static void hdmi_poweron(struct hdmi_context *hdata)
{
- struct hdmi_context *hdata = display_to_hdmi(display);
struct hdmi_resources *res = &hdata->res;
mutex_lock(&hdata->hdmi_mutex);
@@ -2060,12 +2059,11 @@ static void hdmi_poweron(struct exynos_drm_display *display)
clk_prepare_enable(res->sclk_hdmi);
hdmiphy_poweron(hdata);
- hdmi_commit(display);
+ hdmi_commit(&hdata->display);
}
-static void hdmi_poweroff(struct exynos_drm_display *display)
+static void hdmi_poweroff(struct hdmi_context *hdata)
{
- struct hdmi_context *hdata = display_to_hdmi(display);
struct hdmi_resources *res = &hdata->res;
mutex_lock(&hdata->hdmi_mutex);
@@ -2109,7 +2107,7 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
- hdmi_poweron(display);
+ hdmi_poweron(hdata);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
@@ -2128,7 +2126,7 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
if (funcs && funcs->dpms)
(*funcs->dpms)(crtc, mode);
- hdmi_poweroff(display);
+ hdmi_poweroff(hdata);
break;
default:
DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 064ed6597def..3518bc4654c5 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -72,6 +72,7 @@ struct mixer_resources {
spinlock_t reg_slock;
struct clk *mixer;
struct clk *vp;
+ struct clk *hdmi;
struct clk *sclk_mixer;
struct clk *sclk_hdmi;
struct clk *mout_mixer;
@@ -84,10 +85,10 @@ enum mixer_version_id {
};
struct mixer_context {
- struct exynos_drm_manager manager;
struct platform_device *pdev;
struct device *dev;
struct drm_device *drm_dev;
+ struct exynos_drm_crtc *crtc;
int pipe;
bool interlace;
bool powered;
@@ -103,11 +104,6 @@ struct mixer_context {
atomic_t wait_vsync_event;
};
-static inline struct mixer_context *mgr_to_mixer(struct exynos_drm_manager *mgr)
-{
- return container_of(mgr, struct mixer_context, manager);
-}
-
struct mixer_drv_data {
enum mixer_version_id version;
bool is_vp_enabled;
@@ -417,8 +413,6 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
win_data = &ctx->win_data[win];
switch (win_data->pixel_format) {
- case DRM_FORMAT_NV12MT:
- tiled_mode = true;
case DRM_FORMAT_NV12:
crcb_mode = false;
buf_num = 2;
@@ -587,8 +581,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
/* setup display size */
if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
win == MIXER_DEFAULT_WIN) {
- val = MXR_MXR_RES_HEIGHT(win_data->fb_height);
- val |= MXR_MXR_RES_WIDTH(win_data->fb_width);
+ val = MXR_MXR_RES_HEIGHT(win_data->mode_height);
+ val |= MXR_MXR_RES_WIDTH(win_data->mode_width);
mixer_reg_write(res, MXR_RESOLUTION, val);
}
@@ -774,6 +768,12 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
return -ENODEV;
}
+ mixer_res->hdmi = devm_clk_get(dev, "hdmi");
+ if (IS_ERR(mixer_res->hdmi)) {
+ dev_err(dev, "failed to get clock 'hdmi'\n");
+ return PTR_ERR(mixer_res->hdmi);
+ }
+
mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
if (IS_ERR(mixer_res->sclk_hdmi)) {
dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
@@ -854,16 +854,15 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
return 0;
}
-static int mixer_initialize(struct exynos_drm_manager *mgr,
+static int mixer_initialize(struct mixer_context *mixer_ctx,
struct drm_device *drm_dev)
{
int ret;
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
struct exynos_drm_private *priv;
priv = drm_dev->dev_private;
- mgr->drm_dev = mixer_ctx->drm_dev = drm_dev;
- mgr->pipe = mixer_ctx->pipe = priv->pipe++;
+ mixer_ctx->drm_dev = drm_dev;
+ mixer_ctx->pipe = priv->pipe++;
/* acquire resources: regs, irqs, clocks */
ret = mixer_resources_init(mixer_ctx);
@@ -887,17 +886,15 @@ static int mixer_initialize(struct exynos_drm_manager *mgr,
return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
}
-static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
+static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
{
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
-
if (is_drm_iommu_supported(mixer_ctx->drm_dev))
drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
}
-static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
+static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
{
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
+ struct mixer_context *mixer_ctx = crtc->ctx;
struct mixer_resources *res = &mixer_ctx->mixer_res;
if (!mixer_ctx->powered) {
@@ -912,34 +909,34 @@ static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
return 0;
}
-static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
+static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
{
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
+ struct mixer_context *mixer_ctx = crtc->ctx;
struct mixer_resources *res = &mixer_ctx->mixer_res;
/* disable vsync interrupt */
mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
}
-static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
- struct exynos_drm_overlay *overlay)
+static void mixer_win_mode_set(struct exynos_drm_crtc *crtc,
+ struct exynos_drm_plane *plane)
{
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
+ struct mixer_context *mixer_ctx = crtc->ctx;
struct hdmi_win_data *win_data;
int win;
- if (!overlay) {
- DRM_ERROR("overlay is NULL\n");
+ if (!plane) {
+ DRM_ERROR("plane is NULL\n");
return;
}
DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
- overlay->fb_width, overlay->fb_height,
- overlay->fb_x, overlay->fb_y,
- overlay->crtc_width, overlay->crtc_height,
- overlay->crtc_x, overlay->crtc_y);
+ plane->fb_width, plane->fb_height,
+ plane->fb_x, plane->fb_y,
+ plane->crtc_width, plane->crtc_height,
+ plane->crtc_x, plane->crtc_y);
- win = overlay->zpos;
+ win = plane->zpos;
if (win == DEFAULT_ZPOS)
win = MIXER_DEFAULT_WIN;
@@ -950,32 +947,32 @@ static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
win_data = &mixer_ctx->win_data[win];
- win_data->dma_addr = overlay->dma_addr[0];
- win_data->chroma_dma_addr = overlay->dma_addr[1];
- win_data->pixel_format = overlay->pixel_format;
- win_data->bpp = overlay->bpp;
+ win_data->dma_addr = plane->dma_addr[0];
+ win_data->chroma_dma_addr = plane->dma_addr[1];
+ win_data->pixel_format = plane->pixel_format;
+ win_data->bpp = plane->bpp;
- win_data->crtc_x = overlay->crtc_x;
- win_data->crtc_y = overlay->crtc_y;
- win_data->crtc_width = overlay->crtc_width;
- win_data->crtc_height = overlay->crtc_height;
+ win_data->crtc_x = plane->crtc_x;
+ win_data->crtc_y = plane->crtc_y;
+ win_data->crtc_width = plane->crtc_width;
+ win_data->crtc_height = plane->crtc_height;
- win_data->fb_x = overlay->fb_x;
- win_data->fb_y = overlay->fb_y;
- win_data->fb_width = overlay->fb_width;
- win_data->fb_height = overlay->fb_height;
- win_data->src_width = overlay->src_width;
- win_data->src_height = overlay->src_height;
+ win_data->fb_x = plane->fb_x;
+ win_data->fb_y = plane->fb_y;
+ win_data->fb_width = plane->fb_width;
+ win_data->fb_height = plane->fb_height;
+ win_data->src_width = plane->src_width;
+ win_data->src_height = plane->src_height;
- win_data->mode_width = overlay->mode_width;
- win_data->mode_height = overlay->mode_height;
+ win_data->mode_width = plane->mode_width;
+ win_data->mode_height = plane->mode_height;
- win_data->scan_flags = overlay->scan_flag;
+ win_data->scan_flags = plane->scan_flag;
}
-static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
+static void mixer_win_commit(struct exynos_drm_crtc *crtc, int zpos)
{
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
+ struct mixer_context *mixer_ctx = crtc->ctx;
int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
DRM_DEBUG_KMS("win: %d\n", win);
@@ -995,9 +992,9 @@ static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
mixer_ctx->win_data[win].enabled = true;
}
-static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
+static void mixer_win_disable(struct exynos_drm_crtc *crtc, int zpos)
{
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
+ struct mixer_context *mixer_ctx = crtc->ctx;
struct mixer_resources *res = &mixer_ctx->mixer_res;
int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
unsigned long flags;
@@ -1023,9 +1020,9 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
mixer_ctx->win_data[win].enabled = false;
}
-static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
+static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
{
- struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
+ struct mixer_context *mixer_ctx = crtc->ctx;
int err;
mutex_lock(&mixer_ctx->mixer_mutex);
@@ -1035,7 +1032,7 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
}
mutex_unlock(&mixer_ctx->mixer_mutex);
- err = drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe);
+ err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe);
if (err < 0) {
DRM_DEBUG_KMS("failed to acquire vblank counter\n");
return;
@@ -1052,26 +1049,24 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
HZ/20))
DRM_DEBUG_KMS("vblank wait timed out.\n");
- drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe);
+ drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
}
-static void mixer_window_suspend(struct exynos_drm_manager *mgr)
+static void mixer_window_suspend(struct mixer_context *ctx)
{
- struct mixer_context *ctx = mgr_to_mixer(mgr);
struct hdmi_win_data *win_data;
int i;
for (i = 0; i < MIXER_WIN_NR; i++) {
win_data = &ctx->win_data[i];
win_data->resume = win_data->enabled;
- mixer_win_disable(mgr, i);
+ mixer_win_disable(ctx->crtc, i);
}
- mixer_wait_for_vblank(mgr);
+ mixer_wait_for_vblank(ctx->crtc);
}
-static void mixer_window_resume(struct exynos_drm_manager *mgr)
+static void mixer_window_resume(struct mixer_context *ctx)
{
- struct mixer_context *ctx = mgr_to_mixer(mgr);
struct hdmi_win_data *win_data;
int i;
@@ -1080,13 +1075,12 @@ static void mixer_window_resume(struct exynos_drm_manager *mgr)
win_data->enabled = win_data->resume;
win_data->resume = false;
if (win_data->enabled)
- mixer_win_commit(mgr, i);
+ mixer_win_commit(ctx->crtc, i);
}
}
-static void mixer_poweron(struct exynos_drm_manager *mgr)
+static void mixer_poweron(struct mixer_context *ctx)
{
- struct mixer_context *ctx = mgr_to_mixer(mgr);
struct mixer_resources *res = &ctx->mixer_res;
mutex_lock(&ctx->mixer_mutex);
@@ -1100,6 +1094,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
pm_runtime_get_sync(ctx->dev);
clk_prepare_enable(res->mixer);
+ clk_prepare_enable(res->hdmi);
if (ctx->vp_enabled) {
clk_prepare_enable(res->vp);
if (ctx->has_sclk)
@@ -1115,12 +1110,11 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
mixer_win_reset(ctx);
- mixer_window_resume(mgr);
+ mixer_window_resume(ctx);
}
-static void mixer_poweroff(struct exynos_drm_manager *mgr)
+static void mixer_poweroff(struct mixer_context *ctx)
{
- struct mixer_context *ctx = mgr_to_mixer(mgr);
struct mixer_resources *res = &ctx->mixer_res;
mutex_lock(&ctx->mixer_mutex);
@@ -1131,7 +1125,7 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
mutex_unlock(&ctx->mixer_mutex);
mixer_stop(ctx);
- mixer_window_suspend(mgr);
+ mixer_window_suspend(ctx);
ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
@@ -1139,6 +1133,7 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
ctx->powered = false;
mutex_unlock(&ctx->mixer_mutex);
+ clk_disable_unprepare(res->hdmi);
clk_disable_unprepare(res->mixer);
if (ctx->vp_enabled) {
clk_disable_unprepare(res->vp);
@@ -1149,16 +1144,16 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
pm_runtime_put_sync(ctx->dev);
}
-static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
+static void mixer_dpms(struct exynos_drm_crtc *crtc, int mode)
{
switch (mode) {
case DRM_MODE_DPMS_ON:
- mixer_poweron(mgr);
+ mixer_poweron(crtc->ctx);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- mixer_poweroff(mgr);
+ mixer_poweroff(crtc->ctx);
break;
default:
DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
@@ -1186,7 +1181,7 @@ int mixer_check_mode(struct drm_display_mode *mode)
return -EINVAL;
}
-static struct exynos_drm_manager_ops mixer_manager_ops = {
+static struct exynos_drm_crtc_ops mixer_crtc_ops = {
.dpms = mixer_dpms,
.enable_vblank = mixer_enable_vblank,
.disable_vblank = mixer_disable_vblank,
@@ -1257,24 +1252,31 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
struct drm_device *drm_dev = data;
int ret;
- ret = mixer_initialize(&ctx->manager, drm_dev);
+ ret = mixer_initialize(ctx, drm_dev);
if (ret)
return ret;
- ret = exynos_drm_crtc_create(&ctx->manager);
- if (ret) {
- mixer_mgr_remove(&ctx->manager);
- return ret;
+ ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
+ EXYNOS_DISPLAY_TYPE_HDMI,
+ &mixer_crtc_ops, ctx);
+ if (IS_ERR(ctx->crtc)) {
+ mixer_ctx_remove(ctx);
+ ret = PTR_ERR(ctx->crtc);
+ goto free_ctx;
}
return 0;
+
+free_ctx:
+ devm_kfree(dev, ctx);
+ return ret;
}
static void mixer_unbind(struct device *dev, struct device *master, void *data)
{
struct mixer_context *ctx = dev_get_drvdata(dev);
- mixer_mgr_remove(&ctx->manager);
+ mixer_ctx_remove(ctx);
}
static const struct component_ops mixer_component_ops = {
@@ -1297,9 +1299,6 @@ static int mixer_probe(struct platform_device *pdev)
mutex_init(&ctx->mixer_mutex);
- ctx->manager.type = EXYNOS_DISPLAY_TYPE_HDMI;
- ctx->manager.ops = &mixer_manager_ops;
-
if (dev->of_node) {
const struct of_device_id *match;
@@ -1321,7 +1320,7 @@ static int mixer_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctx);
ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
- ctx->manager.type);
+ EXYNOS_DISPLAY_TYPE_HDMI);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index ddd90ddbc200..2d42ce6d3757 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -593,6 +593,7 @@ int psb_fbdev_init(struct drm_device *dev)
{
struct psb_fbdev *fbdev;
struct drm_psb_private *dev_priv = dev->dev_private;
+ int ret;
fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
if (!fbdev) {
@@ -604,16 +605,29 @@ int psb_fbdev_init(struct drm_device *dev)
drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs);
- drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
- INTELFB_CONN_LIMIT);
+ ret = drm_fb_helper_init(dev, &fbdev->psb_fb_helper,
+ dev_priv->ops->crtcs, INTELFB_CONN_LIMIT);
+ if (ret)
+ goto free;
- drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
+ ret = drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
+ if (ret)
+ goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);
- drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
+ ret = drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32);
+ if (ret)
+ goto fini;
+
return 0;
+
+fini:
+ drm_fb_helper_fini(&fbdev->psb_fb_helper);
+free:
+ kfree(fbdev);
+ return ret;
}
static void psb_fbdev_fini(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c
index faf1c0c5ab2e..fa140e04d5fa 100644
--- a/drivers/gpu/drm/i2c/adv7511.c
+++ b/drivers/gpu/drm/i2c/adv7511.c
@@ -644,9 +644,6 @@ static int adv7511_encoder_mode_valid(struct drm_encoder *encoder,
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- return MODE_NO_INTERLACE;
-
return MODE_OK;
}
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 4e39ab34eb1c..74acca9bcd9d 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -11,6 +11,8 @@ config DRM_I915
select SHMEM
select TMPFS
select DRM_KMS_HELPER
+ select DRM_PANEL
+ select DRM_MIPI_DSI
# 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
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index e4083e41a600..f01922591679 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -19,6 +19,7 @@ i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o
# GEM code
i915-y += i915_cmd_parser.o \
+ i915_gem_batch_pool.o \
i915_gem_context.o \
i915_gem_render_state.o \
i915_gem_debug.o \
@@ -47,6 +48,7 @@ i915-y += intel_renderstate_gen6.o \
i915-y += intel_audio.o \
intel_bios.o \
intel_display.o \
+ intel_fbc.o \
intel_fifo_underrun.o \
intel_frontbuffer.o \
intel_modes.o \
@@ -64,11 +66,12 @@ i915-y += dvo_ch7017.o \
dvo_ns2501.o \
dvo_sil164.o \
dvo_tfp410.o \
+ intel_atomic.o \
+ intel_atomic_plane.o \
intel_crt.o \
intel_ddi.o \
intel_dp.o \
intel_dp_mst.o \
- intel_dsi_cmd.o \
intel_dsi.o \
intel_dsi_pll.o \
intel_dsi_panel_vbt.o \
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index 22c992a78ac6..806e812340d0 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -152,6 +152,7 @@ static const struct drm_i915_cmd_descriptor render_cmds[] = {
CMD( MI_PREDICATE, SMI, F, 1, S ),
CMD( MI_TOPOLOGY_FILTER, SMI, F, 1, S ),
CMD( MI_DISPLAY_FLIP, SMI, !F, 0xFF, R ),
+ CMD( MI_SET_APPID, SMI, F, 1, S ),
CMD( MI_SET_CONTEXT, SMI, !F, 0xFF, R ),
CMD( MI_URB_CLEAR, SMI, !F, 0xFF, S ),
CMD( MI_STORE_DWORD_IMM, SMI, !F, 0x3F, B,
@@ -210,6 +211,7 @@ static const struct drm_i915_cmd_descriptor hsw_render_cmds[] = {
CMD( MI_SET_PREDICATE, SMI, F, 1, S ),
CMD( MI_RS_CONTROL, SMI, F, 1, S ),
CMD( MI_URB_ATOMIC_ALLOC, SMI, F, 1, S ),
+ CMD( MI_SET_APPID, SMI, F, 1, S ),
CMD( MI_RS_CONTEXT, SMI, F, 1, S ),
CMD( MI_LOAD_SCAN_LINES_INCL, SMI, !F, 0x3F, M ),
CMD( MI_LOAD_SCAN_LINES_EXCL, SMI, !F, 0x3F, R ),
@@ -229,6 +231,7 @@ static const struct drm_i915_cmd_descriptor hsw_render_cmds[] = {
static const struct drm_i915_cmd_descriptor video_cmds[] = {
CMD( MI_ARB_ON_OFF, SMI, F, 1, R ),
+ CMD( MI_SET_APPID, SMI, F, 1, S ),
CMD( MI_STORE_DWORD_IMM, SMI, !F, 0xFF, B,
.bits = {{
.offset = 0,
@@ -272,6 +275,7 @@ static const struct drm_i915_cmd_descriptor video_cmds[] = {
static const struct drm_i915_cmd_descriptor vecs_cmds[] = {
CMD( MI_ARB_ON_OFF, SMI, F, 1, R ),
+ CMD( MI_SET_APPID, SMI, F, 1, S ),
CMD( MI_STORE_DWORD_IMM, SMI, !F, 0xFF, B,
.bits = {{
.offset = 0,
@@ -401,6 +405,7 @@ static const struct drm_i915_cmd_table hsw_blt_ring_cmds[] = {
#define REG64(addr) (addr), (addr + sizeof(u32))
static const u32 gen7_render_regs[] = {
+ REG64(GPGPU_THREADS_DISPATCHED),
REG64(HS_INVOCATION_COUNT),
REG64(DS_INVOCATION_COUNT),
REG64(IA_VERTICES_COUNT),
@@ -481,13 +486,17 @@ static u32 gen7_bsd_get_cmd_length_mask(u32 cmd_header)
u32 client = (cmd_header & INSTR_CLIENT_MASK) >> INSTR_CLIENT_SHIFT;
u32 subclient =
(cmd_header & INSTR_SUBCLIENT_MASK) >> INSTR_SUBCLIENT_SHIFT;
+ u32 op = (cmd_header & INSTR_26_TO_24_MASK) >> INSTR_26_TO_24_SHIFT;
if (client == INSTR_MI_CLIENT)
return 0x3F;
else if (client == INSTR_RC_CLIENT) {
- if (subclient == INSTR_MEDIA_SUBCLIENT)
- return 0xFFF;
- else
+ if (subclient == INSTR_MEDIA_SUBCLIENT) {
+ if (op == 6)
+ return 0xFFFF;
+ else
+ return 0xFFF;
+ } else
return 0xFF;
}
@@ -716,13 +725,13 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
BUG_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count));
BUG_ON(!validate_regs_sorted(ring));
- if (hash_empty(ring->cmd_hash)) {
- ret = init_hash_table(ring, cmd_tables, cmd_table_count);
- if (ret) {
- DRM_ERROR("CMD: cmd_parser_init failed!\n");
- fini_hash_table(ring);
- return ret;
- }
+ WARN_ON(!hash_empty(ring->cmd_hash));
+
+ ret = init_hash_table(ring, cmd_tables, cmd_table_count);
+ if (ret) {
+ DRM_ERROR("CMD: cmd_parser_init failed!\n");
+ fini_hash_table(ring);
+ return ret;
}
ring->needs_cmd_parser = true;
@@ -840,6 +849,69 @@ finish:
return (u32*)addr;
}
+/* Returns a vmap'd pointer to dest_obj, which the caller must unmap */
+static u32 *copy_batch(struct drm_i915_gem_object *dest_obj,
+ struct drm_i915_gem_object *src_obj,
+ u32 batch_start_offset,
+ u32 batch_len)
+{
+ int ret = 0;
+ int needs_clflush = 0;
+ u32 *src_base, *dest_base = NULL;
+ u32 *src_addr, *dest_addr;
+ u32 offset = batch_start_offset / sizeof(*dest_addr);
+ u32 end = batch_start_offset + batch_len;
+
+ if (end > dest_obj->base.size || end > src_obj->base.size)
+ return ERR_PTR(-E2BIG);
+
+ ret = i915_gem_obj_prepare_shmem_read(src_obj, &needs_clflush);
+ if (ret) {
+ DRM_DEBUG_DRIVER("CMD: failed to prep read\n");
+ return ERR_PTR(ret);
+ }
+
+ src_base = vmap_batch(src_obj);
+ if (!src_base) {
+ DRM_DEBUG_DRIVER("CMD: Failed to vmap batch\n");
+ ret = -ENOMEM;
+ goto unpin_src;
+ }
+
+ src_addr = src_base + offset;
+
+ if (needs_clflush)
+ drm_clflush_virt_range((char *)src_addr, batch_len);
+
+ ret = i915_gem_object_set_to_cpu_domain(dest_obj, true);
+ if (ret) {
+ DRM_DEBUG_DRIVER("CMD: Failed to set batch CPU domain\n");
+ goto unmap_src;
+ }
+
+ dest_base = vmap_batch(dest_obj);
+ if (!dest_base) {
+ DRM_DEBUG_DRIVER("CMD: Failed to vmap shadow batch\n");
+ ret = -ENOMEM;
+ goto unmap_src;
+ }
+
+ dest_addr = dest_base + offset;
+
+ if (batch_start_offset != 0)
+ memset((u8 *)dest_base, 0, batch_start_offset);
+
+ memcpy(dest_addr, src_addr, batch_len);
+ memset((u8 *)dest_addr + batch_len, 0, dest_obj->base.size - end);
+
+unmap_src:
+ vunmap(src_base);
+unpin_src:
+ i915_gem_object_unpin_pages(src_obj);
+
+ return ret ? ERR_PTR(ret) : dest_base;
+}
+
/**
* i915_needs_cmd_parser() - should a given ring use software command parsing?
* @ring: the ring in question
@@ -956,7 +1028,9 @@ static bool check_cmd(const struct intel_engine_cs *ring,
* i915_parse_cmds() - parse a submitted batch buffer for privilege violations
* @ring: the ring on which the batch is to execute
* @batch_obj: the batch buffer in question
+ * @shadow_batch_obj: copy of the batch buffer in question
* @batch_start_offset: byte offset in the batch at which execution starts
+ * @batch_len: length of the commands in batch_obj
* @is_master: is the submitting process the drm master?
*
* Parses the specified batch buffer looking for privilege violations as
@@ -967,33 +1041,38 @@ static bool check_cmd(const struct intel_engine_cs *ring,
*/
int i915_parse_cmds(struct intel_engine_cs *ring,
struct drm_i915_gem_object *batch_obj,
+ struct drm_i915_gem_object *shadow_batch_obj,
u32 batch_start_offset,
+ u32 batch_len,
bool is_master)
{
int ret = 0;
u32 *cmd, *batch_base, *batch_end;
struct drm_i915_cmd_descriptor default_desc = { 0 };
- int needs_clflush = 0;
bool oacontrol_set = false; /* OACONTROL tracking. See check_cmd() */
- ret = i915_gem_obj_prepare_shmem_read(batch_obj, &needs_clflush);
+ ret = i915_gem_obj_ggtt_pin(shadow_batch_obj, 4096, 0);
if (ret) {
- DRM_DEBUG_DRIVER("CMD: failed to prep read\n");
- return ret;
+ DRM_DEBUG_DRIVER("CMD: Failed to pin shadow batch\n");
+ return -1;
}
- batch_base = vmap_batch(batch_obj);
- if (!batch_base) {
- DRM_DEBUG_DRIVER("CMD: Failed to vmap batch\n");
- i915_gem_object_unpin_pages(batch_obj);
- return -ENOMEM;
+ batch_base = copy_batch(shadow_batch_obj, batch_obj,
+ batch_start_offset, batch_len);
+ if (IS_ERR(batch_base)) {
+ DRM_DEBUG_DRIVER("CMD: Failed to copy batch\n");
+ i915_gem_object_ggtt_unpin(shadow_batch_obj);
+ return PTR_ERR(batch_base);
}
- if (needs_clflush)
- drm_clflush_virt_range((char *)batch_base, batch_obj->base.size);
-
cmd = batch_base + (batch_start_offset / sizeof(*cmd));
- batch_end = cmd + (batch_obj->base.size / sizeof(*batch_end));
+
+ /*
+ * We use the batch length as size because the shadow object is as
+ * large or larger and copy_batch() will write MI_NOPs to the extra
+ * space. Parsing should be faster in some cases this way.
+ */
+ batch_end = cmd + (batch_len / sizeof(*batch_end));
while (cmd < batch_end) {
const struct drm_i915_cmd_descriptor *desc;
@@ -1053,8 +1132,7 @@ int i915_parse_cmds(struct intel_engine_cs *ring,
}
vunmap(batch_base);
-
- i915_gem_object_unpin_pages(batch_obj);
+ i915_gem_object_ggtt_unpin(shadow_batch_obj);
return ret;
}
@@ -1076,6 +1154,7 @@ int i915_cmd_parser_get_version(void)
* hardware parsing enabled (so does not allow new use cases).
* 2. Allow access to the MI_PREDICATE_SRC0 and
* MI_PREDICATE_SRC1 registers.
+ * 3. Allow access to the GPGPU_THREADS_DISPATCHED register.
*/
- return 2;
+ return 3;
}
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 779a275eb1fd..96e811fe24ca 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -96,9 +96,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
static const char *get_pin_flag(struct drm_i915_gem_object *obj)
{
- if (obj->user_pin_count > 0)
- return "P";
- else if (i915_gem_obj_is_pinned(obj))
+ if (i915_gem_obj_is_pinned(obj))
return "p";
else
return " ";
@@ -125,7 +123,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
struct i915_vma *vma;
int pin_count = 0;
- seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %u %u %u%s%s%s",
+ seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %x %x %x%s%s%s",
&obj->base,
get_pin_flag(obj),
get_tiling_flag(obj),
@@ -133,9 +131,9 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
obj->base.size / 1024,
obj->base.read_domains,
obj->base.write_domain,
- obj->last_read_seqno,
- obj->last_write_seqno,
- obj->last_fenced_seqno,
+ i915_gem_request_get_seqno(obj->last_read_req),
+ i915_gem_request_get_seqno(obj->last_write_req),
+ i915_gem_request_get_seqno(obj->last_fenced_req),
i915_cache_level_str(to_i915(obj->base.dev), obj->cache_level),
obj->dirty ? " dirty" : "",
obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
@@ -154,8 +152,9 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
seq_puts(m, " (pp");
else
seq_puts(m, " (g");
- seq_printf(m, "gtt offset: %08lx, size: %08lx)",
- vma->node.start, vma->node.size);
+ seq_printf(m, "gtt offset: %08lx, size: %08lx, type: %u)",
+ vma->node.start, vma->node.size,
+ vma->ggtt_view.type);
}
if (obj->stolen)
seq_printf(m, " (stolen: %08lx)", obj->stolen->start);
@@ -168,8 +167,9 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
*t = '\0';
seq_printf(m, " (%s mappable)", s);
}
- if (obj->ring != NULL)
- seq_printf(m, " (%s)", obj->ring->name);
+ if (obj->last_read_req != NULL)
+ seq_printf(m, " (%s)",
+ i915_gem_request_get_ring(obj->last_read_req)->name);
if (obj->frontbuffer_bits)
seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);
}
@@ -336,7 +336,7 @@ static int per_file_stats(int id, void *ptr, void *data)
if (ppgtt->file_priv != stats->file_priv)
continue;
- if (obj->ring) /* XXX per-vma statistic */
+ if (obj->active) /* XXX per-vma statistic */
stats->active += obj->base.size;
else
stats->inactive += obj->base.size;
@@ -346,7 +346,7 @@ static int per_file_stats(int id, void *ptr, void *data)
} else {
if (i915_gem_obj_ggtt_bound(obj)) {
stats->global += obj->base.size;
- if (obj->ring)
+ if (obj->active)
stats->active += obj->base.size;
else
stats->inactive += obj->base.size;
@@ -360,6 +360,33 @@ static int per_file_stats(int id, void *ptr, void *data)
return 0;
}
+#define print_file_stats(m, name, stats) \
+ seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu inactive, %zu global, %zu shared, %zu unbound)\n", \
+ name, \
+ stats.count, \
+ stats.total, \
+ stats.active, \
+ stats.inactive, \
+ stats.global, \
+ stats.shared, \
+ stats.unbound)
+
+static void print_batch_pool_stats(struct seq_file *m,
+ struct drm_i915_private *dev_priv)
+{
+ struct drm_i915_gem_object *obj;
+ struct file_stats stats;
+
+ memset(&stats, 0, sizeof(stats));
+
+ list_for_each_entry(obj,
+ &dev_priv->mm.batch_pool.cache_list,
+ batch_pool_list)
+ per_file_stats(0, obj, &stats);
+
+ print_file_stats(m, "batch pool", stats);
+}
+
#define count_vmas(list, member) do { \
list_for_each_entry(vma, list, member) { \
size += i915_gem_obj_ggtt_size(vma->obj); \
@@ -442,6 +469,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
dev_priv->gtt.mappable_end - dev_priv->gtt.base.start);
seq_putc(m, '\n');
+ print_batch_pool_stats(m, dev_priv);
+
+ seq_putc(m, '\n');
list_for_each_entry_reverse(file, &dev->filelist, lhead) {
struct file_stats stats;
struct task_struct *task;
@@ -459,15 +489,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
*/
rcu_read_lock();
task = pid_task(file->pid, PIDTYPE_PID);
- seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu inactive, %zu global, %zu shared, %zu unbound)\n",
- task ? task->comm : "<unknown>",
- stats.count,
- stats.total,
- stats.active,
- stats.inactive,
- stats.global,
- stats.shared,
- stats.unbound);
+ print_file_stats(m, task ? task->comm : "<unknown>", stats);
rcu_read_unlock();
}
@@ -543,14 +565,16 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n",
pipe, plane);
}
- if (work->flip_queued_ring) {
- seq_printf(m, "Flip queued on %s at seqno %u, next seqno %u [current breadcrumb %u], completed? %d\n",
- work->flip_queued_ring->name,
- work->flip_queued_seqno,
+ if (work->flip_queued_req) {
+ struct intel_engine_cs *ring =
+ i915_gem_request_get_ring(work->flip_queued_req);
+
+ seq_printf(m, "Flip queued on %s at seqno %x, next seqno %x [current breadcrumb %x], completed? %d\n",
+ ring->name,
+ i915_gem_request_get_seqno(work->flip_queued_req),
dev_priv->next_seqno,
- work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
- i915_seqno_passed(work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
- work->flip_queued_seqno));
+ ring->get_seqno(ring, true),
+ i915_gem_request_completed(work->flip_queued_req, true));
} else
seq_printf(m, "Flip not associated with any ring\n");
seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
@@ -582,6 +606,36 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
return 0;
}
+static int i915_gem_batch_pool_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj;
+ int count = 0;
+ int ret;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ seq_puts(m, "cache:\n");
+ list_for_each_entry(obj,
+ &dev_priv->mm.batch_pool.cache_list,
+ batch_pool_list) {
+ seq_puts(m, " ");
+ describe_obj(m, obj);
+ seq_putc(m, '\n');
+ count++;
+ }
+
+ seq_printf(m, "total: %d\n", count);
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
static int i915_gem_request_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = m->private;
@@ -604,7 +658,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
list_for_each_entry(gem_request,
&ring->request_list,
list) {
- seq_printf(m, " %d @ %d\n",
+ seq_printf(m, " %x @ %d\n",
gem_request->seqno,
(int) (jiffies - gem_request->emitted_jiffies));
}
@@ -622,7 +676,7 @@ static void i915_ring_seqno_info(struct seq_file *m,
struct intel_engine_cs *ring)
{
if (ring->get_seqno) {
- seq_printf(m, "Current sequence (%s): %u\n",
+ seq_printf(m, "Current sequence (%s): %x\n",
ring->name, ring->get_seqno(ring, false));
}
}
@@ -1051,7 +1105,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
if (ret)
goto out;
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
reqf = I915_READ(GEN6_RPNSWREQ);
reqf &= ~GEN6_TURBO_DISABLE;
@@ -1059,7 +1113,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
reqf >>= 24;
else
reqf >>= 25;
- reqf *= GT_FREQUENCY_MULTIPLIER;
+ reqf = intel_gpu_freq(dev_priv, reqf);
rpmodectl = I915_READ(GEN6_RP_CONTROL);
rpinclimit = I915_READ(GEN6_RP_UP_THRESHOLD);
@@ -1076,9 +1130,9 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
else
cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
- cagf *= GT_FREQUENCY_MULTIPLIER;
+ cagf = intel_gpu_freq(dev_priv, cagf);
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
mutex_unlock(&dev->struct_mutex);
if (IS_GEN6(dev) || IS_GEN7(dev)) {
@@ -1124,18 +1178,18 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
max_freq = (rp_state_cap & 0xff0000) >> 16;
seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
- max_freq * GT_FREQUENCY_MULTIPLIER);
+ intel_gpu_freq(dev_priv, max_freq));
max_freq = (rp_state_cap & 0xff00) >> 8;
seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
- max_freq * GT_FREQUENCY_MULTIPLIER);
+ intel_gpu_freq(dev_priv, max_freq));
max_freq = rp_state_cap & 0xff;
seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
- max_freq * GT_FREQUENCY_MULTIPLIER);
+ intel_gpu_freq(dev_priv, max_freq));
seq_printf(m, "Max overclocked frequency: %dMHz\n",
- dev_priv->rps.max_freq * GT_FREQUENCY_MULTIPLIER);
+ intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
} else if (IS_VALLEYVIEW(dev)) {
u32 freq_sts;
@@ -1145,16 +1199,17 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);
seq_printf(m, "max GPU freq: %d MHz\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq));
+ intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
seq_printf(m, "min GPU freq: %d MHz\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq));
+ intel_gpu_freq(dev_priv, dev_priv->rps.min_freq));
- seq_printf(m, "efficient (RPe) frequency: %d MHz\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
+ seq_printf(m,
+ "efficient (RPe) frequency: %d MHz\n",
+ intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
seq_printf(m, "current GPU freq: %d MHz\n",
- vlv_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
+ intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
mutex_unlock(&dev_priv->rps.hw_lock);
} else {
seq_puts(m, "no P-state info available\n");
@@ -1165,6 +1220,53 @@ out:
return ret;
}
+static int i915_hangcheck_info(struct seq_file *m, void *unused)
+{
+ struct drm_info_node *node = m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine_cs *ring;
+ u64 acthd[I915_NUM_RINGS];
+ u32 seqno[I915_NUM_RINGS];
+ int i;
+
+ if (!i915.enable_hangcheck) {
+ seq_printf(m, "Hangcheck disabled\n");
+ return 0;
+ }
+
+ intel_runtime_pm_get(dev_priv);
+
+ for_each_ring(ring, dev_priv, i) {
+ seqno[i] = ring->get_seqno(ring, false);
+ acthd[i] = intel_ring_get_active_head(ring);
+ }
+
+ intel_runtime_pm_put(dev_priv);
+
+ if (delayed_work_pending(&dev_priv->gpu_error.hangcheck_work)) {
+ seq_printf(m, "Hangcheck active, fires in %dms\n",
+ jiffies_to_msecs(dev_priv->gpu_error.hangcheck_work.timer.expires -
+ jiffies));
+ } else
+ seq_printf(m, "Hangcheck inactive\n");
+
+ for_each_ring(ring, dev_priv, i) {
+ seq_printf(m, "%s:\n", ring->name);
+ seq_printf(m, "\tseqno = %x [current %x]\n",
+ ring->hangcheck.seqno, seqno[i]);
+ seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n",
+ (long long)ring->hangcheck.acthd,
+ (long long)acthd[i]);
+ seq_printf(m, "\tmax ACTHD = 0x%08llx\n",
+ (long long)ring->hangcheck.max_acthd);
+ seq_printf(m, "\tscore = %d\n", ring->hangcheck.score);
+ seq_printf(m, "\taction = %d\n", ring->hangcheck.action);
+ }
+
+ return 0;
+}
+
static int ironlake_drpc_info(struct seq_file *m)
{
struct drm_info_node *node = m->private;
@@ -1234,14 +1336,31 @@ static int ironlake_drpc_info(struct seq_file *m)
return 0;
}
-static int vlv_drpc_info(struct seq_file *m)
+static int i915_forcewake_domains(struct seq_file *m, void *data)
{
+ struct drm_info_node *node = m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_uncore_forcewake_domain *fw_domain;
+ int i;
+ spin_lock_irq(&dev_priv->uncore.lock);
+ for_each_fw_domain(fw_domain, dev_priv, i) {
+ seq_printf(m, "%s.wake_count = %u\n",
+ intel_uncore_forcewake_domain_to_str(i),
+ fw_domain->wake_count);
+ }
+ spin_unlock_irq(&dev_priv->uncore.lock);
+
+ return 0;
+}
+
+static int vlv_drpc_info(struct seq_file *m)
+{
struct drm_info_node *node = m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 rpmodectl1, rcctl1, pw_status;
- unsigned fw_rendercount = 0, fw_mediacount = 0;
intel_runtime_pm_get(dev_priv);
@@ -1273,22 +1392,11 @@ static int vlv_drpc_info(struct seq_file *m)
seq_printf(m, "Media RC6 residency since boot: %u\n",
I915_READ(VLV_GT_MEDIA_RC6));
- spin_lock_irq(&dev_priv->uncore.lock);
- fw_rendercount = dev_priv->uncore.fw_rendercount;
- fw_mediacount = dev_priv->uncore.fw_mediacount;
- spin_unlock_irq(&dev_priv->uncore.lock);
-
- seq_printf(m, "Forcewake Render Count = %u\n", fw_rendercount);
- seq_printf(m, "Forcewake Media Count = %u\n", fw_mediacount);
-
-
- return 0;
+ return i915_forcewake_domains(m, NULL);
}
-
static int gen6_drpc_info(struct seq_file *m)
{
-
struct drm_info_node *node = m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1302,7 +1410,7 @@ static int gen6_drpc_info(struct seq_file *m)
intel_runtime_pm_get(dev_priv);
spin_lock_irq(&dev_priv->uncore.lock);
- forcewake_count = dev_priv->uncore.forcewake_count;
+ forcewake_count = dev_priv->uncore.fw_domain[FW_DOMAIN_ID_RENDER].wake_count;
spin_unlock_irq(&dev_priv->uncore.lock);
if (forcewake_count) {
@@ -1617,7 +1725,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
GEN6_PCODE_READ_MIN_FREQ_TABLE,
&ia_freq);
seq_printf(m, "%d\t\t%d\t\t\t\t%d\n",
- gpu_freq * GT_FREQUENCY_MULTIPLIER,
+ intel_gpu_freq(dev_priv, gpu_freq),
((ia_freq >> 0) & 0xff) * 100,
((ia_freq >> 8) & 0xff) * 100);
}
@@ -1874,7 +1982,7 @@ static int i915_execlists(struct seq_file *m, void *data)
intel_runtime_pm_get(dev_priv);
for_each_ring(ring, dev_priv, ring_id) {
- struct intel_ctx_submit_request *head_req = NULL;
+ struct drm_i915_gem_request *head_req = NULL;
int count = 0;
unsigned long flags;
@@ -1907,7 +2015,7 @@ static int i915_execlists(struct seq_file *m, void *data)
list_for_each(cursor, &ring->execlist_queue)
count++;
head_req = list_first_entry_or_null(&ring->execlist_queue,
- struct intel_ctx_submit_request, execlist_link);
+ struct drm_i915_gem_request, execlist_link);
spin_unlock_irqrestore(&ring->execlist_lock, flags);
seq_printf(m, "\t%d requests in queue\n", count);
@@ -1930,30 +2038,6 @@ static int i915_execlists(struct seq_file *m, void *data)
return 0;
}
-static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned forcewake_count = 0, fw_rendercount = 0, fw_mediacount = 0;
-
- spin_lock_irq(&dev_priv->uncore.lock);
- if (IS_VALLEYVIEW(dev)) {
- fw_rendercount = dev_priv->uncore.fw_rendercount;
- fw_mediacount = dev_priv->uncore.fw_mediacount;
- } else
- forcewake_count = dev_priv->uncore.forcewake_count;
- spin_unlock_irq(&dev_priv->uncore.lock);
-
- if (IS_VALLEYVIEW(dev)) {
- seq_printf(m, "fw_rendercount = %u\n", fw_rendercount);
- seq_printf(m, "fw_mediacount = %u\n", fw_mediacount);
- } else
- seq_printf(m, "forcewake count = %u\n", forcewake_count);
-
- return 0;
-}
-
static const char *swizzle_string(unsigned swizzle)
{
switch (swizzle) {
@@ -2155,6 +2239,8 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 psrperf = 0;
+ u32 stat[3];
+ enum pipe pipe;
bool enabled = false;
intel_runtime_pm_get(dev_priv);
@@ -2169,14 +2255,39 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
seq_printf(m, "Re-enable work scheduled: %s\n",
yesno(work_busy(&dev_priv->psr.work.work)));
- enabled = HAS_PSR(dev) &&
- I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE;
- seq_printf(m, "HW Enabled & Active bit: %s\n", yesno(enabled));
+ if (HAS_PSR(dev)) {
+ if (HAS_DDI(dev))
+ enabled = I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE;
+ else {
+ for_each_pipe(dev_priv, pipe) {
+ stat[pipe] = I915_READ(VLV_PSRSTAT(pipe)) &
+ VLV_EDP_PSR_CURR_STATE_MASK;
+ if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
+ (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE))
+ enabled = true;
+ }
+ }
+ }
+ seq_printf(m, "HW Enabled & Active bit: %s", yesno(enabled));
+
+ if (!HAS_DDI(dev))
+ for_each_pipe(dev_priv, pipe) {
+ if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
+ (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE))
+ seq_printf(m, " pipe %c", pipe_name(pipe));
+ }
+ seq_puts(m, "\n");
+
+ seq_printf(m, "Link standby: %s\n",
+ yesno((bool)dev_priv->psr.link_standby));
- if (HAS_PSR(dev))
+ /* CHV PSR has no kind of performance counter */
+ if (HAS_PSR(dev) && HAS_DDI(dev)) {
psrperf = I915_READ(EDP_PSR_PERF_CNT(dev)) &
EDP_PSR_PERF_CNT_MASK;
- seq_printf(m, "Performance_Counter: %u\n", psrperf);
+
+ seq_printf(m, "Performance_Counter: %u\n", psrperf);
+ }
mutex_unlock(&dev_priv->psr.lock);
intel_runtime_pm_put(dev_priv);
@@ -2319,10 +2430,18 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
return "AUDIO";
case POWER_DOMAIN_PLLS:
return "PLLS";
+ case POWER_DOMAIN_AUX_A:
+ return "AUX_A";
+ case POWER_DOMAIN_AUX_B:
+ return "AUX_B";
+ case POWER_DOMAIN_AUX_C:
+ return "AUX_C";
+ case POWER_DOMAIN_AUX_D:
+ return "AUX_D";
case POWER_DOMAIN_INIT:
return "INIT";
default:
- WARN_ON(1);
+ MISSING_CASE(domain);
return "?";
}
}
@@ -2547,7 +2666,8 @@ static int i915_display_info(struct seq_file *m, void *unused)
seq_printf(m, "CRTC %d: pipe: %c, active=%s (size=%dx%d)\n",
crtc->base.base.id, pipe_name(crtc->pipe),
- yesno(crtc->active), crtc->config.pipe_src_w, crtc->config.pipe_src_h);
+ yesno(crtc->active), crtc->config->pipe_src_w,
+ crtc->config->pipe_src_h);
if (crtc->active) {
intel_crtc_info(m, crtc);
@@ -2718,6 +2838,9 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
enum pipe pipe;
int plane;
+ if (INTEL_INFO(dev)->gen < 9)
+ return 0;
+
drm_modeset_lock_all(dev);
ddb = &dev_priv->wm.skl_hw.ddb;
@@ -2830,7 +2953,7 @@ i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
char buf[PIPE_CRC_BUFFER_LEN];
- int head, tail, n_entries, n;
+ int n_entries;
ssize_t bytes_read;
/*
@@ -2862,36 +2985,39 @@ i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,
}
/* We now have one or more entries to read */
- head = pipe_crc->head;
- tail = pipe_crc->tail;
- n_entries = min((size_t)CIRC_CNT(head, tail, INTEL_PIPE_CRC_ENTRIES_NR),
- count / PIPE_CRC_LINE_LEN);
- spin_unlock_irq(&pipe_crc->lock);
+ n_entries = count / PIPE_CRC_LINE_LEN;
bytes_read = 0;
- n = 0;
- do {
- struct intel_pipe_crc_entry *entry = &pipe_crc->entries[tail];
+ while (n_entries > 0) {
+ struct intel_pipe_crc_entry *entry =
+ &pipe_crc->entries[pipe_crc->tail];
int ret;
+ if (CIRC_CNT(pipe_crc->head, pipe_crc->tail,
+ INTEL_PIPE_CRC_ENTRIES_NR) < 1)
+ break;
+
+ BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR);
+ pipe_crc->tail = (pipe_crc->tail + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
+
bytes_read += snprintf(buf, PIPE_CRC_BUFFER_LEN,
"%8u %8x %8x %8x %8x %8x\n",
entry->frame, entry->crc[0],
entry->crc[1], entry->crc[2],
entry->crc[3], entry->crc[4]);
- ret = copy_to_user(user_buf + n * PIPE_CRC_LINE_LEN,
- buf, PIPE_CRC_LINE_LEN);
+ spin_unlock_irq(&pipe_crc->lock);
+
+ ret = copy_to_user(user_buf, buf, PIPE_CRC_LINE_LEN);
if (ret == PIPE_CRC_LINE_LEN)
return -EFAULT;
- BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR);
- tail = (tail + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
- n++;
- } while (--n_entries);
+ user_buf += PIPE_CRC_LINE_LEN;
+ n_entries--;
+
+ spin_lock_irq(&pipe_crc->lock);
+ }
- spin_lock_irq(&pipe_crc->lock);
- pipe_crc->tail = tail;
spin_unlock_irq(&pipe_crc->lock);
return bytes_read;
@@ -3072,6 +3198,12 @@ static int vlv_pipe_crc_ctl_reg(struct drm_device *dev,
*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV;
need_stable_symbols = true;
break;
+ case INTEL_PIPE_CRC_SOURCE_DP_D:
+ if (!IS_CHERRYVIEW(dev))
+ return -EINVAL;
+ *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_VLV;
+ need_stable_symbols = true;
+ break;
case INTEL_PIPE_CRC_SOURCE_NONE:
*val = 0;
break;
@@ -3092,11 +3224,19 @@ static int vlv_pipe_crc_ctl_reg(struct drm_device *dev,
uint32_t tmp = I915_READ(PORT_DFT2_G4X);
tmp |= DC_BALANCE_RESET_VLV;
- if (pipe == PIPE_A)
+ switch (pipe) {
+ case PIPE_A:
tmp |= PIPE_A_SCRAMBLE_RESET;
- else
+ break;
+ case PIPE_B:
tmp |= PIPE_B_SCRAMBLE_RESET;
-
+ break;
+ case PIPE_C:
+ tmp |= PIPE_C_SCRAMBLE_RESET;
+ break;
+ default:
+ return -EINVAL;
+ }
I915_WRITE(PORT_DFT2_G4X, tmp);
}
@@ -3185,10 +3325,19 @@ static void vlv_undo_pipe_scramble_reset(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t tmp = I915_READ(PORT_DFT2_G4X);
- if (pipe == PIPE_A)
+ switch (pipe) {
+ case PIPE_A:
tmp &= ~PIPE_A_SCRAMBLE_RESET;
- else
+ break;
+ case PIPE_B:
tmp &= ~PIPE_B_SCRAMBLE_RESET;
+ break;
+ case PIPE_C:
+ tmp &= ~PIPE_C_SCRAMBLE_RESET;
+ break;
+ default:
+ return;
+ }
if (!(tmp & PIPE_SCRAMBLE_RESET_MASK))
tmp &= ~DC_BALANCE_RESET_VLV;
I915_WRITE(PORT_DFT2_G4X, tmp);
@@ -3252,9 +3401,9 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
* relevant on hsw with pipe A when using the always-on power well
* routing.
*/
- if (crtc->config.cpu_transcoder == TRANSCODER_EDP &&
- !crtc->config.pch_pfit.enabled) {
- crtc->config.pch_pfit.force_thru = true;
+ if (crtc->config->cpu_transcoder == TRANSCODER_EDP &&
+ !crtc->config->pch_pfit.enabled) {
+ crtc->config->pch_pfit.force_thru = true;
intel_display_power_get(dev_priv,
POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
@@ -3278,8 +3427,8 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
* relevant on hsw with pipe A when using the always-on power well
* routing.
*/
- if (crtc->config.pch_pfit.force_thru) {
- crtc->config.pch_pfit.force_thru = false;
+ if (crtc->config->pch_pfit.force_thru) {
+ crtc->config->pch_pfit.force_thru = false;
dev_priv->display.crtc_disable(&crtc->base);
dev_priv->display.crtc_enable(&crtc->base);
@@ -3359,13 +3508,15 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
/* none -> real source transition */
if (source) {
+ struct intel_pipe_crc_entry *entries;
+
DRM_DEBUG_DRIVER("collecting CRCs for pipe %c, %s\n",
pipe_name(pipe), pipe_crc_source_name(source));
- pipe_crc->entries = kzalloc(sizeof(*pipe_crc->entries) *
- INTEL_PIPE_CRC_ENTRIES_NR,
- GFP_KERNEL);
- if (!pipe_crc->entries)
+ entries = kcalloc(INTEL_PIPE_CRC_ENTRIES_NR,
+ sizeof(pipe_crc->entries[0]),
+ GFP_KERNEL);
+ if (!entries)
return -ENOMEM;
/*
@@ -3377,6 +3528,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
hsw_disable_ips(crtc);
spin_lock_irq(&pipe_crc->lock);
+ kfree(pipe_crc->entries);
+ pipe_crc->entries = entries;
pipe_crc->head = 0;
pipe_crc->tail = 0;
spin_unlock_irq(&pipe_crc->lock);
@@ -3404,6 +3557,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
spin_lock_irq(&pipe_crc->lock);
entries = pipe_crc->entries;
pipe_crc->entries = NULL;
+ pipe_crc->head = 0;
+ pipe_crc->tail = 0;
spin_unlock_irq(&pipe_crc->lock);
kfree(entries);
@@ -3826,6 +3981,17 @@ i915_wedged_set(void *data, u64 val)
struct drm_device *dev = data;
struct drm_i915_private *dev_priv = dev->dev_private;
+ /*
+ * There is no safeguard against this debugfs entry colliding
+ * with the hangcheck calling same i915_handle_error() in
+ * parallel, causing an explosion. For now we assume that the
+ * test harness is responsible enough not to inject gpu hangs
+ * while it is writing to 'i915_wedged'
+ */
+
+ if (i915_reset_in_progress(&dev_priv->gpu_error))
+ return -EAGAIN;
+
intel_runtime_pm_get(dev_priv);
i915_handle_error(dev, val,
@@ -4012,10 +4178,7 @@ i915_max_freq_get(void *data, u64 *val)
if (ret)
return ret;
- if (IS_VALLEYVIEW(dev))
- *val = vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
- else
- *val = dev_priv->rps.max_freq_softlimit * GT_FREQUENCY_MULTIPLIER;
+ *val = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
mutex_unlock(&dev_priv->rps.hw_lock);
return 0;
@@ -4044,12 +4207,12 @@ i915_max_freq_set(void *data, u64 val)
* Turbo will still be enabled, but won't go above the set value.
*/
if (IS_VALLEYVIEW(dev)) {
- val = vlv_freq_opcode(dev_priv, val);
+ val = intel_freq_opcode(dev_priv, val);
hw_max = dev_priv->rps.max_freq;
hw_min = dev_priv->rps.min_freq;
} else {
- do_div(val, GT_FREQUENCY_MULTIPLIER);
+ val = intel_freq_opcode(dev_priv, val);
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
hw_max = dev_priv->rps.max_freq;
@@ -4093,10 +4256,7 @@ i915_min_freq_get(void *data, u64 *val)
if (ret)
return ret;
- if (IS_VALLEYVIEW(dev))
- *val = vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
- else
- *val = dev_priv->rps.min_freq_softlimit * GT_FREQUENCY_MULTIPLIER;
+ *val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
mutex_unlock(&dev_priv->rps.hw_lock);
return 0;
@@ -4125,12 +4285,12 @@ i915_min_freq_set(void *data, u64 val)
* Turbo will still be enabled, but won't go below the set value.
*/
if (IS_VALLEYVIEW(dev)) {
- val = vlv_freq_opcode(dev_priv, val);
+ val = intel_freq_opcode(dev_priv, val);
hw_max = dev_priv->rps.max_freq;
hw_min = dev_priv->rps.min_freq;
} else {
- do_div(val, GT_FREQUENCY_MULTIPLIER);
+ val = intel_freq_opcode(dev_priv, val);
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
hw_max = dev_priv->rps.max_freq;
@@ -4222,7 +4382,8 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
if (INTEL_INFO(dev)->gen < 6)
return 0;
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_runtime_pm_get(dev_priv);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
return 0;
}
@@ -4235,7 +4396,8 @@ static int i915_forcewake_release(struct inode *inode, struct file *file)
if (INTEL_INFO(dev)->gen < 6)
return 0;
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+ intel_runtime_pm_put(dev_priv);
return 0;
}
@@ -4296,7 +4458,9 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS},
{"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS},
{"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS},
+ {"i915_gem_batch_pool", i915_gem_batch_pool_info, 0},
{"i915_frequency_info", i915_frequency_info, 0},
+ {"i915_hangcheck_info", i915_hangcheck_info, 0},
{"i915_drpc_info", i915_drpc_info, 0},
{"i915_emon_status", i915_emon_status, 0},
{"i915_ring_freq_table", i915_ring_freq_table, 0},
@@ -4308,7 +4472,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_context_status", i915_context_status, 0},
{"i915_dump_lrc", i915_dump_lrc, 0},
{"i915_execlists", i915_execlists, 0},
- {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
+ {"i915_forcewake_domains", i915_forcewake_domains, 0},
{"i915_swizzle_info", i915_swizzle_info, 0},
{"i915_ppgtt_info", i915_ppgtt_info, 0},
{"i915_llc", i915_llc, 0},
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 26b3199e0af2..1a46787129e7 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -92,6 +92,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_VEBOX:
value = intel_ring_initialized(&dev_priv->ring[VECS]);
break;
+ case I915_PARAM_HAS_BSD2:
+ value = intel_ring_initialized(&dev_priv->ring[VCS2]);
+ break;
case I915_PARAM_HAS_RELAXED_FENCING:
value = 1;
break;
@@ -143,6 +146,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_COHERENT_PHYS_GTT:
value = 1;
break;
+ case I915_PARAM_MMAP_VERSION:
+ value = 1;
+ break;
default:
DRM_DEBUG("Unknown parameter %d\n", param->param);
return -EINVAL;
@@ -598,6 +604,17 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
info->num_pipes = 0;
}
}
+
+ if (IS_CHERRYVIEW(dev)) {
+ u32 fuse, mask_eu;
+
+ fuse = I915_READ(CHV_FUSE_GT);
+ mask_eu = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK |
+ CHV_FGT_EU_DIS_SS0_R1_MASK |
+ CHV_FGT_EU_DIS_SS1_R0_MASK |
+ CHV_FGT_EU_DIS_SS1_R1_MASK);
+ info->eu_total = 16 - hweight32(mask_eu);
+ }
}
/**
@@ -773,6 +790,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_freewq;
}
+ dev_priv->gpu_error.hangcheck_wq =
+ alloc_ordered_workqueue("i915-hangcheck", 0);
+ if (dev_priv->gpu_error.hangcheck_wq == NULL) {
+ DRM_ERROR("Failed to create our hangcheck workqueue.\n");
+ ret = -ENOMEM;
+ goto out_freedpwq;
+ }
+
intel_irq_init(dev_priv);
intel_uncore_sanitize(dev);
@@ -847,6 +872,8 @@ out_gem_unload:
intel_teardown_gmbus(dev);
intel_teardown_mchbar(dev);
pm_qos_remove_request(&dev_priv->pm_qos);
+ destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
+out_freedpwq:
destroy_workqueue(dev_priv->dp_wq);
out_freewq:
destroy_workqueue(dev_priv->wq);
@@ -917,8 +944,7 @@ int i915_driver_unload(struct drm_device *dev)
}
/* Free error state after interrupts are fully disabled. */
- del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
- cancel_work_sync(&dev_priv->gpu_error.work);
+ cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
i915_destroy_error_state(dev);
if (dev->pdev->msi_enabled)
@@ -932,6 +958,7 @@ int i915_driver_unload(struct drm_device *dev)
mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev);
+ i915_gem_batch_pool_fini(&dev_priv->mm.batch_pool);
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);
i915_gem_cleanup_stolen(dev);
@@ -942,6 +969,7 @@ int i915_driver_unload(struct drm_device *dev)
destroy_workqueue(dev_priv->dp_wq);
destroy_workqueue(dev_priv->wq);
+ destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
pm_qos_remove_request(&dev_priv->pm_qos);
i915_global_gtt_cleanup(dev);
@@ -1008,6 +1036,13 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
kfree(file_priv);
}
+static int
+i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ return -ENODEV;
+}
+
const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH),
@@ -1029,8 +1064,8 @@ const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
- DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
@@ -1059,6 +1094,8 @@ const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_get_reset_stats_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
};
int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 489b220af02b..8039cec71fc2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -835,6 +835,8 @@ int i915_reset(struct drm_device *dev)
return ret;
}
+ intel_overlay_reset(dev_priv);
+
/* Ok, now get things going again... */
/*
@@ -1290,7 +1292,9 @@ static int vlv_suspend_complete(struct drm_i915_private *dev_priv)
err = vlv_allow_gt_wake(dev_priv, false);
if (err)
goto err2;
- vlv_save_gunit_s0ix_state(dev_priv);
+
+ if (!IS_CHERRYVIEW(dev_priv->dev))
+ vlv_save_gunit_s0ix_state(dev_priv);
err = vlv_force_gfx_clock(dev_priv, false);
if (err)
@@ -1321,7 +1325,8 @@ static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
*/
ret = vlv_force_gfx_clock(dev_priv, true);
- vlv_restore_gunit_s0ix_state(dev_priv);
+ if (!IS_CHERRYVIEW(dev_priv->dev))
+ vlv_restore_gunit_s0ix_state(dev_priv);
err = vlv_allow_gt_wake(dev_priv, true);
if (!ret)
@@ -1354,8 +1359,6 @@ static int intel_runtime_suspend(struct device *device)
if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev)))
return -ENODEV;
- assert_force_wake_inactive(dev_priv);
-
DRM_DEBUG_KMS("Suspending device\n");
/*
@@ -1393,7 +1396,8 @@ static int intel_runtime_suspend(struct device *device)
return ret;
}
- del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
+ cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
+ intel_uncore_forcewake_reset(dev, false);
dev_priv->pm.suspended = true;
/*
@@ -1421,6 +1425,8 @@ static int intel_runtime_suspend(struct device *device)
intel_opregion_notify_adapter(dev, PCI_D3hot);
}
+ assert_forcewakes_inactive(dev_priv);
+
DRM_DEBUG_KMS("Device suspended\n");
return 0;
}
@@ -1631,6 +1637,14 @@ static int __init i915_init(void)
#endif
}
+ /*
+ * FIXME: Note that we're lying to the DRM core here so that we can get access
+ * to the atomic ioctl and the atomic properties. Only plane operations on
+ * a single CRTC will actually work.
+ */
+ if (i915.nuclear_pageflip)
+ driver.driver_features |= DRIVER_ATOMIC;
+
return drm_pci_init(&driver, &i915_pci_driver);
}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 24cc36a9f3ff..f2a825e39646 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -55,10 +55,51 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20141121"
+#define DRIVER_DATE "20150130"
#undef WARN_ON
-#define WARN_ON(x) WARN(x, "WARN_ON(" #x ")")
+/* Many gcc seem to no see through this and fall over :( */
+#if 0
+#define WARN_ON(x) ({ \
+ bool __i915_warn_cond = (x); \
+ if (__builtin_constant_p(__i915_warn_cond)) \
+ BUILD_BUG_ON(__i915_warn_cond); \
+ WARN(__i915_warn_cond, "WARN_ON(" #x ")"); })
+#else
+#define WARN_ON(x) WARN((x), "WARN_ON(" #x ")")
+#endif
+
+#define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \
+ (long) (x), __func__);
+
+/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
+ * WARN_ON()) for hw state sanity checks to check for unexpected conditions
+ * which may not necessarily be a user visible problem. This will either
+ * WARN() or DRM_ERROR() depending on the verbose_checks moduleparam, to
+ * enable distros and users to tailor their preferred amount of i915 abrt
+ * spam.
+ */
+#define I915_STATE_WARN(condition, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ if (unlikely(__ret_warn_on)) { \
+ if (i915.verbose_state_checks) \
+ WARN(1, format); \
+ else \
+ DRM_ERROR(format); \
+ } \
+ unlikely(__ret_warn_on); \
+})
+
+#define I915_STATE_WARN_ON(condition) ({ \
+ int __ret_warn_on = !!(condition); \
+ if (unlikely(__ret_warn_on)) { \
+ if (i915.verbose_state_checks) \
+ WARN(1, "WARN_ON(" #condition ")\n"); \
+ else \
+ DRM_ERROR("WARN_ON(" #condition ")\n"); \
+ } \
+ unlikely(__ret_warn_on); \
+})
enum pipe {
INVALID_PIPE = -1,
@@ -143,6 +184,10 @@ enum intel_display_power_domain {
POWER_DOMAIN_VGA,
POWER_DOMAIN_AUDIO,
POWER_DOMAIN_PLLS,
+ POWER_DOMAIN_AUX_A,
+ POWER_DOMAIN_AUX_B,
+ POWER_DOMAIN_AUX_C,
+ POWER_DOMAIN_AUX_D,
POWER_DOMAIN_INIT,
POWER_DOMAIN_NUM,
@@ -458,8 +503,8 @@ struct drm_i915_error_state {
struct intel_connector;
struct intel_encoder;
-struct intel_crtc_config;
-struct intel_plane_config;
+struct intel_crtc_state;
+struct intel_initial_plane_config;
struct intel_crtc;
struct intel_limit;
struct dpll;
@@ -497,10 +542,11 @@ struct drm_i915_display_funcs {
/* Returns the active state of the crtc, and if the crtc is active,
* fills out the pipe-config with the hw state. */
bool (*get_pipe_config)(struct intel_crtc *,
- struct intel_crtc_config *);
- void (*get_plane_config)(struct intel_crtc *,
- struct intel_plane_config *);
- int (*crtc_compute_clock)(struct intel_crtc *crtc);
+ struct intel_crtc_state *);
+ void (*get_initial_plane_config)(struct intel_crtc *,
+ struct intel_initial_plane_config *);
+ int (*crtc_compute_clock)(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state);
void (*crtc_enable)(struct drm_crtc *crtc);
void (*crtc_disable)(struct drm_crtc *crtc);
void (*off)(struct drm_crtc *crtc);
@@ -533,11 +579,28 @@ struct drm_i915_display_funcs {
void (*enable_backlight)(struct intel_connector *connector);
};
+enum forcewake_domain_id {
+ FW_DOMAIN_ID_RENDER = 0,
+ FW_DOMAIN_ID_BLITTER,
+ FW_DOMAIN_ID_MEDIA,
+
+ FW_DOMAIN_ID_COUNT
+};
+
+enum forcewake_domains {
+ FORCEWAKE_RENDER = (1 << FW_DOMAIN_ID_RENDER),
+ FORCEWAKE_BLITTER = (1 << FW_DOMAIN_ID_BLITTER),
+ FORCEWAKE_MEDIA = (1 << FW_DOMAIN_ID_MEDIA),
+ FORCEWAKE_ALL = (FORCEWAKE_RENDER |
+ FORCEWAKE_BLITTER |
+ FORCEWAKE_MEDIA)
+};
+
struct intel_uncore_funcs {
void (*force_wake_get)(struct drm_i915_private *dev_priv,
- int fw_engine);
+ enum forcewake_domains domains);
void (*force_wake_put)(struct drm_i915_private *dev_priv,
- int fw_engine);
+ enum forcewake_domains domains);
uint8_t (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
@@ -560,14 +623,31 @@ struct intel_uncore {
struct intel_uncore_funcs funcs;
unsigned fifo_count;
- unsigned forcewake_count;
-
- unsigned fw_rendercount;
- unsigned fw_mediacount;
- unsigned fw_blittercount;
-
- struct timer_list force_wake_timer;
-};
+ enum forcewake_domains fw_domains;
+
+ struct intel_uncore_forcewake_domain {
+ struct drm_i915_private *i915;
+ enum forcewake_domain_id id;
+ unsigned wake_count;
+ struct timer_list timer;
+ u32 reg_set;
+ u32 val_set;
+ u32 val_clear;
+ u32 reg_ack;
+ u32 reg_post;
+ u32 val_reset;
+ } fw_domain[FW_DOMAIN_ID_COUNT];
+};
+
+/* Iterate over initialised fw domains */
+#define for_each_fw_domain_mask(domain__, mask__, dev_priv__, i__) \
+ for ((i__) = 0, (domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
+ (i__) < FW_DOMAIN_ID_COUNT; \
+ (i__)++, (domain__) = &(dev_priv__)->uncore.fw_domain[i__]) \
+ if (((mask__) & (dev_priv__)->uncore.fw_domains) & (1 << (i__)))
+
+#define for_each_fw_domain(domain__, dev_priv__, i__) \
+ for_each_fw_domain_mask(domain__, FORCEWAKE_ALL, dev_priv__, i__)
#define DEV_INFO_FOR_EACH_FLAG(func, sep) \
func(is_mobile) sep \
@@ -612,6 +692,7 @@ struct intel_device_info {
int trans_offsets[I915_MAX_TRANSCODERS];
int palette_offsets[I915_MAX_PIPES];
int cursor_offsets[I915_MAX_PIPES];
+ unsigned int eu_total;
};
#undef DEFINE_FLAG
@@ -637,6 +718,11 @@ struct i915_ctx_hang_stats {
/* Time when this context was last blamed for a GPU reset */
unsigned long guilty_ts;
+ /* If the contexts causes a second GPU hang within this time,
+ * it is permanently banned from submitting any more work.
+ */
+ unsigned long ban_period_seconds;
+
/* This context is banned to submit more work */
bool banned;
};
@@ -679,7 +765,7 @@ struct intel_context {
struct {
struct drm_i915_gem_object *state;
struct intel_ringbuffer *ringbuf;
- int unpin_count;
+ int pin_count;
} engine[I915_NUM_RINGS];
struct list_head link;
@@ -730,11 +816,33 @@ struct i915_fbc {
} no_fbc_reason;
};
-struct i915_drrs {
- struct intel_connector *connector;
+/**
+ * HIGH_RR is the highest eDP panel refresh rate read from EDID
+ * LOW_RR is the lowest eDP panel refresh rate found from EDID
+ * parsing for same resolution.
+ */
+enum drrs_refresh_rate_type {
+ DRRS_HIGH_RR,
+ DRRS_LOW_RR,
+ DRRS_MAX_RR, /* RR count */
+};
+
+enum drrs_support_type {
+ DRRS_NOT_SUPPORTED = 0,
+ STATIC_DRRS_SUPPORT = 1,
+ SEAMLESS_DRRS_SUPPORT = 2
};
struct intel_dp;
+struct i915_drrs {
+ struct mutex mutex;
+ struct delayed_work work;
+ struct intel_dp *dp;
+ unsigned busy_frontbuffer_bits;
+ enum drrs_refresh_rate_type refresh_rate_type;
+ enum drrs_support_type type;
+};
+
struct i915_psr {
struct mutex lock;
bool sink_support;
@@ -743,6 +851,7 @@ struct i915_psr {
bool active;
struct delayed_work work;
unsigned busy_frontbuffer_bits;
+ bool link_standby;
};
enum intel_pch {
@@ -1130,6 +1239,11 @@ struct intel_l3_parity {
int which_slice;
};
+struct i915_gem_batch_pool {
+ struct drm_device *dev;
+ struct list_head cache_list;
+};
+
struct i915_gem_mm {
/** Memory allocator for GTT stolen memory */
struct drm_mm stolen;
@@ -1143,6 +1257,13 @@ struct i915_gem_mm {
*/
struct list_head unbound_list;
+ /*
+ * A pool of objects to use as shadow copies of client batch buffers
+ * when the command parser is enabled. Prevents the client from
+ * modifying the batch contents after software parsing.
+ */
+ struct i915_gem_batch_pool batch_pool;
+
/** Usable portion of the GTT for GEM */
unsigned long stolen_base; /* limited to low memory (32-bit) */
@@ -1224,14 +1345,13 @@ struct i915_gpu_error {
/* Hang gpu twice in this window and your context gets banned */
#define DRM_I915_CTX_BAN_PERIOD DIV_ROUND_UP(8*DRM_I915_HANGCHECK_PERIOD, 1000)
- struct timer_list hangcheck_timer;
+ struct workqueue_struct *hangcheck_wq;
+ struct delayed_work hangcheck_work;
/* For reset and error_state handling. */
spinlock_t lock;
/* Protected by the above dev->gpu_error.lock. */
struct drm_i915_error_state *first_error;
- struct work_struct work;
-
unsigned long missed_irq_rings;
@@ -1301,10 +1421,11 @@ struct ddi_vbt_port_info {
uint8_t supports_dp:1;
};
-enum drrs_support_type {
- DRRS_NOT_SUPPORTED = 0,
- STATIC_DRRS_SUPPORT = 1,
- SEAMLESS_DRRS_SUPPORT = 2
+enum psr_lines_to_wait {
+ PSR_0_LINES_TO_WAIT = 0,
+ PSR_1_LINE_TO_WAIT,
+ PSR_4_LINES_TO_WAIT,
+ PSR_8_LINES_TO_WAIT
};
struct intel_vbt_data {
@@ -1336,6 +1457,15 @@ struct intel_vbt_data {
struct edp_power_seq edp_pps;
struct {
+ bool full_link;
+ bool require_aux_wakeup;
+ int idle_frames;
+ enum psr_lines_to_wait lines_to_wait;
+ int tp1_wakeup_time;
+ int tp2_tp3_wakeup_time;
+ } psr;
+
+ struct {
u16 pwm_freq_hz;
bool present;
bool active_low_pwm;
@@ -1773,6 +1903,8 @@ struct drm_i915_private {
void (*stop_ring)(struct intel_engine_cs *ring);
} gt;
+ uint32_t request_uniq;
+
/*
* NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
* will be rejected. Instead look for a better place.
@@ -1861,6 +1993,8 @@ struct drm_i915_gem_object {
/** Used in execbuf to temporarily hold a ref */
struct list_head obj_exec_link;
+ struct list_head batch_pool_list;
+
/**
* This is set if the object is on the active lists (has pending
* rendering and so a non-zero seqno), and is not set if it i s on
@@ -1920,6 +2054,7 @@ struct drm_i915_gem_object {
*/
unsigned long gt_ro:1;
unsigned int cache_level:3;
+ unsigned int cache_dirty:1;
unsigned int has_dma_mapping:1;
@@ -1932,13 +2067,11 @@ struct drm_i915_gem_object {
void *dma_buf_vmapping;
int vmapping_count;
- struct intel_engine_cs *ring;
-
/** Breadcrumb of last rendering to the buffer. */
- uint32_t last_read_seqno;
- uint32_t last_write_seqno;
+ struct drm_i915_gem_request *last_read_req;
+ struct drm_i915_gem_request *last_write_req;
/** Breadcrumb of last fenced GPU access to the buffer. */
- uint32_t last_fenced_seqno;
+ struct drm_i915_gem_request *last_fenced_req;
/** Current tiling stride for the object, if it's tiled. */
uint32_t stride;
@@ -1949,10 +2082,6 @@ struct drm_i915_gem_object {
/** Record of address bit 17 of each page at last unbind. */
unsigned long *bit_17;
- /** User space pin count and filp owning the pin */
- unsigned long user_pin_count;
- struct drm_file *pin_filp;
-
union {
/** for phy allocated objects */
struct drm_dma_handle *phys_handle;
@@ -1981,11 +2110,14 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
* The request queue allows us to note sequence numbers that have been emitted
* and may be associated with active buffers to be retired.
*
- * By keeping this list, we can avoid having to do questionable
- * sequence-number comparisons on buffer last_rendering_seqnos, and associate
- * an emission time with seqnos for tracking how far ahead of the GPU we are.
+ * By keeping this list, we can avoid having to do questionable sequence
+ * number comparisons on buffer last_read|write_seqno. It also allows an
+ * emission time to be associated with the request for tracking how far ahead
+ * of the GPU the submission is.
*/
struct drm_i915_gem_request {
+ struct kref ref;
+
/** On Which ring this request was generated */
struct intel_engine_cs *ring;
@@ -1995,7 +2127,14 @@ struct drm_i915_gem_request {
/** Position in the ringbuffer of the start of the request */
u32 head;
- /** Position in the ringbuffer of the end of the request */
+ /**
+ * Position in the ringbuffer of the start of the postfix.
+ * This is required to calculate the maximum available ringbuffer
+ * space without overwriting the postfix.
+ */
+ u32 postfix;
+
+ /** Position in the ringbuffer of the end of the whole request */
u32 tail;
/** Context related to this request */
@@ -2013,8 +2152,75 @@ struct drm_i915_gem_request {
struct drm_i915_file_private *file_priv;
/** file_priv list entry for this request */
struct list_head client_list;
+
+ uint32_t uniq;
+
+ /**
+ * The ELSP only accepts two elements at a time, so we queue
+ * context/tail pairs on a given queue (ring->execlist_queue) until the
+ * hardware is available. The queue serves a double purpose: we also use
+ * it to keep track of the up to 2 contexts currently in the hardware
+ * (usually one in execution and the other queued up by the GPU): We
+ * only remove elements from the head of the queue when the hardware
+ * informs us that an element has been completed.
+ *
+ * All accesses to the queue are mediated by a spinlock
+ * (ring->execlist_lock).
+ */
+
+ /** Execlist link in the submission queue.*/
+ struct list_head execlist_link;
+
+ /** Execlists no. of times this request has been sent to the ELSP */
+ int elsp_submitted;
+
};
+void i915_gem_request_free(struct kref *req_ref);
+
+static inline uint32_t
+i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
+{
+ return req ? req->seqno : 0;
+}
+
+static inline struct intel_engine_cs *
+i915_gem_request_get_ring(struct drm_i915_gem_request *req)
+{
+ return req ? req->ring : NULL;
+}
+
+static inline void
+i915_gem_request_reference(struct drm_i915_gem_request *req)
+{
+ kref_get(&req->ref);
+}
+
+static inline void
+i915_gem_request_unreference(struct drm_i915_gem_request *req)
+{
+ WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
+ kref_put(&req->ref, i915_gem_request_free);
+}
+
+static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
+ struct drm_i915_gem_request *src)
+{
+ if (src)
+ i915_gem_request_reference(src);
+
+ if (*pdst)
+ i915_gem_request_unreference(*pdst);
+
+ *pdst = src;
+}
+
+/*
+ * XXX: i915_gem_request_completed should be here but currently needs the
+ * definition of i915_seqno_passed() which is below. It will be moved in
+ * a later patch when the call to i915_seqno_passed() is obsoleted...
+ */
+
struct drm_i915_file_private {
struct drm_i915_private *dev_priv;
struct drm_file *file;
@@ -2247,7 +2453,9 @@ struct drm_i915_cmd_table {
#define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi)
#define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg)
-#define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev))
+#define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev) || \
+ IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || \
+ IS_SKYLAKE(dev))
#define HAS_RUNTIME_PM(dev) (IS_GEN6(dev) || IS_HASWELL(dev) || \
IS_BROADWELL(dev) || IS_VALLEYVIEW(dev))
#define HAS_RC6(dev) (INTEL_INFO(dev)->gen >= 6)
@@ -2317,6 +2525,8 @@ struct i915_params {
bool disable_vtd_wa;
int use_mmio_flip;
bool mmio_debug;
+ bool verbose_state_checks;
+ bool nuclear_pageflip;
};
extern struct i915_params i915 __read_mostly;
@@ -2361,6 +2571,12 @@ extern void intel_uncore_init(struct drm_device *dev);
extern void intel_uncore_check_errors(struct drm_device *dev);
extern void intel_uncore_fini(struct drm_device *dev);
extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
+const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
+void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+ enum forcewake_domains domains);
+void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+ enum forcewake_domains domains);
+void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
void
i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
@@ -2417,10 +2633,6 @@ int i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_execbuffer2(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
@@ -2465,10 +2677,23 @@ void i915_gem_vma_destroy(struct i915_vma *vma);
#define PIN_GLOBAL 0x4
#define PIN_OFFSET_BIAS 0x8
#define PIN_OFFSET_MASK (~4095)
+int __must_check i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm,
+ uint32_t alignment,
+ uint64_t flags,
+ const struct i915_ggtt_view *view);
+static inline
int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
uint32_t alignment,
- uint64_t flags);
+ uint64_t flags)
+{
+ return i915_gem_object_pin_view(obj, vm, alignment, flags,
+ &i915_ggtt_view_normal);
+}
+
+int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
+ u32 flags);
int __must_check i915_vma_unbind(struct i915_vma *vma);
int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
@@ -2517,6 +2742,18 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
return (int32_t)(seq1 - seq2) >= 0;
}
+static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
+ bool lazy_coherency)
+{
+ u32 seqno;
+
+ BUG_ON(req == NULL);
+
+ seqno = req->ring->get_seqno(req->ring, lazy_coherency);
+
+ return i915_seqno_passed(seqno, req->seqno);
+}
+
int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno);
int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno);
int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
@@ -2532,7 +2769,7 @@ bool i915_gem_retire_requests(struct drm_device *dev);
void i915_gem_retire_requests_ring(struct intel_engine_cs *ring);
int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
bool interruptible);
-int __must_check i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno);
+int __must_check i915_gem_check_olr(struct drm_i915_gem_request *req);
static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
{
@@ -2575,17 +2812,15 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
int __must_check i915_gem_suspend(struct drm_device *dev);
int __i915_add_request(struct intel_engine_cs *ring,
struct drm_file *file,
- struct drm_i915_gem_object *batch_obj,
- u32 *seqno);
-#define i915_add_request(ring, seqno) \
- __i915_add_request(ring, NULL, NULL, seqno)
-int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
+ struct drm_i915_gem_object *batch_obj);
+#define i915_add_request(ring) \
+ __i915_add_request(ring, NULL, NULL)
+int __i915_wait_request(struct drm_i915_gem_request *req,
unsigned reset_counter,
bool interruptible,
s64 *timeout,
struct drm_i915_file_private *file_priv);
-int __must_check i915_wait_seqno(struct intel_engine_cs *ring,
- uint32_t seqno);
+int __must_check i915_wait_request(struct drm_i915_gem_request *req);
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,
@@ -2619,18 +2854,51 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
void i915_gem_restore_fences(struct drm_device *dev);
+unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o,
+ struct i915_address_space *vm,
+ enum i915_ggtt_view_type view);
+static inline
unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o,
- struct i915_address_space *vm);
+ struct i915_address_space *vm)
+{
+ return i915_gem_obj_offset_view(o, vm, I915_GGTT_VIEW_NORMAL);
+}
bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o);
+bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o,
+ struct i915_address_space *vm,
+ enum i915_ggtt_view_type view);
+static inline
bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
- struct i915_address_space *vm);
+ struct i915_address_space *vm)
+{
+ return i915_gem_obj_bound_view(o, vm, I915_GGTT_VIEW_NORMAL);
+}
+
unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
struct i915_address_space *vm);
+struct i915_vma *i915_gem_obj_to_vma_view(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm,
+ const struct i915_ggtt_view *view);
+static inline
struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm);
+ struct i915_address_space *vm)
+{
+ return i915_gem_obj_to_vma_view(obj, vm, &i915_ggtt_view_normal);
+}
+
+struct i915_vma *
+i915_gem_obj_lookup_or_create_vma_view(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm,
+ const struct i915_ggtt_view *view);
+
+static inline
struct i915_vma *
i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm);
+ struct i915_address_space *vm)
+{
+ return i915_gem_obj_lookup_or_create_vma_view(obj, vm,
+ &i915_ggtt_view_normal);
+}
struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj);
static inline bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj) {
@@ -2727,6 +2995,10 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/* i915_gem_evict.c */
int __must_check i915_gem_evict_something(struct drm_device *dev,
@@ -2812,6 +3084,13 @@ void i915_destroy_error_state(struct drm_device *dev);
void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone);
const char *i915_cache_level_str(struct drm_i915_private *i915, int type);
+/* i915_gem_batch_pool.c */
+void i915_gem_batch_pool_init(struct drm_device *dev,
+ struct i915_gem_batch_pool *pool);
+void i915_gem_batch_pool_fini(struct i915_gem_batch_pool *pool);
+struct drm_i915_gem_object*
+i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, size_t size);
+
/* i915_cmd_parser.c */
int i915_cmd_parser_get_version(void);
int i915_cmd_parser_init_ring(struct intel_engine_cs *ring);
@@ -2819,7 +3098,9 @@ void i915_cmd_parser_fini_ring(struct intel_engine_cs *ring);
bool i915_needs_cmd_parser(struct intel_engine_cs *ring);
int i915_parse_cmds(struct intel_engine_cs *ring,
struct drm_i915_gem_object *batch_obj,
+ struct drm_i915_gem_object *shadow_batch_obj,
u32 batch_start_offset,
+ u32 batch_len,
bool is_master);
/* i915_suspend.c */
@@ -2899,9 +3180,6 @@ extern void intel_modeset_setup_hw_state(struct drm_device *dev,
bool force_restore);
extern void i915_redisable_vga(struct drm_device *dev);
extern void i915_redisable_vga_power_on(struct drm_device *dev);
-extern bool intel_fbc_enabled(struct drm_device *dev);
-extern void bdw_fbc_sw_flush(struct drm_device *dev, u32 value);
-extern void intel_disable_fbc(struct drm_device *dev);
extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
extern void intel_init_pch_refclk(struct drm_device *dev);
extern void gen6_set_rps(struct drm_device *dev, u8 val);
@@ -2930,20 +3208,12 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
struct drm_device *dev,
struct intel_display_error_state *error);
-/* On SNB platform, before reading ring registers forcewake bit
- * must be set to prevent GT core from power down and stale values being
- * returned.
- */
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine);
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
-void assert_force_wake_inactive(struct drm_i915_private *dev_priv);
-
int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
/* intel_sideband.c */
-u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr);
-void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val);
+u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
+void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
@@ -2964,15 +3234,8 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val);
-int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
-
-#define FORCEWAKE_RENDER (1 << 0)
-#define FORCEWAKE_MEDIA (1 << 1)
-#define FORCEWAKE_BLITTER (1 << 2)
-#define FORCEWAKE_ALL (FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
- FORCEWAKE_BLITTER)
-
+int intel_gpu_freq(struct drm_i915_private *dev_priv, int val);
+int intel_freq_opcode(struct drm_i915_private *dev_priv, int val);
#define I915_READ8(reg) dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
#define I915_WRITE8(reg, val) dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
@@ -3077,4 +3340,11 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
}
}
+static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
+ struct drm_i915_gem_request *req)
+{
+ if (ring->trace_irq_req == NULL && ring->irq_get(ring))
+ i915_gem_request_assign(&ring->trace_irq_req, req);
+}
+
#endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 5f614828d365..c26d36cc4b31 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -39,8 +39,7 @@
#include <linux/dma-buf.h>
static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
-static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj,
- bool force);
+static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
static __must_check int
i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
bool readonly);
@@ -153,12 +152,6 @@ int i915_mutex_lock_interruptible(struct drm_device *dev)
return 0;
}
-static inline bool
-i915_gem_object_is_inactive(struct drm_i915_gem_object *obj)
-{
- return i915_gem_obj_bound_any(obj) && !obj->active;
-}
-
int
i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
@@ -1157,19 +1150,18 @@ i915_gem_check_wedge(struct i915_gpu_error *error,
}
/*
- * Compare seqno against outstanding lazy request. Emit a request if they are
- * equal.
+ * Compare arbitrary request against outstanding lazy request. Emit on match.
*/
int
-i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno)
+i915_gem_check_olr(struct drm_i915_gem_request *req)
{
int ret;
- BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
+ WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
ret = 0;
- if (seqno == ring->outstanding_lazy_seqno)
- ret = i915_add_request(ring, NULL);
+ if (req == req->ring->outstanding_lazy_request)
+ ret = i915_add_request(req->ring);
return ret;
}
@@ -1194,10 +1186,9 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
}
/**
- * __i915_wait_seqno - wait until execution of seqno has finished
- * @ring: the ring expected to report seqno
- * @seqno: duh!
- * @reset_counter: reset sequence associated with the given seqno
+ * __i915_wait_request - wait until execution of request has finished
+ * @req: duh!
+ * @reset_counter: reset sequence associated with the given request
* @interruptible: do an interruptible wait (normally yes)
* @timeout: in - how long to wait (NULL forever); out - how much time remaining
*
@@ -1208,15 +1199,16 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
* reset_counter _must_ be read before, and an appropriate smp_rmb must be
* inserted.
*
- * Returns 0 if the seqno was found within the alloted time. Else returns the
+ * Returns 0 if the request was found within the alloted time. Else returns the
* errno with remaining time filled in timeout argument.
*/
-int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
+int __i915_wait_request(struct drm_i915_gem_request *req,
unsigned reset_counter,
bool interruptible,
s64 *timeout,
struct drm_i915_file_private *file_priv)
{
+ struct intel_engine_cs *ring = i915_gem_request_get_ring(req);
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const bool irq_test_in_progress =
@@ -1228,7 +1220,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled");
- if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
+ if (i915_gem_request_completed(req, true))
return 0;
timeout_expire = timeout ?
@@ -1246,7 +1238,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
return -ENODEV;
/* Record current time in case interrupted by signal, or wedged */
- trace_i915_gem_request_wait_begin(ring, seqno);
+ trace_i915_gem_request_wait_begin(req);
before = ktime_get_raw_ns();
for (;;) {
struct timer_list timer;
@@ -1265,7 +1257,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
break;
}
- if (i915_seqno_passed(ring->get_seqno(ring, false), seqno)) {
+ if (i915_gem_request_completed(req, false)) {
ret = 0;
break;
}
@@ -1297,7 +1289,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
}
}
now = ktime_get_raw_ns();
- trace_i915_gem_request_wait_end(ring, seqno);
+ trace_i915_gem_request_wait_end(req);
if (!irq_test_in_progress)
ring->irq_put(ring);
@@ -1324,32 +1316,40 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
}
/**
- * Waits for a sequence number to be signaled, and cleans up the
+ * Waits for a request to be signaled, and cleans up the
* request and object lists appropriately for that event.
*/
int
-i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno)
+i915_wait_request(struct drm_i915_gem_request *req)
{
- struct drm_device *dev = ring->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- bool interruptible = dev_priv->mm.interruptible;
+ struct drm_device *dev;
+ struct drm_i915_private *dev_priv;
+ bool interruptible;
unsigned reset_counter;
int ret;
+ BUG_ON(req == NULL);
+
+ dev = req->ring->dev;
+ dev_priv = dev->dev_private;
+ interruptible = dev_priv->mm.interruptible;
+
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
- BUG_ON(seqno == 0);
ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
if (ret)
return ret;
- ret = i915_gem_check_olr(ring, seqno);
+ ret = i915_gem_check_olr(req);
if (ret)
return ret;
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
- return __i915_wait_seqno(ring, seqno, reset_counter, interruptible,
- NULL, NULL);
+ i915_gem_request_reference(req);
+ ret = __i915_wait_request(req, reset_counter,
+ interruptible, NULL, NULL);
+ i915_gem_request_unreference(req);
+ return ret;
}
static int
@@ -1361,11 +1361,11 @@ i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj)
/* Manually manage the write flush as we may have not yet
* retired the buffer.
*
- * Note that the last_write_seqno is always the earlier of
- * the two (read/write) seqno, so if we haved successfully waited,
+ * Note that the last_write_req is always the earlier of
+ * the two (read/write) requests, so if we haved successfully waited,
* we know we have passed the last write.
*/
- obj->last_write_seqno = 0;
+ i915_gem_request_assign(&obj->last_write_req, NULL);
return 0;
}
@@ -1378,15 +1378,14 @@ static __must_check int
i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
bool readonly)
{
- struct intel_engine_cs *ring = obj->ring;
- u32 seqno;
+ struct drm_i915_gem_request *req;
int ret;
- seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
- if (seqno == 0)
+ req = readonly ? obj->last_write_req : obj->last_read_req;
+ if (!req)
return 0;
- ret = i915_wait_seqno(ring, seqno);
+ ret = i915_wait_request(req);
if (ret)
return ret;
@@ -1401,33 +1400,33 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
struct drm_i915_file_private *file_priv,
bool readonly)
{
+ struct drm_i915_gem_request *req;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_engine_cs *ring = obj->ring;
unsigned reset_counter;
- u32 seqno;
int ret;
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
BUG_ON(!dev_priv->mm.interruptible);
- seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
- if (seqno == 0)
+ req = readonly ? obj->last_write_req : obj->last_read_req;
+ if (!req)
return 0;
ret = i915_gem_check_wedge(&dev_priv->gpu_error, true);
if (ret)
return ret;
- ret = i915_gem_check_olr(ring, seqno);
+ ret = i915_gem_check_olr(req);
if (ret)
return ret;
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
+ i915_gem_request_reference(req);
mutex_unlock(&dev->struct_mutex);
- ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL,
- file_priv);
+ ret = __i915_wait_request(req, reset_counter, true, NULL, file_priv);
mutex_lock(&dev->struct_mutex);
+ i915_gem_request_unreference(req);
if (ret)
return ret;
@@ -1481,18 +1480,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
if (ret)
goto unref;
- if (read_domains & I915_GEM_DOMAIN_GTT) {
+ if (read_domains & I915_GEM_DOMAIN_GTT)
ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
-
- /* Silently promote "you're not bound, there was nothing to do"
- * to success, since the client was just asking us to
- * make sure everything was done.
- */
- if (ret == -EINVAL)
- ret = 0;
- } else {
+ else
ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
- }
unref:
drm_gem_object_unreference(&obj->base);
@@ -1524,7 +1515,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
/* Pinned buffers may be scanout, so flush the cache */
if (obj->pin_display)
- i915_gem_object_flush_cpu_write_domain(obj, true);
+ i915_gem_object_flush_cpu_write_domain(obj);
drm_gem_object_unreference(&obj->base);
unlock:
@@ -1557,6 +1548,12 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct drm_gem_object *obj;
unsigned long addr;
+ if (args->flags & ~(I915_MMAP_WC))
+ return -EINVAL;
+
+ if (args->flags & I915_MMAP_WC && !cpu_has_pat)
+ return -ENODEV;
+
obj = drm_gem_object_lookup(dev, file, args->handle);
if (obj == NULL)
return -ENOENT;
@@ -1572,6 +1569,19 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
addr = vm_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED,
args->offset);
+ if (args->flags & I915_MMAP_WC) {
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+
+ down_write(&mm->mmap_sem);
+ vma = find_vma(mm, addr);
+ if (vma)
+ vma->vm_page_prot =
+ pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ else
+ addr = -ENOMEM;
+ up_write(&mm->mmap_sem);
+ }
drm_gem_object_unreference_unlocked(obj);
if (IS_ERR((void *)addr))
return addr;
@@ -2256,14 +2266,18 @@ static void
i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
struct intel_engine_cs *ring)
{
- u32 seqno = intel_ring_get_seqno(ring);
+ struct drm_i915_gem_request *req;
+ struct intel_engine_cs *old_ring;
BUG_ON(ring == NULL);
- if (obj->ring != ring && obj->last_write_seqno) {
- /* Keep the seqno relative to the current ring */
- obj->last_write_seqno = seqno;
+
+ req = intel_ring_get_request(ring);
+ old_ring = i915_gem_request_get_ring(obj->last_read_req);
+
+ if (old_ring != ring && obj->last_write_req) {
+ /* Keep the request relative to the current ring */
+ i915_gem_request_assign(&obj->last_write_req, req);
}
- obj->ring = ring;
/* Add a reference if we're newly entering the active list. */
if (!obj->active) {
@@ -2273,7 +2287,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
list_move_tail(&obj->ring_list, &ring->active_list);
- obj->last_read_seqno = seqno;
+ i915_gem_request_assign(&obj->last_read_req, req);
}
void i915_vma_move_to_active(struct i915_vma *vma,
@@ -2286,29 +2300,25 @@ void i915_vma_move_to_active(struct i915_vma *vma,
static void
i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
{
- struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
- struct i915_address_space *vm;
struct i915_vma *vma;
BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS);
BUG_ON(!obj->active);
- list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
- vma = i915_gem_obj_to_vma(obj, vm);
- if (vma && !list_empty(&vma->mm_list))
- list_move_tail(&vma->mm_list, &vm->inactive_list);
+ list_for_each_entry(vma, &obj->vma_list, vma_link) {
+ if (!list_empty(&vma->mm_list))
+ list_move_tail(&vma->mm_list, &vma->vm->inactive_list);
}
intel_fb_obj_flush(obj, true);
list_del_init(&obj->ring_list);
- obj->ring = NULL;
- obj->last_read_seqno = 0;
- obj->last_write_seqno = 0;
+ i915_gem_request_assign(&obj->last_read_req, NULL);
+ i915_gem_request_assign(&obj->last_write_req, NULL);
obj->base.write_domain = 0;
- obj->last_fenced_seqno = 0;
+ i915_gem_request_assign(&obj->last_fenced_req, NULL);
obj->active = 0;
drm_gem_object_unreference(&obj->base);
@@ -2319,13 +2329,10 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
static void
i915_gem_object_retire(struct drm_i915_gem_object *obj)
{
- struct intel_engine_cs *ring = obj->ring;
-
- if (ring == NULL)
+ if (obj->last_read_req == NULL)
return;
- if (i915_seqno_passed(ring->get_seqno(ring, true),
- obj->last_read_seqno))
+ if (i915_gem_request_completed(obj->last_read_req, true))
i915_gem_object_move_to_inactive(obj);
}
@@ -2401,22 +2408,20 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
int __i915_add_request(struct intel_engine_cs *ring,
struct drm_file *file,
- struct drm_i915_gem_object *obj,
- u32 *out_seqno)
+ struct drm_i915_gem_object *obj)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
struct drm_i915_gem_request *request;
struct intel_ringbuffer *ringbuf;
- u32 request_ring_position, request_start;
+ u32 request_start;
int ret;
- request = ring->preallocated_lazy_request;
+ request = ring->outstanding_lazy_request;
if (WARN_ON(request == NULL))
return -ENOMEM;
if (i915.enable_execlists) {
- struct intel_context *ctx = request->ctx;
- ringbuf = ctx->engine[ring->id].ringbuf;
+ ringbuf = request->ctx->engine[ring->id].ringbuf;
} else
ringbuf = ring->buffer;
@@ -2429,7 +2434,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
* what.
*/
if (i915.enable_execlists) {
- ret = logical_ring_flush_all_caches(ringbuf);
+ ret = logical_ring_flush_all_caches(ringbuf, request->ctx);
if (ret)
return ret;
} else {
@@ -2443,10 +2448,10 @@ int __i915_add_request(struct intel_engine_cs *ring,
* GPU processing the request, we never over-estimate the
* position of the head.
*/
- request_ring_position = intel_ring_get_tail(ringbuf);
+ request->postfix = intel_ring_get_tail(ringbuf);
if (i915.enable_execlists) {
- ret = ring->emit_request(ringbuf);
+ ret = ring->emit_request(ringbuf, request);
if (ret)
return ret;
} else {
@@ -2455,10 +2460,8 @@ int __i915_add_request(struct intel_engine_cs *ring,
return ret;
}
- request->seqno = intel_ring_get_seqno(ring);
- request->ring = ring;
request->head = request_start;
- request->tail = request_ring_position;
+ request->tail = intel_ring_get_tail(ringbuf);
/* Whilst this request exists, batch_obj will be on the
* active_list, and so will hold the active reference. Only when this
@@ -2491,9 +2494,8 @@ int __i915_add_request(struct intel_engine_cs *ring,
spin_unlock(&file_priv->mm.lock);
}
- trace_i915_gem_request_add(ring, request->seqno);
- ring->outstanding_lazy_seqno = 0;
- ring->preallocated_lazy_request = NULL;
+ trace_i915_gem_request_add(request);
+ ring->outstanding_lazy_request = NULL;
i915_queue_hangcheck(ring->dev);
@@ -2503,8 +2505,6 @@ int __i915_add_request(struct intel_engine_cs *ring,
round_jiffies_up_relative(HZ));
intel_mark_busy(dev_priv->dev);
- if (out_seqno)
- *out_seqno = request->seqno;
return 0;
}
@@ -2532,7 +2532,8 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv,
if (ctx->hang_stats.banned)
return true;
- if (elapsed <= DRM_I915_CTX_BAN_PERIOD) {
+ if (ctx->hang_stats.ban_period_seconds &&
+ elapsed <= ctx->hang_stats.ban_period_seconds) {
if (!i915_gem_context_is_default(ctx)) {
DRM_DEBUG("context hanging too fast, banning!\n");
return true;
@@ -2568,33 +2569,39 @@ static void i915_set_reset_status(struct drm_i915_private *dev_priv,
static void i915_gem_free_request(struct drm_i915_gem_request *request)
{
- struct intel_context *ctx = request->ctx;
-
list_del(&request->list);
i915_gem_request_remove_from_client(request);
+ i915_gem_request_unreference(request);
+}
+
+void i915_gem_request_free(struct kref *req_ref)
+{
+ struct drm_i915_gem_request *req = container_of(req_ref,
+ typeof(*req), ref);
+ struct intel_context *ctx = req->ctx;
+
if (ctx) {
if (i915.enable_execlists) {
- struct intel_engine_cs *ring = request->ring;
+ struct intel_engine_cs *ring = req->ring;
if (ctx != ring->default_context)
intel_lr_context_unpin(ring, ctx);
}
+
i915_gem_context_unreference(ctx);
}
- kfree(request);
+
+ kfree(req);
}
struct drm_i915_gem_request *
i915_gem_find_active_request(struct intel_engine_cs *ring)
{
struct drm_i915_gem_request *request;
- u32 completed_seqno;
-
- completed_seqno = ring->get_seqno(ring, false);
list_for_each_entry(request, &ring->request_list, list) {
- if (i915_seqno_passed(completed_seqno, request->seqno))
+ if (i915_gem_request_completed(request, false))
continue;
return request;
@@ -2641,13 +2648,17 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
* pinned in place.
*/
while (!list_empty(&ring->execlist_queue)) {
- struct intel_ctx_submit_request *submit_req;
+ struct drm_i915_gem_request *submit_req;
submit_req = list_first_entry(&ring->execlist_queue,
- struct intel_ctx_submit_request,
+ struct drm_i915_gem_request,
execlist_link);
list_del(&submit_req->execlist_link);
intel_runtime_pm_put(dev_priv);
+
+ if (submit_req->ctx != ring->default_context)
+ intel_lr_context_unpin(ring, submit_req->ctx);
+
i915_gem_context_unreference(submit_req->ctx);
kfree(submit_req);
}
@@ -2669,10 +2680,8 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
i915_gem_free_request(request);
}
- /* These may not have been flush before the reset, do so now */
- kfree(ring->preallocated_lazy_request);
- ring->preallocated_lazy_request = NULL;
- ring->outstanding_lazy_seqno = 0;
+ /* This may not have been flushed before the reset, so clean it now */
+ i915_gem_request_assign(&ring->outstanding_lazy_request, NULL);
}
void i915_gem_restore_fences(struct drm_device *dev)
@@ -2724,15 +2733,11 @@ void i915_gem_reset(struct drm_device *dev)
void
i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
{
- uint32_t seqno;
-
if (list_empty(&ring->request_list))
return;
WARN_ON(i915_verify_lists(ring->dev));
- seqno = ring->get_seqno(ring, true);
-
/* Move any buffers on the active list that are no longer referenced
* by the ringbuffer to the flushing/inactive lists as appropriate,
* before we free the context associated with the requests.
@@ -2744,7 +2749,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
struct drm_i915_gem_object,
ring_list);
- if (!i915_seqno_passed(seqno, obj->last_read_seqno))
+ if (!i915_gem_request_completed(obj->last_read_req, true))
break;
i915_gem_object_move_to_inactive(obj);
@@ -2759,10 +2764,10 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
struct drm_i915_gem_request,
list);
- if (!i915_seqno_passed(seqno, request->seqno))
+ if (!i915_gem_request_completed(request, true))
break;
- trace_i915_gem_request_retire(ring, request->seqno);
+ trace_i915_gem_request_retire(request);
/* This is one of the few common intersection points
* between legacy ringbuffer submission and execlists:
@@ -2780,15 +2785,15 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
* of tail of the request to update the last known position
* of the GPU head.
*/
- ringbuf->last_retired_head = request->tail;
+ ringbuf->last_retired_head = request->postfix;
i915_gem_free_request(request);
}
- if (unlikely(ring->trace_irq_seqno &&
- i915_seqno_passed(seqno, ring->trace_irq_seqno))) {
+ if (unlikely(ring->trace_irq_req &&
+ i915_gem_request_completed(ring->trace_irq_req, true))) {
ring->irq_put(ring);
- ring->trace_irq_seqno = 0;
+ i915_gem_request_assign(&ring->trace_irq_req, NULL);
}
WARN_ON(i915_verify_lists(ring->dev));
@@ -2860,14 +2865,17 @@ i915_gem_idle_work_handler(struct work_struct *work)
static int
i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
{
+ struct intel_engine_cs *ring;
int ret;
if (obj->active) {
- ret = i915_gem_check_olr(obj->ring, obj->last_read_seqno);
+ ring = i915_gem_request_get_ring(obj->last_read_req);
+
+ ret = i915_gem_check_olr(obj->last_read_req);
if (ret)
return ret;
- i915_gem_retire_requests_ring(obj->ring);
+ i915_gem_retire_requests_ring(ring);
}
return 0;
@@ -2901,9 +2909,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_wait *args = data;
struct drm_i915_gem_object *obj;
- struct intel_engine_cs *ring = NULL;
+ struct drm_i915_gem_request *req;
unsigned reset_counter;
- u32 seqno = 0;
int ret = 0;
if (args->flags != 0)
@@ -2924,13 +2931,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
if (ret)
goto out;
- if (obj->active) {
- seqno = obj->last_read_seqno;
- ring = obj->ring;
- }
+ if (!obj->active || !obj->last_read_req)
+ goto out;
- if (seqno == 0)
- goto out;
+ req = obj->last_read_req;
/* Do this after OLR check to make sure we make forward progress polling
* on this IOCTL with a timeout <=0 (like busy ioctl)
@@ -2942,10 +2946,15 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
drm_gem_object_unreference(&obj->base);
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
+ i915_gem_request_reference(req);
mutex_unlock(&dev->struct_mutex);
- return __i915_wait_seqno(ring, seqno, reset_counter, true,
- &args->timeout_ns, file->driver_priv);
+ ret = __i915_wait_request(req, reset_counter, true, &args->timeout_ns,
+ file->driver_priv);
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_request_unreference(req);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
out:
drm_gem_object_unreference(&obj->base);
@@ -2969,10 +2978,12 @@ int
i915_gem_object_sync(struct drm_i915_gem_object *obj,
struct intel_engine_cs *to)
{
- struct intel_engine_cs *from = obj->ring;
+ struct intel_engine_cs *from;
u32 seqno;
int ret, idx;
+ from = i915_gem_request_get_ring(obj->last_read_req);
+
if (from == NULL || to == from)
return 0;
@@ -2981,24 +2992,25 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
idx = intel_ring_sync_index(from, to);
- seqno = obj->last_read_seqno;
+ seqno = i915_gem_request_get_seqno(obj->last_read_req);
/* Optimization: Avoid semaphore sync when we are sure we already
* waited for an object with higher seqno */
if (seqno <= from->semaphore.sync_seqno[idx])
return 0;
- ret = i915_gem_check_olr(obj->ring, seqno);
+ ret = i915_gem_check_olr(obj->last_read_req);
if (ret)
return ret;
- trace_i915_gem_ring_sync_to(from, to, seqno);
+ trace_i915_gem_ring_sync_to(from, to, obj->last_read_req);
ret = to->semaphore.sync_to(to, from, seqno);
if (!ret)
- /* We use last_read_seqno because sync_to()
+ /* We use last_read_req because sync_to()
* might have just caused seqno wrap under
* the radar.
*/
- from->semaphore.sync_seqno[idx] = obj->last_read_seqno;
+ from->semaphore.sync_seqno[idx] =
+ i915_gem_request_get_seqno(obj->last_read_req);
return ret;
}
@@ -3054,10 +3066,8 @@ int i915_vma_unbind(struct i915_vma *vma)
* cause memory corruption through use-after-free.
*/
- /* Throw away the active reference before moving to the unbound list */
- i915_gem_object_retire(obj);
-
- if (i915_is_ggtt(vma->vm)) {
+ if (i915_is_ggtt(vma->vm) &&
+ vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
i915_gem_object_finish_gtt(obj);
/* release the fence reg _after_ flushing */
@@ -3071,8 +3081,15 @@ int i915_vma_unbind(struct i915_vma *vma)
vma->unbind_vma(vma);
list_del_init(&vma->mm_list);
- if (i915_is_ggtt(vma->vm))
- obj->map_and_fenceable = false;
+ if (i915_is_ggtt(vma->vm)) {
+ if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
+ obj->map_and_fenceable = false;
+ } else if (vma->ggtt_view.pages) {
+ sg_free_table(vma->ggtt_view.pages);
+ kfree(vma->ggtt_view.pages);
+ vma->ggtt_view.pages = NULL;
+ }
+ }
drm_mm_remove_node(&vma->node);
i915_gem_vma_destroy(vma);
@@ -3080,6 +3097,10 @@ int i915_vma_unbind(struct i915_vma *vma)
/* Since the unbound list is global, only move to that list if
* no more VMAs exist. */
if (list_empty(&obj->vma_list)) {
+ /* Throw away the active reference before
+ * moving to the unbound list. */
+ i915_gem_object_retire(obj);
+
i915_gem_gtt_finish_object(obj);
list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list);
}
@@ -3270,17 +3291,12 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg,
"bogus fence setup with stride: 0x%x, tiling mode: %i\n",
obj->stride, obj->tiling_mode);
- switch (INTEL_INFO(dev)->gen) {
- case 9:
- case 8:
- case 7:
- case 6:
- case 5:
- case 4: i965_write_fence_reg(dev, reg, obj); break;
- case 3: i915_write_fence_reg(dev, reg, obj); break;
- case 2: i830_write_fence_reg(dev, reg, obj); break;
- default: BUG();
- }
+ if (IS_GEN2(dev))
+ i830_write_fence_reg(dev, reg, obj);
+ else if (IS_GEN3(dev))
+ i915_write_fence_reg(dev, reg, obj);
+ else if (INTEL_INFO(dev)->gen >= 4)
+ i965_write_fence_reg(dev, reg, obj);
/* And similarly be paranoid that no direct access to this region
* is reordered to before the fence is installed.
@@ -3319,12 +3335,12 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
static int
i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
{
- if (obj->last_fenced_seqno) {
- int ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno);
+ if (obj->last_fenced_req) {
+ int ret = i915_wait_request(obj->last_fenced_req);
if (ret)
return ret;
- obj->last_fenced_seqno = 0;
+ i915_gem_request_assign(&obj->last_fenced_req, NULL);
}
return 0;
@@ -3497,7 +3513,8 @@ static struct i915_vma *
i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
unsigned alignment,
- uint64_t flags)
+ uint64_t flags,
+ const struct i915_ggtt_view *view)
{
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3547,7 +3564,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
i915_gem_object_pin_pages(obj);
- vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
+ vma = i915_gem_obj_lookup_or_create_vma_view(obj, vm, view);
if (IS_ERR(vma))
goto err_unpin;
@@ -3577,15 +3594,19 @@ search_free:
if (ret)
goto err_remove_node;
+ trace_i915_vma_bind(vma, flags);
+ ret = i915_vma_bind(vma, obj->cache_level,
+ flags & PIN_GLOBAL ? GLOBAL_BIND : 0);
+ if (ret)
+ goto err_finish_gtt;
+
list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
list_add_tail(&vma->mm_list, &vm->inactive_list);
- trace_i915_vma_bind(vma, flags);
- vma->bind_vma(vma, obj->cache_level,
- flags & PIN_GLOBAL ? GLOBAL_BIND : 0);
-
return vma;
+err_finish_gtt:
+ i915_gem_gtt_finish_object(obj);
err_remove_node:
drm_mm_remove_node(&vma->node);
err_free_vma:
@@ -3622,11 +3643,14 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj,
* snooping behaviour occurs naturally as the result of our domain
* tracking.
*/
- if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level))
+ if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) {
+ obj->cache_dirty = true;
return false;
+ }
trace_i915_gem_object_clflush(obj);
drm_clflush_sg(obj->pages);
+ obj->cache_dirty = false;
return true;
}
@@ -3662,15 +3686,14 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj)
/** Flushes the CPU write domain for the object if it's dirty. */
static void
-i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj,
- bool force)
+i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj)
{
uint32_t old_write_domain;
if (obj->base.write_domain != I915_GEM_DOMAIN_CPU)
return;
- if (i915_gem_clflush_object(obj, force))
+ if (i915_gem_clflush_object(obj, obj->pin_display))
i915_gem_chipset_flush(obj->base.dev);
old_write_domain = obj->base.write_domain;
@@ -3692,15 +3715,10 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj,
int
i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
{
- struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
- struct i915_vma *vma = i915_gem_obj_to_ggtt(obj);
uint32_t old_write_domain, old_read_domains;
+ struct i915_vma *vma;
int ret;
- /* Not valid to be called on unbound objects. */
- if (vma == NULL)
- return -EINVAL;
-
if (obj->base.write_domain == I915_GEM_DOMAIN_GTT)
return 0;
@@ -3709,7 +3727,20 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
return ret;
i915_gem_object_retire(obj);
- i915_gem_object_flush_cpu_write_domain(obj, false);
+
+ /* Flush and acquire obj->pages so that we are coherent through
+ * direct access in memory with previous cached writes through
+ * shmemfs and that our cache domain tracking remains valid.
+ * For example, if the obj->filp was moved to swap without us
+ * being notified and releasing the pages, we would mistakenly
+ * continue to assume that the obj remained out of the CPU cached
+ * domain.
+ */
+ ret = i915_gem_object_get_pages(obj);
+ if (ret)
+ return ret;
+
+ i915_gem_object_flush_cpu_write_domain(obj);
/* Serialise direct access to this object with the barriers for
* coherent writes from the GPU, by effectively invalidating the
@@ -3740,9 +3771,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
old_write_domain);
/* And bump the LRU for this access */
- if (i915_gem_object_is_inactive(obj))
+ vma = i915_gem_obj_to_ggtt(obj);
+ if (vma && drm_mm_node_allocated(&vma->node) && !obj->active)
list_move_tail(&vma->mm_list,
- &dev_priv->gtt.base.inactive_list);
+ &to_i915(obj->base.dev)->gtt.base.inactive_list);
return 0;
}
@@ -3788,36 +3820,23 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
}
list_for_each_entry(vma, &obj->vma_list, vma_link)
- if (drm_mm_node_allocated(&vma->node))
- vma->bind_vma(vma, cache_level,
- vma->bound & GLOBAL_BIND);
+ if (drm_mm_node_allocated(&vma->node)) {
+ ret = i915_vma_bind(vma, cache_level,
+ vma->bound & GLOBAL_BIND);
+ if (ret)
+ return ret;
+ }
}
list_for_each_entry(vma, &obj->vma_list, vma_link)
vma->node.color = cache_level;
obj->cache_level = cache_level;
- if (cpu_write_needs_clflush(obj)) {
- 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.
- */
- i915_gem_object_retire(obj);
- WARN_ON(obj->base.write_domain & ~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);
+ if (obj->cache_dirty &&
+ obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
+ cpu_write_needs_clflush(obj)) {
+ if (i915_gem_clflush_object(obj, true))
+ i915_gem_chipset_flush(obj->base.dev);
}
return 0;
@@ -3909,18 +3928,14 @@ static bool is_pin_display(struct drm_i915_gem_object *obj)
if (!vma)
return false;
- /* There are 3 sources that pin objects:
+ /* There are 2 sources that pin objects:
* 1. The display engine (scanouts, sprites, cursors);
* 2. Reservations for execbuffer;
- * 3. The user.
*
* We can ignore reservations as we hold the struct_mutex and
- * are only called outside of the reservation path. The user
- * can only increment pin_count once, and so if after
- * subtracting the potential reference by the user, any pin_count
- * remains, it must be due to another use by the display engine.
+ * are only called outside of the reservation path.
*/
- return vma->pin_count - !!obj->user_pin_count;
+ return vma->pin_count;
}
/*
@@ -3937,7 +3952,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
bool was_pin_display;
int ret;
- if (pipelined != obj->ring) {
+ if (pipelined != i915_gem_request_get_ring(obj->last_read_req)) {
ret = i915_gem_object_sync(obj, pipelined);
if (ret)
return ret;
@@ -3971,7 +3986,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
if (ret)
goto err_unpin_display;
- i915_gem_object_flush_cpu_write_domain(obj, true);
+ i915_gem_object_flush_cpu_write_domain(obj);
old_write_domain = obj->base.write_domain;
old_read_domains = obj->base.read_domains;
@@ -4089,10 +4104,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_file_private *file_priv = file->driver_priv;
unsigned long recent_enough = jiffies - msecs_to_jiffies(20);
- struct drm_i915_gem_request *request;
- struct intel_engine_cs *ring = NULL;
+ struct drm_i915_gem_request *request, *target = NULL;
unsigned reset_counter;
- u32 seqno = 0;
int ret;
ret = i915_gem_wait_for_error(&dev_priv->gpu_error);
@@ -4108,19 +4121,24 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
if (time_after_eq(request->emitted_jiffies, recent_enough))
break;
- ring = request->ring;
- seqno = request->seqno;
+ target = request;
}
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
+ if (target)
+ i915_gem_request_reference(target);
spin_unlock(&file_priv->mm.lock);
- if (seqno == 0)
+ if (target == NULL)
return 0;
- ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL, NULL);
+ ret = __i915_wait_request(target, reset_counter, true, NULL, NULL);
if (ret == 0)
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_request_unreference(target);
+ mutex_unlock(&dev->struct_mutex);
+
return ret;
}
@@ -4144,10 +4162,11 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags)
}
int
-i915_gem_object_pin(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm,
- uint32_t alignment,
- uint64_t flags)
+i915_gem_object_pin_view(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm,
+ uint32_t alignment,
+ uint64_t flags,
+ const struct i915_ggtt_view *view)
{
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
struct i915_vma *vma;
@@ -4163,7 +4182,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
if (WARN_ON((flags & (PIN_MAPPABLE | PIN_GLOBAL)) == PIN_MAPPABLE))
return -EINVAL;
- vma = i915_gem_obj_to_vma(obj, vm);
+ vma = i915_gem_obj_to_vma_view(obj, vm, view);
if (vma) {
if (WARN_ON(vma->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
return -EBUSY;
@@ -4173,7 +4192,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
"bo is already pinned with incorrect alignment:"
" offset=%lx, req.alignment=%x, req.map_and_fenceable=%d,"
" obj->map_and_fenceable=%d\n",
- i915_gem_obj_offset(obj, vm), alignment,
+ i915_gem_obj_offset_view(obj, vm, view->type),
+ alignment,
!!(flags & PIN_MAPPABLE),
obj->map_and_fenceable);
ret = i915_vma_unbind(vma);
@@ -4186,13 +4206,17 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
bound = vma ? vma->bound : 0;
if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
- vma = i915_gem_object_bind_to_vm(obj, vm, alignment, flags);
+ vma = i915_gem_object_bind_to_vm(obj, vm, alignment,
+ flags, view);
if (IS_ERR(vma))
return PTR_ERR(vma);
}
- if (flags & PIN_GLOBAL && !(vma->bound & GLOBAL_BIND))
- vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND);
+ if (flags & PIN_GLOBAL && !(vma->bound & GLOBAL_BIND)) {
+ ret = i915_vma_bind(vma, obj->cache_level, GLOBAL_BIND);
+ if (ret)
+ return ret;
+ }
if ((bound ^ vma->bound) & GLOBAL_BIND) {
bool mappable, fenceable;
@@ -4264,102 +4288,6 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
}
int
-i915_gem_pin_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_i915_gem_pin *args = data;
- struct drm_i915_gem_object *obj;
- int ret;
-
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- return -ENODEV;
-
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
-
- obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
- if (&obj->base == NULL) {
- ret = -ENOENT;
- goto unlock;
- }
-
- if (obj->madv != I915_MADV_WILLNEED) {
- DRM_DEBUG("Attempting to pin a purgeable buffer\n");
- ret = -EFAULT;
- goto out;
- }
-
- if (obj->pin_filp != NULL && obj->pin_filp != file) {
- DRM_DEBUG("Already pinned in i915_gem_pin_ioctl(): %d\n",
- args->handle);
- ret = -EINVAL;
- goto out;
- }
-
- if (obj->user_pin_count == ULONG_MAX) {
- ret = -EBUSY;
- goto out;
- }
-
- if (obj->user_pin_count == 0) {
- ret = i915_gem_obj_ggtt_pin(obj, args->alignment, PIN_MAPPABLE);
- if (ret)
- goto out;
- }
-
- obj->user_pin_count++;
- obj->pin_filp = file;
-
- args->offset = i915_gem_obj_ggtt_offset(obj);
-out:
- drm_gem_object_unreference(&obj->base);
-unlock:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-int
-i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file)
-{
- struct drm_i915_gem_pin *args = data;
- struct drm_i915_gem_object *obj;
- int ret;
-
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- return -ENODEV;
-
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
-
- obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
- if (&obj->base == NULL) {
- ret = -ENOENT;
- goto unlock;
- }
-
- if (obj->pin_filp != file) {
- DRM_DEBUG("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
- args->handle);
- ret = -EINVAL;
- goto out;
- }
- obj->user_pin_count--;
- if (obj->user_pin_count == 0) {
- obj->pin_filp = NULL;
- i915_gem_object_ggtt_unpin(obj);
- }
-
-out:
- drm_gem_object_unreference(&obj->base);
-unlock:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-int
i915_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -4385,9 +4313,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
ret = i915_gem_object_flush_active(obj);
args->busy = obj->active;
- if (obj->ring) {
+ if (obj->last_read_req) {
+ struct intel_engine_cs *ring;
BUILD_BUG_ON(I915_NUM_RINGS > 16);
- args->busy |= intel_ring_flag(obj->ring) << 16;
+ ring = i915_gem_request_get_ring(obj->last_read_req);
+ args->busy |= intel_ring_flag(ring) << 16;
}
drm_gem_object_unreference(&obj->base);
@@ -4467,6 +4397,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
INIT_LIST_HEAD(&obj->ring_list);
INIT_LIST_HEAD(&obj->obj_exec_link);
INIT_LIST_HEAD(&obj->vma_list);
+ INIT_LIST_HEAD(&obj->batch_pool_list);
obj->ops = ops;
@@ -4622,12 +4553,13 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
intel_runtime_pm_put(dev_priv);
}
-struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm)
+struct i915_vma *i915_gem_obj_to_vma_view(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm,
+ const struct i915_ggtt_view *view)
{
struct i915_vma *vma;
list_for_each_entry(vma, &obj->vma_list, vma_link)
- if (vma->vm == vm)
+ if (vma->vm == vm && vma->ggtt_view.type == view->type)
return vma;
return NULL;
@@ -4683,10 +4615,15 @@ i915_gem_suspend(struct drm_device *dev)
i915_gem_stop_ringbuffers(dev);
mutex_unlock(&dev->struct_mutex);
- del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
+ cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
cancel_delayed_work_sync(&dev_priv->mm.retire_work);
flush_delayed_work(&dev_priv->mm.idle_work);
+ /* Assert that we sucessfully flushed all the work and
+ * reset the GPU back to its idle, low power state.
+ */
+ WARN_ON(dev_priv->mm.busy);
+
return 0;
err:
@@ -4798,14 +4735,6 @@ int i915_gem_init_rings(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- /*
- * At least 830 can leave some of the unused rings
- * "active" (ie. head != tail) after resume which
- * will prevent c3 entry. Makes sure all unused rings
- * are totally idle.
- */
- init_unused_rings(dev);
-
ret = intel_init_render_ring_buffer(dev);
if (ret)
return ret;
@@ -4858,6 +4787,7 @@ int
i915_gem_init_hw(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine_cs *ring;
int ret, i;
if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
@@ -4884,9 +4814,19 @@ i915_gem_init_hw(struct drm_device *dev)
i915_gem_init_swizzling(dev);
- ret = dev_priv->gt.init_rings(dev);
- if (ret)
- return ret;
+ /*
+ * At least 830 can leave some of the unused rings
+ * "active" (ie. head != tail) after resume which
+ * will prevent c3 entry. Makes sure all unused rings
+ * are totally idle.
+ */
+ init_unused_rings(dev);
+
+ for_each_ring(ring, dev_priv, i) {
+ ret = ring->init_hw(ring);
+ if (ret)
+ return ret;
+ }
for (i = 0; i < NUM_L3_SLICES(dev); i++)
i915_gem_l3_remap(&dev_priv->ring[RCS], i);
@@ -4939,18 +4879,18 @@ int i915_gem_init(struct drm_device *dev)
}
ret = i915_gem_init_userptr(dev);
- if (ret) {
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
+ if (ret)
+ goto out_unlock;
i915_gem_init_global_gtt(dev);
ret = i915_gem_context_init(dev);
- if (ret) {
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
+ if (ret)
+ goto out_unlock;
+
+ ret = dev_priv->gt.init_rings(dev);
+ if (ret)
+ goto out_unlock;
ret = i915_gem_init_hw(dev);
if (ret == -EIO) {
@@ -4962,6 +4902,8 @@ int i915_gem_init(struct drm_device *dev)
atomic_set_mask(I915_WEDGED, &dev_priv->gpu_error.reset_counter);
ret = 0;
}
+
+out_unlock:
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -5062,6 +5004,8 @@ i915_gem_load(struct drm_device *dev)
dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom;
register_oom_notifier(&dev_priv->mm.oom_notifier);
+ i915_gem_batch_pool_init(dev, &dev_priv->mm.batch_pool);
+
mutex_init(&dev_priv->fb_tracking.lock);
}
@@ -5155,7 +5099,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
if (!mutex_is_locked(mutex))
return false;
-#if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES)
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)
return mutex->owner == task;
#else
/* Since UP may be pre-empted, we cannot assume that we own the lock */
@@ -5222,8 +5166,9 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
}
/* All the new VM stuff */
-unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o,
- struct i915_address_space *vm)
+unsigned long i915_gem_obj_offset_view(struct drm_i915_gem_object *o,
+ struct i915_address_space *vm,
+ enum i915_ggtt_view_type view)
{
struct drm_i915_private *dev_priv = o->base.dev->dev_private;
struct i915_vma *vma;
@@ -5231,7 +5176,7 @@ unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o,
WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
list_for_each_entry(vma, &o->vma_list, vma_link) {
- if (vma->vm == vm)
+ if (vma->vm == vm && vma->ggtt_view.type == view)
return vma->node.start;
}
@@ -5240,13 +5185,16 @@ unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o,
return -1;
}
-bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
- struct i915_address_space *vm)
+bool i915_gem_obj_bound_view(struct drm_i915_gem_object *o,
+ struct i915_address_space *vm,
+ enum i915_ggtt_view_type view)
{
struct i915_vma *vma;
list_for_each_entry(vma, &o->vma_list, vma_link)
- if (vma->vm == vm && drm_mm_node_allocated(&vma->node))
+ if (vma->vm == vm &&
+ vma->ggtt_view.type == view &&
+ drm_mm_node_allocated(&vma->node))
return true;
return false;
@@ -5378,11 +5326,13 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr)
struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj)
{
+ struct i915_address_space *ggtt = i915_obj_to_ggtt(obj);
struct i915_vma *vma;
- vma = list_first_entry(&obj->vma_list, typeof(*vma), vma_link);
- if (vma->vm != i915_obj_to_ggtt(obj))
- return NULL;
+ list_for_each_entry(vma, &obj->vma_list, vma_link)
+ if (vma->vm == ggtt &&
+ vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL)
+ return vma;
- return vma;
+ return NULL;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
new file mode 100644
index 000000000000..c690170a1c4f
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "i915_drv.h"
+
+/**
+ * DOC: batch pool
+ *
+ * In order to submit batch buffers as 'secure', the software command parser
+ * must ensure that a batch buffer cannot be modified after parsing. It does
+ * this by copying the user provided batch buffer contents to a kernel owned
+ * buffer from which the hardware will actually execute, and by carefully
+ * managing the address space bindings for such buffers.
+ *
+ * The batch pool framework provides a mechanism for the driver to manage a
+ * set of scratch buffers to use for this purpose. The framework can be
+ * extended to support other uses cases should they arise.
+ */
+
+/**
+ * i915_gem_batch_pool_init() - initialize a batch buffer pool
+ * @dev: the drm device
+ * @pool: the batch buffer pool
+ */
+void i915_gem_batch_pool_init(struct drm_device *dev,
+ struct i915_gem_batch_pool *pool)
+{
+ pool->dev = dev;
+ INIT_LIST_HEAD(&pool->cache_list);
+}
+
+/**
+ * i915_gem_batch_pool_fini() - clean up a batch buffer pool
+ * @pool: the pool to clean up
+ *
+ * Note: Callers must hold the struct_mutex.
+ */
+void i915_gem_batch_pool_fini(struct i915_gem_batch_pool *pool)
+{
+ WARN_ON(!mutex_is_locked(&pool->dev->struct_mutex));
+
+ while (!list_empty(&pool->cache_list)) {
+ struct drm_i915_gem_object *obj =
+ list_first_entry(&pool->cache_list,
+ struct drm_i915_gem_object,
+ batch_pool_list);
+
+ WARN_ON(obj->active);
+
+ list_del_init(&obj->batch_pool_list);
+ drm_gem_object_unreference(&obj->base);
+ }
+}
+
+/**
+ * i915_gem_batch_pool_get() - select a buffer from the pool
+ * @pool: the batch buffer pool
+ * @size: the minimum desired size of the returned buffer
+ *
+ * Finds or allocates a batch buffer in the pool with at least the requested
+ * size. The caller is responsible for any domain, active/inactive, or
+ * purgeability management for the returned buffer.
+ *
+ * Note: Callers must hold the struct_mutex
+ *
+ * Return: the selected batch buffer object
+ */
+struct drm_i915_gem_object *
+i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
+ size_t size)
+{
+ struct drm_i915_gem_object *obj = NULL;
+ struct drm_i915_gem_object *tmp, *next;
+
+ WARN_ON(!mutex_is_locked(&pool->dev->struct_mutex));
+
+ list_for_each_entry_safe(tmp, next,
+ &pool->cache_list, batch_pool_list) {
+
+ if (tmp->active)
+ continue;
+
+ /* While we're looping, do some clean up */
+ if (tmp->madv == __I915_MADV_PURGED) {
+ list_del(&tmp->batch_pool_list);
+ drm_gem_object_unreference(&tmp->base);
+ continue;
+ }
+
+ /*
+ * Select a buffer that is at least as big as needed
+ * but not 'too much' bigger. A better way to do this
+ * might be to bucket the pool objects based on size.
+ */
+ if (tmp->base.size >= size &&
+ tmp->base.size <= (2 * size)) {
+ obj = tmp;
+ break;
+ }
+ }
+
+ if (!obj) {
+ obj = i915_gem_alloc_object(pool->dev, size);
+ if (!obj)
+ return ERR_PTR(-ENOMEM);
+
+ list_add_tail(&obj->batch_pool_list, &pool->cache_list);
+ }
+ else
+ /* Keep list in LRU order */
+ list_move_tail(&obj->batch_pool_list, &pool->cache_list);
+
+ obj->madv = I915_MADV_WILLNEED;
+
+ return obj;
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index d011ec82ef1e..8603bf48d3ee 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -222,6 +222,8 @@ __create_hw_context(struct drm_device *dev,
* is no remap info, it will be a NOP. */
ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;
+ ctx->hang_stats.ban_period_seconds = DRM_I915_CTX_BAN_PERIOD;
+
return ctx;
err_out:
@@ -408,14 +410,25 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
BUG_ON(!dev_priv->ring[RCS].default_context);
- if (i915.enable_execlists)
- return 0;
+ if (i915.enable_execlists) {
+ for_each_ring(ring, dev_priv, i) {
+ if (ring->init_context) {
+ ret = ring->init_context(ring,
+ ring->default_context);
+ if (ret) {
+ DRM_ERROR("ring init context: %d\n",
+ ret);
+ return ret;
+ }
+ }
+ }
- for_each_ring(ring, dev_priv, i) {
- ret = i915_switch_context(ring, ring->default_context);
- if (ret)
- return ret;
- }
+ } else
+ for_each_ring(ring, dev_priv, i) {
+ ret = i915_switch_context(ring, ring->default_context);
+ if (ret)
+ return ret;
+ }
return 0;
}
@@ -611,9 +624,14 @@ static int do_switch(struct intel_engine_cs *ring,
goto unpin_out;
vma = i915_gem_obj_to_ggtt(to->legacy_hw_ctx.rcs_state);
- if (!(vma->bound & GLOBAL_BIND))
- vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level,
- GLOBAL_BIND);
+ if (!(vma->bound & GLOBAL_BIND)) {
+ ret = i915_vma_bind(vma,
+ to->legacy_hw_ctx.rcs_state->cache_level,
+ GLOBAL_BIND);
+ /* This shouldn't ever fail. */
+ if (WARN_ONCE(ret, "GGTT context bind failed!"))
+ goto unpin_out;
+ }
if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
hw_flags |= MI_RESTORE_INHIBIT;
@@ -651,7 +669,8 @@ static int do_switch(struct intel_engine_cs *ring,
* swapped, but there is no way to do that yet.
*/
from->legacy_hw_ctx.rcs_state->dirty = 1;
- BUG_ON(from->legacy_hw_ctx.rcs_state->ring != ring);
+ BUG_ON(i915_gem_request_get_ring(
+ from->legacy_hw_ctx.rcs_state->last_read_req) != ring);
/* obj is kept alive until the next request by its active ref */
i915_gem_object_ggtt_unpin(from->legacy_hw_ctx.rcs_state);
@@ -671,10 +690,6 @@ done:
if (ret)
DRM_ERROR("ring init context: %d\n", ret);
}
-
- ret = i915_gem_render_state_init(ring);
- if (ret)
- DRM_ERROR("init render state: %d\n", ret);
}
return 0;
@@ -779,3 +794,72 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id);
return 0;
}
+
+int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_file_private *file_priv = file->driver_priv;
+ struct drm_i915_gem_context_param *args = data;
+ struct intel_context *ctx;
+ int ret;
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ ctx = i915_gem_context_get(file_priv, args->ctx_id);
+ if (IS_ERR(ctx)) {
+ mutex_unlock(&dev->struct_mutex);
+ return PTR_ERR(ctx);
+ }
+
+ args->size = 0;
+ switch (args->param) {
+ case I915_CONTEXT_PARAM_BAN_PERIOD:
+ args->value = ctx->hang_stats.ban_period_seconds;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_file_private *file_priv = file->driver_priv;
+ struct drm_i915_gem_context_param *args = data;
+ struct intel_context *ctx;
+ int ret;
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ return ret;
+
+ ctx = i915_gem_context_get(file_priv, args->ctx_id);
+ if (IS_ERR(ctx)) {
+ mutex_unlock(&dev->struct_mutex);
+ return PTR_ERR(ctx);
+ }
+
+ switch (args->param) {
+ case I915_CONTEXT_PARAM_BAN_PERIOD:
+ if (args->size)
+ ret = -EINVAL;
+ else if (args->value < ctx->hang_stats.ban_period_seconds &&
+ !capable(CAP_SYS_ADMIN))
+ ret = -EPERM;
+ else
+ ctx->hang_stats.ban_period_seconds = args->value;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 886ff2ee7a28..e3a49d94da3a 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -50,11 +50,12 @@ mark_free(struct i915_vma *vma, struct list_head *unwind)
* i915_gem_evict_something - Evict vmas to make room for binding a new one
* @dev: drm_device
* @vm: address space to evict from
- * @size: size of the desired free space
+ * @min_size: size of the desired free space
* @alignment: alignment constraint of the desired free space
* @cache_level: cache_level for the desired space
- * @mappable: whether the free space must be mappable
- * @nonblocking: whether evicting active objects is allowed or not
+ * @start: start (inclusive) of the range from which to evict objects
+ * @end: end (exclusive) of the range from which to evict objects
+ * @flags: additional flags to control the eviction algorithm
*
* This function will try to evict vmas until a free space satisfying the
* requirements is found. Callers must check first whether any such hole exists
@@ -196,7 +197,6 @@ found:
/**
* i915_gem_evict_vm - Evict all idle vmas from a vm
- *
* @vm: Address space to cleanse
* @do_idle: Boolean directing whether to idle first.
*
@@ -214,6 +214,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
struct i915_vma *vma, *next;
int ret;
+ WARN_ON(!mutex_is_locked(&vm->dev->struct_mutex));
trace_i915_gem_evict_vm(vm);
if (do_idle) {
@@ -222,6 +223,8 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
return ret;
i915_gem_retire_requests(vm->dev);
+
+ WARN_ON(!list_empty(&vm->active_list));
}
list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 11738316394a..b773368fc62c 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -37,6 +37,7 @@
#define __EXEC_OBJECT_HAS_FENCE (1<<30)
#define __EXEC_OBJECT_NEEDS_MAP (1<<29)
#define __EXEC_OBJECT_NEEDS_BIAS (1<<28)
+#define __EXEC_OBJECT_PURGEABLE (1<<27)
#define BATCH_OFFSET_BIAS (256*1024)
@@ -223,7 +224,12 @@ i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
if (entry->flags & __EXEC_OBJECT_HAS_PIN)
vma->pin_count--;
- entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
+ if (entry->flags & __EXEC_OBJECT_PURGEABLE)
+ obj->madv = I915_MADV_DONTNEED;
+
+ entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE |
+ __EXEC_OBJECT_HAS_PIN |
+ __EXEC_OBJECT_PURGEABLE);
}
static void eb_destroy(struct eb_vmas *eb)
@@ -357,9 +363,12 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
* through the ppgtt for non_secure batchbuffers. */
if (unlikely(IS_GEN6(dev) &&
reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
- !(target_vma->bound & GLOBAL_BIND)))
- target_vma->bind_vma(target_vma, target_i915_obj->cache_level,
- GLOBAL_BIND);
+ !(target_vma->bound & GLOBAL_BIND))) {
+ ret = i915_vma_bind(target_vma, target_i915_obj->cache_level,
+ GLOBAL_BIND);
+ if (WARN_ONCE(ret, "Unexpected failure to bind target VMA!"))
+ return ret;
+ }
/* Validate that the target is in a valid r/w GPU domain */
if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
@@ -943,7 +952,7 @@ void
i915_gem_execbuffer_move_to_active(struct list_head *vmas,
struct intel_engine_cs *ring)
{
- u32 seqno = intel_ring_get_seqno(ring);
+ struct drm_i915_gem_request *req = intel_ring_get_request(ring);
struct i915_vma *vma;
list_for_each_entry(vma, vmas, exec_list) {
@@ -960,7 +969,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
i915_vma_move_to_active(vma, ring);
if (obj->base.write_domain) {
obj->dirty = 1;
- obj->last_write_seqno = seqno;
+ i915_gem_request_assign(&obj->last_write_req, req);
intel_fb_obj_invalidate(obj, ring);
@@ -968,7 +977,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
}
if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
- obj->last_fenced_seqno = seqno;
+ i915_gem_request_assign(&obj->last_fenced_req, req);
if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
struct drm_i915_private *dev_priv = to_i915(ring->dev);
list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
@@ -990,7 +999,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev,
ring->gpu_caches_dirty = true;
/* Add a breadcrumb for the completion of the batch buffer */
- (void)__i915_add_request(ring, file, obj, NULL);
+ (void)__i915_add_request(ring, file, obj);
}
static int
@@ -1060,6 +1069,67 @@ i915_emit_box(struct intel_engine_cs *ring,
return 0;
}
+static struct drm_i915_gem_object*
+i915_gem_execbuffer_parse(struct intel_engine_cs *ring,
+ struct drm_i915_gem_exec_object2 *shadow_exec_entry,
+ struct eb_vmas *eb,
+ struct drm_i915_gem_object *batch_obj,
+ u32 batch_start_offset,
+ u32 batch_len,
+ bool is_master,
+ u32 *flags)
+{
+ struct drm_i915_private *dev_priv = to_i915(batch_obj->base.dev);
+ struct drm_i915_gem_object *shadow_batch_obj;
+ bool need_reloc = false;
+ int ret;
+
+ shadow_batch_obj = i915_gem_batch_pool_get(&dev_priv->mm.batch_pool,
+ batch_obj->base.size);
+ if (IS_ERR(shadow_batch_obj))
+ return shadow_batch_obj;
+
+ ret = i915_parse_cmds(ring,
+ batch_obj,
+ shadow_batch_obj,
+ batch_start_offset,
+ batch_len,
+ is_master);
+ if (ret) {
+ if (ret == -EACCES)
+ return batch_obj;
+ } else {
+ struct i915_vma *vma;
+
+ memset(shadow_exec_entry, 0, sizeof(*shadow_exec_entry));
+
+ vma = i915_gem_obj_to_ggtt(shadow_batch_obj);
+ vma->exec_entry = shadow_exec_entry;
+ vma->exec_entry->flags = __EXEC_OBJECT_PURGEABLE;
+ drm_gem_object_reference(&shadow_batch_obj->base);
+ i915_gem_execbuffer_reserve_vma(vma, ring, &need_reloc);
+ list_add_tail(&vma->exec_list, &eb->vmas);
+
+ shadow_batch_obj->base.pending_read_domains =
+ batch_obj->base.pending_read_domains;
+
+ /*
+ * Set the DISPATCH_SECURE bit to remove the NON_SECURE
+ * bit from MI_BATCH_BUFFER_START commands issued in the
+ * dispatch_execbuffer implementations. We specifically
+ * don't want that set when the command parser is
+ * enabled.
+ *
+ * FIXME: with aliasing ppgtt, buffers that should only
+ * be in ggtt still end up in the aliasing ppgtt. remove
+ * this check when that is fixed.
+ */
+ if (USES_FULL_PPGTT(dev))
+ *flags |= I915_DISPATCH_SECURE;
+ }
+
+ return ret ? ERR_PTR(ret) : shadow_batch_obj;
+}
int
i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
@@ -1208,7 +1278,7 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
return ret;
}
- trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
+ trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), flags);
i915_gem_execbuffer_move_to_active(vmas, ring);
i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
@@ -1277,6 +1347,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_private *dev_priv = dev->dev_private;
struct eb_vmas *eb;
struct drm_i915_gem_object *batch_obj;
+ struct drm_i915_gem_exec_object2 shadow_exec_entry;
struct intel_engine_cs *ring;
struct intel_context *ctx;
struct i915_address_space *vm;
@@ -1309,13 +1380,35 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}
+ if (((args->flags & I915_EXEC_RING_MASK) != I915_EXEC_BSD) &&
+ ((args->flags & I915_EXEC_BSD_MASK) != 0)) {
+ DRM_DEBUG("execbuf with non bsd ring but with invalid "
+ "bsd dispatch flags: %d\n", (int)(args->flags));
+ return -EINVAL;
+ }
+
if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_DEFAULT)
ring = &dev_priv->ring[RCS];
else if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_BSD) {
if (HAS_BSD2(dev)) {
int ring_id;
- ring_id = gen8_dispatch_bsd_ring(dev, file);
- ring = &dev_priv->ring[ring_id];
+
+ switch (args->flags & I915_EXEC_BSD_MASK) {
+ case I915_EXEC_BSD_DEFAULT:
+ ring_id = gen8_dispatch_bsd_ring(dev, file);
+ ring = &dev_priv->ring[ring_id];
+ break;
+ case I915_EXEC_BSD_RING1:
+ ring = &dev_priv->ring[VCS];
+ break;
+ case I915_EXEC_BSD_RING2:
+ ring = &dev_priv->ring[VCS2];
+ break;
+ default:
+ DRM_DEBUG("execbuf with unknown bsd ring: %d\n",
+ (int)(args->flags & I915_EXEC_BSD_MASK));
+ return -EINVAL;
+ }
} else
ring = &dev_priv->ring[VCS];
} else
@@ -1393,28 +1486,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
ret = -EINVAL;
goto err;
}
- batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
if (i915_needs_cmd_parser(ring)) {
- ret = i915_parse_cmds(ring,
- batch_obj,
- args->batch_start_offset,
- file->is_master);
- if (ret) {
- if (ret != -EACCES)
- goto err;
- } else {
- /*
- * XXX: Actually do this when enabling batch copy...
- *
- * Set the DISPATCH_SECURE bit to remove the NON_SECURE bit
- * from MI_BATCH_BUFFER_START commands issued in the
- * dispatch_execbuffer implementations. We specifically don't
- * want that set when the command parser is enabled.
- */
+ batch_obj = i915_gem_execbuffer_parse(ring,
+ &shadow_exec_entry,
+ eb,
+ batch_obj,
+ args->batch_start_offset,
+ args->batch_len,
+ file->is_master,
+ &flags);
+ if (IS_ERR(batch_obj)) {
+ ret = PTR_ERR(batch_obj);
+ goto err;
}
}
+ batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
+
/* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
* batch" bit. Hence we need to pin secure batches into the global gtt.
* hsw should have this fixed, but bdw mucks it up again. */
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 171f6eafdeee..746f77fb57a3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -30,6 +30,68 @@
#include "i915_trace.h"
#include "intel_drv.h"
+/**
+ * DOC: Global GTT views
+ *
+ * Background and previous state
+ *
+ * Historically objects could exists (be bound) in global GTT space only as
+ * singular instances with a view representing all of the object's backing pages
+ * in a linear fashion. This view will be called a normal view.
+ *
+ * To support multiple views of the same object, where the number of mapped
+ * pages is not equal to the backing store, or where the layout of the pages
+ * is not linear, concept of a GGTT view was added.
+ *
+ * One example of an alternative view is a stereo display driven by a single
+ * image. In this case we would have a framebuffer looking like this
+ * (2x2 pages):
+ *
+ * 12
+ * 34
+ *
+ * Above would represent a normal GGTT view as normally mapped for GPU or CPU
+ * rendering. In contrast, fed to the display engine would be an alternative
+ * view which could look something like this:
+ *
+ * 1212
+ * 3434
+ *
+ * In this example both the size and layout of pages in the alternative view is
+ * different from the normal view.
+ *
+ * Implementation and usage
+ *
+ * GGTT views are implemented using VMAs and are distinguished via enum
+ * i915_ggtt_view_type and struct i915_ggtt_view.
+ *
+ * A new flavour of core GEM functions which work with GGTT bound objects were
+ * added with the _view suffix. They take the struct i915_ggtt_view parameter
+ * encapsulating all metadata required to implement a view.
+ *
+ * As a helper for callers which are only interested in the normal view,
+ * globally const i915_ggtt_view_normal singleton instance exists. All old core
+ * GEM API functions, the ones not taking the view parameter, are operating on,
+ * or with the normal GGTT view.
+ *
+ * Code wanting to add or use a new GGTT view needs to:
+ *
+ * 1. Add a new enum with a suitable name.
+ * 2. Extend the metadata in the i915_ggtt_view structure if required.
+ * 3. Add support to i915_get_vma_pages().
+ *
+ * New views are required to build a scatter-gather table from within the
+ * i915_get_vma_pages function. This table is stored in the vma.ggtt_view and
+ * exists for the lifetime of an VMA.
+ *
+ * Core API is designed to have copy semantics which means that passed in
+ * struct i915_ggtt_view does not need to be persistent (left around after
+ * calling the core API functions).
+ *
+ */
+
+const struct i915_ggtt_view i915_ggtt_view_normal;
+
static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv);
static void chv_setup_private_ppat(struct drm_i915_private *dev_priv);
@@ -40,8 +102,6 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6;
has_full_ppgtt = INTEL_INFO(dev)->gen >= 7;
- if (IS_GEN8(dev))
- has_full_ppgtt = false; /* XXX why? */
/*
* We don't allow disabling PPGTT for gen9+ as it's a requirement for
@@ -72,7 +132,10 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
return 0;
}
- return has_aliasing_ppgtt ? 1 : 0;
+ if (INTEL_INFO(dev)->gen >= 8 && i915.enable_execlists)
+ return 2;
+ else
+ return has_aliasing_ppgtt ? 1 : 0;
}
@@ -132,7 +195,7 @@ static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
pte |= GEN6_PTE_UNCACHED;
break;
default:
- WARN_ON(1);
+ MISSING_CASE(level);
}
return pte;
@@ -156,7 +219,7 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
pte |= GEN6_PTE_UNCACHED;
break;
default:
- WARN_ON(1);
+ MISSING_CASE(level);
}
return pte;
@@ -1102,10 +1165,8 @@ static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
if (INTEL_INFO(dev)->gen < 8)
return gen6_ppgtt_init(ppgtt);
- else if (IS_GEN8(dev) || IS_GEN9(dev))
- return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total);
else
- BUG();
+ return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total);
}
int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
{
@@ -1146,7 +1207,7 @@ int i915_ppgtt_init_hw(struct drm_device *dev)
else if (INTEL_INFO(dev)->gen >= 8)
gen8_ppgtt_enable(dev);
else
- WARN_ON(1);
+ MISSING_CASE(INTEL_INFO(dev)->gen);
if (ppgtt) {
for_each_ring(ring, dev_priv, i) {
@@ -1341,9 +1402,12 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
/* The bind_vma code tries to be smart about tracking mappings.
* Unfortunately above, we've just wiped out the mappings
* without telling our object about it. So we need to fake it.
+ *
+ * Bind is not expected to fail since this is only called on
+ * resume and assumption is all requirements exist already.
*/
vma->bound &= ~GLOBAL_BIND;
- vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND);
+ WARN_ON(i915_vma_bind(vma, obj->cache_level, GLOBAL_BIND));
}
@@ -1538,7 +1602,7 @@ static void i915_ggtt_bind_vma(struct i915_vma *vma,
AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY;
BUG_ON(!i915_is_ggtt(vma->vm));
- intel_gtt_insert_sg_entries(vma->obj->pages, entry, flags);
+ intel_gtt_insert_sg_entries(vma->ggtt_view.pages, entry, flags);
vma->bound = GLOBAL_BIND;
}
@@ -1588,7 +1652,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) {
if (!(vma->bound & GLOBAL_BIND) ||
(cache_level != obj->cache_level)) {
- vma->vm->insert_entries(vma->vm, obj->pages,
+ vma->vm->insert_entries(vma->vm, vma->ggtt_view.pages,
vma->node.start,
cache_level, flags);
vma->bound |= GLOBAL_BIND;
@@ -1600,7 +1664,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
(cache_level != obj->cache_level))) {
struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
appgtt->base.insert_entries(&appgtt->base,
- vma->obj->pages,
+ vma->ggtt_view.pages,
vma->node.start,
cache_level, flags);
vma->bound |= LOCAL_BIND;
@@ -2165,7 +2229,8 @@ int i915_gem_gtt_init(struct drm_device *dev)
}
static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm)
+ struct i915_address_space *vm,
+ const struct i915_ggtt_view *view)
{
struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL);
if (vma == NULL)
@@ -2176,12 +2241,9 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
INIT_LIST_HEAD(&vma->exec_list);
vma->vm = vm;
vma->obj = obj;
+ vma->ggtt_view = *view;
- switch (INTEL_INFO(vm->dev)->gen) {
- case 9:
- case 8:
- case 7:
- case 6:
+ if (INTEL_INFO(vm->dev)->gen >= 6) {
if (i915_is_ggtt(vm)) {
vma->unbind_vma = ggtt_unbind_vma;
vma->bind_vma = ggtt_bind_vma;
@@ -2189,39 +2251,73 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj,
vma->unbind_vma = ppgtt_unbind_vma;
vma->bind_vma = ppgtt_bind_vma;
}
- break;
- case 5:
- case 4:
- case 3:
- case 2:
+ } else {
BUG_ON(!i915_is_ggtt(vm));
vma->unbind_vma = i915_ggtt_unbind_vma;
vma->bind_vma = i915_ggtt_bind_vma;
- break;
- default:
- BUG();
}
- /* Keep GGTT vmas first to make debug easier */
- if (i915_is_ggtt(vm))
- list_add(&vma->vma_link, &obj->vma_list);
- else {
- list_add_tail(&vma->vma_link, &obj->vma_list);
+ list_add_tail(&vma->vma_link, &obj->vma_list);
+ if (!i915_is_ggtt(vm))
i915_ppgtt_get(i915_vm_to_ppgtt(vm));
- }
return vma;
}
struct i915_vma *
-i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
- struct i915_address_space *vm)
+i915_gem_obj_lookup_or_create_vma_view(struct drm_i915_gem_object *obj,
+ struct i915_address_space *vm,
+ const struct i915_ggtt_view *view)
{
struct i915_vma *vma;
- vma = i915_gem_obj_to_vma(obj, vm);
+ vma = i915_gem_obj_to_vma_view(obj, vm, view);
if (!vma)
- vma = __i915_gem_vma_create(obj, vm);
+ vma = __i915_gem_vma_create(obj, vm, view);
return vma;
}
+
+static inline
+int i915_get_vma_pages(struct i915_vma *vma)
+{
+ if (vma->ggtt_view.pages)
+ return 0;
+
+ if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL)
+ vma->ggtt_view.pages = vma->obj->pages;
+ else
+ WARN_ONCE(1, "GGTT view %u not implemented!\n",
+ vma->ggtt_view.type);
+
+ if (!vma->ggtt_view.pages) {
+ DRM_ERROR("Failed to get pages for VMA view type %u!\n",
+ vma->ggtt_view.type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * i915_vma_bind - Sets up PTEs for an VMA in it's corresponding address space.
+ * @vma: VMA to map
+ * @cache_level: mapping cache level
+ * @flags: flags like global or local mapping
+ *
+ * DMA addresses are taken from the scatter-gather table of this object (or of
+ * this VMA in case of non-default GGTT views) and PTE entries set up.
+ * Note that DMA addresses are also the only part of the SG table we care about.
+ */
+int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
+ u32 flags)
+{
+ int ret = i915_get_vma_pages(vma);
+
+ if (ret)
+ return ret;
+
+ vma->bind_vma(vma, cache_level, flags);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index beaf4bcfdac8..e377c7d27bd4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -109,7 +109,20 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
#define GEN8_PPAT_ELLC_OVERRIDE (0<<2)
#define GEN8_PPAT(i, x) ((uint64_t) (x) << ((i) * 8))
+enum i915_ggtt_view_type {
+ I915_GGTT_VIEW_NORMAL = 0,
+};
+
+struct i915_ggtt_view {
+ enum i915_ggtt_view_type type;
+
+ struct sg_table *pages;
+};
+
+extern const struct i915_ggtt_view i915_ggtt_view_normal;
+
enum i915_cache_level;
+
/**
* A VMA represents a GEM BO that is bound into an address space. Therefore, a
* VMA's presence cannot be guaranteed before binding, or after unbinding the
@@ -129,6 +142,15 @@ struct i915_vma {
#define PTE_READ_ONLY (1<<2)
unsigned int bound : 4;
+ /**
+ * Support different GGTT views into the same object.
+ * This means there can be multiple VMA mappings per object and per VM.
+ * i915_ggtt_view_type is used to distinguish between those entries.
+ * The default one of zero (I915_GGTT_VIEW_NORMAL) is default and also
+ * assumed in GEM functions which take no ggtt view parameter.
+ */
+ struct i915_ggtt_view ggtt_view;
+
/** This object's place on the active/inactive lists */
struct list_head mm_list;
@@ -146,11 +168,10 @@ struct i915_vma {
/**
* How many users have pinned this object in GTT space. The following
- * users can each hold at most one reference: pwrite/pread, pin_ioctl
- * (via user_pin_count), execbuffer (objects are not allowed multiple
- * times for the same batchbuffer), and the framebuffer code. When
- * switching/pageflipping, the framebuffer code has at most two buffers
- * pinned per crtc.
+ * users can each hold at most one reference: pwrite/pread, execbuffer
+ * (objects are not allowed multiple times for the same batchbuffer),
+ * and the framebuffer code. When switching/pageflipping, the
+ * framebuffer code has at most two buffers pinned per crtc.
*
* 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. */
@@ -182,7 +203,7 @@ struct i915_address_space {
* List of objects currently involved in rendering.
*
* Includes buffers having the contents of their GPU caches
- * flushed, not necessarily primitives. last_rendering_seqno
+ * flushed, not necessarily primitives. last_read_req
* represents when the rendering involved will be completed.
*
* A reference is held on the buffer while on this list.
@@ -193,7 +214,7 @@ struct i915_address_space {
* LRU list of objects which are not in the ringbuffer and
* are ready to unbind, but are still in the GTT.
*
- * last_rendering_seqno is 0 while an object is in this list.
+ * last_read_req is NULL while an object is in this list.
*
* A reference is not held on the buffer while on this list,
* as merely being GTT-bound shouldn't prevent its being
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 98dcd94acba8..521548a08578 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -173,7 +173,7 @@ int i915_gem_render_state_init(struct intel_engine_cs *ring)
i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
- ret = __i915_add_request(ring, NULL, so.obj, NULL);
+ ret = __i915_add_request(ring, NULL, so.obj);
/* __i915_add_request moves object to inactive if it fails */
out:
i915_gem_render_state_fini(&so);
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 4727a4e2c87c..7a24bd1a51f6 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -399,7 +399,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
}
obj->fence_dirty =
- obj->last_fenced_seqno ||
+ obj->last_fenced_req ||
obj->fence_reg != I915_FENCE_REG_NONE;
obj->tiling_mode = args->tiling_mode;
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index d182058383a9..1719078c763a 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -113,7 +113,10 @@ restart:
continue;
obj = mo->obj;
- drm_gem_object_reference(&obj->base);
+
+ if (!kref_get_unless_zero(&obj->base.refcount))
+ continue;
+
spin_unlock(&mn->lock);
cancel_userptr(obj);
@@ -149,7 +152,20 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
it = interval_tree_iter_first(&mn->objects, start, end);
if (it != NULL) {
obj = container_of(it, struct i915_mmu_object, it)->obj;
- drm_gem_object_reference(&obj->base);
+
+ /* The mmu_object is released late when destroying the
+ * GEM object so it is entirely possible to gain a
+ * reference on an object in the process of being freed
+ * since our serialisation is via the spinlock and not
+ * the struct_mutex - and consequently use it after it
+ * is freed and then double free it.
+ */
+ if (!kref_get_unless_zero(&obj->base.refcount)) {
+ spin_unlock(&mn->lock);
+ serial = 0;
+ continue;
+ }
+
serial = mn->serial;
}
spin_unlock(&mn->lock);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index cdaee6ce05f8..48ddbf44c862 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -670,8 +670,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
err->size = obj->base.size;
err->name = obj->base.name;
- err->rseqno = obj->last_read_seqno;
- err->wseqno = obj->last_write_seqno;
+ err->rseqno = i915_gem_request_get_seqno(obj->last_read_req);
+ err->wseqno = i915_gem_request_get_seqno(obj->last_write_req);
err->gtt_offset = vma->node.start;
err->read_domains = obj->base.read_domains;
err->write_domain = obj->base.write_domain;
@@ -679,13 +679,12 @@ static void capture_bo(struct drm_i915_error_buffer *err,
err->pinned = 0;
if (i915_gem_obj_is_pinned(obj))
err->pinned = 1;
- if (obj->user_pin_count > 0)
- err->pinned = -1;
err->tiling = obj->tiling_mode;
err->dirty = obj->dirty;
err->purgeable = obj->madv != I915_MADV_WILLNEED;
err->userptr = obj->userptr.mm != NULL;
- err->ring = obj->ring ? obj->ring->id : -1;
+ err->ring = obj->last_read_req ?
+ i915_gem_request_get_ring(obj->last_read_req)->id : -1;
err->cache_level = obj->cache_level;
}
@@ -719,10 +718,8 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer *err,
break;
list_for_each_entry(vma, &obj->vma_list, vma_link)
- if (vma->vm == vm && vma->pin_count > 0) {
+ if (vma->vm == vm && vma->pin_count > 0)
capture_bo(err++, vma);
- break;
- }
}
return err - first;
@@ -767,32 +764,21 @@ static void i915_gem_record_fences(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
- /* Fences */
- switch (INTEL_INFO(dev)->gen) {
- case 9:
- case 8:
- case 7:
- case 6:
- for (i = 0; i < dev_priv->num_fence_regs; i++)
- error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
- break;
- case 5:
- case 4:
- for (i = 0; i < 16; i++)
- error->fence[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
- break;
- case 3:
- if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
- for (i = 0; i < 8; i++)
- error->fence[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
- case 2:
+ if (IS_GEN3(dev) || IS_GEN2(dev)) {
for (i = 0; i < 8; i++)
error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
- break;
-
- default:
- BUG();
- }
+ if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
+ for (i = 0; i < 8; i++)
+ error->fence[i+8] = I915_READ(FENCE_REG_945_8 +
+ (i * 4));
+ } else if (IS_GEN5(dev) || IS_GEN4(dev))
+ for (i = 0; i < 16; i++)
+ error->fence[i] = I915_READ64(FENCE_REG_965_0 +
+ (i * 8));
+ else if (INTEL_INFO(dev)->gen >= 6)
+ for (i = 0; i < dev_priv->num_fence_regs; i++)
+ error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 +
+ (i * 8));
}
@@ -926,9 +912,13 @@ static void i915_record_ring_state(struct drm_device *dev,
ering->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(ring));
- switch (INTEL_INFO(dev)->gen) {
- case 9:
- case 8:
+ if (IS_GEN6(dev))
+ ering->vm_info.pp_dir_base =
+ I915_READ(RING_PP_DIR_BASE_READ(ring));
+ else if (IS_GEN7(dev))
+ ering->vm_info.pp_dir_base =
+ I915_READ(RING_PP_DIR_BASE(ring));
+ else if (INTEL_INFO(dev)->gen >= 8)
for (i = 0; i < 4; i++) {
ering->vm_info.pdp[i] =
I915_READ(GEN8_RING_PDP_UDW(ring, i));
@@ -936,16 +926,6 @@ static void i915_record_ring_state(struct drm_device *dev,
ering->vm_info.pdp[i] |=
I915_READ(GEN8_RING_PDP_LDW(ring, i));
}
- break;
- case 7:
- ering->vm_info.pp_dir_base =
- I915_READ(RING_PP_DIR_BASE(ring));
- break;
- case 6:
- ering->vm_info.pp_dir_base =
- I915_READ(RING_PP_DIR_BASE_READ(ring));
- break;
- }
}
}
@@ -1072,7 +1052,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
erq = &error->ring[i].requests[count++];
erq->seqno = request->seqno;
erq->jiffies = request->emitted_jiffies;
- erq->tail = request->tail;
+ erq->tail = request->postfix;
}
}
}
@@ -1097,10 +1077,8 @@ static void i915_gem_capture_vm(struct drm_i915_private *dev_priv,
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
list_for_each_entry(vma, &obj->vma_list, vma_link)
- if (vma->vm == vm && vma->pin_count > 0) {
+ if (vma->vm == vm && vma->pin_count > 0)
i++;
- break;
- }
}
error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx];
@@ -1378,26 +1356,15 @@ void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone)
struct drm_i915_private *dev_priv = dev->dev_private;
memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG);
- switch (INTEL_INFO(dev)->gen) {
- case 2:
- case 3:
+ if (IS_GEN2(dev) || IS_GEN3(dev))
instdone[0] = I915_READ(INSTDONE);
- break;
- case 4:
- case 5:
- case 6:
+ else if (IS_GEN4(dev) || IS_GEN5(dev) || IS_GEN6(dev)) {
instdone[0] = I915_READ(INSTDONE_I965);
instdone[1] = I915_READ(INSTDONE1);
- break;
- default:
- WARN_ONCE(1, "Unsupported platform\n");
- case 7:
- case 8:
- case 9:
+ } else if (INTEL_INFO(dev)->gen >= 7) {
instdone[0] = I915_READ(GEN7_INSTDONE_1);
instdone[1] = I915_READ(GEN7_SC_INSTDONE);
instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
instdone[3] = I915_READ(GEN7_ROW_INSTDONE);
- break;
}
}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b051a238baf9..4145d95902f5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -45,7 +45,7 @@
* and related files, but that will be described in separate chapters.
*/
-static const u32 hpd_ibx[] = {
+static const u32 hpd_ibx[HPD_NUM_PINS] = {
[HPD_CRT] = SDE_CRT_HOTPLUG,
[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
[HPD_PORT_B] = SDE_PORTB_HOTPLUG,
@@ -53,7 +53,7 @@ static const u32 hpd_ibx[] = {
[HPD_PORT_D] = SDE_PORTD_HOTPLUG
};
-static const u32 hpd_cpt[] = {
+static const u32 hpd_cpt[HPD_NUM_PINS] = {
[HPD_CRT] = SDE_CRT_HOTPLUG_CPT,
[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG_CPT,
[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
@@ -61,7 +61,7 @@ static const u32 hpd_cpt[] = {
[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
};
-static const u32 hpd_mask_i915[] = {
+static const u32 hpd_mask_i915[HPD_NUM_PINS] = {
[HPD_CRT] = CRT_HOTPLUG_INT_EN,
[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN,
@@ -70,7 +70,7 @@ static const u32 hpd_mask_i915[] = {
[HPD_PORT_D] = PORTD_HOTPLUG_INT_EN
};
-static const u32 hpd_status_g4x[] = {
+static const u32 hpd_status_g4x[HPD_NUM_PINS] = {
[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X,
[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X,
@@ -79,7 +79,7 @@ static const u32 hpd_status_g4x[] = {
[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
};
-static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
+static const u32 hpd_status_i915[HPD_NUM_PINS] = { /* i915 and valleyview are the same */
[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915,
@@ -183,6 +183,8 @@ static void ilk_update_gt_irq(struct drm_i915_private *dev_priv,
{
assert_spin_locked(&dev_priv->irq_lock);
+ WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
@@ -229,6 +231,8 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
{
uint32_t new_val;
+ WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
assert_spin_locked(&dev_priv->irq_lock);
new_val = dev_priv->pm_irq_mask;
@@ -348,6 +352,8 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
sdeimr &= ~interrupt_mask;
sdeimr |= (~enabled_irq_mask & interrupt_mask);
+ WARN_ON(enabled_irq_mask & ~interrupt_mask);
+
assert_spin_locked(&dev_priv->irq_lock);
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
@@ -587,7 +593,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
struct intel_crtc *intel_crtc =
to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
const struct drm_display_mode *mode =
- &intel_crtc->config.adjusted_mode;
+ &intel_crtc->config->base.adjusted_mode;
htotal = mode->crtc_htotal;
hsync_start = mode->crtc_hsync_start;
@@ -658,7 +664,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
+ const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
enum pipe pipe = crtc->pipe;
int position, vtotal;
@@ -685,7 +691,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
+ const struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode;
int position;
int vbl_start, vbl_end, hsync_start, htotal, vtotal;
bool in_vbl = true;
@@ -843,7 +849,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
vblank_time, flags,
crtc,
- &to_intel_crtc(crtc)->config.adjusted_mode);
+ &to_intel_crtc(crtc)->config->base.adjusted_mode);
}
static bool intel_hpd_irq_event(struct drm_device *dev,
@@ -873,7 +879,7 @@ static void i915_digport_work_func(struct work_struct *work)
container_of(work, struct drm_i915_private, dig_port_work);
u32 long_port_mask, short_port_mask;
struct intel_digital_port *intel_dig_port;
- int i, ret;
+ int i;
u32 old_bits = 0;
spin_lock_irq(&dev_priv->irq_lock);
@@ -897,9 +903,11 @@ static void i915_digport_work_func(struct work_struct *work)
valid = true;
if (valid) {
+ enum irqreturn ret;
+
ret = intel_dig_port->hpd_pulse(intel_dig_port, long_hpd);
- if (ret == true) {
- /* if we get true fallback to old school hpd */
+ if (ret == IRQ_NONE) {
+ /* fall back to old school hpd */
old_bits |= (1 << intel_dig_port->base.hpd_pin);
}
}
@@ -1033,7 +1041,7 @@ static void notify_ring(struct drm_device *dev,
if (!intel_ring_initialized(ring))
return;
- trace_i915_gem_request_complete(ring);
+ trace_i915_gem_request_notify(ring);
wake_up_all(&ring->irq_queue);
}
@@ -1399,14 +1407,14 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
if (rcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, ring);
if (rcs & GT_CONTEXT_SWITCH_INTERRUPT)
- intel_execlists_handle_ctx_events(ring);
+ intel_lrc_irq_handler(ring);
bcs = tmp >> GEN8_BCS_IRQ_SHIFT;
ring = &dev_priv->ring[BCS];
if (bcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, ring);
if (bcs & GT_CONTEXT_SWITCH_INTERRUPT)
- intel_execlists_handle_ctx_events(ring);
+ intel_lrc_irq_handler(ring);
} else
DRM_ERROR("The master control interrupt lied (GT0)!\n");
}
@@ -1422,14 +1430,14 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
if (vcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, ring);
if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
- intel_execlists_handle_ctx_events(ring);
+ intel_lrc_irq_handler(ring);
vcs = tmp >> GEN8_VCS2_IRQ_SHIFT;
ring = &dev_priv->ring[VCS2];
if (vcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, ring);
if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
- intel_execlists_handle_ctx_events(ring);
+ intel_lrc_irq_handler(ring);
} else
DRM_ERROR("The master control interrupt lied (GT1)!\n");
}
@@ -1456,7 +1464,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
if (vcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, ring);
if (vcs & GT_CONTEXT_SWITCH_INTERRUPT)
- intel_execlists_handle_ctx_events(ring);
+ intel_lrc_irq_handler(ring);
} else
DRM_ERROR("The master control interrupt lied (GT3)!\n");
}
@@ -1516,7 +1524,7 @@ static inline enum port get_port_from_pin(enum hpd_pin pin)
static inline void intel_hpd_irq_handler(struct drm_device *dev,
u32 hotplug_trigger,
u32 dig_hotplug_reg,
- const u32 *hpd)
+ const u32 hpd[HPD_NUM_PINS])
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
@@ -2413,19 +2421,15 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv,
}
/**
- * i915_error_work_func - do process context error handling work
- * @work: work struct
+ * i915_reset_and_wakeup - do process context error handling work
*
* Fire an error uevent so userspace can see that a hang or error
* was detected.
*/
-static void i915_error_work_func(struct work_struct *work)
+static void i915_reset_and_wakeup(struct drm_device *dev)
{
- struct i915_gpu_error *error = container_of(work, struct i915_gpu_error,
- work);
- struct drm_i915_private *dev_priv =
- container_of(error, struct drm_i915_private, gpu_error);
- struct drm_device *dev = dev_priv->dev;
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct i915_gpu_error *error = &dev_priv->gpu_error;
char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL };
@@ -2592,10 +2596,10 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
}
/**
- * i915_handle_error - handle an error interrupt
+ * i915_handle_error - handle a gpu error
* @dev: drm device
*
- * Do some basic checking of regsiter state at error interrupt time and
+ * Do some basic checking of regsiter state at error time and
* dump it to the syslog. Also call i915_capture_error_state() to make
* sure we get a record and make it available in debugfs. Fire a uevent
* so userspace knows something bad happened (should trigger collection
@@ -2620,9 +2624,9 @@ void i915_handle_error(struct drm_device *dev, bool wedged,
&dev_priv->gpu_error.reset_counter);
/*
- * Wakeup waiting processes so that the reset work function
- * i915_error_work_func doesn't deadlock trying to grab various
- * locks. By bumping the reset counter first, the woken
+ * Wakeup waiting processes so that the reset function
+ * i915_reset_and_wakeup doesn't deadlock trying to grab
+ * various locks. By bumping the reset counter first, the woken
* processes will see a reset in progress and back off,
* releasing their locks and then wait for the reset completion.
* We must do this for _all_ gpu waiters that might hold locks
@@ -2635,13 +2639,7 @@ void i915_handle_error(struct drm_device *dev, bool wedged,
i915_error_wake_up(dev_priv, false);
}
- /*
- * Our reset work can grab modeset locks (since it needs to reset the
- * state of outstanding pagelips). Hence it must not be run on our own
- * dev-priv->wq work queue for otherwise the flush_work in the pageflip
- * code will deadlock.
- */
- schedule_work(&dev_priv->gpu_error.work);
+ i915_reset_and_wakeup(dev);
}
/* Called from drm generic code, passed 'crtc' which
@@ -2769,18 +2767,18 @@ static void gen8_disable_vblank(struct drm_device *dev, int pipe)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}
-static u32
-ring_last_seqno(struct intel_engine_cs *ring)
+static struct drm_i915_gem_request *
+ring_last_request(struct intel_engine_cs *ring)
{
return list_entry(ring->request_list.prev,
- struct drm_i915_gem_request, list)->seqno;
+ struct drm_i915_gem_request, list);
}
static bool
-ring_idle(struct intel_engine_cs *ring, u32 seqno)
+ring_idle(struct intel_engine_cs *ring)
{
return (list_empty(&ring->request_list) ||
- i915_seqno_passed(seqno, ring_last_seqno(ring)));
+ i915_gem_request_completed(ring_last_request(ring), false));
}
static bool
@@ -2966,7 +2964,7 @@ ring_stuck(struct intel_engine_cs *ring, u64 acthd)
return HANGCHECK_HUNG;
}
-/**
+/*
* This is called when the chip hasn't reported back with completed
* batchbuffers in a long time. We keep track per ring seqno progress and
* if there are no progress, hangcheck score for that ring is increased.
@@ -2974,10 +2972,12 @@ ring_stuck(struct intel_engine_cs *ring, u64 acthd)
* we kick the ring. If we see no progress on three subsequent calls
* we assume chip is wedged and try to fix it by resetting the chip.
*/
-static void i915_hangcheck_elapsed(unsigned long data)
+static void i915_hangcheck_elapsed(struct work_struct *work)
{
- struct drm_device *dev = (struct drm_device *)data;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_private *dev_priv =
+ container_of(work, typeof(*dev_priv),
+ gpu_error.hangcheck_work.work);
+ struct drm_device *dev = dev_priv->dev;
struct intel_engine_cs *ring;
int i;
int busy_count = 0, rings_hung = 0;
@@ -3000,7 +3000,7 @@ static void i915_hangcheck_elapsed(unsigned long data)
acthd = intel_ring_get_active_head(ring);
if (ring->hangcheck.seqno == seqno) {
- if (ring_idle(ring, seqno)) {
+ if (ring_idle(ring)) {
ring->hangcheck.action = HANGCHECK_IDLE;
if (waitqueue_active(&ring->irq_queue)) {
@@ -3091,17 +3091,18 @@ static void i915_hangcheck_elapsed(unsigned long data)
void i915_queue_hangcheck(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct timer_list *timer = &dev_priv->gpu_error.hangcheck_timer;
+ struct i915_gpu_error *e = &to_i915(dev)->gpu_error;
if (!i915.enable_hangcheck)
return;
- /* Don't continually defer the hangcheck, but make sure it is active */
- if (timer_pending(timer))
- return;
- mod_timer(timer,
- round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES));
+ /* Don't continually defer the hangcheck so that it is always run at
+ * least once after work has been scheduled on any ring. Otherwise,
+ * we will ignore a hung ring if a second ring is kept busy.
+ */
+
+ queue_delayed_work(e->hangcheck_wq, &e->hangcheck_work,
+ round_jiffies_up_relative(DRM_I915_HANGCHECK_JIFFIES));
}
static void ibx_irq_reset(struct drm_device *dev)
@@ -4139,26 +4140,24 @@ static void i915_hpd_irq_setup(struct drm_device *dev)
assert_spin_locked(&dev_priv->irq_lock);
- if (I915_HAS_HOTPLUG(dev)) {
- hotplug_en = I915_READ(PORT_HOTPLUG_EN);
- hotplug_en &= ~HOTPLUG_INT_EN_MASK;
- /* Note HDMI and DP share hotplug bits */
- /* enable bits are the same for all generations */
- for_each_intel_encoder(dev, intel_encoder)
- if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED)
- hotplug_en |= hpd_mask_i915[intel_encoder->hpd_pin];
- /* Programming the CRT detection parameters tends
- to generate a spurious hotplug event about three
- seconds later. So just do it once.
- */
- if (IS_G4X(dev))
- hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
- hotplug_en &= ~CRT_HOTPLUG_VOLTAGE_COMPARE_MASK;
- hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
-
- /* Ignore TV since it's buggy */
- I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
- }
+ hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+ hotplug_en &= ~HOTPLUG_INT_EN_MASK;
+ /* Note HDMI and DP share hotplug bits */
+ /* enable bits are the same for all generations */
+ for_each_intel_encoder(dev, intel_encoder)
+ if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED)
+ hotplug_en |= hpd_mask_i915[intel_encoder->hpd_pin];
+ /* Programming the CRT detection parameters tends
+ to generate a spurious hotplug event about three
+ seconds later. So just do it once.
+ */
+ if (IS_G4X(dev))
+ hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
+ hotplug_en &= ~CRT_HOTPLUG_VOLTAGE_COMPARE_MASK;
+ hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
+
+ /* Ignore TV since it's buggy */
+ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
}
static irqreturn_t i965_irq_handler(int irq, void *arg)
@@ -4336,7 +4335,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
INIT_WORK(&dev_priv->dig_port_work, i915_digport_work_func);
- INIT_WORK(&dev_priv->gpu_error.work, i915_error_work_func);
INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
@@ -4347,9 +4345,8 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
else
dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
- setup_timer(&dev_priv->gpu_error.hangcheck_timer,
- i915_hangcheck_elapsed,
- (unsigned long) dev);
+ INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work,
+ i915_hangcheck_elapsed);
INIT_DELAYED_WORK(&dev_priv->hotplug_reenable_work,
intel_hpd_irq_reenable_work);
@@ -4422,14 +4419,14 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev->driver->irq_postinstall = i915_irq_postinstall;
dev->driver->irq_uninstall = i915_irq_uninstall;
dev->driver->irq_handler = i915_irq_handler;
- dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
} else {
dev->driver->irq_preinstall = i965_irq_preinstall;
dev->driver->irq_postinstall = i965_irq_postinstall;
dev->driver->irq_uninstall = i965_irq_uninstall;
dev->driver->irq_handler = i965_irq_handler;
- dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
}
+ if (I915_HAS_HOTPLUG(dev_priv))
+ dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
dev->driver->enable_vblank = i915_enable_vblank;
dev->driver->disable_vblank = i915_disable_vblank;
}
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index c91cb2033cc5..44f2262a5553 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -35,7 +35,7 @@ struct i915_params i915 __read_mostly = {
.vbt_sdvo_panel_type = -1,
.enable_rc6 = -1,
.enable_fbc = -1,
- .enable_execlists = 0,
+ .enable_execlists = -1,
.enable_hangcheck = true,
.enable_ppgtt = -1,
.enable_psr = 0,
@@ -51,6 +51,8 @@ struct i915_params i915 __read_mostly = {
.disable_vtd_wa = 0,
.use_mmio_flip = 0,
.mmio_debug = 0,
+ .verbose_state_checks = 1,
+ .nuclear_pageflip = 0,
};
module_param_named(modeset, i915.modeset, int, 0400);
@@ -122,7 +124,7 @@ MODULE_PARM_DESC(enable_ppgtt,
module_param_named(enable_execlists, i915.enable_execlists, int, 0400);
MODULE_PARM_DESC(enable_execlists,
"Override execlists usage. "
- "(-1=auto, 0=disabled [default], 1=enabled)");
+ "(-1=auto [default], 0=disabled, 1=enabled)");
module_param_named(enable_psr, i915.enable_psr, int, 0600);
MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)");
@@ -173,3 +175,11 @@ module_param_named(mmio_debug, i915.mmio_debug, bool, 0600);
MODULE_PARM_DESC(mmio_debug,
"Enable the MMIO debug code (default: false). This may negatively "
"affect performance.");
+
+module_param_named(verbose_state_checks, i915.verbose_state_checks, bool, 0600);
+MODULE_PARM_DESC(verbose_state_checks,
+ "Enable verbose logs (ie. WARN_ON()) in case of unexpected hw state conditions.");
+
+module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0600);
+MODULE_PARM_DESC(nuclear_pageflip,
+ "Force atomic modeset functionality; only planes work for now (default: false).");
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 172de3b3433b..33b3d0a24071 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -31,6 +31,8 @@
#define _PORT(port, a, b) ((a) + (port)*((b)-(a)))
#define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \
(pipe) == PIPE_B ? (b) : (c))
+#define _PORT3(port, a, b, c) ((port) == PORT_A ? (a) : \
+ (port) == PORT_B ? (b) : (c))
#define _MASKED_FIELD(mask, value) ({ \
if (__builtin_constant_p(mask)) \
@@ -217,6 +219,8 @@
#define INSTR_SUBCLIENT_SHIFT 27
#define INSTR_SUBCLIENT_MASK 0x18000000
#define INSTR_MEDIA_SUBCLIENT 0x2
+#define INSTR_26_TO_24_MASK 0x7000000
+#define INSTR_26_TO_24_SHIFT 24
/*
* Memory interface instructions used by the kernel
@@ -246,6 +250,7 @@
#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
#define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0)
#define MI_SUSPEND_FLUSH_EN (1<<0)
+#define MI_SET_APPID MI_INSTR(0x0e, 0)
#define MI_OVERLAY_FLIP MI_INSTR(0x11, 0)
#define MI_OVERLAY_CONTINUE (0x0<<21)
#define MI_OVERLAY_ON (0x1<<21)
@@ -303,8 +308,9 @@
#define MI_SEMAPHORE_POLL (1<<15)
#define MI_SEMAPHORE_SAD_GTE_SDD (1<<12)
#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
-#define MI_STORE_DWORD_IMM_GEN8 MI_INSTR(0x20, 2)
-#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
+#define MI_STORE_DWORD_IMM_GEN4 MI_INSTR(0x20, 2)
+#define MI_MEM_VIRTUAL (1 << 22) /* 945,g33,965 */
+#define MI_USE_GGTT (1 << 22) /* g4x+ */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
#define MI_STORE_DWORD_INDEX_SHIFT 2
/* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM:
@@ -470,17 +476,18 @@
*/
#define BCS_SWCTRL 0x22200
-#define HS_INVOCATION_COUNT 0x2300
-#define DS_INVOCATION_COUNT 0x2308
-#define IA_VERTICES_COUNT 0x2310
-#define IA_PRIMITIVES_COUNT 0x2318
-#define VS_INVOCATION_COUNT 0x2320
-#define GS_INVOCATION_COUNT 0x2328
-#define GS_PRIMITIVES_COUNT 0x2330
-#define CL_INVOCATION_COUNT 0x2338
-#define CL_PRIMITIVES_COUNT 0x2340
-#define PS_INVOCATION_COUNT 0x2348
-#define PS_DEPTH_COUNT 0x2350
+#define GPGPU_THREADS_DISPATCHED 0x2290
+#define HS_INVOCATION_COUNT 0x2300
+#define DS_INVOCATION_COUNT 0x2308
+#define IA_VERTICES_COUNT 0x2310
+#define IA_PRIMITIVES_COUNT 0x2318
+#define VS_INVOCATION_COUNT 0x2320
+#define GS_INVOCATION_COUNT 0x2328
+#define GS_PRIMITIVES_COUNT 0x2330
+#define CL_INVOCATION_COUNT 0x2338
+#define CL_PRIMITIVES_COUNT 0x2340
+#define PS_INVOCATION_COUNT 0x2348
+#define PS_DEPTH_COUNT 0x2350
/* There are the 4 64-bit counter registers, one for each stream output */
#define GEN7_SO_NUM_PRIMS_WRITTEN(n) (0x5200 + (n) * 8)
@@ -598,6 +605,15 @@ enum punit_power_well {
#define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */
#define PUNIT_FUSE_BUS1 0xf5 /* bits 55:48 */
+#define FB_GFX_FMAX_AT_VMAX_FUSE 0x136
+#define FB_GFX_FREQ_FUSE_MASK 0xff
+#define FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT 24
+#define FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT 16
+#define FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT 8
+
+#define FB_GFX_FMIN_AT_VMIN_FUSE 0x137
+#define FB_GFX_FMIN_AT_VMIN_FUSE_SHIFT 8
+
#define PUNIT_GPU_STATUS_REG 0xdb
#define PUNIT_GPU_STATUS_MAX_FREQ_SHIFT 16
#define PUNIT_GPU_STATUS_MAX_FREQ_MASK 0xff
@@ -1464,6 +1480,17 @@ enum punit_power_well {
#define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12)
#define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10)
+/* Fuse readout registers for GT */
+#define CHV_FUSE_GT (VLV_DISPLAY_BASE + 0x2168)
+#define CHV_FGT_EU_DIS_SS0_R0_SHIFT 16
+#define CHV_FGT_EU_DIS_SS0_R0_MASK (0xf << CHV_FGT_EU_DIS_SS0_R0_SHIFT)
+#define CHV_FGT_EU_DIS_SS0_R1_SHIFT 20
+#define CHV_FGT_EU_DIS_SS0_R1_MASK (0xf << CHV_FGT_EU_DIS_SS0_R1_SHIFT)
+#define CHV_FGT_EU_DIS_SS1_R0_SHIFT 24
+#define CHV_FGT_EU_DIS_SS1_R0_MASK (0xf << CHV_FGT_EU_DIS_SS1_R0_SHIFT)
+#define CHV_FGT_EU_DIS_SS1_R1_SHIFT 28
+#define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
+
#define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050
#define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0)
#define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2)
@@ -1509,7 +1536,7 @@ enum punit_power_well {
#define I915_ISP_INTERRUPT (1<<22)
#define I915_LPE_PIPE_B_INTERRUPT (1<<21)
#define I915_LPE_PIPE_A_INTERRUPT (1<<20)
-#define I915_MIPIB_INTERRUPT (1<<19)
+#define I915_MIPIC_INTERRUPT (1<<19)
#define I915_MIPIA_INTERRUPT (1<<18)
#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
@@ -2539,6 +2566,42 @@ enum punit_power_well {
#define PIPESRC(trans) _TRANSCODER2(trans, _PIPEASRC)
#define PIPE_MULT(trans) _TRANSCODER2(trans, _PIPE_MULT_A)
+/* VLV eDP PSR registers */
+#define _PSRCTLA (VLV_DISPLAY_BASE + 0x60090)
+#define _PSRCTLB (VLV_DISPLAY_BASE + 0x61090)
+#define VLV_EDP_PSR_ENABLE (1<<0)
+#define VLV_EDP_PSR_RESET (1<<1)
+#define VLV_EDP_PSR_MODE_MASK (7<<2)
+#define VLV_EDP_PSR_MODE_HW_TIMER (1<<3)
+#define VLV_EDP_PSR_MODE_SW_TIMER (1<<2)
+#define VLV_EDP_PSR_SINGLE_FRAME_UPDATE (1<<7)
+#define VLV_EDP_PSR_ACTIVE_ENTRY (1<<8)
+#define VLV_EDP_PSR_SRC_TRANSMITTER_STATE (1<<9)
+#define VLV_EDP_PSR_DBL_FRAME (1<<10)
+#define VLV_EDP_PSR_FRAME_COUNT_MASK (0xff<<16)
+#define VLV_EDP_PSR_IDLE_FRAME_SHIFT 16
+#define VLV_PSRCTL(pipe) _PIPE(pipe, _PSRCTLA, _PSRCTLB)
+
+#define _VSCSDPA (VLV_DISPLAY_BASE + 0x600a0)
+#define _VSCSDPB (VLV_DISPLAY_BASE + 0x610a0)
+#define VLV_EDP_PSR_SDP_FREQ_MASK (3<<30)
+#define VLV_EDP_PSR_SDP_FREQ_ONCE (1<<31)
+#define VLV_EDP_PSR_SDP_FREQ_EVFRAME (1<<30)
+#define VLV_VSCSDP(pipe) _PIPE(pipe, _VSCSDPA, _VSCSDPB)
+
+#define _PSRSTATA (VLV_DISPLAY_BASE + 0x60094)
+#define _PSRSTATB (VLV_DISPLAY_BASE + 0x61094)
+#define VLV_EDP_PSR_LAST_STATE_MASK (7<<3)
+#define VLV_EDP_PSR_CURR_STATE_MASK 7
+#define VLV_EDP_PSR_DISABLED (0<<0)
+#define VLV_EDP_PSR_INACTIVE (1<<0)
+#define VLV_EDP_PSR_IN_TRANS_TO_ACTIVE (2<<0)
+#define VLV_EDP_PSR_ACTIVE_NORFB_UP (3<<0)
+#define VLV_EDP_PSR_ACTIVE_SF_UPDATE (4<<0)
+#define VLV_EDP_PSR_EXIT (5<<0)
+#define VLV_EDP_PSR_IN_TRANS (1<<7)
+#define VLV_PSRSTAT(pipe) _PIPE(pipe, _PSRSTATA, _PSRSTATB)
+
/* HSW+ eDP PSR registers */
#define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800)
#define EDP_PSR_CTL(dev) (EDP_PSR_BASE(dev) + 0)
@@ -2762,7 +2825,8 @@ enum punit_power_well {
#define DC_BALANCE_RESET (1 << 25)
#define PORT_DFT2_G4X (dev_priv->info.display_mmio_offset + 0x61154)
#define DC_BALANCE_RESET_VLV (1 << 31)
-#define PIPE_SCRAMBLE_RESET_MASK (0x3 << 0)
+#define PIPE_SCRAMBLE_RESET_MASK ((1 << 14) | (0x3 << 0))
+#define PIPE_C_SCRAMBLE_RESET (1 << 14) /* chv */
#define PIPE_B_SCRAMBLE_RESET (1 << 1)
#define PIPE_A_SCRAMBLE_RESET (1 << 0)
@@ -3704,6 +3768,11 @@ enum punit_power_well {
#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11)
#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff)
#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0
+#define DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL (1 << 14)
+#define DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL (1 << 13)
+#define DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL (1 << 12)
+#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (1f << 5)
+#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5)
#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1)
/*
@@ -5158,6 +5227,9 @@ enum punit_power_well {
#define COMMON_SLICE_CHICKEN2 0x7014
# define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1<<0)
+#define HIZ_CHICKEN 0x7018
+# define CHV_HZ_8X8_MODE_IN_1X (1<<15)
+
#define GEN7_L3SQCREG1 0xB010
#define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000
@@ -6005,6 +6077,13 @@ enum punit_power_well {
#define GEN6_PMINTRMSK 0xA168
#define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31)
#define VLV_PWRDWNUPCTL 0xA294
+#define GEN9_MEDIA_PG_IDLE_HYSTERESIS 0xA0C4
+#define GEN9_RENDER_PG_IDLE_HYSTERESIS 0xA0C8
+#define GEN9_PG_ENABLE 0xA210
+
+#define VLV_CHICKEN_3 (VLV_DISPLAY_BASE + 0x7040C)
+#define PIXEL_OVERLAP_CNT_MASK (3 << 30)
+#define PIXEL_OVERLAP_CNT_SHIFT 30
#define GEN6_PMISR 0x44020
#define GEN6_PMIMR 0x44024 /* rps_lock */
@@ -6119,6 +6198,7 @@ enum punit_power_well {
#define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6)
#define HALF_SLICE_CHICKEN3 0xe184
+#define HSW_SAMPLE_C_PERFORMANCE (1<<9)
#define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8)
#define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1)
@@ -6631,29 +6711,31 @@ enum punit_power_well {
#define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
#define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
-/* VLV MIPI registers */
+/* MIPI DSI registers */
+
+#define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */
#define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190)
-#define _MIPIB_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700)
-#define MIPI_PORT_CTRL(tc) _TRANSCODER(tc, _MIPIA_PORT_CTRL, \
- _MIPIB_PORT_CTRL)
-#define DPI_ENABLE (1 << 31) /* A + B */
+#define _MIPIC_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700)
+#define MIPI_PORT_CTRL(port) _MIPI_PORT(port, _MIPIA_PORT_CTRL, _MIPIC_PORT_CTRL)
+#define DPI_ENABLE (1 << 31) /* A + C */
#define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27
#define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27)
+#define DUAL_LINK_MODE_SHIFT 26
#define DUAL_LINK_MODE_MASK (1 << 26)
#define DUAL_LINK_MODE_FRONT_BACK (0 << 26)
#define DUAL_LINK_MODE_PIXEL_ALTERNATIVE (1 << 26)
-#define DITHERING_ENABLE (1 << 25) /* A + B */
+#define DITHERING_ENABLE (1 << 25) /* A + C */
#define FLOPPED_HSTX (1 << 23)
#define DE_INVERT (1 << 19) /* XXX */
#define MIPIA_FLISDSI_DELAY_COUNT_SHIFT 18
#define MIPIA_FLISDSI_DELAY_COUNT_MASK (0xf << 18)
#define AFE_LATCHOUT (1 << 17)
#define LP_OUTPUT_HOLD (1 << 16)
-#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_SHIFT 15
-#define MIPIB_FLISDSI_DELAY_COUNT_HIGH_MASK (1 << 15)
-#define MIPIB_MIPI4DPHY_DELAY_COUNT_SHIFT 11
-#define MIPIB_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 11)
+#define MIPIC_FLISDSI_DELAY_COUNT_HIGH_SHIFT 15
+#define MIPIC_FLISDSI_DELAY_COUNT_HIGH_MASK (1 << 15)
+#define MIPIC_MIPI4DPHY_DELAY_COUNT_SHIFT 11
+#define MIPIC_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 11)
#define CSB_SHIFT 9
#define CSB_MASK (3 << 9)
#define CSB_20MHZ (0 << 9)
@@ -6662,10 +6744,10 @@ enum punit_power_well {
#define BANDGAP_MASK (1 << 8)
#define BANDGAP_PNW_CIRCUIT (0 << 8)
#define BANDGAP_LNC_CIRCUIT (1 << 8)
-#define MIPIB_FLISDSI_DELAY_COUNT_LOW_SHIFT 5
-#define MIPIB_FLISDSI_DELAY_COUNT_LOW_MASK (7 << 5)
-#define TEARING_EFFECT_DELAY (1 << 4) /* A + B */
-#define TEARING_EFFECT_SHIFT 2 /* A + B */
+#define MIPIC_FLISDSI_DELAY_COUNT_LOW_SHIFT 5
+#define MIPIC_FLISDSI_DELAY_COUNT_LOW_MASK (7 << 5)
+#define TEARING_EFFECT_DELAY (1 << 4) /* A + C */
+#define TEARING_EFFECT_SHIFT 2 /* A + C */
#define TEARING_EFFECT_MASK (3 << 2)
#define TEARING_EFFECT_OFF (0 << 2)
#define TEARING_EFFECT_DSI (1 << 2)
@@ -6677,9 +6759,9 @@ enum punit_power_well {
#define LANE_CONFIGURATION_DUAL_LINK_B (2 << 0)
#define _MIPIA_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61194)
-#define _MIPIB_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61704)
-#define MIPI_TEARING_CTRL(tc) _TRANSCODER(tc, \
- _MIPIA_TEARING_CTRL, _MIPIB_TEARING_CTRL)
+#define _MIPIC_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61704)
+#define MIPI_TEARING_CTRL(port) _MIPI_PORT(port, \
+ _MIPIA_TEARING_CTRL, _MIPIC_TEARING_CTRL)
#define TEARING_EFFECT_DELAY_SHIFT 0
#define TEARING_EFFECT_DELAY_MASK (0xffff << 0)
@@ -6689,9 +6771,9 @@ enum punit_power_well {
/* MIPI DSI Controller and D-PHY registers */
#define _MIPIA_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb000)
-#define _MIPIB_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb800)
-#define MIPI_DEVICE_READY(tc) _TRANSCODER(tc, _MIPIA_DEVICE_READY, \
- _MIPIB_DEVICE_READY)
+#define _MIPIC_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb800)
+#define MIPI_DEVICE_READY(port) _MIPI_PORT(port, _MIPIA_DEVICE_READY, \
+ _MIPIC_DEVICE_READY)
#define BUS_POSSESSION (1 << 3) /* set to give bus to receiver */
#define ULPS_STATE_MASK (3 << 1)
#define ULPS_STATE_ENTER (2 << 1)
@@ -6700,13 +6782,13 @@ enum punit_power_well {
#define DEVICE_READY (1 << 0)
#define _MIPIA_INTR_STAT (dev_priv->mipi_mmio_base + 0xb004)
-#define _MIPIB_INTR_STAT (dev_priv->mipi_mmio_base + 0xb804)
-#define MIPI_INTR_STAT(tc) _TRANSCODER(tc, _MIPIA_INTR_STAT, \
- _MIPIB_INTR_STAT)
+#define _MIPIC_INTR_STAT (dev_priv->mipi_mmio_base + 0xb804)
+#define MIPI_INTR_STAT(port) _MIPI_PORT(port, _MIPIA_INTR_STAT, \
+ _MIPIC_INTR_STAT)
#define _MIPIA_INTR_EN (dev_priv->mipi_mmio_base + 0xb008)
-#define _MIPIB_INTR_EN (dev_priv->mipi_mmio_base + 0xb808)
-#define MIPI_INTR_EN(tc) _TRANSCODER(tc, _MIPIA_INTR_EN, \
- _MIPIB_INTR_EN)
+#define _MIPIC_INTR_EN (dev_priv->mipi_mmio_base + 0xb808)
+#define MIPI_INTR_EN(port) _MIPI_PORT(port, _MIPIA_INTR_EN, \
+ _MIPIC_INTR_EN)
#define TEARING_EFFECT (1 << 31)
#define SPL_PKT_SENT_INTERRUPT (1 << 30)
#define GEN_READ_DATA_AVAIL (1 << 29)
@@ -6741,9 +6823,9 @@ enum punit_power_well {
#define RXSOT_ERROR (1 << 0)
#define _MIPIA_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb00c)
-#define _MIPIB_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb80c)
-#define MIPI_DSI_FUNC_PRG(tc) _TRANSCODER(tc, _MIPIA_DSI_FUNC_PRG, \
- _MIPIB_DSI_FUNC_PRG)
+#define _MIPIC_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb80c)
+#define MIPI_DSI_FUNC_PRG(port) _MIPI_PORT(port, _MIPIA_DSI_FUNC_PRG, \
+ _MIPIC_DSI_FUNC_PRG)
#define CMD_MODE_DATA_WIDTH_MASK (7 << 13)
#define CMD_MODE_NOT_SUPPORTED (0 << 13)
#define CMD_MODE_DATA_WIDTH_16_BIT (1 << 13)
@@ -6765,93 +6847,93 @@ enum punit_power_well {
#define DATA_LANES_PRG_REG_MASK (7 << 0)
#define _MIPIA_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb010)
-#define _MIPIB_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb810)
-#define MIPI_HS_TX_TIMEOUT(tc) _TRANSCODER(tc, _MIPIA_HS_TX_TIMEOUT, \
- _MIPIB_HS_TX_TIMEOUT)
+#define _MIPIC_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb810)
+#define MIPI_HS_TX_TIMEOUT(port) _MIPI_PORT(port, _MIPIA_HS_TX_TIMEOUT, \
+ _MIPIC_HS_TX_TIMEOUT)
#define HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK 0xffffff
#define _MIPIA_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb014)
-#define _MIPIB_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb814)
-#define MIPI_LP_RX_TIMEOUT(tc) _TRANSCODER(tc, _MIPIA_LP_RX_TIMEOUT, \
- _MIPIB_LP_RX_TIMEOUT)
+#define _MIPIC_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb814)
+#define MIPI_LP_RX_TIMEOUT(port) _MIPI_PORT(port, _MIPIA_LP_RX_TIMEOUT, \
+ _MIPIC_LP_RX_TIMEOUT)
#define LOW_POWER_RX_TIMEOUT_COUNTER_MASK 0xffffff
#define _MIPIA_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb018)
-#define _MIPIB_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb818)
-#define MIPI_TURN_AROUND_TIMEOUT(tc) _TRANSCODER(tc, \
- _MIPIA_TURN_AROUND_TIMEOUT, _MIPIB_TURN_AROUND_TIMEOUT)
+#define _MIPIC_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb818)
+#define MIPI_TURN_AROUND_TIMEOUT(port) _MIPI_PORT(port, \
+ _MIPIA_TURN_AROUND_TIMEOUT, _MIPIC_TURN_AROUND_TIMEOUT)
#define TURN_AROUND_TIMEOUT_MASK 0x3f
#define _MIPIA_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb01c)
-#define _MIPIB_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb81c)
-#define MIPI_DEVICE_RESET_TIMER(tc) _TRANSCODER(tc, \
- _MIPIA_DEVICE_RESET_TIMER, _MIPIB_DEVICE_RESET_TIMER)
+#define _MIPIC_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb81c)
+#define MIPI_DEVICE_RESET_TIMER(port) _MIPI_PORT(port, \
+ _MIPIA_DEVICE_RESET_TIMER, _MIPIC_DEVICE_RESET_TIMER)
#define DEVICE_RESET_TIMER_MASK 0xffff
#define _MIPIA_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb020)
-#define _MIPIB_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb820)
-#define MIPI_DPI_RESOLUTION(tc) _TRANSCODER(tc, _MIPIA_DPI_RESOLUTION, \
- _MIPIB_DPI_RESOLUTION)
+#define _MIPIC_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb820)
+#define MIPI_DPI_RESOLUTION(port) _MIPI_PORT(port, _MIPIA_DPI_RESOLUTION, \
+ _MIPIC_DPI_RESOLUTION)
#define VERTICAL_ADDRESS_SHIFT 16
#define VERTICAL_ADDRESS_MASK (0xffff << 16)
#define HORIZONTAL_ADDRESS_SHIFT 0
#define HORIZONTAL_ADDRESS_MASK 0xffff
#define _MIPIA_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb024)
-#define _MIPIB_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb824)
-#define MIPI_DBI_FIFO_THROTTLE(tc) _TRANSCODER(tc, \
- _MIPIA_DBI_FIFO_THROTTLE, _MIPIB_DBI_FIFO_THROTTLE)
+#define _MIPIC_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb824)
+#define MIPI_DBI_FIFO_THROTTLE(port) _MIPI_PORT(port, \
+ _MIPIA_DBI_FIFO_THROTTLE, _MIPIC_DBI_FIFO_THROTTLE)
#define DBI_FIFO_EMPTY_HALF (0 << 0)
#define DBI_FIFO_EMPTY_QUARTER (1 << 0)
#define DBI_FIFO_EMPTY_7_LOCATIONS (2 << 0)
/* regs below are bits 15:0 */
#define _MIPIA_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb028)
-#define _MIPIB_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb828)
-#define MIPI_HSYNC_PADDING_COUNT(tc) _TRANSCODER(tc, \
- _MIPIA_HSYNC_PADDING_COUNT, _MIPIB_HSYNC_PADDING_COUNT)
+#define _MIPIC_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb828)
+#define MIPI_HSYNC_PADDING_COUNT(port) _MIPI_PORT(port, \
+ _MIPIA_HSYNC_PADDING_COUNT, _MIPIC_HSYNC_PADDING_COUNT)
#define _MIPIA_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb02c)
-#define _MIPIB_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb82c)
-#define MIPI_HBP_COUNT(tc) _TRANSCODER(tc, _MIPIA_HBP_COUNT, \
- _MIPIB_HBP_COUNT)
+#define _MIPIC_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb82c)
+#define MIPI_HBP_COUNT(port) _MIPI_PORT(port, _MIPIA_HBP_COUNT, \
+ _MIPIC_HBP_COUNT)
#define _MIPIA_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb030)
-#define _MIPIB_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb830)
-#define MIPI_HFP_COUNT(tc) _TRANSCODER(tc, _MIPIA_HFP_COUNT, \
- _MIPIB_HFP_COUNT)
+#define _MIPIC_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb830)
+#define MIPI_HFP_COUNT(port) _MIPI_PORT(port, _MIPIA_HFP_COUNT, \
+ _MIPIC_HFP_COUNT)
#define _MIPIA_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb034)
-#define _MIPIB_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb834)
-#define MIPI_HACTIVE_AREA_COUNT(tc) _TRANSCODER(tc, \
- _MIPIA_HACTIVE_AREA_COUNT, _MIPIB_HACTIVE_AREA_COUNT)
+#define _MIPIC_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb834)
+#define MIPI_HACTIVE_AREA_COUNT(port) _MIPI_PORT(port, \
+ _MIPIA_HACTIVE_AREA_COUNT, _MIPIC_HACTIVE_AREA_COUNT)
#define _MIPIA_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb038)
-#define _MIPIB_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb838)
-#define MIPI_VSYNC_PADDING_COUNT(tc) _TRANSCODER(tc, \
- _MIPIA_VSYNC_PADDING_COUNT, _MIPIB_VSYNC_PADDING_COUNT)
+#define _MIPIC_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb838)
+#define MIPI_VSYNC_PADDING_COUNT(port) _MIPI_PORT(port, \
+ _MIPIA_VSYNC_PADDING_COUNT, _MIPIC_VSYNC_PADDING_COUNT)
#define _MIPIA_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb03c)
-#define _MIPIB_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb83c)
-#define MIPI_VBP_COUNT(tc) _TRANSCODER(tc, _MIPIA_VBP_COUNT, \
- _MIPIB_VBP_COUNT)
+#define _MIPIC_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb83c)
+#define MIPI_VBP_COUNT(port) _MIPI_PORT(port, _MIPIA_VBP_COUNT, \
+ _MIPIC_VBP_COUNT)
#define _MIPIA_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb040)
-#define _MIPIB_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb840)
-#define MIPI_VFP_COUNT(tc) _TRANSCODER(tc, _MIPIA_VFP_COUNT, \
- _MIPIB_VFP_COUNT)
+#define _MIPIC_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb840)
+#define MIPI_VFP_COUNT(port) _MIPI_PORT(port, _MIPIA_VFP_COUNT, \
+ _MIPIC_VFP_COUNT)
#define _MIPIA_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb044)
-#define _MIPIB_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb844)
-#define MIPI_HIGH_LOW_SWITCH_COUNT(tc) _TRANSCODER(tc, \
- _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIB_HIGH_LOW_SWITCH_COUNT)
+#define _MIPIC_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb844)
+#define MIPI_HIGH_LOW_SWITCH_COUNT(port) _MIPI_PORT(port, \
+ _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIC_HIGH_LOW_SWITCH_COUNT)
/* regs above are bits 15:0 */
#define _MIPIA_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb048)
-#define _MIPIB_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb848)
-#define MIPI_DPI_CONTROL(tc) _TRANSCODER(tc, _MIPIA_DPI_CONTROL, \
- _MIPIB_DPI_CONTROL)
+#define _MIPIC_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb848)
+#define MIPI_DPI_CONTROL(port) _MIPI_PORT(port, _MIPIA_DPI_CONTROL, \
+ _MIPIC_DPI_CONTROL)
#define DPI_LP_MODE (1 << 6)
#define BACKLIGHT_OFF (1 << 5)
#define BACKLIGHT_ON (1 << 4)
@@ -6861,30 +6943,30 @@ enum punit_power_well {
#define SHUTDOWN (1 << 0)
#define _MIPIA_DPI_DATA (dev_priv->mipi_mmio_base + 0xb04c)
-#define _MIPIB_DPI_DATA (dev_priv->mipi_mmio_base + 0xb84c)
-#define MIPI_DPI_DATA(tc) _TRANSCODER(tc, _MIPIA_DPI_DATA, \
- _MIPIB_DPI_DATA)
+#define _MIPIC_DPI_DATA (dev_priv->mipi_mmio_base + 0xb84c)
+#define MIPI_DPI_DATA(port) _MIPI_PORT(port, _MIPIA_DPI_DATA, \
+ _MIPIC_DPI_DATA)
#define COMMAND_BYTE_SHIFT 0
#define COMMAND_BYTE_MASK (0x3f << 0)
#define _MIPIA_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb050)
-#define _MIPIB_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb850)
-#define MIPI_INIT_COUNT(tc) _TRANSCODER(tc, _MIPIA_INIT_COUNT, \
- _MIPIB_INIT_COUNT)
+#define _MIPIC_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb850)
+#define MIPI_INIT_COUNT(port) _MIPI_PORT(port, _MIPIA_INIT_COUNT, \
+ _MIPIC_INIT_COUNT)
#define MASTER_INIT_TIMER_SHIFT 0
#define MASTER_INIT_TIMER_MASK (0xffff << 0)
#define _MIPIA_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb054)
-#define _MIPIB_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb854)
-#define MIPI_MAX_RETURN_PKT_SIZE(tc) _TRANSCODER(tc, \
- _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIB_MAX_RETURN_PKT_SIZE)
+#define _MIPIC_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb854)
+#define MIPI_MAX_RETURN_PKT_SIZE(port) _MIPI_PORT(port, \
+ _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIC_MAX_RETURN_PKT_SIZE)
#define MAX_RETURN_PKT_SIZE_SHIFT 0
#define MAX_RETURN_PKT_SIZE_MASK (0x3ff << 0)
#define _MIPIA_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb058)
-#define _MIPIB_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb858)
-#define MIPI_VIDEO_MODE_FORMAT(tc) _TRANSCODER(tc, \
- _MIPIA_VIDEO_MODE_FORMAT, _MIPIB_VIDEO_MODE_FORMAT)
+#define _MIPIC_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb858)
+#define MIPI_VIDEO_MODE_FORMAT(port) _MIPI_PORT(port, \
+ _MIPIA_VIDEO_MODE_FORMAT, _MIPIC_VIDEO_MODE_FORMAT)
#define RANDOM_DPI_DISPLAY_RESOLUTION (1 << 4)
#define DISABLE_VIDEO_BTA (1 << 3)
#define IP_TG_CONFIG (1 << 2)
@@ -6893,9 +6975,9 @@ enum punit_power_well {
#define VIDEO_MODE_BURST (3 << 0)
#define _MIPIA_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb05c)
-#define _MIPIB_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb85c)
-#define MIPI_EOT_DISABLE(tc) _TRANSCODER(tc, _MIPIA_EOT_DISABLE, \
- _MIPIB_EOT_DISABLE)
+#define _MIPIC_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb85c)
+#define MIPI_EOT_DISABLE(port) _MIPI_PORT(port, _MIPIA_EOT_DISABLE, \
+ _MIPIC_EOT_DISABLE)
#define LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 7)
#define HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 6)
#define LOW_CONTENTION_RECOVERY_DISABLE (1 << 5)
@@ -6906,32 +6988,32 @@ enum punit_power_well {
#define EOT_DISABLE (1 << 0)
#define _MIPIA_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb060)
-#define _MIPIB_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb860)
-#define MIPI_LP_BYTECLK(tc) _TRANSCODER(tc, _MIPIA_LP_BYTECLK, \
- _MIPIB_LP_BYTECLK)
+#define _MIPIC_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb860)
+#define MIPI_LP_BYTECLK(port) _MIPI_PORT(port, _MIPIA_LP_BYTECLK, \
+ _MIPIC_LP_BYTECLK)
#define LP_BYTECLK_SHIFT 0
#define LP_BYTECLK_MASK (0xffff << 0)
/* bits 31:0 */
#define _MIPIA_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb064)
-#define _MIPIB_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb864)
-#define MIPI_LP_GEN_DATA(tc) _TRANSCODER(tc, _MIPIA_LP_GEN_DATA, \
- _MIPIB_LP_GEN_DATA)
+#define _MIPIC_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb864)
+#define MIPI_LP_GEN_DATA(port) _MIPI_PORT(port, _MIPIA_LP_GEN_DATA, \
+ _MIPIC_LP_GEN_DATA)
/* bits 31:0 */
#define _MIPIA_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb068)
-#define _MIPIB_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb868)
-#define MIPI_HS_GEN_DATA(tc) _TRANSCODER(tc, _MIPIA_HS_GEN_DATA, \
- _MIPIB_HS_GEN_DATA)
+#define _MIPIC_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb868)
+#define MIPI_HS_GEN_DATA(port) _MIPI_PORT(port, _MIPIA_HS_GEN_DATA, \
+ _MIPIC_HS_GEN_DATA)
#define _MIPIA_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb06c)
-#define _MIPIB_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb86c)
-#define MIPI_LP_GEN_CTRL(tc) _TRANSCODER(tc, _MIPIA_LP_GEN_CTRL, \
- _MIPIB_LP_GEN_CTRL)
+#define _MIPIC_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb86c)
+#define MIPI_LP_GEN_CTRL(port) _MIPI_PORT(port, _MIPIA_LP_GEN_CTRL, \
+ _MIPIC_LP_GEN_CTRL)
#define _MIPIA_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb070)
-#define _MIPIB_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb870)
-#define MIPI_HS_GEN_CTRL(tc) _TRANSCODER(tc, _MIPIA_HS_GEN_CTRL, \
- _MIPIB_HS_GEN_CTRL)
+#define _MIPIC_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb870)
+#define MIPI_HS_GEN_CTRL(port) _MIPI_PORT(port, _MIPIA_HS_GEN_CTRL, \
+ _MIPIC_HS_GEN_CTRL)
#define LONG_PACKET_WORD_COUNT_SHIFT 8
#define LONG_PACKET_WORD_COUNT_MASK (0xffff << 8)
#define SHORT_PACKET_PARAM_SHIFT 8
@@ -6943,9 +7025,9 @@ enum punit_power_well {
/* data type values, see include/video/mipi_display.h */
#define _MIPIA_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb074)
-#define _MIPIB_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb874)
-#define MIPI_GEN_FIFO_STAT(tc) _TRANSCODER(tc, _MIPIA_GEN_FIFO_STAT, \
- _MIPIB_GEN_FIFO_STAT)
+#define _MIPIC_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb874)
+#define MIPI_GEN_FIFO_STAT(port) _MIPI_PORT(port, _MIPIA_GEN_FIFO_STAT, \
+ _MIPIC_GEN_FIFO_STAT)
#define DPI_FIFO_EMPTY (1 << 28)
#define DBI_FIFO_EMPTY (1 << 27)
#define LP_CTRL_FIFO_EMPTY (1 << 26)
@@ -6962,17 +7044,17 @@ enum punit_power_well {
#define HS_DATA_FIFO_FULL (1 << 0)
#define _MIPIA_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb078)
-#define _MIPIB_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb878)
-#define MIPI_HS_LP_DBI_ENABLE(tc) _TRANSCODER(tc, \
- _MIPIA_HS_LS_DBI_ENABLE, _MIPIB_HS_LS_DBI_ENABLE)
+#define _MIPIC_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb878)
+#define MIPI_HS_LP_DBI_ENABLE(port) _MIPI_PORT(port, \
+ _MIPIA_HS_LS_DBI_ENABLE, _MIPIC_HS_LS_DBI_ENABLE)
#define DBI_HS_LP_MODE_MASK (1 << 0)
#define DBI_LP_MODE (1 << 0)
#define DBI_HS_MODE (0 << 0)
#define _MIPIA_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb080)
-#define _MIPIB_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb880)
-#define MIPI_DPHY_PARAM(tc) _TRANSCODER(tc, _MIPIA_DPHY_PARAM, \
- _MIPIB_DPHY_PARAM)
+#define _MIPIC_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb880)
+#define MIPI_DPHY_PARAM(port) _MIPI_PORT(port, _MIPIA_DPHY_PARAM, \
+ _MIPIC_DPHY_PARAM)
#define EXIT_ZERO_COUNT_SHIFT 24
#define EXIT_ZERO_COUNT_MASK (0x3f << 24)
#define TRAIL_COUNT_SHIFT 16
@@ -6984,36 +7066,36 @@ enum punit_power_well {
/* bits 31:0 */
#define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084)
-#define _MIPIB_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884)
-#define MIPI_DBI_BW_CTRL(tc) _TRANSCODER(tc, _MIPIA_DBI_BW_CTRL, \
- _MIPIB_DBI_BW_CTRL)
+#define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884)
+#define MIPI_DBI_BW_CTRL(port) _MIPI_PORT(port, _MIPIA_DBI_BW_CTRL, \
+ _MIPIC_DBI_BW_CTRL)
#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base \
+ 0xb088)
-#define _MIPIB_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base \
+#define _MIPIC_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base \
+ 0xb888)
-#define MIPI_CLK_LANE_SWITCH_TIME_CNT(tc) _TRANSCODER(tc, \
- _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIB_CLK_LANE_SWITCH_TIME_CNT)
+#define MIPI_CLK_LANE_SWITCH_TIME_CNT(port) _MIPI_PORT(port, \
+ _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIC_CLK_LANE_SWITCH_TIME_CNT)
#define LP_HS_SSW_CNT_SHIFT 16
#define LP_HS_SSW_CNT_MASK (0xffff << 16)
#define HS_LP_PWR_SW_CNT_SHIFT 0
#define HS_LP_PWR_SW_CNT_MASK (0xffff << 0)
#define _MIPIA_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb08c)
-#define _MIPIB_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb88c)
-#define MIPI_STOP_STATE_STALL(tc) _TRANSCODER(tc, \
- _MIPIA_STOP_STATE_STALL, _MIPIB_STOP_STATE_STALL)
+#define _MIPIC_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb88c)
+#define MIPI_STOP_STATE_STALL(port) _MIPI_PORT(port, \
+ _MIPIA_STOP_STATE_STALL, _MIPIC_STOP_STATE_STALL)
#define STOP_STATE_STALL_COUNTER_SHIFT 0
#define STOP_STATE_STALL_COUNTER_MASK (0xff << 0)
#define _MIPIA_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb090)
-#define _MIPIB_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb890)
-#define MIPI_INTR_STAT_REG_1(tc) _TRANSCODER(tc, \
- _MIPIA_INTR_STAT_REG_1, _MIPIB_INTR_STAT_REG_1)
+#define _MIPIC_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb890)
+#define MIPI_INTR_STAT_REG_1(port) _MIPI_PORT(port, \
+ _MIPIA_INTR_STAT_REG_1, _MIPIC_INTR_STAT_REG_1)
#define _MIPIA_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb094)
-#define _MIPIB_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb894)
-#define MIPI_INTR_EN_REG_1(tc) _TRANSCODER(tc, _MIPIA_INTR_EN_REG_1, \
- _MIPIB_INTR_EN_REG_1)
+#define _MIPIC_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb894)
+#define MIPI_INTR_EN_REG_1(port) _MIPI_PORT(port, _MIPIA_INTR_EN_REG_1, \
+ _MIPIC_INTR_EN_REG_1)
#define RX_CONTENTION_DETECTED (1 << 0)
/* XXX: only pipe A ?!? */
@@ -7032,9 +7114,9 @@ enum punit_power_well {
/* MIPI adapter registers */
#define _MIPIA_CTRL (dev_priv->mipi_mmio_base + 0xb104)
-#define _MIPIB_CTRL (dev_priv->mipi_mmio_base + 0xb904)
-#define MIPI_CTRL(tc) _TRANSCODER(tc, _MIPIA_CTRL, \
- _MIPIB_CTRL)
+#define _MIPIC_CTRL (dev_priv->mipi_mmio_base + 0xb904)
+#define MIPI_CTRL(port) _MIPI_PORT(port, _MIPIA_CTRL, \
+ _MIPIC_CTRL)
#define ESCAPE_CLOCK_DIVIDER_SHIFT 5 /* A only */
#define ESCAPE_CLOCK_DIVIDER_MASK (3 << 5)
#define ESCAPE_CLOCK_DIVIDER_1 (0 << 5)
@@ -7047,24 +7129,24 @@ enum punit_power_well {
#define RGB_FLIP_TO_BGR (1 << 2)
#define _MIPIA_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb108)
-#define _MIPIB_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb908)
-#define MIPI_DATA_ADDRESS(tc) _TRANSCODER(tc, _MIPIA_DATA_ADDRESS, \
- _MIPIB_DATA_ADDRESS)
+#define _MIPIC_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb908)
+#define MIPI_DATA_ADDRESS(port) _MIPI_PORT(port, _MIPIA_DATA_ADDRESS, \
+ _MIPIC_DATA_ADDRESS)
#define DATA_MEM_ADDRESS_SHIFT 5
#define DATA_MEM_ADDRESS_MASK (0x7ffffff << 5)
#define DATA_VALID (1 << 0)
#define _MIPIA_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb10c)
-#define _MIPIB_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb90c)
-#define MIPI_DATA_LENGTH(tc) _TRANSCODER(tc, _MIPIA_DATA_LENGTH, \
- _MIPIB_DATA_LENGTH)
+#define _MIPIC_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb90c)
+#define MIPI_DATA_LENGTH(port) _MIPI_PORT(port, _MIPIA_DATA_LENGTH, \
+ _MIPIC_DATA_LENGTH)
#define DATA_LENGTH_SHIFT 0
#define DATA_LENGTH_MASK (0xfffff << 0)
#define _MIPIA_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb110)
-#define _MIPIB_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb910)
-#define MIPI_COMMAND_ADDRESS(tc) _TRANSCODER(tc, \
- _MIPIA_COMMAND_ADDRESS, _MIPIB_COMMAND_ADDRESS)
+#define _MIPIC_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb910)
+#define MIPI_COMMAND_ADDRESS(port) _MIPI_PORT(port, \
+ _MIPIA_COMMAND_ADDRESS, _MIPIC_COMMAND_ADDRESS)
#define COMMAND_MEM_ADDRESS_SHIFT 5
#define COMMAND_MEM_ADDRESS_MASK (0x7ffffff << 5)
#define AUTO_PWG_ENABLE (1 << 2)
@@ -7072,22 +7154,22 @@ enum punit_power_well {
#define COMMAND_VALID (1 << 0)
#define _MIPIA_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb114)
-#define _MIPIB_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb914)
-#define MIPI_COMMAND_LENGTH(tc) _TRANSCODER(tc, _MIPIA_COMMAND_LENGTH, \
- _MIPIB_COMMAND_LENGTH)
+#define _MIPIC_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb914)
+#define MIPI_COMMAND_LENGTH(port) _MIPI_PORT(port, _MIPIA_COMMAND_LENGTH, \
+ _MIPIC_COMMAND_LENGTH)
#define COMMAND_LENGTH_SHIFT(n) (8 * (n)) /* n: 0...3 */
#define COMMAND_LENGTH_MASK(n) (0xff << (8 * (n)))
#define _MIPIA_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb118)
-#define _MIPIB_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb918)
-#define MIPI_READ_DATA_RETURN(tc, n) \
- (_TRANSCODER(tc, _MIPIA_READ_DATA_RETURN0, _MIPIB_READ_DATA_RETURN0) \
+#define _MIPIC_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb918)
+#define MIPI_READ_DATA_RETURN(port, n) \
+ (_MIPI_PORT(port, _MIPIA_READ_DATA_RETURN0, _MIPIC_READ_DATA_RETURN0) \
+ 4 * (n)) /* n: 0...7 */
#define _MIPIA_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb138)
-#define _MIPIB_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb938)
-#define MIPI_READ_DATA_VALID(tc) _TRANSCODER(tc, \
- _MIPIA_READ_DATA_VALID, _MIPIB_READ_DATA_VALID)
+#define _MIPIC_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb938)
+#define MIPI_READ_DATA_VALID(port) _MIPI_PORT(port, \
+ _MIPIA_READ_DATA_VALID, _MIPIC_READ_DATA_VALID)
#define READ_DATA_VALID(n) (1 << (n))
/* For UMS only (deprecated): */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 26368822a33f..9f19ed38cdc3 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -264,7 +264,7 @@ static void i915_restore_display(struct drm_device *dev)
}
/* only restore FBC info on the platform that supports FBC*/
- intel_disable_fbc(dev);
+ intel_fbc_disable(dev);
/* restore FBC interval */
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 4a5af695307e..49f5ade0edb7 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -49,14 +49,14 @@ static u32 calc_residency(struct drm_device *dev, const u32 reg)
/* On VLV and CHV, residency time is in CZ units rather than 1.28us */
if (IS_VALLEYVIEW(dev)) {
- u32 reg, czcount_30ns;
+ u32 clk_reg, czcount_30ns;
if (IS_CHERRYVIEW(dev))
- reg = CHV_CLK_CTL1;
+ clk_reg = CHV_CLK_CTL1;
else
- reg = VLV_CLK_CTL2;
+ clk_reg = VLV_CLK_CTL2;
- czcount_30ns = I915_READ(reg) >> CLK_CTL2_CZCOUNT_30NS_SHIFT;
+ czcount_30ns = I915_READ(clk_reg) >> CLK_CTL2_CZCOUNT_30NS_SHIFT;
if (!czcount_30ns) {
WARN(!czcount_30ns, "bogus CZ count value");
@@ -116,8 +116,6 @@ show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
struct drm_minor *dminor = dev_to_drm_minor(kdev);
u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p);
- if (IS_VALLEYVIEW(dminor->dev))
- rc6p_residency = 0;
return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency);
}
@@ -126,8 +124,6 @@ show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{
struct drm_minor *dminor = dev_to_drm_minor(kdev);
u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp);
- if (IS_VALLEYVIEW(dminor->dev))
- rc6pp_residency = 0;
return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency);
}
@@ -285,7 +281,7 @@ static struct bin_attribute dpf_attrs_1 = {
.private = (void *)1
};
-static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
+static ssize_t gt_act_freq_mhz_show(struct device *kdev,
struct device_attribute *attr, char *buf)
{
struct drm_minor *minor = dev_to_drm_minor(kdev);
@@ -301,9 +297,14 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
if (IS_VALLEYVIEW(dev_priv->dev)) {
u32 freq;
freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
- ret = vlv_gpu_freq(dev_priv, (freq >> 8) & 0xff);
+ ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff);
} else {
- ret = dev_priv->rps.cur_freq * GT_FREQUENCY_MULTIPLIER;
+ u32 rpstat = I915_READ(GEN6_RPSTAT1);
+ if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+ ret = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
+ else
+ ret = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
+ ret = intel_gpu_freq(dev_priv, ret);
}
mutex_unlock(&dev_priv->rps.hw_lock);
@@ -312,6 +313,27 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
return snprintf(buf, PAGE_SIZE, "%d\n", ret);
}
+static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
+ struct device_attribute *attr, char *buf)
+{
+ struct drm_minor *minor = dev_to_drm_minor(kdev);
+ struct drm_device *dev = minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+
+ flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+ intel_runtime_pm_get(dev_priv);
+
+ mutex_lock(&dev_priv->rps.hw_lock);
+ ret = intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+
+ intel_runtime_pm_put(dev_priv);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
struct device_attribute *attr, char *buf)
{
@@ -319,8 +341,9 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
struct drm_device *dev = minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- return snprintf(buf, PAGE_SIZE, "%d\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
+ return snprintf(buf, PAGE_SIZE,
+ "%d\n",
+ intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
}
static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
@@ -333,10 +356,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
mutex_lock(&dev_priv->rps.hw_lock);
- if (IS_VALLEYVIEW(dev_priv->dev))
- ret = vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
- else
- ret = dev_priv->rps.max_freq_softlimit * GT_FREQUENCY_MULTIPLIER;
+ ret = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit);
mutex_unlock(&dev_priv->rps.hw_lock);
return snprintf(buf, PAGE_SIZE, "%d\n", ret);
@@ -360,10 +380,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
mutex_lock(&dev_priv->rps.hw_lock);
- if (IS_VALLEYVIEW(dev_priv->dev))
- val = vlv_freq_opcode(dev_priv, val);
- else
- val /= GT_FREQUENCY_MULTIPLIER;
+ val = intel_freq_opcode(dev_priv, val);
if (val < dev_priv->rps.min_freq ||
val > dev_priv->rps.max_freq ||
@@ -374,21 +391,21 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
if (val > dev_priv->rps.rp0_freq)
DRM_DEBUG("User requested overclocking to %d\n",
- val * GT_FREQUENCY_MULTIPLIER);
+ intel_gpu_freq(dev_priv, val));
dev_priv->rps.max_freq_softlimit = val;
- if (dev_priv->rps.cur_freq > val) {
- if (IS_VALLEYVIEW(dev))
- valleyview_set_rps(dev, val);
- else
- gen6_set_rps(dev, val);
- } else if (!IS_VALLEYVIEW(dev)) {
- /* We still need gen6_set_rps to process the new max_delay and
- * update the interrupt limits even though frequency request is
- * unchanged. */
- gen6_set_rps(dev, dev_priv->rps.cur_freq);
- }
+ val = clamp_t(int, dev_priv->rps.cur_freq,
+ dev_priv->rps.min_freq_softlimit,
+ dev_priv->rps.max_freq_softlimit);
+
+ /* We still need *_set_rps to process the new max_delay and
+ * update the interrupt limits and PMINTRMSK even though
+ * frequency request may be unchanged. */
+ if (IS_VALLEYVIEW(dev))
+ valleyview_set_rps(dev, val);
+ else
+ gen6_set_rps(dev, val);
mutex_unlock(&dev_priv->rps.hw_lock);
@@ -405,10 +422,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
mutex_lock(&dev_priv->rps.hw_lock);
- if (IS_VALLEYVIEW(dev_priv->dev))
- ret = vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
- else
- ret = dev_priv->rps.min_freq_softlimit * GT_FREQUENCY_MULTIPLIER;
+ ret = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit);
mutex_unlock(&dev_priv->rps.hw_lock);
return snprintf(buf, PAGE_SIZE, "%d\n", ret);
@@ -432,10 +446,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
mutex_lock(&dev_priv->rps.hw_lock);
- if (IS_VALLEYVIEW(dev))
- val = vlv_freq_opcode(dev_priv, val);
- else
- val /= GT_FREQUENCY_MULTIPLIER;
+ val = intel_freq_opcode(dev_priv, val);
if (val < dev_priv->rps.min_freq ||
val > dev_priv->rps.max_freq ||
@@ -446,17 +457,17 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
dev_priv->rps.min_freq_softlimit = val;
- if (dev_priv->rps.cur_freq < val) {
- if (IS_VALLEYVIEW(dev))
- valleyview_set_rps(dev, val);
- else
- gen6_set_rps(dev, val);
- } else if (!IS_VALLEYVIEW(dev)) {
- /* We still need gen6_set_rps to process the new min_delay and
- * update the interrupt limits even though frequency request is
- * unchanged. */
- gen6_set_rps(dev, dev_priv->rps.cur_freq);
- }
+ val = clamp_t(int, dev_priv->rps.cur_freq,
+ dev_priv->rps.min_freq_softlimit,
+ dev_priv->rps.max_freq_softlimit);
+
+ /* We still need *_set_rps to process the new min_delay and
+ * update the interrupt limits and PMINTRMSK even though
+ * frequency request may be unchanged. */
+ if (IS_VALLEYVIEW(dev))
+ valleyview_set_rps(dev, val);
+ else
+ gen6_set_rps(dev, val);
mutex_unlock(&dev_priv->rps.hw_lock);
@@ -464,6 +475,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
}
+static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
@@ -494,19 +506,22 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr
if (attr == &dev_attr_gt_RP0_freq_mhz) {
if (IS_VALLEYVIEW(dev))
- val = vlv_gpu_freq(dev_priv, dev_priv->rps.rp0_freq);
+ val = intel_gpu_freq(dev_priv, dev_priv->rps.rp0_freq);
else
- val = ((rp_state_cap & 0x0000ff) >> 0) * GT_FREQUENCY_MULTIPLIER;
+ val = intel_gpu_freq(dev_priv,
+ ((rp_state_cap & 0x0000ff) >> 0));
} else if (attr == &dev_attr_gt_RP1_freq_mhz) {
if (IS_VALLEYVIEW(dev))
- val = vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq);
+ val = intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq);
else
- val = ((rp_state_cap & 0x00ff00) >> 8) * GT_FREQUENCY_MULTIPLIER;
+ val = intel_gpu_freq(dev_priv,
+ ((rp_state_cap & 0x00ff00) >> 8));
} else if (attr == &dev_attr_gt_RPn_freq_mhz) {
if (IS_VALLEYVIEW(dev))
- val = vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq);
+ val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq);
else
- val = ((rp_state_cap & 0xff0000) >> 16) * GT_FREQUENCY_MULTIPLIER;
+ val = intel_gpu_freq(dev_priv,
+ ((rp_state_cap & 0xff0000) >> 16));
} else {
BUG();
}
@@ -514,6 +529,7 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr
}
static const struct attribute *gen6_attrs[] = {
+ &dev_attr_gt_act_freq_mhz.attr,
&dev_attr_gt_cur_freq_mhz.attr,
&dev_attr_gt_max_freq_mhz.attr,
&dev_attr_gt_min_freq_mhz.attr,
@@ -524,6 +540,7 @@ static const struct attribute *gen6_attrs[] = {
};
static const struct attribute *vlv_attrs[] = {
+ &dev_attr_gt_act_freq_mhz.attr,
&dev_attr_gt_cur_freq_mhz.attr,
&dev_attr_gt_max_freq_mhz.attr,
&dev_attr_gt_min_freq_mhz.attr,
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 751d4ad14d62..6058a01b4443 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -328,8 +328,8 @@ TRACE_EVENT(i915_gem_evict_vm,
TRACE_EVENT(i915_gem_ring_sync_to,
TP_PROTO(struct intel_engine_cs *from,
struct intel_engine_cs *to,
- u32 seqno),
- TP_ARGS(from, to, seqno),
+ struct drm_i915_gem_request *req),
+ TP_ARGS(from, to, req),
TP_STRUCT__entry(
__field(u32, dev)
@@ -342,7 +342,7 @@ TRACE_EVENT(i915_gem_ring_sync_to,
__entry->dev = from->dev->primary->index;
__entry->sync_from = from->id;
__entry->sync_to = to->id;
- __entry->seqno = seqno;
+ __entry->seqno = i915_gem_request_get_seqno(req);
),
TP_printk("dev=%u, sync-from=%u, sync-to=%u, seqno=%u",
@@ -352,8 +352,8 @@ TRACE_EVENT(i915_gem_ring_sync_to,
);
TRACE_EVENT(i915_gem_ring_dispatch,
- TP_PROTO(struct intel_engine_cs *ring, u32 seqno, u32 flags),
- TP_ARGS(ring, seqno, flags),
+ TP_PROTO(struct drm_i915_gem_request *req, u32 flags),
+ TP_ARGS(req, flags),
TP_STRUCT__entry(
__field(u32, dev)
@@ -363,11 +363,13 @@ TRACE_EVENT(i915_gem_ring_dispatch,
),
TP_fast_assign(
+ struct intel_engine_cs *ring =
+ i915_gem_request_get_ring(req);
__entry->dev = ring->dev->primary->index;
__entry->ring = ring->id;
- __entry->seqno = seqno;
+ __entry->seqno = i915_gem_request_get_seqno(req);
__entry->flags = flags;
- i915_trace_irq_get(ring, seqno);
+ i915_trace_irq_get(ring, req);
),
TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x",
@@ -398,31 +400,36 @@ TRACE_EVENT(i915_gem_ring_flush,
);
DECLARE_EVENT_CLASS(i915_gem_request,
- TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
- TP_ARGS(ring, seqno),
+ TP_PROTO(struct drm_i915_gem_request *req),
+ TP_ARGS(req),
TP_STRUCT__entry(
__field(u32, dev)
__field(u32, ring)
+ __field(u32, uniq)
__field(u32, seqno)
),
TP_fast_assign(
+ struct intel_engine_cs *ring =
+ i915_gem_request_get_ring(req);
__entry->dev = ring->dev->primary->index;
__entry->ring = ring->id;
- __entry->seqno = seqno;
+ __entry->uniq = req ? req->uniq : 0;
+ __entry->seqno = i915_gem_request_get_seqno(req);
),
- TP_printk("dev=%u, ring=%u, seqno=%u",
- __entry->dev, __entry->ring, __entry->seqno)
+ TP_printk("dev=%u, ring=%u, uniq=%u, seqno=%u",
+ __entry->dev, __entry->ring, __entry->uniq,
+ __entry->seqno)
);
DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
- TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
- TP_ARGS(ring, seqno)
+ TP_PROTO(struct drm_i915_gem_request *req),
+ TP_ARGS(req)
);
-TRACE_EVENT(i915_gem_request_complete,
+TRACE_EVENT(i915_gem_request_notify,
TP_PROTO(struct intel_engine_cs *ring),
TP_ARGS(ring),
@@ -443,17 +450,23 @@ TRACE_EVENT(i915_gem_request_complete,
);
DEFINE_EVENT(i915_gem_request, i915_gem_request_retire,
- TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
- TP_ARGS(ring, seqno)
+ TP_PROTO(struct drm_i915_gem_request *req),
+ TP_ARGS(req)
+);
+
+DEFINE_EVENT(i915_gem_request, i915_gem_request_complete,
+ TP_PROTO(struct drm_i915_gem_request *req),
+ TP_ARGS(req)
);
TRACE_EVENT(i915_gem_request_wait_begin,
- TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
- TP_ARGS(ring, seqno),
+ TP_PROTO(struct drm_i915_gem_request *req),
+ TP_ARGS(req),
TP_STRUCT__entry(
__field(u32, dev)
__field(u32, ring)
+ __field(u32, uniq)
__field(u32, seqno)
__field(bool, blocking)
),
@@ -465,20 +478,24 @@ TRACE_EVENT(i915_gem_request_wait_begin,
* less desirable.
*/
TP_fast_assign(
+ struct intel_engine_cs *ring =
+ i915_gem_request_get_ring(req);
__entry->dev = ring->dev->primary->index;
__entry->ring = ring->id;
- __entry->seqno = seqno;
- __entry->blocking = mutex_is_locked(&ring->dev->struct_mutex);
+ __entry->uniq = req ? req->uniq : 0;
+ __entry->seqno = i915_gem_request_get_seqno(req);
+ __entry->blocking =
+ mutex_is_locked(&ring->dev->struct_mutex);
),
- TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s",
- __entry->dev, __entry->ring, __entry->seqno,
- __entry->blocking ? "yes (NB)" : "no")
+ TP_printk("dev=%u, ring=%u, uniq=%u, seqno=%u, blocking=%s",
+ __entry->dev, __entry->ring, __entry->uniq,
+ __entry->seqno, __entry->blocking ? "yes (NB)" : "no")
);
DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end,
- TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
- TP_ARGS(ring, seqno)
+ TP_PROTO(struct drm_i915_gem_request *req),
+ TP_ARGS(req)
);
DECLARE_EVENT_CLASS(i915_ring,
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
new file mode 100644
index 000000000000..19a9dd5408f3
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: atomic modeset support
+ *
+ * The functions here implement the state management and hardware programming
+ * dispatch required by the atomic modeset infrastructure.
+ * See intel_atomic_plane.c for the plane-specific atomic functionality.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include "intel_drv.h"
+
+
+/**
+ * intel_atomic_check - validate state object
+ * @dev: drm device
+ * @state: state to validate
+ */
+int intel_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ int nplanes = dev->mode_config.num_total_plane;
+ int ncrtcs = dev->mode_config.num_crtc;
+ int nconnectors = dev->mode_config.num_connector;
+ enum pipe nuclear_pipe = INVALID_PIPE;
+ int ret;
+ int i;
+ bool not_nuclear = false;
+
+ /*
+ * FIXME: At the moment, we only support "nuclear pageflip" on a
+ * single CRTC. Cross-crtc updates will be added later.
+ */
+ for (i = 0; i < nplanes; i++) {
+ struct intel_plane *plane = to_intel_plane(state->planes[i]);
+ if (!plane)
+ continue;
+
+ if (nuclear_pipe == INVALID_PIPE) {
+ nuclear_pipe = plane->pipe;
+ } else if (nuclear_pipe != plane->pipe) {
+ DRM_DEBUG_KMS("i915 only support atomic plane operations on a single CRTC at the moment\n");
+ return -EINVAL;
+ }
+ }
+
+ /*
+ * FIXME: We only handle planes for now; make sure there are no CRTC's
+ * or connectors involved.
+ */
+ state->allow_modeset = false;
+ for (i = 0; i < ncrtcs; i++) {
+ struct intel_crtc *crtc = to_intel_crtc(state->crtcs[i]);
+ if (crtc && crtc->pipe != nuclear_pipe)
+ not_nuclear = true;
+ }
+ for (i = 0; i < nconnectors; i++)
+ if (state->connectors[i] != NULL)
+ not_nuclear = true;
+
+ if (not_nuclear) {
+ DRM_DEBUG_KMS("i915 only supports atomic plane operations at the moment\n");
+ return -EINVAL;
+ }
+
+ ret = drm_atomic_helper_check_planes(dev, state);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+
+/**
+ * intel_atomic_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the top-level driver state object
+ * @async: asynchronous commit
+ *
+ * This function commits a top-level state object that has been validated
+ * with drm_atomic_helper_check().
+ *
+ * FIXME: Atomic modeset support for i915 is not yet complete. At the moment
+ * we can only handle plane-related operations and do not yet support
+ * asynchronous commit.
+ *
+ * RETURNS
+ * Zero for success or -errno.
+ */
+int intel_atomic_commit(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ bool async)
+{
+ int ret;
+ int i;
+
+ if (async) {
+ DRM_DEBUG_KMS("i915 does not yet support async commit\n");
+ return -EINVAL;
+ }
+
+ ret = drm_atomic_helper_prepare_planes(dev, state);
+ if (ret)
+ return ret;
+
+ /* Point of no return */
+
+ /*
+ * FIXME: The proper sequence here will eventually be:
+ *
+ * drm_atomic_helper_swap_state(dev, state)
+ * drm_atomic_helper_commit_pre_planes(dev, state);
+ * drm_atomic_helper_commit_planes(dev, state);
+ * drm_atomic_helper_commit_post_planes(dev, state);
+ * drm_atomic_helper_wait_for_vblanks(dev, state);
+ * drm_atomic_helper_cleanup_planes(dev, state);
+ * drm_atomic_state_free(state);
+ *
+ * once we have full atomic modeset. For now, just manually update
+ * plane states to avoid clobbering good states with dummy states
+ * while nuclear pageflipping.
+ */
+ for (i = 0; i < dev->mode_config.num_total_plane; i++) {
+ struct drm_plane *plane = state->planes[i];
+
+ if (!plane)
+ continue;
+
+ plane->state->state = state;
+ swap(state->plane_states[i], plane->state);
+ plane->state->state = NULL;
+ }
+ drm_atomic_helper_commit_planes(dev, state);
+ drm_atomic_helper_wait_for_vblanks(dev, state);
+ drm_atomic_helper_cleanup_planes(dev, state);
+ drm_atomic_state_free(state);
+
+ return 0;
+}
+
+/**
+ * intel_connector_atomic_get_property - fetch connector property value
+ * @connector: connector to fetch property for
+ * @state: state containing the property value
+ * @property: property to look up
+ * @val: pointer to write property value into
+ *
+ * The DRM core does not store shadow copies of properties for
+ * atomic-capable drivers. This entrypoint is used to fetch
+ * the current value of a driver-specific connector property.
+ */
+int
+intel_connector_atomic_get_property(struct drm_connector *connector,
+ const struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t *val)
+{
+ int i;
+
+ /*
+ * TODO: We only have atomic modeset for planes at the moment, so the
+ * crtc/connector code isn't quite ready yet. Until it's ready,
+ * continue to look up all property values in the DRM's shadow copy
+ * in obj->properties->values[].
+ *
+ * When the crtc/connector state work matures, this function should
+ * be updated to read the values out of the state structure instead.
+ */
+ for (i = 0; i < connector->base.properties->count; i++) {
+ if (connector->base.properties->properties[i] == property) {
+ *val = connector->base.properties->values[i];
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*
+ * intel_crtc_duplicate_state - duplicate crtc state
+ * @crtc: drm crtc
+ *
+ * Allocates and returns a copy of the crtc state (both common and
+ * Intel-specific) for the specified crtc.
+ *
+ * Returns: The newly allocated crtc state, or NULL on failure.
+ */
+struct drm_crtc_state *
+intel_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ if (WARN_ON(!intel_crtc->config))
+ return kzalloc(sizeof(*intel_crtc->config), GFP_KERNEL);
+
+ return kmemdup(intel_crtc->config, sizeof(*intel_crtc->config),
+ GFP_KERNEL);
+}
+
+/**
+ * intel_crtc_destroy_state - destroy crtc state
+ * @crtc: drm crtc
+ *
+ * Destroys the crtc state (both common and Intel-specific) for the
+ * specified crtc.
+ */
+void
+intel_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ drm_atomic_helper_crtc_destroy_state(crtc, state);
+}
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
new file mode 100644
index 000000000000..9e6f727dfd19
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: atomic plane helpers
+ *
+ * The functions here are used by the atomic plane helper functions to
+ * implement legacy plane updates (i.e., drm_plane->update_plane() and
+ * drm_plane->disable_plane()). This allows plane updates to use the
+ * atomic state infrastructure and perform plane updates as separate
+ * prepare/check/commit/cleanup steps.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include "intel_drv.h"
+
+/**
+ * intel_create_plane_state - create plane state object
+ * @plane: drm plane
+ *
+ * Allocates a fresh plane state for the given plane and sets some of
+ * the state values to sensible initial values.
+ *
+ * Returns: A newly allocated plane state, or NULL on failure
+ */
+struct intel_plane_state *
+intel_create_plane_state(struct drm_plane *plane)
+{
+ struct intel_plane_state *state;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return NULL;
+
+ state->base.plane = plane;
+ state->base.rotation = BIT(DRM_ROTATE_0);
+
+ return state;
+}
+
+/**
+ * intel_plane_duplicate_state - duplicate plane state
+ * @plane: drm plane
+ *
+ * Allocates and returns a copy of the plane state (both common and
+ * Intel-specific) for the specified plane.
+ *
+ * Returns: The newly allocated plane state, or NULL on failure.
+ */
+struct drm_plane_state *
+intel_plane_duplicate_state(struct drm_plane *plane)
+{
+ struct drm_plane_state *state;
+ struct intel_plane_state *intel_state;
+
+ if (WARN_ON(!plane->state))
+ intel_state = intel_create_plane_state(plane);
+ else
+ intel_state = kmemdup(plane->state, sizeof(*intel_state),
+ GFP_KERNEL);
+
+ if (!intel_state)
+ return NULL;
+
+ state = &intel_state->base;
+ if (state->fb)
+ drm_framebuffer_reference(state->fb);
+
+ return state;
+}
+
+/**
+ * intel_plane_destroy_state - destroy plane state
+ * @plane: drm plane
+ * @state: state object to destroy
+ *
+ * Destroys the plane state (both common and Intel-specific) for the
+ * specified plane.
+ */
+void
+intel_plane_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ drm_atomic_helper_plane_destroy_state(plane, state);
+}
+
+static int intel_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct drm_crtc *crtc = state->crtc;
+ struct intel_crtc *intel_crtc;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct intel_plane_state *intel_state = to_intel_plane_state(state);
+
+ crtc = crtc ? crtc : plane->crtc;
+ intel_crtc = to_intel_crtc(crtc);
+
+ /*
+ * Both crtc and plane->crtc could be NULL if we're updating a
+ * property while the plane is disabled. We don't actually have
+ * anything driver-specific we need to test in that case, so
+ * just return success.
+ */
+ if (!crtc)
+ return 0;
+
+ /*
+ * The original src/dest coordinates are stored in state->base, but
+ * we want to keep another copy internal to our driver that we can
+ * clip/modify ourselves.
+ */
+ intel_state->src.x1 = state->src_x;
+ intel_state->src.y1 = state->src_y;
+ intel_state->src.x2 = state->src_x + state->src_w;
+ intel_state->src.y2 = state->src_y + state->src_h;
+ intel_state->dst.x1 = state->crtc_x;
+ intel_state->dst.y1 = state->crtc_y;
+ intel_state->dst.x2 = state->crtc_x + state->crtc_w;
+ intel_state->dst.y2 = state->crtc_y + state->crtc_h;
+
+ /* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
+ intel_state->clip.x1 = 0;
+ intel_state->clip.y1 = 0;
+ intel_state->clip.x2 =
+ intel_crtc->active ? intel_crtc->config->pipe_src_w : 0;
+ intel_state->clip.y2 =
+ intel_crtc->active ? intel_crtc->config->pipe_src_h : 0;
+
+ /*
+ * Disabling a plane is always okay; we just need to update
+ * fb tracking in a special way since cleanup_fb() won't
+ * get called by the plane helpers.
+ */
+ if (state->fb == NULL && plane->state->fb != NULL) {
+ /*
+ * 'prepare' is never called when plane is being disabled, so
+ * we need to handle frontbuffer tracking as a special case
+ */
+ intel_crtc->atomic.disabled_planes |=
+ (1 << drm_plane_index(plane));
+ }
+
+ return intel_plane->check_plane(plane, intel_state);
+}
+
+static void intel_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct intel_plane_state *intel_state =
+ to_intel_plane_state(plane->state);
+
+ /* Don't disable an already disabled plane */
+ if (!plane->state->fb && !old_state->fb)
+ return;
+
+ intel_plane->commit_plane(plane, intel_state);
+}
+
+const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
+ .prepare_fb = intel_prepare_plane_fb,
+ .cleanup_fb = intel_cleanup_plane_fb,
+ .atomic_check = intel_plane_atomic_check,
+ .atomic_update = intel_plane_atomic_update,
+};
+
+/**
+ * intel_plane_atomic_get_property - fetch plane property value
+ * @plane: plane to fetch property for
+ * @state: state containing the property value
+ * @property: property to look up
+ * @val: pointer to write property value into
+ *
+ * The DRM core does not store shadow copies of properties for
+ * atomic-capable drivers. This entrypoint is used to fetch
+ * the current value of a driver-specific plane property.
+ */
+int
+intel_plane_atomic_get_property(struct drm_plane *plane,
+ const struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t *val)
+{
+ struct drm_mode_config *config = &plane->dev->mode_config;
+
+ if (property == config->rotation_property) {
+ *val = state->rotation;
+ } else {
+ DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * intel_plane_atomic_set_property - set plane property value
+ * @plane: plane to set property for
+ * @state: state to update property value in
+ * @property: property to set
+ * @val: value to set property to
+ *
+ * Writes the specified property value for a plane into the provided atomic
+ * state object.
+ *
+ * Returns 0 on success, -EINVAL on unrecognized properties
+ */
+int
+intel_plane_atomic_set_property(struct drm_plane *plane,
+ struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t val)
+{
+ struct drm_mode_config *config = &plane->dev->mode_config;
+
+ if (property == config->rotation_property) {
+ state->rotation = val;
+ } else {
+ DRM_DEBUG_KMS("Unknown plane property '%s'\n", property->name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index ee41b882e71a..2396cc702d18 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -400,7 +400,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
{
struct drm_encoder *encoder = &intel_encoder->base;
struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
- struct drm_display_mode *mode = &crtc->config.adjusted_mode;
+ struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
struct drm_connector *connector;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index a4bd90f36a03..3f178258d9f9 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -664,6 +664,50 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
}
}
+static void
+parse_psr(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
+{
+ struct bdb_psr *psr;
+ struct psr_table *psr_table;
+
+ psr = find_section(bdb, BDB_PSR);
+ if (!psr) {
+ DRM_DEBUG_KMS("No PSR BDB found.\n");
+ return;
+ }
+
+ psr_table = &psr->psr_table[panel_type];
+
+ dev_priv->vbt.psr.full_link = psr_table->full_link;
+ dev_priv->vbt.psr.require_aux_wakeup = psr_table->require_aux_to_wakeup;
+
+ /* Allowed VBT values goes from 0 to 15 */
+ dev_priv->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
+ psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames;
+
+ switch (psr_table->lines_to_wait) {
+ case 0:
+ dev_priv->vbt.psr.lines_to_wait = PSR_0_LINES_TO_WAIT;
+ break;
+ case 1:
+ dev_priv->vbt.psr.lines_to_wait = PSR_1_LINE_TO_WAIT;
+ break;
+ case 2:
+ dev_priv->vbt.psr.lines_to_wait = PSR_4_LINES_TO_WAIT;
+ break;
+ case 3:
+ dev_priv->vbt.psr.lines_to_wait = PSR_8_LINES_TO_WAIT;
+ break;
+ default:
+ DRM_DEBUG_KMS("VBT has unknown PSR lines to wait %u\n",
+ psr_table->lines_to_wait);
+ break;
+ }
+
+ dev_priv->vbt.psr.tp1_wakeup_time = psr_table->tp1_wakeup_time;
+ dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time;
+}
+
static u8 *goto_next_sequence(u8 *data, int *size)
{
u16 len;
@@ -1241,6 +1285,7 @@ intel_parse_bios(struct drm_device *dev)
parse_device_mapping(dev_priv, bdb);
parse_driver_features(dev_priv, bdb);
parse_edp(dev_priv, bdb);
+ parse_psr(dev_priv, bdb);
parse_mipi(dev_priv, bdb);
parse_ddi_ports(dev_priv, bdb);
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 7603765c91fc..a6a8710f665f 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -80,7 +80,7 @@ struct vbios_data {
#define BDB_EXT_MMIO_REGS 6
#define BDB_SWF_IO 7
#define BDB_SWF_MMIO 8
-#define BDB_DOT_CLOCK_TABLE 9
+#define BDB_PSR 9
#define BDB_MODE_REMOVAL_TABLE 10
#define BDB_CHILD_DEVICE_TABLE 11
#define BDB_DRIVER_FEATURES 12
@@ -556,6 +556,26 @@ struct bdb_edp {
u16 edp_t3_optimization;
} __packed;
+struct psr_table {
+ /* Feature bits */
+ u8 full_link:1;
+ u8 require_aux_to_wakeup:1;
+ u8 feature_bits_rsvd:6;
+
+ /* Wait times */
+ u8 idle_frames:4;
+ u8 lines_to_wait:3;
+ u8 wait_times_rsvd:1;
+
+ /* TP wake up time in multiple of 100 */
+ u16 tp1_wakeup_time;
+ u16 tp2_tp3_wakeup_time;
+} __packed;
+
+struct bdb_psr {
+ struct psr_table psr_table[16];
+} __packed;
+
void intel_setup_bios(struct drm_device *dev);
int intel_parse_bios(struct drm_device *dev);
@@ -798,7 +818,8 @@ struct mipi_config {
#define DUAL_LINK_PIXEL_ALT 2
u16 dual_link:2;
u16 lane_cnt:2;
- u16 rsvd3:12;
+ u16 pixel_overlap:3;
+ u16 rsvd3:9;
u16 rsvd4;
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index a9af9a4866db..e66e17af0a56 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -28,6 +28,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
@@ -110,31 +111,31 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
}
static void intel_crt_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = encoder->base.dev;
int dotclock;
- pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder);
+ pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
dotclock = pipe_config->port_clock;
if (HAS_PCH_SPLIT(dev))
ironlake_check_encoder_dotclock(pipe_config, dotclock);
- pipe_config->adjusted_mode.crtc_clock = dotclock;
+ pipe_config->base.adjusted_mode.crtc_clock = dotclock;
}
static void hsw_crt_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
intel_ddi_get_config(encoder, pipe_config);
- pipe_config->adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
+ pipe_config->base.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_PVSYNC |
DRM_MODE_FLAG_NVSYNC);
- pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder);
+ pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
}
static void hsw_crt_pre_enable(struct intel_encoder *encoder)
@@ -157,7 +158,7 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crt *crt = intel_encoder_to_crt(encoder);
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
- struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
u32 adpa;
if (INTEL_INFO(dev)->gen >= 5)
@@ -303,7 +304,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
}
static bool intel_crt_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = encoder->base.dev;
@@ -792,6 +793,8 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = intel_crt_destroy,
.set_property = intel_crt_set_property,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+ .atomic_get_property = intel_connector_atomic_get_property,
};
static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e6b45cd150d3..f14e8a2a022d 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -128,15 +128,15 @@ static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
};
static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
- { 0x00000018, 0x000000a0 },
- { 0x00004014, 0x00000098 },
+ { 0x00000018, 0x000000a2 },
+ { 0x00004014, 0x0000009B },
{ 0x00006012, 0x00000088 },
- { 0x00008010, 0x00000080 },
- { 0x00000018, 0x00000098 },
+ { 0x00008010, 0x00000087 },
+ { 0x00000018, 0x0000009B },
{ 0x00004014, 0x00000088 },
- { 0x00006012, 0x00000080 },
+ { 0x00006012, 0x00000087 },
{ 0x00000018, 0x00000088 },
- { 0x00004014, 0x00000080 },
+ { 0x00004014, 0x00000087 },
};
static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
@@ -328,7 +328,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
/* Enable the PCH Receiver FDI PLL */
rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
FDI_RX_PLL_ENABLE |
- FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
+ FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
POSTING_READ(_FDI_RXA_CTL);
udelay(220);
@@ -338,8 +338,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
/* Configure Port Clock Select */
- I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config.ddi_pll_sel);
- WARN_ON(intel_crtc->config.ddi_pll_sel != PORT_CLK_SEL_SPLL);
+ I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
+ WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
/* Start the training iterating through available voltages and emphasis,
* testing each value twice. */
@@ -357,7 +357,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
* port reversal bit */
I915_WRITE(DDI_BUF_CTL(PORT_E),
DDI_BUF_CTL_ENABLE |
- ((intel_crtc->config.fdi_lanes - 1) << 1) |
+ ((intel_crtc->config->fdi_lanes - 1) << 1) |
DDI_BUF_TRANS_SELECT(i / 2));
POSTING_READ(DDI_BUF_CTL(PORT_E));
@@ -732,7 +732,7 @@ static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
static void skl_ddi_clock_get(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
int link_clock = 0;
@@ -768,15 +768,15 @@ static void skl_ddi_clock_get(struct intel_encoder *encoder,
pipe_config->port_clock = link_clock;
if (pipe_config->has_dp_encoder)
- pipe_config->adjusted_mode.crtc_clock =
+ pipe_config->base.adjusted_mode.crtc_clock =
intel_dotclock_calculate(pipe_config->port_clock,
&pipe_config->dp_m_n);
else
- pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
+ pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
}
static void hsw_ddi_clock_get(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
int link_clock = 0;
@@ -820,21 +820,26 @@ static void hsw_ddi_clock_get(struct intel_encoder *encoder,
pipe_config->port_clock = link_clock * 2;
if (pipe_config->has_pch_encoder)
- pipe_config->adjusted_mode.crtc_clock =
+ pipe_config->base.adjusted_mode.crtc_clock =
intel_dotclock_calculate(pipe_config->port_clock,
&pipe_config->fdi_m_n);
else if (pipe_config->has_dp_encoder)
- pipe_config->adjusted_mode.crtc_clock =
+ pipe_config->base.adjusted_mode.crtc_clock =
intel_dotclock_calculate(pipe_config->port_clock,
&pipe_config->dp_m_n);
else
- pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
+ pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
}
void intel_ddi_clock_get(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
- hsw_ddi_clock_get(encoder, pipe_config);
+ struct drm_device *dev = encoder->base.dev;
+
+ if (INTEL_INFO(dev)->gen <= 8)
+ hsw_ddi_clock_get(encoder, pipe_config);
+ else
+ skl_ddi_clock_get(encoder, pipe_config);
}
static void
@@ -904,6 +909,7 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
static bool
hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
+ struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder,
int clock)
{
@@ -918,16 +924,16 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
WRPLL_DIVIDER_POST(p);
- intel_crtc->new_config->dpll_hw_state.wrpll = val;
+ crtc_state->dpll_hw_state.wrpll = val;
- pll = intel_get_shared_dpll(intel_crtc);
+ pll = intel_get_shared_dpll(intel_crtc, crtc_state);
if (pll == NULL) {
DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
pipe_name(intel_crtc->pipe));
return false;
}
- intel_crtc->new_config->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
+ crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
}
return true;
@@ -1090,6 +1096,7 @@ found:
static bool
skl_ddi_pll_select(struct intel_crtc *intel_crtc,
+ struct intel_crtc_state *crtc_state,
struct intel_encoder *intel_encoder,
int clock)
{
@@ -1139,11 +1146,11 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
} else /* eDP */
return true;
- intel_crtc->new_config->dpll_hw_state.ctrl1 = ctrl1;
- intel_crtc->new_config->dpll_hw_state.cfgcr1 = cfgcr1;
- intel_crtc->new_config->dpll_hw_state.cfgcr2 = cfgcr2;
+ crtc_state->dpll_hw_state.ctrl1 = ctrl1;
+ crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
+ crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
- pll = intel_get_shared_dpll(intel_crtc);
+ pll = intel_get_shared_dpll(intel_crtc, crtc_state);
if (pll == NULL) {
DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
pipe_name(intel_crtc->pipe));
@@ -1151,7 +1158,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
}
/* shared DPLL id 0 is DPLL 1 */
- intel_crtc->new_config->ddi_pll_sel = pll->id + 1;
+ crtc_state->ddi_pll_sel = pll->id + 1;
return true;
}
@@ -1163,17 +1170,20 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
* For private DPLLs, compute_config() should do the selection for us. This
* function should be folded into compute_config() eventually.
*/
-bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
+bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
+ struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = intel_crtc->base.dev;
struct intel_encoder *intel_encoder =
intel_ddi_get_crtc_new_encoder(intel_crtc);
- int clock = intel_crtc->new_config->port_clock;
+ int clock = crtc_state->port_clock;
if (IS_SKYLAKE(dev))
- return skl_ddi_pll_select(intel_crtc, intel_encoder, clock);
+ return skl_ddi_pll_select(intel_crtc, crtc_state,
+ intel_encoder, clock);
else
- return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock);
+ return hsw_ddi_pll_select(intel_crtc, crtc_state,
+ intel_encoder, clock);
}
void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
@@ -1181,13 +1191,13 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
int type = intel_encoder->type;
uint32_t temp;
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
temp = TRANS_MSA_SYNC_CLK;
- switch (intel_crtc->config.pipe_bpp) {
+ switch (intel_crtc->config->pipe_bpp) {
case 18:
temp |= TRANS_MSA_6_BPC;
break;
@@ -1212,7 +1222,7 @@ void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
uint32_t temp;
temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
if (state == true)
@@ -1230,7 +1240,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = intel_crtc->pipe;
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
enum port port = intel_ddi_get_encoder_port(intel_encoder);
int type = intel_encoder->type;
uint32_t temp;
@@ -1239,7 +1249,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
temp = TRANS_DDI_FUNC_ENABLE;
temp |= TRANS_DDI_SELECT_PORT(port);
- switch (intel_crtc->config.pipe_bpp) {
+ switch (intel_crtc->config->pipe_bpp) {
case 18:
temp |= TRANS_DDI_BPC_6;
break;
@@ -1256,9 +1266,9 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
BUG();
}
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
+ if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
temp |= TRANS_DDI_PVSYNC;
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
+ if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
temp |= TRANS_DDI_PHSYNC;
if (cpu_transcoder == TRANSCODER_EDP) {
@@ -1269,8 +1279,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
* using motion blur mitigation (which we don't
* support). */
if (IS_HASWELL(dev) &&
- (intel_crtc->config.pch_pfit.enabled ||
- intel_crtc->config.pch_pfit.force_thru))
+ (intel_crtc->config->pch_pfit.enabled ||
+ intel_crtc->config->pch_pfit.force_thru))
temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
else
temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1288,14 +1298,14 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
}
if (type == INTEL_OUTPUT_HDMI) {
- if (intel_crtc->config.has_hdmi_sink)
+ if (intel_crtc->config->has_hdmi_sink)
temp |= TRANS_DDI_MODE_SELECT_HDMI;
else
temp |= TRANS_DDI_MODE_SELECT_DVI;
} else if (type == INTEL_OUTPUT_ANALOG) {
temp |= TRANS_DDI_MODE_SELECT_FDI;
- temp |= (intel_crtc->config.fdi_lanes - 1) << 1;
+ temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
} else if (type == INTEL_OUTPUT_DISPLAYPORT ||
type == INTEL_OUTPUT_EDP) {
@@ -1445,7 +1455,7 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
enum port port = intel_ddi_get_encoder_port(intel_encoder);
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
if (cpu_transcoder != TRANSCODER_EDP)
I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
@@ -1455,7 +1465,7 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
{
struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
if (cpu_transcoder != TRANSCODER_EDP)
I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
@@ -1477,7 +1487,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
}
if (IS_SKYLAKE(dev)) {
- uint32_t dpll = crtc->config.ddi_pll_sel;
+ uint32_t dpll = crtc->config->ddi_pll_sel;
uint32_t val;
/*
@@ -1492,7 +1502,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
DPLL_CTRL1_SSC(dpll) |
DPLL_CRTL1_LINK_RATE_MASK(dpll));
- val |= crtc->config.dpll_hw_state.ctrl1 << (dpll * 6);
+ val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
I915_WRITE(DPLL_CTRL1, val);
POSTING_READ(DPLL_CTRL1);
@@ -1509,8 +1519,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
I915_WRITE(DPLL_CTRL2, val);
} else {
- WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
- I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
+ WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
+ I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
}
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
@@ -1527,8 +1537,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
intel_hdmi->set_infoframes(encoder,
- crtc->config.has_hdmi_sink,
- &crtc->config.adjusted_mode);
+ crtc->config->has_hdmi_sink,
+ &crtc->config->base.adjusted_mode);
}
}
@@ -1600,9 +1610,10 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
intel_edp_backlight_on(intel_dp);
intel_psr_enable(intel_dp);
+ intel_edp_drrs_enable(intel_dp);
}
- if (intel_crtc->config.has_audio) {
+ if (intel_crtc->config->has_audio) {
intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
intel_audio_codec_enable(intel_encoder);
}
@@ -1617,7 +1628,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (intel_crtc->config.has_audio) {
+ if (intel_crtc->config->has_audio) {
intel_audio_codec_disable(intel_encoder);
intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
}
@@ -1625,6 +1636,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
if (type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ intel_edp_drrs_disable(intel_dp);
intel_psr_disable(intel_dp);
intel_edp_backlight_off(intel_dp);
}
@@ -2022,14 +2034,13 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
}
void intel_ddi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
struct intel_hdmi *intel_hdmi;
u32 temp, flags = 0;
- struct drm_device *dev = dev_priv->dev;
temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
if (temp & TRANS_DDI_PHSYNC)
@@ -2041,7 +2052,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
else
flags |= DRM_MODE_FLAG_NVSYNC;
- pipe_config->adjusted_mode.flags |= flags;
+ pipe_config->base.adjusted_mode.flags |= flags;
switch (temp & TRANS_DDI_BPC_MASK) {
case TRANS_DDI_BPC_6:
@@ -2106,10 +2117,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
}
- if (INTEL_INFO(dev)->gen <= 8)
- hsw_ddi_clock_get(encoder, pipe_config);
- else
- skl_ddi_clock_get(encoder, pipe_config);
+ intel_ddi_clock_get(encoder, pipe_config);
}
static void intel_ddi_destroy(struct drm_encoder *encoder)
@@ -2119,7 +2127,7 @@ static void intel_ddi_destroy(struct drm_encoder *encoder)
}
static bool intel_ddi_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
int type = encoder->type;
int port = intel_ddi_get_encoder_port(encoder);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e7a16f119a29..3d220a67f865 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -37,6 +37,7 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_dp_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
@@ -76,9 +77,9 @@ static const uint32_t intel_cursor_formats[] = {
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
int x, int y, struct drm_framebuffer *old_fb);
@@ -95,9 +96,11 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc);
static void haswell_set_pipeconf(struct drm_crtc *crtc);
static void intel_set_pipe_csc(struct drm_crtc *crtc);
static void vlv_prepare_pll(struct intel_crtc *crtc,
- const struct intel_crtc_config *pipe_config);
+ const struct intel_crtc_state *pipe_config);
static void chv_prepare_pll(struct intel_crtc *crtc,
- const struct intel_crtc_config *pipe_config);
+ const struct intel_crtc_state *pipe_config);
+static void intel_begin_crtc_commit(struct drm_crtc *crtc);
+static void intel_finish_crtc_commit(struct drm_crtc *crtc);
static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
{
@@ -895,7 +898,7 @@ bool intel_crtc_active(struct drm_crtc *crtc)
* properly reconstruct framebuffers.
*/
return intel_crtc->active && crtc->primary->fb &&
- intel_crtc->config.adjusted_mode.crtc_clock;
+ intel_crtc->config->base.adjusted_mode.crtc_clock;
}
enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
@@ -904,7 +907,7 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- return intel_crtc->config.cpu_transcoder;
+ return intel_crtc->config->cpu_transcoder;
}
static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
@@ -946,7 +949,7 @@ static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
enum pipe pipe = crtc->pipe;
if (INTEL_INFO(dev)->gen >= 4) {
@@ -1024,7 +1027,7 @@ void assert_pll(struct drm_i915_private *dev_priv,
reg = DPLL(pipe);
val = I915_READ(reg);
cur_state = !!(val & DPLL_VCO_ENABLE);
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"PLL state assertion failure (expected %s, current %s)\n",
state_string(state), state_string(cur_state));
}
@@ -1040,7 +1043,7 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
mutex_unlock(&dev_priv->dpio_lock);
cur_state = val & DSI_PLL_VCO_EN;
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"DSI PLL state assertion failure (expected %s, current %s)\n",
state_string(state), state_string(cur_state));
}
@@ -1052,10 +1055,10 @@ intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
- if (crtc->config.shared_dpll < 0)
+ if (crtc->config->shared_dpll < 0)
return NULL;
- return &dev_priv->shared_dplls[crtc->config.shared_dpll];
+ return &dev_priv->shared_dplls[crtc->config->shared_dpll];
}
/* For ILK+ */
@@ -1071,7 +1074,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
return;
cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"%s assertion failure (expected %s, current %s)\n",
pll->name, state_string(state), state_string(cur_state));
}
@@ -1095,7 +1098,7 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv,
val = I915_READ(reg);
cur_state = !!(val & FDI_TX_ENABLE);
}
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"FDI TX state assertion failure (expected %s, current %s)\n",
state_string(state), state_string(cur_state));
}
@@ -1112,7 +1115,7 @@ static void assert_fdi_rx(struct drm_i915_private *dev_priv,
reg = FDI_RX_CTL(pipe);
val = I915_READ(reg);
cur_state = !!(val & FDI_RX_ENABLE);
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"FDI RX state assertion failure (expected %s, current %s)\n",
state_string(state), state_string(cur_state));
}
@@ -1135,7 +1138,7 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
reg = FDI_TX_CTL(pipe);
val = I915_READ(reg);
- WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
+ I915_STATE_WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
}
void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
@@ -1148,7 +1151,7 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
reg = FDI_RX_CTL(pipe);
val = I915_READ(reg);
cur_state = !!(val & FDI_RX_PLL_ENABLE);
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"FDI RX PLL assertion failure (expected %s, current %s)\n",
state_string(state), state_string(cur_state));
}
@@ -1190,7 +1193,7 @@ void assert_panel_unlocked(struct drm_i915_private *dev_priv,
((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS))
locked = false;
- WARN(panel_pipe == pipe && locked,
+ I915_STATE_WARN(panel_pipe == pipe && locked,
"panel assertion failure, pipe %c regs locked\n",
pipe_name(pipe));
}
@@ -1206,7 +1209,7 @@ static void assert_cursor(struct drm_i915_private *dev_priv,
else
cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"cursor on pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), state_string(state), state_string(cur_state));
}
@@ -1236,7 +1239,7 @@ void assert_pipe(struct drm_i915_private *dev_priv,
cur_state = !!(val & PIPECONF_ENABLE);
}
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), state_string(state), state_string(cur_state));
}
@@ -1251,7 +1254,7 @@ static void assert_plane(struct drm_i915_private *dev_priv,
reg = DSPCNTR(plane);
val = I915_READ(reg);
cur_state = !!(val & DISPLAY_PLANE_ENABLE);
- WARN(cur_state != state,
+ I915_STATE_WARN(cur_state != state,
"plane %c assertion failure (expected %s, current %s)\n",
plane_name(plane), state_string(state), state_string(cur_state));
}
@@ -1271,7 +1274,7 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv,
if (INTEL_INFO(dev)->gen >= 4) {
reg = DSPCNTR(pipe);
val = I915_READ(reg);
- WARN(val & DISPLAY_PLANE_ENABLE,
+ I915_STATE_WARN(val & DISPLAY_PLANE_ENABLE,
"plane %c assertion failure, should be disabled but not\n",
plane_name(pipe));
return;
@@ -1283,7 +1286,7 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv,
val = I915_READ(reg);
cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
DISPPLANE_SEL_PIPE_SHIFT;
- WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
+ I915_STATE_WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
"plane %c assertion failure, should be off on pipe %c but is still active\n",
plane_name(i), pipe_name(pipe));
}
@@ -1299,7 +1302,7 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
if (INTEL_INFO(dev)->gen >= 9) {
for_each_sprite(pipe, sprite) {
val = I915_READ(PLANE_CTL(pipe, sprite));
- WARN(val & PLANE_CTL_ENABLE,
+ I915_STATE_WARN(val & PLANE_CTL_ENABLE,
"plane %d assertion failure, should be off on pipe %c but is still active\n",
sprite, pipe_name(pipe));
}
@@ -1307,20 +1310,20 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
for_each_sprite(pipe, sprite) {
reg = SPCNTR(pipe, sprite);
val = I915_READ(reg);
- WARN(val & SP_ENABLE,
+ I915_STATE_WARN(val & SP_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n",
sprite_name(pipe, sprite), pipe_name(pipe));
}
} else if (INTEL_INFO(dev)->gen >= 7) {
reg = SPRCTL(pipe);
val = I915_READ(reg);
- WARN(val & SPRITE_ENABLE,
+ I915_STATE_WARN(val & SPRITE_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n",
plane_name(pipe), pipe_name(pipe));
} else if (INTEL_INFO(dev)->gen >= 5) {
reg = DVSCNTR(pipe);
val = I915_READ(reg);
- WARN(val & DVS_ENABLE,
+ I915_STATE_WARN(val & DVS_ENABLE,
"sprite %c assertion failure, should be off on pipe %c but is still active\n",
plane_name(pipe), pipe_name(pipe));
}
@@ -1328,7 +1331,7 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
static void assert_vblank_disabled(struct drm_crtc *crtc)
{
- if (WARN_ON(drm_crtc_vblank_get(crtc) == 0))
+ if (I915_STATE_WARN_ON(drm_crtc_vblank_get(crtc) == 0))
drm_crtc_vblank_put(crtc);
}
@@ -1337,12 +1340,12 @@ static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
u32 val;
bool enabled;
- WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev)));
+ I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev)));
val = I915_READ(PCH_DREF_CONTROL);
enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
DREF_SUPERSPREAD_SOURCE_MASK));
- WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
+ I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
}
static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
@@ -1355,7 +1358,7 @@ static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
reg = PCH_TRANSCONF(pipe);
val = I915_READ(reg);
enabled = !!(val & TRANS_ENABLE);
- WARN(enabled,
+ I915_STATE_WARN(enabled,
"transcoder assertion failed, should be off on pipe %c but is still active\n",
pipe_name(pipe));
}
@@ -1435,11 +1438,11 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe, int reg, u32 port_sel)
{
u32 val = I915_READ(reg);
- WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
+ I915_STATE_WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
"PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
reg, pipe_name(pipe));
- WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0
+ I915_STATE_WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0
&& (val & DP_PIPEB_SELECT),
"IBX PCH dp port still using transcoder B\n");
}
@@ -1448,11 +1451,11 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe, int reg)
{
u32 val = I915_READ(reg);
- WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
+ I915_STATE_WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
"PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
reg, pipe_name(pipe));
- WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_ENABLE) == 0
+ I915_STATE_WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_ENABLE) == 0
&& (val & SDVO_PIPE_B_SELECT),
"IBX PCH hdmi port still using transcoder B\n");
}
@@ -1469,13 +1472,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
reg = PCH_ADPA;
val = I915_READ(reg);
- WARN(adpa_pipe_enabled(dev_priv, pipe, val),
+ I915_STATE_WARN(adpa_pipe_enabled(dev_priv, pipe, val),
"PCH VGA enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
reg = PCH_LVDS;
val = I915_READ(reg);
- WARN(lvds_pipe_enabled(dev_priv, pipe, val),
+ I915_STATE_WARN(lvds_pipe_enabled(dev_priv, pipe, val),
"PCH LVDS enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
@@ -1505,7 +1508,7 @@ static void intel_init_dpio(struct drm_device *dev)
}
static void vlv_enable_pll(struct intel_crtc *crtc,
- const struct intel_crtc_config *pipe_config)
+ const struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1544,7 +1547,7 @@ static void vlv_enable_pll(struct intel_crtc *crtc,
}
static void chv_enable_pll(struct intel_crtc *crtc,
- const struct intel_crtc_config *pipe_config)
+ const struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1599,7 +1602,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int reg = DPLL(crtc->pipe);
- u32 dpll = crtc->config.dpll_hw_state.dpll;
+ u32 dpll = crtc->config->dpll_hw_state.dpll;
assert_pipe_disabled(dev_priv, crtc->pipe);
@@ -1629,7 +1632,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
if (INTEL_INFO(dev)->gen >= 4) {
I915_WRITE(DPLL_MD(crtc->pipe),
- crtc->config.dpll_hw_state.dpll_md);
+ crtc->config->dpll_hw_state.dpll_md);
} else {
/* The pixel multiplier can only be updated once the
* DPLL is enabled and the clocks are stable.
@@ -2034,7 +2037,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
else
assert_pll_enabled(dev_priv, pipe);
else {
- if (crtc->config.has_pch_encoder) {
+ if (crtc->config->has_pch_encoder) {
/* if driving the PCH, we need FDI enabled */
assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
assert_fdi_tx_pll_enabled(dev_priv,
@@ -2068,7 +2071,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
static void intel_disable_pipe(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
- enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
enum pipe pipe = crtc->pipe;
int reg;
u32 val;
@@ -2090,7 +2093,7 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
* Double wide has implications for planes
* so best keep it disabled when not needed.
*/
- if (crtc->config.double_wide)
+ if (crtc->config->double_wide)
val &= ~PIPECONF_DOUBLE_WIDE;
/* Don't disable pipe or pipe PLLs if needed */
@@ -2165,7 +2168,8 @@ static void intel_disable_primary_hw_plane(struct drm_plane *plane,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- assert_pipe_enabled(dev_priv, intel_crtc->pipe);
+ if (WARN_ON(!intel_crtc->active))
+ return;
if (!intel_crtc->primary_enabled)
return;
@@ -2185,11 +2189,12 @@ static bool need_vtd_wa(struct drm_device *dev)
return false;
}
-static int intel_align_height(struct drm_device *dev, int height, bool tiled)
+int
+intel_fb_align_height(struct drm_device *dev, int height, unsigned int tiling)
{
int tile_height;
- tile_height = tiled ? (IS_GEN2(dev) ? 16 : 8) : 1;
+ tile_height = tiling ? (IS_GEN2(dev) ? 16 : 8) : 1;
return ALIGN(height, tile_height);
}
@@ -2312,7 +2317,7 @@ unsigned long intel_gen4_compute_page_offset(int *x, int *y,
}
}
-int intel_format_to_fourcc(int format)
+static int i9xx_format_to_fourcc(int format)
{
switch (format) {
case DISPPLANE_8BPP:
@@ -2333,8 +2338,35 @@ int intel_format_to_fourcc(int format)
}
}
-static bool intel_alloc_plane_obj(struct intel_crtc *crtc,
- struct intel_plane_config *plane_config)
+static int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
+{
+ switch (format) {
+ case PLANE_CTL_FORMAT_RGB_565:
+ return DRM_FORMAT_RGB565;
+ default:
+ case PLANE_CTL_FORMAT_XRGB_8888:
+ if (rgb_order) {
+ if (alpha)
+ return DRM_FORMAT_ABGR8888;
+ else
+ return DRM_FORMAT_XBGR8888;
+ } else {
+ if (alpha)
+ return DRM_FORMAT_ARGB8888;
+ else
+ return DRM_FORMAT_XRGB8888;
+ }
+ case PLANE_CTL_FORMAT_XRGB_2101010:
+ if (rgb_order)
+ return DRM_FORMAT_XBGR2101010;
+ else
+ return DRM_FORMAT_XRGB2101010;
+ }
+}
+
+static bool
+intel_alloc_plane_obj(struct intel_crtc *crtc,
+ struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_gem_object *obj = NULL;
@@ -2349,10 +2381,9 @@ static bool intel_alloc_plane_obj(struct intel_crtc *crtc,
if (!obj)
return false;
- if (plane_config->tiled) {
- obj->tiling_mode = I915_TILING_X;
+ obj->tiling_mode = plane_config->tiling;
+ if (obj->tiling_mode == I915_TILING_X)
obj->stride = crtc->base.primary->fb->pitches[0];
- }
mode_cmd.pixel_format = crtc->base.primary->fb->pixel_format;
mode_cmd.width = crtc->base.primary->fb->width;
@@ -2379,8 +2410,9 @@ out_unref_obj:
return false;
}
-static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
- struct intel_plane_config *plane_config)
+static void
+intel_find_plane_obj(struct intel_crtc *intel_crtc,
+ struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2468,13 +2500,13 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
* which should always be the user's requested size.
*/
I915_WRITE(DSPSIZE(plane),
- ((intel_crtc->config.pipe_src_h - 1) << 16) |
- (intel_crtc->config.pipe_src_w - 1));
+ ((intel_crtc->config->pipe_src_h - 1) << 16) |
+ (intel_crtc->config->pipe_src_w - 1));
I915_WRITE(DSPPOS(plane), 0);
} else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) {
I915_WRITE(PRIMSIZE(plane),
- ((intel_crtc->config.pipe_src_h - 1) << 16) |
- (intel_crtc->config.pipe_src_w - 1));
+ ((intel_crtc->config->pipe_src_h - 1) << 16) |
+ (intel_crtc->config->pipe_src_w - 1));
I915_WRITE(PRIMPOS(plane), 0);
I915_WRITE(PRIMCNSTALPHA(plane), 0);
}
@@ -2529,17 +2561,17 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
intel_crtc->dspaddr_offset = linear_offset;
}
- if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+ if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
dspcntr |= DISPPLANE_ROTATE_180;
- x += (intel_crtc->config.pipe_src_w - 1);
- y += (intel_crtc->config.pipe_src_h - 1);
+ x += (intel_crtc->config->pipe_src_w - 1);
+ y += (intel_crtc->config->pipe_src_h - 1);
/* Finding the last pixel of the last line of the display
data and adding to linear_offset*/
linear_offset +=
- (intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
- (intel_crtc->config.pipe_src_w - 1) * pixel_size;
+ (intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
+ (intel_crtc->config->pipe_src_w - 1) * pixel_size;
}
I915_WRITE(reg, dspcntr);
@@ -2631,18 +2663,18 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
pixel_size,
fb->pitches[0]);
linear_offset -= intel_crtc->dspaddr_offset;
- if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+ if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
dspcntr |= DISPPLANE_ROTATE_180;
if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
- x += (intel_crtc->config.pipe_src_w - 1);
- y += (intel_crtc->config.pipe_src_h - 1);
+ x += (intel_crtc->config->pipe_src_w - 1);
+ y += (intel_crtc->config->pipe_src_h - 1);
/* Finding the last pixel of the last line of the display
data and adding to linear_offset*/
linear_offset +=
- (intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
- (intel_crtc->config.pipe_src_w - 1) * pixel_size;
+ (intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
+ (intel_crtc->config->pipe_src_w - 1) * pixel_size;
}
}
@@ -2728,7 +2760,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
}
plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
- if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180))
+ if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180))
plane_ctl |= PLANE_CTL_ROTATE_180;
I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
@@ -2741,8 +2773,8 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
I915_WRITE(PLANE_POS(pipe, 0), 0);
I915_WRITE(PLANE_OFFSET(pipe, 0), (y << 16) | x);
I915_WRITE(PLANE_SIZE(pipe, 0),
- (intel_crtc->config.pipe_src_h - 1) << 16 |
- (intel_crtc->config.pipe_src_w - 1));
+ (intel_crtc->config->pipe_src_h - 1) << 16 |
+ (intel_crtc->config->pipe_src_w - 1));
I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj));
@@ -2938,85 +2970,20 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
* then update the pipesrc and pfit state, even on the flip path.
*/
- adjusted_mode = &crtc->config.adjusted_mode;
+ adjusted_mode = &crtc->config->base.adjusted_mode;
I915_WRITE(PIPESRC(crtc->pipe),
((adjusted_mode->crtc_hdisplay - 1) << 16) |
(adjusted_mode->crtc_vdisplay - 1));
- if (!crtc->config.pch_pfit.enabled &&
+ if (!crtc->config->pch_pfit.enabled &&
(intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
I915_WRITE(PF_CTL(crtc->pipe), 0);
I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
}
- crtc->config.pipe_src_w = adjusted_mode->crtc_hdisplay;
- crtc->config.pipe_src_h = adjusted_mode->crtc_vdisplay;
-}
-
-static int
-intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *fb)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
- struct drm_framebuffer *old_fb = crtc->primary->fb;
- struct drm_i915_gem_object *old_obj = intel_fb_obj(old_fb);
- int ret;
-
- if (intel_crtc_has_pending_flip(crtc)) {
- DRM_ERROR("pipe is still busy with an old pageflip\n");
- return -EBUSY;
- }
-
- /* no fb bound */
- if (!fb) {
- DRM_ERROR("No FB bound\n");
- return 0;
- }
-
- if (intel_crtc->plane > INTEL_INFO(dev)->num_pipes) {
- DRM_ERROR("no plane for crtc: plane %c, num_pipes %d\n",
- plane_name(intel_crtc->plane),
- INTEL_INFO(dev)->num_pipes);
- return -EINVAL;
- }
-
- mutex_lock(&dev->struct_mutex);
- ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, NULL);
- if (ret == 0)
- i915_gem_track_fb(old_obj, intel_fb_obj(fb),
- INTEL_FRONTBUFFER_PRIMARY(pipe));
- mutex_unlock(&dev->struct_mutex);
- if (ret != 0) {
- DRM_ERROR("pin & fence failed\n");
- return ret;
- }
-
- dev_priv->display.update_primary_plane(crtc, fb, x, y);
-
- if (intel_crtc->active)
- intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
-
- crtc->primary->fb = fb;
- crtc->x = x;
- crtc->y = y;
-
- if (old_fb) {
- if (intel_crtc->active && old_fb != fb)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(old_obj);
- mutex_unlock(&dev->struct_mutex);
- }
-
- mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
+ crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
+ crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
}
static void intel_fdi_normal_train(struct drm_crtc *crtc)
@@ -3063,7 +3030,7 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
static bool pipe_has_enabled_pch(struct intel_crtc *crtc)
{
return crtc->base.enabled && crtc->active &&
- crtc->config.has_pch_encoder;
+ crtc->config->has_pch_encoder;
}
static void ivb_modeset_global_resources(struct drm_device *dev)
@@ -3118,7 +3085,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_DP_PORT_WIDTH_MASK;
- temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
+ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_1;
I915_WRITE(reg, temp | FDI_TX_ENABLE);
@@ -3216,7 +3183,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_DP_PORT_WIDTH_MASK;
- temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
+ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_PATTERN_1;
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
@@ -3367,7 +3334,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_DP_PORT_WIDTH_MASK;
- temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
+ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
temp |= snb_b_fdi_train_param[j/2];
@@ -3455,7 +3422,7 @@ static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
- temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
+ temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE);
@@ -3639,7 +3606,7 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
+ int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
u32 divsel, phaseinc, auxdiv, phasedir = 0;
u32 temp;
@@ -3728,7 +3695,7 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder),
I915_READ(HTOTAL(cpu_transcoder)));
@@ -3774,7 +3741,7 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
case PIPE_A:
break;
case PIPE_B:
- if (intel_crtc->config.fdi_lanes > 2)
+ if (intel_crtc->config->fdi_lanes > 2)
WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT);
else
cpt_enable_fdi_bc_bifurcation(dev);
@@ -3826,7 +3793,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
temp = I915_READ(PCH_DPLL_SEL);
temp |= TRANS_DPLL_ENABLE(pipe);
sel = TRANS_DPLLB_SEL(pipe);
- if (intel_crtc->config.shared_dpll == DPLL_ID_PCH_PLL_B)
+ if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B)
temp |= sel;
else
temp &= ~sel;
@@ -3849,7 +3816,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
intel_fdi_normal_train(crtc);
/* For PCH DP, enable TRANS_DP_CTL */
- if (HAS_PCH_CPT(dev) && intel_crtc->config.has_dp_encoder) {
+ if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) {
u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
reg = TRANS_DP_CTL(pipe);
temp = I915_READ(reg);
@@ -3890,7 +3857,7 @@ static void lpt_pch_enable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
@@ -3920,10 +3887,11 @@ void intel_put_shared_dpll(struct intel_crtc *crtc)
WARN_ON(pll->active);
}
- crtc->config.shared_dpll = DPLL_ID_PRIVATE;
+ crtc->config->shared_dpll = DPLL_ID_PRIVATE;
}
-struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
+struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct intel_shared_dpll *pll;
@@ -3949,7 +3917,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
if (pll->new_config->crtc_mask == 0)
continue;
- if (memcmp(&crtc->new_config->dpll_hw_state,
+ if (memcmp(&crtc_state->dpll_hw_state,
&pll->new_config->hw_state,
sizeof(pll->new_config->hw_state)) == 0) {
DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n",
@@ -3974,9 +3942,9 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
found:
if (pll->new_config->crtc_mask == 0)
- pll->new_config->hw_state = crtc->new_config->dpll_hw_state;
+ pll->new_config->hw_state = crtc_state->dpll_hw_state;
- crtc->new_config->shared_dpll = i;
+ crtc_state->shared_dpll = i;
DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
pipe_name(crtc->pipe));
@@ -4073,10 +4041,10 @@ static void skylake_pfit_enable(struct intel_crtc *crtc)
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = crtc->pipe;
- if (crtc->config.pch_pfit.enabled) {
+ if (crtc->config->pch_pfit.enabled) {
I915_WRITE(PS_CTL(pipe), PS_ENABLE);
- I915_WRITE(PS_WIN_POS(pipe), crtc->config.pch_pfit.pos);
- I915_WRITE(PS_WIN_SZ(pipe), crtc->config.pch_pfit.size);
+ I915_WRITE(PS_WIN_POS(pipe), crtc->config->pch_pfit.pos);
+ I915_WRITE(PS_WIN_SZ(pipe), crtc->config->pch_pfit.size);
}
}
@@ -4086,7 +4054,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = crtc->pipe;
- if (crtc->config.pch_pfit.enabled) {
+ if (crtc->config->pch_pfit.enabled) {
/* Force use of hard-coded filter coefficients
* as some pre-programmed values are broken,
* e.g. x201.
@@ -4096,12 +4064,12 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
PF_PIPE_SEL_IVB(pipe));
else
I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
- I915_WRITE(PF_WIN_POS(pipe), crtc->config.pch_pfit.pos);
- I915_WRITE(PF_WIN_SZ(pipe), crtc->config.pch_pfit.size);
+ I915_WRITE(PF_WIN_POS(pipe), crtc->config->pch_pfit.pos);
+ I915_WRITE(PF_WIN_SZ(pipe), crtc->config->pch_pfit.size);
}
}
-static void intel_enable_planes(struct drm_crtc *crtc)
+static void intel_enable_sprite_planes(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
enum pipe pipe = to_intel_crtc(crtc)->pipe;
@@ -4115,7 +4083,7 @@ static void intel_enable_planes(struct drm_crtc *crtc)
}
}
-static void intel_disable_planes(struct drm_crtc *crtc)
+static void intel_disable_sprite_planes(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
enum pipe pipe = to_intel_crtc(crtc)->pipe;
@@ -4125,7 +4093,7 @@ static void intel_disable_planes(struct drm_crtc *crtc)
drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
intel_plane = to_intel_plane(plane);
if (intel_plane->pipe == pipe)
- intel_plane_disable(&intel_plane->base);
+ plane->funcs->disable_plane(plane);
}
}
@@ -4134,7 +4102,7 @@ void hsw_enable_ips(struct intel_crtc *crtc)
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!crtc->config.ips_enabled)
+ if (!crtc->config->ips_enabled)
return;
/* We can only enable IPS after we enable a plane and wait for a vblank */
@@ -4167,7 +4135,7 @@ void hsw_disable_ips(struct intel_crtc *crtc)
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!crtc->config.ips_enabled)
+ if (!crtc->config->ips_enabled)
return;
assert_plane_enabled(dev_priv, crtc->plane);
@@ -4216,7 +4184,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
/* Workaround : Do not read or write the pipe palette/gamma data while
* GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
*/
- if (IS_HASWELL(dev) && intel_crtc->config.ips_enabled &&
+ if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled &&
((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
GAMMA_MODE_MODE_SPLIT)) {
hsw_disable_ips(intel_crtc);
@@ -4259,14 +4227,14 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc)
int pipe = intel_crtc->pipe;
intel_enable_primary_hw_plane(crtc->primary, crtc);
- intel_enable_planes(crtc);
+ intel_enable_sprite_planes(crtc);
intel_crtc_update_cursor(crtc, true);
intel_crtc_dpms_overlay(intel_crtc, true);
hsw_enable_ips(intel_crtc);
mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
+ intel_fbc_update(dev);
mutex_unlock(&dev->struct_mutex);
/*
@@ -4288,13 +4256,13 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc)
intel_crtc_wait_for_pending_flips(crtc);
if (dev_priv->fbc.plane == plane)
- intel_disable_fbc(dev);
+ intel_fbc_disable(dev);
hsw_disable_ips(intel_crtc);
intel_crtc_dpms_overlay(intel_crtc, false);
intel_crtc_update_cursor(crtc, false);
- intel_disable_planes(crtc);
+ intel_disable_sprite_planes(crtc);
intel_disable_primary_hw_plane(crtc->primary, crtc);
/*
@@ -4318,17 +4286,17 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
if (intel_crtc->active)
return;
- if (intel_crtc->config.has_pch_encoder)
+ if (intel_crtc->config->has_pch_encoder)
intel_prepare_shared_dpll(intel_crtc);
- if (intel_crtc->config.has_dp_encoder)
+ if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc);
intel_set_pipe_timings(intel_crtc);
- if (intel_crtc->config.has_pch_encoder) {
+ if (intel_crtc->config->has_pch_encoder) {
intel_cpu_transcoder_set_m_n(intel_crtc,
- &intel_crtc->config.fdi_m_n, NULL);
+ &intel_crtc->config->fdi_m_n, NULL);
}
ironlake_set_pipeconf(crtc);
@@ -4342,7 +4310,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
if (encoder->pre_enable)
encoder->pre_enable(encoder);
- if (intel_crtc->config.has_pch_encoder) {
+ if (intel_crtc->config->has_pch_encoder) {
/* Note: FDI PLL enabling _must_ be done before we enable the
* cpu pipes, hence this is separate from all the other fdi/pch
* enabling. */
@@ -4363,18 +4331,18 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
intel_update_watermarks(crtc);
intel_enable_pipe(intel_crtc);
- if (intel_crtc->config.has_pch_encoder)
+ if (intel_crtc->config->has_pch_encoder)
ironlake_pch_enable(crtc);
+ assert_vblank_disabled(crtc);
+ drm_crtc_vblank_on(crtc);
+
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
if (HAS_PCH_CPT(dev))
cpt_verify_modeset(dev, intel_crtc->pipe);
- assert_vblank_disabled(crtc);
- drm_crtc_vblank_on(crtc);
-
intel_crtc_enable_planes(crtc);
}
@@ -4429,19 +4397,19 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
if (intel_crtc_to_shared_dpll(intel_crtc))
intel_enable_shared_dpll(intel_crtc);
- if (intel_crtc->config.has_dp_encoder)
+ if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc);
intel_set_pipe_timings(intel_crtc);
- if (intel_crtc->config.cpu_transcoder != TRANSCODER_EDP) {
- I915_WRITE(PIPE_MULT(intel_crtc->config.cpu_transcoder),
- intel_crtc->config.pixel_multiplier - 1);
+ if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) {
+ I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder),
+ intel_crtc->config->pixel_multiplier - 1);
}
- if (intel_crtc->config.has_pch_encoder) {
+ if (intel_crtc->config->has_pch_encoder) {
intel_cpu_transcoder_set_m_n(intel_crtc,
- &intel_crtc->config.fdi_m_n, NULL);
+ &intel_crtc->config->fdi_m_n, NULL);
}
haswell_set_pipeconf(crtc);
@@ -4455,7 +4423,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
if (encoder->pre_enable)
encoder->pre_enable(encoder);
- if (intel_crtc->config.has_pch_encoder) {
+ if (intel_crtc->config->has_pch_encoder) {
intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
true);
dev_priv->display.fdi_link_train(crtc);
@@ -4480,20 +4448,20 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_update_watermarks(crtc);
intel_enable_pipe(intel_crtc);
- if (intel_crtc->config.has_pch_encoder)
+ if (intel_crtc->config->has_pch_encoder)
lpt_pch_enable(crtc);
- if (intel_crtc->config.dp_encoder_is_mst)
+ if (intel_crtc->config->dp_encoder_is_mst)
intel_ddi_set_vc_payload_alloc(crtc, true);
+ assert_vblank_disabled(crtc);
+ drm_crtc_vblank_on(crtc);
+
for_each_encoder_on_crtc(dev, crtc, encoder) {
encoder->enable(encoder);
intel_opregion_notify_encoder(encoder, true);
}
- assert_vblank_disabled(crtc);
- drm_crtc_vblank_on(crtc);
-
/* If we change the relative order between pipe/planes enabling, we need
* to change the workaround. */
haswell_mode_set_planes_workaround(intel_crtc);
@@ -4508,7 +4476,7 @@ static void skylake_pfit_disable(struct intel_crtc *crtc)
/* To avoid upsetting the power well on haswell only disable the pfit if
* it's in use. The hw state code will make sure we get this right. */
- if (crtc->config.pch_pfit.enabled) {
+ if (crtc->config->pch_pfit.enabled) {
I915_WRITE(PS_CTL(pipe), 0);
I915_WRITE(PS_WIN_POS(pipe), 0);
I915_WRITE(PS_WIN_SZ(pipe), 0);
@@ -4523,7 +4491,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
/* To avoid upsetting the power well on haswell only disable the pfit if
* it's in use. The hw state code will make sure we get this right. */
- if (crtc->config.pch_pfit.enabled) {
+ if (crtc->config->pch_pfit.enabled) {
I915_WRITE(PF_CTL(pipe), 0);
I915_WRITE(PF_WIN_POS(pipe), 0);
I915_WRITE(PF_WIN_SZ(pipe), 0);
@@ -4544,13 +4512,13 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
intel_crtc_disable_planes(crtc);
- drm_crtc_vblank_off(crtc);
- assert_vblank_disabled(crtc);
-
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder);
- if (intel_crtc->config.has_pch_encoder)
+ drm_crtc_vblank_off(crtc);
+ assert_vblank_disabled(crtc);
+
+ if (intel_crtc->config->has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
intel_disable_pipe(intel_crtc);
@@ -4561,7 +4529,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
if (encoder->post_disable)
encoder->post_disable(encoder);
- if (intel_crtc->config.has_pch_encoder) {
+ if (intel_crtc->config->has_pch_encoder) {
ironlake_fdi_disable(crtc);
ironlake_disable_pch_transcoder(dev_priv, pipe);
@@ -4591,7 +4559,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
intel_update_watermarks(crtc);
mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
+ intel_fbc_update(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -4601,27 +4569,27 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
if (!intel_crtc->active)
return;
intel_crtc_disable_planes(crtc);
- drm_crtc_vblank_off(crtc);
- assert_vblank_disabled(crtc);
-
for_each_encoder_on_crtc(dev, crtc, encoder) {
intel_opregion_notify_encoder(encoder, false);
encoder->disable(encoder);
}
- if (intel_crtc->config.has_pch_encoder)
+ drm_crtc_vblank_off(crtc);
+ assert_vblank_disabled(crtc);
+
+ if (intel_crtc->config->has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
false);
intel_disable_pipe(intel_crtc);
- if (intel_crtc->config.dp_encoder_is_mst)
+ if (intel_crtc->config->dp_encoder_is_mst)
intel_ddi_set_vc_payload_alloc(crtc, false);
intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
@@ -4633,7 +4601,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
intel_ddi_disable_pipe_clock(intel_crtc);
- if (intel_crtc->config.has_pch_encoder) {
+ if (intel_crtc->config->has_pch_encoder) {
lpt_disable_pch_transcoder(dev_priv);
intel_ddi_fdi_disable(crtc);
}
@@ -4646,7 +4614,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
intel_update_watermarks(crtc);
mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
+ intel_fbc_update(dev);
mutex_unlock(&dev->struct_mutex);
if (intel_crtc_to_shared_dpll(intel_crtc))
@@ -4664,9 +4632,9 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc_config *pipe_config = &crtc->config;
+ struct intel_crtc_state *pipe_config = crtc->config;
- if (!crtc->config.gmch_pfit.control)
+ if (!pipe_config->gmch_pfit.control)
return;
/*
@@ -4745,8 +4713,8 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
mask = BIT(POWER_DOMAIN_PIPE(pipe));
mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
- if (intel_crtc->config.pch_pfit.enabled ||
- intel_crtc->config.pch_pfit.force_thru)
+ if (intel_crtc->config->pch_pfit.enabled ||
+ intel_crtc->config->pch_pfit.force_thru)
mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
@@ -4909,7 +4877,7 @@ static void cherryview_set_cdclk(struct drm_device *dev, int cdclk)
cmd = 0;
break;
default:
- WARN_ON(1);
+ MISSING_CASE(cdclk);
return;
}
@@ -4970,7 +4938,7 @@ static int intel_mode_max_pixclk(struct drm_i915_private *dev_priv)
for_each_intel_crtc(dev, intel_crtc) {
if (intel_crtc->new_enabled)
max_pixclk = max(max_pixclk,
- intel_crtc->new_config->adjusted_mode.crtc_clock);
+ intel_crtc->new_config->base.adjusted_mode.crtc_clock);
}
return max_pixclk;
@@ -5038,12 +5006,12 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
if (!is_dsi) {
if (IS_CHERRYVIEW(dev))
- chv_prepare_pll(intel_crtc, &intel_crtc->config);
+ chv_prepare_pll(intel_crtc, intel_crtc->config);
else
- vlv_prepare_pll(intel_crtc, &intel_crtc->config);
+ vlv_prepare_pll(intel_crtc, intel_crtc->config);
}
- if (intel_crtc->config.has_dp_encoder)
+ if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc);
intel_set_pipe_timings(intel_crtc);
@@ -5067,9 +5035,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
if (!is_dsi) {
if (IS_CHERRYVIEW(dev))
- chv_enable_pll(intel_crtc, &intel_crtc->config);
+ chv_enable_pll(intel_crtc, intel_crtc->config);
else
- vlv_enable_pll(intel_crtc, &intel_crtc->config);
+ vlv_enable_pll(intel_crtc, intel_crtc->config);
}
for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -5083,12 +5051,12 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
intel_update_watermarks(crtc);
intel_enable_pipe(intel_crtc);
- for_each_encoder_on_crtc(dev, crtc, encoder)
- encoder->enable(encoder);
-
assert_vblank_disabled(crtc);
drm_crtc_vblank_on(crtc);
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->enable(encoder);
+
intel_crtc_enable_planes(crtc);
/* Underruns don't raise interrupts, so check manually. */
@@ -5100,8 +5068,8 @@ static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- I915_WRITE(FP0(crtc->pipe), crtc->config.dpll_hw_state.fp0);
- I915_WRITE(FP1(crtc->pipe), crtc->config.dpll_hw_state.fp1);
+ I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0);
+ I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1);
}
static void i9xx_crtc_enable(struct drm_crtc *crtc)
@@ -5119,7 +5087,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
i9xx_set_pll_dividers(intel_crtc);
- if (intel_crtc->config.has_dp_encoder)
+ if (intel_crtc->config->has_dp_encoder)
intel_dp_set_m_n(intel_crtc);
intel_set_pipe_timings(intel_crtc);
@@ -5144,12 +5112,12 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
intel_update_watermarks(crtc);
intel_enable_pipe(intel_crtc);
- for_each_encoder_on_crtc(dev, crtc, encoder)
- encoder->enable(encoder);
-
assert_vblank_disabled(crtc);
drm_crtc_vblank_on(crtc);
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->enable(encoder);
+
intel_crtc_enable_planes(crtc);
/*
@@ -5171,7 +5139,7 @@ static void i9xx_pfit_disable(struct intel_crtc *crtc)
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!crtc->config.gmch_pfit.control)
+ if (!crtc->config->gmch_pfit.control)
return;
assert_pipe_disabled(dev_priv, crtc->pipe);
@@ -5221,12 +5189,12 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
*/
intel_wait_for_vblank(dev, pipe);
- drm_crtc_vblank_off(crtc);
- assert_vblank_disabled(crtc);
-
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder);
+ drm_crtc_vblank_off(crtc);
+ assert_vblank_disabled(crtc);
+
intel_disable_pipe(intel_crtc);
i9xx_pfit_disable(intel_crtc);
@@ -5251,7 +5219,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
intel_update_watermarks(crtc);
mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
+ intel_fbc_update(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -5309,8 +5277,6 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_connector *connector;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *old_obj = intel_fb_obj(crtc->primary->fb);
- enum pipe pipe = to_intel_crtc(crtc)->pipe;
/* crtc should still be enabled when we disable it. */
WARN_ON(!crtc->enabled);
@@ -5318,14 +5284,7 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
dev_priv->display.crtc_disable(crtc);
dev_priv->display.off(crtc);
- if (crtc->primary->fb) {
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(old_obj);
- i915_gem_track_fb(old_obj, NULL,
- INTEL_FRONTBUFFER_PRIMARY(pipe));
- mutex_unlock(&dev->struct_mutex);
- crtc->primary->fb = NULL;
- }
+ crtc->primary->funcs->disable_plane(crtc->primary);
/* Update computed state. */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -5382,25 +5341,25 @@ static void intel_connector_check_state(struct intel_connector *connector)
if (connector->mst_port)
return;
- WARN(connector->base.dpms == DRM_MODE_DPMS_OFF,
+ I915_STATE_WARN(connector->base.dpms == DRM_MODE_DPMS_OFF,
"wrong connector dpms state\n");
- WARN(connector->base.encoder != &encoder->base,
+ I915_STATE_WARN(connector->base.encoder != &encoder->base,
"active connector not linked to encoder\n");
if (encoder) {
- WARN(!encoder->connectors_active,
+ I915_STATE_WARN(!encoder->connectors_active,
"encoder->connectors_active not set\n");
encoder_enabled = encoder->get_hw_state(encoder, &pipe);
- WARN(!encoder_enabled, "encoder not enabled\n");
- if (WARN_ON(!encoder->base.crtc))
+ I915_STATE_WARN(!encoder_enabled, "encoder not enabled\n");
+ if (I915_STATE_WARN_ON(!encoder->base.crtc))
return;
crtc = encoder->base.crtc;
- WARN(!crtc->enabled, "crtc not enabled\n");
- WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
- WARN(pipe != to_intel_crtc(crtc)->pipe,
+ I915_STATE_WARN(!crtc->enabled, "crtc not enabled\n");
+ I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
+ I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe,
"encoder active on the wrong pipe\n");
}
}
@@ -5438,7 +5397,7 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
}
static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *pipe_B_crtc =
@@ -5479,7 +5438,7 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
return true;
case PIPE_C:
if (!pipe_has_enabled_pch(pipe_B_crtc) ||
- pipe_B_crtc->config.fdi_lanes <= 2) {
+ pipe_B_crtc->config->fdi_lanes <= 2) {
if (pipe_config->fdi_lanes > 2) {
DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n",
pipe_name(pipe), pipe_config->fdi_lanes);
@@ -5497,10 +5456,10 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
#define RETRY 1
static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = intel_crtc->base.dev;
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
int lane, link_bw, fdi_dotclock;
bool setup_ok, needs_recompute = false;
@@ -5543,7 +5502,7 @@ retry:
}
static void hsw_compute_ips_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
pipe_config->ips_enabled = i915.enable_ips &&
hsw_crtc_supports_ips(crtc) &&
@@ -5551,11 +5510,11 @@ static void hsw_compute_ips_config(struct intel_crtc *crtc,
}
static int intel_crtc_compute_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
/* FIXME should check pixel clock limits on all platforms */
if (INTEL_INFO(dev)->gen < 4) {
@@ -5800,30 +5759,31 @@ static uint32_t i9xx_dpll_compute_fp(struct dpll *dpll)
}
static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state,
intel_clock_t *reduced_clock)
{
struct drm_device *dev = crtc->base.dev;
u32 fp, fp2 = 0;
if (IS_PINEVIEW(dev)) {
- fp = pnv_dpll_compute_fp(&crtc->new_config->dpll);
+ fp = pnv_dpll_compute_fp(&crtc_state->dpll);
if (reduced_clock)
fp2 = pnv_dpll_compute_fp(reduced_clock);
} else {
- fp = i9xx_dpll_compute_fp(&crtc->new_config->dpll);
+ fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
if (reduced_clock)
fp2 = i9xx_dpll_compute_fp(reduced_clock);
}
- crtc->new_config->dpll_hw_state.fp0 = fp;
+ crtc_state->dpll_hw_state.fp0 = fp;
crtc->lowfreq_avail = false;
if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
reduced_clock && i915.powersave) {
- crtc->new_config->dpll_hw_state.fp1 = fp2;
+ crtc_state->dpll_hw_state.fp1 = fp2;
crtc->lowfreq_avail = true;
} else {
- crtc->new_config->dpll_hw_state.fp1 = fp;
+ crtc_state->dpll_hw_state.fp1 = fp;
}
}
@@ -5876,7 +5836,7 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = crtc->pipe;
- enum transcoder transcoder = crtc->config.cpu_transcoder;
+ enum transcoder transcoder = crtc->config->cpu_transcoder;
if (INTEL_INFO(dev)->gen >= 5) {
I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m);
@@ -5888,7 +5848,7 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
* registers are not unnecessarily accessed).
*/
if (m2_n2 && INTEL_INFO(dev)->gen < 8 &&
- crtc->config.has_drrs) {
+ crtc->config->has_drrs) {
I915_WRITE(PIPE_DATA_M2(transcoder),
TU_SIZE(m2_n2->tu) | m2_n2->gmch_m);
I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2->gmch_n);
@@ -5905,15 +5865,15 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
void intel_dp_set_m_n(struct intel_crtc *crtc)
{
- if (crtc->config.has_pch_encoder)
- intel_pch_transcoder_set_m_n(crtc, &crtc->config.dp_m_n);
+ if (crtc->config->has_pch_encoder)
+ intel_pch_transcoder_set_m_n(crtc, &crtc->config->dp_m_n);
else
- intel_cpu_transcoder_set_m_n(crtc, &crtc->config.dp_m_n,
- &crtc->config.dp_m2_n2);
+ intel_cpu_transcoder_set_m_n(crtc, &crtc->config->dp_m_n,
+ &crtc->config->dp_m2_n2);
}
static void vlv_update_pll(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
u32 dpll, dpll_md;
@@ -5936,7 +5896,7 @@ static void vlv_update_pll(struct intel_crtc *crtc,
}
static void vlv_prepare_pll(struct intel_crtc *crtc,
- const struct intel_crtc_config *pipe_config)
+ const struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5997,7 +5957,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe),
0x00d0000f);
- if (crtc->config.has_dp_encoder) {
+ if (pipe_config->has_dp_encoder) {
/* Use SSC source */
if (pipe == PIPE_A)
vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe),
@@ -6027,7 +5987,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
}
static void chv_update_pll(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLOCK_CHV |
DPLL_REFA_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS |
@@ -6040,7 +6000,7 @@ static void chv_update_pll(struct intel_crtc *crtc,
}
static void chv_prepare_pll(struct intel_crtc *crtc,
- const struct intel_crtc_config *pipe_config)
+ const struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6125,7 +6085,7 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
{
struct intel_crtc *crtc =
to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
- struct intel_crtc_config pipe_config = {
+ struct intel_crtc_state pipe_config = {
.pixel_multiplier = 1,
.dpll = *dpll,
};
@@ -6158,6 +6118,7 @@ void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)
}
static void i9xx_update_pll(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state,
intel_clock_t *reduced_clock,
int num_connectors)
{
@@ -6165,9 +6126,9 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll;
bool is_sdvo;
- struct dpll *clock = &crtc->new_config->dpll;
+ struct dpll *clock = &crtc_state->dpll;
- i9xx_update_pll_dividers(crtc, reduced_clock);
+ i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
is_sdvo = intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO) ||
intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI);
@@ -6180,14 +6141,14 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
dpll |= DPLLB_MODE_DAC_SERIAL;
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
- dpll |= (crtc->new_config->pixel_multiplier - 1)
+ dpll |= (crtc_state->pixel_multiplier - 1)
<< SDVO_MULTIPLIER_SHIFT_HIRES;
}
if (is_sdvo)
dpll |= DPLL_SDVO_HIGH_SPEED;
- if (crtc->new_config->has_dp_encoder)
+ if (crtc_state->has_dp_encoder)
dpll |= DPLL_SDVO_HIGH_SPEED;
/* compute bitmask from p1 value */
@@ -6215,7 +6176,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
if (INTEL_INFO(dev)->gen >= 4)
dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
- if (crtc->new_config->sdvo_tv_clock)
+ if (crtc_state->sdvo_tv_clock)
dpll |= PLL_REF_INPUT_TVCLKINBC;
else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv) && num_connectors < 2)
@@ -6224,25 +6185,26 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
dpll |= PLL_REF_INPUT_DREFCLK;
dpll |= DPLL_VCO_ENABLE;
- crtc->new_config->dpll_hw_state.dpll = dpll;
+ crtc_state->dpll_hw_state.dpll = dpll;
if (INTEL_INFO(dev)->gen >= 4) {
- u32 dpll_md = (crtc->new_config->pixel_multiplier - 1)
+ u32 dpll_md = (crtc_state->pixel_multiplier - 1)
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
- crtc->new_config->dpll_hw_state.dpll_md = dpll_md;
+ crtc_state->dpll_hw_state.dpll_md = dpll_md;
}
}
static void i8xx_update_pll(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state,
intel_clock_t *reduced_clock,
int num_connectors)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll;
- struct dpll *clock = &crtc->new_config->dpll;
+ struct dpll *clock = &crtc_state->dpll;
- i9xx_update_pll_dividers(crtc, reduced_clock);
+ i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
dpll = DPLL_VGA_MODE_DIS;
@@ -6267,7 +6229,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
dpll |= PLL_REF_INPUT_DREFCLK;
dpll |= DPLL_VCO_ENABLE;
- crtc->new_config->dpll_hw_state.dpll = dpll;
+ crtc_state->dpll_hw_state.dpll = dpll;
}
static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
@@ -6275,9 +6237,9 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = intel_crtc->pipe;
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
struct drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
+ &intel_crtc->config->base.adjusted_mode;
uint32_t crtc_vtotal, crtc_vblank_end;
int vsyncshift = 0;
@@ -6335,12 +6297,12 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
* always be the user's requested size.
*/
I915_WRITE(PIPESRC(pipe),
- ((intel_crtc->config.pipe_src_w - 1) << 16) |
- (intel_crtc->config.pipe_src_h - 1));
+ ((intel_crtc->config->pipe_src_w - 1) << 16) |
+ (intel_crtc->config->pipe_src_h - 1));
}
static void intel_get_pipe_timings(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6348,56 +6310,56 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
uint32_t tmp;
tmp = I915_READ(HTOTAL(cpu_transcoder));
- pipe_config->adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
- pipe_config->adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(HBLANK(cpu_transcoder));
- pipe_config->adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1;
- pipe_config->adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(HSYNC(cpu_transcoder));
- pipe_config->adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
- pipe_config->adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(VTOTAL(cpu_transcoder));
- pipe_config->adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
- pipe_config->adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(VBLANK(cpu_transcoder));
- pipe_config->adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1;
- pipe_config->adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1;
tmp = I915_READ(VSYNC(cpu_transcoder));
- pipe_config->adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
- pipe_config->adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
+ pipe_config->base.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
- pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
- pipe_config->adjusted_mode.crtc_vtotal += 1;
- pipe_config->adjusted_mode.crtc_vblank_end += 1;
+ pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
+ pipe_config->base.adjusted_mode.crtc_vtotal += 1;
+ pipe_config->base.adjusted_mode.crtc_vblank_end += 1;
}
tmp = I915_READ(PIPESRC(crtc->pipe));
pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
- pipe_config->requested_mode.vdisplay = pipe_config->pipe_src_h;
- pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w;
+ pipe_config->base.mode.vdisplay = pipe_config->pipe_src_h;
+ pipe_config->base.mode.hdisplay = pipe_config->pipe_src_w;
}
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
- mode->hdisplay = pipe_config->adjusted_mode.crtc_hdisplay;
- mode->htotal = pipe_config->adjusted_mode.crtc_htotal;
- mode->hsync_start = pipe_config->adjusted_mode.crtc_hsync_start;
- mode->hsync_end = pipe_config->adjusted_mode.crtc_hsync_end;
+ mode->hdisplay = pipe_config->base.adjusted_mode.crtc_hdisplay;
+ mode->htotal = pipe_config->base.adjusted_mode.crtc_htotal;
+ mode->hsync_start = pipe_config->base.adjusted_mode.crtc_hsync_start;
+ mode->hsync_end = pipe_config->base.adjusted_mode.crtc_hsync_end;
- mode->vdisplay = pipe_config->adjusted_mode.crtc_vdisplay;
- mode->vtotal = pipe_config->adjusted_mode.crtc_vtotal;
- mode->vsync_start = pipe_config->adjusted_mode.crtc_vsync_start;
- mode->vsync_end = pipe_config->adjusted_mode.crtc_vsync_end;
+ mode->vdisplay = pipe_config->base.adjusted_mode.crtc_vdisplay;
+ mode->vtotal = pipe_config->base.adjusted_mode.crtc_vtotal;
+ mode->vsync_start = pipe_config->base.adjusted_mode.crtc_vsync_start;
+ mode->vsync_end = pipe_config->base.adjusted_mode.crtc_vsync_end;
- mode->flags = pipe_config->adjusted_mode.flags;
+ mode->flags = pipe_config->base.adjusted_mode.flags;
- mode->clock = pipe_config->adjusted_mode.crtc_clock;
- mode->flags |= pipe_config->adjusted_mode.flags;
+ mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
+ mode->flags |= pipe_config->base.adjusted_mode.flags;
}
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
@@ -6412,17 +6374,17 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
(intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE;
- if (intel_crtc->config.double_wide)
+ if (intel_crtc->config->double_wide)
pipeconf |= PIPECONF_DOUBLE_WIDE;
/* only g4x and later have fancy bpc/dither controls */
if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
/* Bspec claims that we can't use dithering for 30bpp pipes. */
- if (intel_crtc->config.dither && intel_crtc->config.pipe_bpp != 30)
+ if (intel_crtc->config->dither && intel_crtc->config->pipe_bpp != 30)
pipeconf |= PIPECONF_DITHER_EN |
PIPECONF_DITHER_TYPE_SP;
- switch (intel_crtc->config.pipe_bpp) {
+ switch (intel_crtc->config->pipe_bpp) {
case 18:
pipeconf |= PIPECONF_6BPC;
break;
@@ -6447,7 +6409,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
}
}
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+ if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
if (INTEL_INFO(dev)->gen < 4 ||
intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
@@ -6456,14 +6418,15 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
} else
pipeconf |= PIPECONF_PROGRESSIVE;
- if (IS_VALLEYVIEW(dev) && intel_crtc->config.limited_color_range)
+ if (IS_VALLEYVIEW(dev) && intel_crtc->config->limited_color_range)
pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
I915_WRITE(PIPECONF(intel_crtc->pipe), pipeconf);
POSTING_READ(PIPECONF(intel_crtc->pipe));
}
-static int i9xx_crtc_compute_clock(struct intel_crtc *crtc)
+static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6495,7 +6458,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc)
if (is_dsi)
return 0;
- if (!crtc->new_config->clock_set) {
+ if (!crtc_state->clock_set) {
refclk = i9xx_get_refclk(crtc, num_connectors);
/*
@@ -6506,7 +6469,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc)
*/
limit = intel_limit(crtc, refclk);
ok = dev_priv->display.find_dpll(limit, crtc,
- crtc->new_config->port_clock,
+ crtc_state->port_clock,
refclk, NULL, &clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
@@ -6527,23 +6490,23 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc)
&reduced_clock);
}
/* Compat-code for transition, will disappear. */
- crtc->new_config->dpll.n = clock.n;
- crtc->new_config->dpll.m1 = clock.m1;
- crtc->new_config->dpll.m2 = clock.m2;
- crtc->new_config->dpll.p1 = clock.p1;
- crtc->new_config->dpll.p2 = clock.p2;
+ crtc_state->dpll.n = clock.n;
+ crtc_state->dpll.m1 = clock.m1;
+ crtc_state->dpll.m2 = clock.m2;
+ crtc_state->dpll.p1 = clock.p1;
+ crtc_state->dpll.p2 = clock.p2;
}
if (IS_GEN2(dev)) {
- i8xx_update_pll(crtc,
+ i8xx_update_pll(crtc, crtc_state,
has_reduced_clock ? &reduced_clock : NULL,
num_connectors);
} else if (IS_CHERRYVIEW(dev)) {
- chv_update_pll(crtc, crtc->new_config);
+ chv_update_pll(crtc, crtc_state);
} else if (IS_VALLEYVIEW(dev)) {
- vlv_update_pll(crtc, crtc->new_config);
+ vlv_update_pll(crtc, crtc_state);
} else {
- i9xx_update_pll(crtc,
+ i9xx_update_pll(crtc, crtc_state,
has_reduced_clock ? &reduced_clock : NULL,
num_connectors);
}
@@ -6552,7 +6515,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc)
}
static void i9xx_get_pfit_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6582,7 +6545,7 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc,
}
static void vlv_crtc_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6611,8 +6574,9 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
pipe_config->port_clock = clock.dot / 5;
}
-static void i9xx_get_plane_config(struct intel_crtc *crtc,
- struct intel_plane_config *plane_config)
+static void
+i9xx_get_initial_plane_config(struct intel_crtc *crtc,
+ struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6620,27 +6584,30 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc,
int pipe = crtc->pipe, plane = crtc->plane;
int fourcc, pixel_format;
int aligned_height;
+ struct drm_framebuffer *fb;
+ struct intel_framebuffer *intel_fb;
- crtc->base.primary->fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
- if (!crtc->base.primary->fb) {
+ intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+ if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
return;
}
+ fb = &intel_fb->base;
+
val = I915_READ(DSPCNTR(plane));
if (INTEL_INFO(dev)->gen >= 4)
if (val & DISPPLANE_TILED)
- plane_config->tiled = true;
+ plane_config->tiling = I915_TILING_X;
pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
- fourcc = intel_format_to_fourcc(pixel_format);
- crtc->base.primary->fb->pixel_format = fourcc;
- crtc->base.primary->fb->bits_per_pixel =
- drm_format_plane_cpp(fourcc, 0) * 8;
+ fourcc = i9xx_format_to_fourcc(pixel_format);
+ fb->pixel_format = fourcc;
+ fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
if (INTEL_INFO(dev)->gen >= 4) {
- if (plane_config->tiled)
+ if (plane_config->tiling)
offset = I915_READ(DSPTILEOFF(plane));
else
offset = I915_READ(DSPLINOFF(plane));
@@ -6651,29 +6618,27 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc,
plane_config->base = base;
val = I915_READ(PIPESRC(pipe));
- crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
- crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
+ fb->width = ((val >> 16) & 0xfff) + 1;
+ fb->height = ((val >> 0) & 0xfff) + 1;
val = I915_READ(DSPSTRIDE(pipe));
- crtc->base.primary->fb->pitches[0] = val & 0xffffffc0;
+ fb->pitches[0] = val & 0xffffffc0;
- aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
- plane_config->tiled);
+ aligned_height = intel_fb_align_height(dev, fb->height,
+ plane_config->tiling);
- plane_config->size = PAGE_ALIGN(crtc->base.primary->fb->pitches[0] *
- aligned_height);
+ plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height);
- DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
- pipe, plane, crtc->base.primary->fb->width,
- crtc->base.primary->fb->height,
- crtc->base.primary->fb->bits_per_pixel, base,
- crtc->base.primary->fb->pitches[0],
+ DRM_DEBUG_KMS("pipe/plane %c/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
+ pipe_name(pipe), plane, fb->width, fb->height,
+ fb->bits_per_pixel, base, fb->pitches[0],
plane_config->size);
+ crtc->base.primary->fb = fb;
}
static void chv_crtc_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6703,7 +6668,7 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc,
}
static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7183,7 +7148,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
val = 0;
- switch (intel_crtc->config.pipe_bpp) {
+ switch (intel_crtc->config->pipe_bpp) {
case 18:
val |= PIPECONF_6BPC;
break;
@@ -7201,15 +7166,15 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
BUG();
}
- if (intel_crtc->config.dither)
+ if (intel_crtc->config->dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+ if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK;
else
val |= PIPECONF_PROGRESSIVE;
- if (intel_crtc->config.limited_color_range)
+ if (intel_crtc->config->limited_color_range)
val |= PIPECONF_COLOR_RANGE_SELECT;
I915_WRITE(PIPECONF(pipe), val);
@@ -7238,7 +7203,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
* consideration.
*/
- if (intel_crtc->config.limited_color_range)
+ if (intel_crtc->config->limited_color_range)
coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */
/*
@@ -7262,7 +7227,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
if (INTEL_INFO(dev)->gen > 6) {
uint16_t postoff = 0;
- if (intel_crtc->config.limited_color_range)
+ if (intel_crtc->config->limited_color_range)
postoff = (16 * (1 << 12) / 255) & 0x1fff;
I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
@@ -7273,7 +7238,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
} else {
uint32_t mode = CSC_MODE_YUV_TO_RGB;
- if (intel_crtc->config.limited_color_range)
+ if (intel_crtc->config->limited_color_range)
mode |= CSC_BLACK_SCREEN_OFFSET;
I915_WRITE(PIPE_CSC_MODE(pipe), mode);
@@ -7286,15 +7251,15 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe;
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
uint32_t val;
val = 0;
- if (IS_HASWELL(dev) && intel_crtc->config.dither)
+ if (IS_HASWELL(dev) && intel_crtc->config->dither)
val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+ if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
val |= PIPECONF_INTERLACED_ILK;
else
val |= PIPECONF_PROGRESSIVE;
@@ -7308,7 +7273,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
val = 0;
- switch (intel_crtc->config.pipe_bpp) {
+ switch (intel_crtc->config->pipe_bpp) {
case 18:
val |= PIPEMISC_DITHER_6_BPC;
break;
@@ -7326,7 +7291,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
BUG();
}
- if (intel_crtc->config.dither)
+ if (intel_crtc->config->dither)
val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
I915_WRITE(PIPEMISC(pipe), val);
@@ -7334,6 +7299,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
}
static bool ironlake_compute_clocks(struct drm_crtc *crtc,
+ struct intel_crtc_state *crtc_state,
intel_clock_t *clock,
bool *has_reduced_clock,
intel_clock_t *reduced_clock)
@@ -7356,7 +7322,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
*/
limit = intel_limit(intel_crtc, refclk);
ret = dev_priv->display.find_dpll(limit, intel_crtc,
- intel_crtc->new_config->port_clock,
+ crtc_state->port_clock,
refclk, NULL, clock);
if (!ret)
return false;
@@ -7395,6 +7361,7 @@ static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor)
}
static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
+ struct intel_crtc_state *crtc_state,
u32 *fp,
intel_clock_t *reduced_clock, u32 *fp2)
{
@@ -7432,10 +7399,10 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
dev_priv->vbt.lvds_ssc_freq == 100000) ||
(HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev)))
factor = 25;
- } else if (intel_crtc->new_config->sdvo_tv_clock)
+ } else if (crtc_state->sdvo_tv_clock)
factor = 20;
- if (ironlake_needs_fb_cb_tune(&intel_crtc->new_config->dpll, factor))
+ if (ironlake_needs_fb_cb_tune(&crtc_state->dpll, factor))
*fp |= FP_CB_TUNE;
if (fp2 && (reduced_clock->m < factor * reduced_clock->n))
@@ -7448,20 +7415,20 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
else
dpll |= DPLLB_MODE_DAC_SERIAL;
- dpll |= (intel_crtc->new_config->pixel_multiplier - 1)
+ dpll |= (crtc_state->pixel_multiplier - 1)
<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
if (is_sdvo)
dpll |= DPLL_SDVO_HIGH_SPEED;
- if (intel_crtc->new_config->has_dp_encoder)
+ if (crtc_state->has_dp_encoder)
dpll |= DPLL_SDVO_HIGH_SPEED;
/* compute bitmask from p1 value */
- dpll |= (1 << (intel_crtc->new_config->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+ dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
/* also FPA1 */
- dpll |= (1 << (intel_crtc->new_config->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+ dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
- switch (intel_crtc->new_config->dpll.p2) {
+ switch (crtc_state->dpll.p2) {
case 5:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
break;
@@ -7484,7 +7451,8 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
return dpll | DPLL_VCO_ENABLE;
}
-static int ironlake_crtc_compute_clock(struct intel_crtc *crtc)
+static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state)
{
struct drm_device *dev = crtc->base.dev;
intel_clock_t clock, reduced_clock;
@@ -7498,39 +7466,39 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc)
WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
"Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
- ok = ironlake_compute_clocks(&crtc->base, &clock,
+ ok = ironlake_compute_clocks(&crtc->base, crtc_state, &clock,
&has_reduced_clock, &reduced_clock);
- if (!ok && !crtc->new_config->clock_set) {
+ if (!ok && !crtc_state->clock_set) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
/* Compat-code for transition, will disappear. */
- if (!crtc->new_config->clock_set) {
- crtc->new_config->dpll.n = clock.n;
- crtc->new_config->dpll.m1 = clock.m1;
- crtc->new_config->dpll.m2 = clock.m2;
- crtc->new_config->dpll.p1 = clock.p1;
- crtc->new_config->dpll.p2 = clock.p2;
+ if (!crtc_state->clock_set) {
+ crtc_state->dpll.n = clock.n;
+ crtc_state->dpll.m1 = clock.m1;
+ crtc_state->dpll.m2 = clock.m2;
+ crtc_state->dpll.p1 = clock.p1;
+ crtc_state->dpll.p2 = clock.p2;
}
/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
- if (crtc->new_config->has_pch_encoder) {
- fp = i9xx_dpll_compute_fp(&crtc->new_config->dpll);
+ if (crtc_state->has_pch_encoder) {
+ fp = i9xx_dpll_compute_fp(&crtc_state->dpll);
if (has_reduced_clock)
fp2 = i9xx_dpll_compute_fp(&reduced_clock);
- dpll = ironlake_compute_dpll(crtc,
+ dpll = ironlake_compute_dpll(crtc, crtc_state,
&fp, &reduced_clock,
has_reduced_clock ? &fp2 : NULL);
- crtc->new_config->dpll_hw_state.dpll = dpll;
- crtc->new_config->dpll_hw_state.fp0 = fp;
+ crtc_state->dpll_hw_state.dpll = dpll;
+ crtc_state->dpll_hw_state.fp0 = fp;
if (has_reduced_clock)
- crtc->new_config->dpll_hw_state.fp1 = fp2;
+ crtc_state->dpll_hw_state.fp1 = fp2;
else
- crtc->new_config->dpll_hw_state.fp1 = fp;
+ crtc_state->dpll_hw_state.fp1 = fp;
- pll = intel_get_shared_dpll(crtc);
+ pll = intel_get_shared_dpll(crtc, crtc_state);
if (pll == NULL) {
DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
pipe_name(crtc->pipe));
@@ -7584,7 +7552,7 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
* registers are not unnecessarily read).
*/
if (m2_n2 && INTEL_INFO(dev)->gen < 8 &&
- crtc->config.has_drrs) {
+ crtc->config->has_drrs) {
m2_n2->link_m = I915_READ(PIPE_LINK_M2(transcoder));
m2_n2->link_n = I915_READ(PIPE_LINK_N2(transcoder));
m2_n2->gmch_m = I915_READ(PIPE_DATA_M2(transcoder))
@@ -7605,9 +7573,9 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
}
void intel_dp_get_m_n(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
- if (crtc->config.has_pch_encoder)
+ if (pipe_config->has_pch_encoder)
intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
else
intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
@@ -7616,14 +7584,14 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,
}
static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
&pipe_config->fdi_m_n, NULL);
}
static void skylake_get_pfit_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7638,8 +7606,80 @@ static void skylake_get_pfit_config(struct intel_crtc *crtc,
}
}
+static void
+skylake_get_initial_plane_config(struct intel_crtc *crtc,
+ struct intel_initial_plane_config *plane_config)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 val, base, offset, stride_mult;
+ int pipe = crtc->pipe;
+ int fourcc, pixel_format;
+ int aligned_height;
+ struct drm_framebuffer *fb;
+ struct intel_framebuffer *intel_fb;
+
+ intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+ if (!intel_fb) {
+ DRM_DEBUG_KMS("failed to alloc fb\n");
+ return;
+ }
+
+ fb = &intel_fb->base;
+
+ val = I915_READ(PLANE_CTL(pipe, 0));
+ if (val & PLANE_CTL_TILED_MASK)
+ plane_config->tiling = I915_TILING_X;
+
+ pixel_format = val & PLANE_CTL_FORMAT_MASK;
+ fourcc = skl_format_to_fourcc(pixel_format,
+ val & PLANE_CTL_ORDER_RGBX,
+ val & PLANE_CTL_ALPHA_MASK);
+ fb->pixel_format = fourcc;
+ fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
+
+ base = I915_READ(PLANE_SURF(pipe, 0)) & 0xfffff000;
+ plane_config->base = base;
+
+ offset = I915_READ(PLANE_OFFSET(pipe, 0));
+
+ val = I915_READ(PLANE_SIZE(pipe, 0));
+ fb->height = ((val >> 16) & 0xfff) + 1;
+ fb->width = ((val >> 0) & 0x1fff) + 1;
+
+ val = I915_READ(PLANE_STRIDE(pipe, 0));
+ switch (plane_config->tiling) {
+ case I915_TILING_NONE:
+ stride_mult = 64;
+ break;
+ case I915_TILING_X:
+ stride_mult = 512;
+ break;
+ default:
+ MISSING_CASE(plane_config->tiling);
+ goto error;
+ }
+ fb->pitches[0] = (val & 0x3ff) * stride_mult;
+
+ aligned_height = intel_fb_align_height(dev, fb->height,
+ plane_config->tiling);
+
+ plane_config->size = ALIGN(fb->pitches[0] * aligned_height, PAGE_SIZE);
+
+ DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
+ pipe_name(pipe), fb->width, fb->height,
+ fb->bits_per_pixel, base, fb->pitches[0],
+ plane_config->size);
+
+ crtc->base.primary->fb = fb;
+ return;
+
+error:
+ kfree(fb);
+}
+
static void ironlake_get_pfit_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7662,68 +7702,71 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc,
}
}
-static void ironlake_get_plane_config(struct intel_crtc *crtc,
- struct intel_plane_config *plane_config)
+static void
+ironlake_get_initial_plane_config(struct intel_crtc *crtc,
+ struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, base, offset;
- int pipe = crtc->pipe, plane = crtc->plane;
+ int pipe = crtc->pipe;
int fourcc, pixel_format;
int aligned_height;
+ struct drm_framebuffer *fb;
+ struct intel_framebuffer *intel_fb;
- crtc->base.primary->fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
- if (!crtc->base.primary->fb) {
+ intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+ if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
return;
}
- val = I915_READ(DSPCNTR(plane));
+ fb = &intel_fb->base;
+
+ val = I915_READ(DSPCNTR(pipe));
if (INTEL_INFO(dev)->gen >= 4)
if (val & DISPPLANE_TILED)
- plane_config->tiled = true;
+ plane_config->tiling = I915_TILING_X;
pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
- fourcc = intel_format_to_fourcc(pixel_format);
- crtc->base.primary->fb->pixel_format = fourcc;
- crtc->base.primary->fb->bits_per_pixel =
- drm_format_plane_cpp(fourcc, 0) * 8;
+ fourcc = i9xx_format_to_fourcc(pixel_format);
+ fb->pixel_format = fourcc;
+ fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
- base = I915_READ(DSPSURF(plane)) & 0xfffff000;
+ base = I915_READ(DSPSURF(pipe)) & 0xfffff000;
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
- offset = I915_READ(DSPOFFSET(plane));
+ offset = I915_READ(DSPOFFSET(pipe));
} else {
- if (plane_config->tiled)
- offset = I915_READ(DSPTILEOFF(plane));
+ if (plane_config->tiling)
+ offset = I915_READ(DSPTILEOFF(pipe));
else
- offset = I915_READ(DSPLINOFF(plane));
+ offset = I915_READ(DSPLINOFF(pipe));
}
plane_config->base = base;
val = I915_READ(PIPESRC(pipe));
- crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
- crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
+ fb->width = ((val >> 16) & 0xfff) + 1;
+ fb->height = ((val >> 0) & 0xfff) + 1;
val = I915_READ(DSPSTRIDE(pipe));
- crtc->base.primary->fb->pitches[0] = val & 0xffffffc0;
+ fb->pitches[0] = val & 0xffffffc0;
- aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
- plane_config->tiled);
+ aligned_height = intel_fb_align_height(dev, fb->height,
+ plane_config->tiling);
- plane_config->size = PAGE_ALIGN(crtc->base.primary->fb->pitches[0] *
- aligned_height);
+ plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height);
- DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
- pipe, plane, crtc->base.primary->fb->width,
- crtc->base.primary->fb->height,
- crtc->base.primary->fb->bits_per_pixel, base,
- crtc->base.primary->fb->pitches[0],
+ DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
+ pipe_name(pipe), fb->width, fb->height,
+ fb->bits_per_pixel, base, fb->pitches[0],
plane_config->size);
+
+ crtc->base.primary->fb = fb;
}
static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7810,24 +7853,24 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
struct intel_crtc *crtc;
for_each_intel_crtc(dev, crtc)
- WARN(crtc->active, "CRTC for pipe %c enabled\n",
+ I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe));
- WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
- WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
- WARN(I915_READ(WRPLL_CTL1) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
- WARN(I915_READ(WRPLL_CTL2) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
- WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n");
- WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
+ I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
+ I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
+ I915_STATE_WARN(I915_READ(WRPLL_CTL1) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
+ I915_STATE_WARN(I915_READ(WRPLL_CTL2) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
+ I915_STATE_WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n");
+ I915_STATE_WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
"CPU PWM1 enabled\n");
if (IS_HASWELL(dev))
- WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
+ I915_STATE_WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
"CPU PWM2 enabled\n");
- WARN(I915_READ(BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
+ I915_STATE_WARN(I915_READ(BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
"PCH PWM1 enabled\n");
- WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE,
+ I915_STATE_WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE,
"Utility pin enabled\n");
- WARN(I915_READ(PCH_GTC_CTL) & PCH_GTC_ENABLE, "PCH GTC enabled\n");
+ I915_STATE_WARN(I915_READ(PCH_GTC_CTL) & PCH_GTC_ENABLE, "PCH GTC enabled\n");
/*
* In theory we can still leave IRQs enabled, as long as only the HPD
@@ -7835,7 +7878,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
* gen-specific and since we only disable LCPLL after we fully disable
* the interrupts, the check below should be enough.
*/
- WARN(intel_irqs_enabled(dev_priv), "IRQs enabled\n");
+ I915_STATE_WARN(intel_irqs_enabled(dev_priv), "IRQs enabled\n");
}
static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
@@ -7933,19 +7976,8 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
/*
* Make sure we're not on PC8 state before disabling PC8, otherwise
* we'll hang the machine. To prevent PC8 state, just enable force_wake.
- *
- * The other problem is that hsw_restore_lcpll() is called as part of
- * the runtime PM resume sequence, so we can't just call
- * gen6_gt_force_wake_get() because that function calls
- * intel_runtime_pm_get(), and we can't change the runtime PM refcount
- * while we are on the resume sequence. So to solve this problem we have
- * to call special forcewake code that doesn't touch runtime PM and
- * doesn't enable the forcewake delayed work.
*/
- spin_lock_irq(&dev_priv->uncore.lock);
- if (dev_priv->uncore.forcewake_count++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
- spin_unlock_irq(&dev_priv->uncore.lock);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
if (val & LCPLL_POWER_DOWN_ALLOW) {
val &= ~LCPLL_POWER_DOWN_ALLOW;
@@ -7975,11 +8007,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
DRM_ERROR("Switching back to LCPLL failed\n");
}
- /* See the big comment above. */
- spin_lock_irq(&dev_priv->uncore.lock);
- if (--dev_priv->uncore.forcewake_count == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
- spin_unlock_irq(&dev_priv->uncore.lock);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
/*
@@ -8041,9 +8069,10 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv)
intel_prepare_ddi(dev);
}
-static int haswell_crtc_compute_clock(struct intel_crtc *crtc)
+static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state)
{
- if (!intel_ddi_pll_select(crtc))
+ if (!intel_ddi_pll_select(crtc, crtc_state))
return -EINVAL;
crtc->lowfreq_avail = false;
@@ -8053,14 +8082,23 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc)
static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
- u32 temp;
+ u32 temp, dpll_ctl1;
temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
switch (pipe_config->ddi_pll_sel) {
+ case SKL_DPLL0:
+ /*
+ * On SKL the eDP DPLL (DPLL0 as we don't use SSC) is not part
+ * of the shared DPLL framework and thus needs to be read out
+ * separately
+ */
+ dpll_ctl1 = I915_READ(DPLL_CTRL1);
+ pipe_config->dpll_hw_state.ctrl1 = dpll_ctl1 & 0x3f;
+ break;
case SKL_DPLL1:
pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
break;
@@ -8075,7 +8113,7 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
enum port port,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
@@ -8090,7 +8128,7 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
}
static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -8132,7 +8170,7 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
}
static bool haswell_get_pipe_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -8286,7 +8324,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
cntl |= CURSOR_MODE_256_ARGB_AX;
break;
default:
- WARN_ON(1);
+ MISSING_CASE(intel_crtc->cursor_width);
return;
}
cntl |= pipe << 28; /* Connect to correct pipe */
@@ -8295,7 +8333,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
cntl |= CURSOR_PIPE_CSC_ENABLE;
}
- if (to_intel_plane(crtc->cursor)->rotation == BIT(DRM_ROTATE_180))
+ if (crtc->cursor->state->rotation == BIT(DRM_ROTATE_180))
cntl |= CURSOR_ROTATE_180;
if (intel_crtc->cursor_cntl != cntl) {
@@ -8326,10 +8364,10 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
if (on)
base = intel_crtc->cursor_addr;
- if (x >= intel_crtc->config.pipe_src_w)
+ if (x >= intel_crtc->config->pipe_src_w)
base = 0;
- if (y >= intel_crtc->config.pipe_src_h)
+ if (y >= intel_crtc->config->pipe_src_h)
base = 0;
if (x < 0) {
@@ -8357,7 +8395,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
/* ILK+ do this automagically */
if (HAS_GMCH_DISPLAY(dev) &&
- to_intel_plane(crtc->cursor)->rotation == BIT(DRM_ROTATE_180)) {
+ crtc->cursor->state->rotation == BIT(DRM_ROTATE_180)) {
base += (intel_crtc->cursor_height *
intel_crtc->cursor_width - 1) * 4;
}
@@ -8405,109 +8443,6 @@ static bool cursor_size_ok(struct drm_device *dev,
return true;
}
-static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc,
- struct drm_i915_gem_object *obj,
- uint32_t width, uint32_t height)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
- unsigned old_width;
- uint32_t addr;
- int ret;
-
- /* if we want to turn off the cursor ignore width and height */
- if (!obj) {
- DRM_DEBUG_KMS("cursor off\n");
- addr = 0;
- mutex_lock(&dev->struct_mutex);
- goto finish;
- }
-
- /* we only need to pin inside GTT if cursor is non-phy */
- mutex_lock(&dev->struct_mutex);
- if (!INTEL_INFO(dev)->cursor_needs_physical) {
- unsigned alignment;
-
- /*
- * Global gtt pte registers are special registers which actually
- * forward writes to a chunk of system memory. Which means that
- * there is no risk that the register values disappear as soon
- * as we call intel_runtime_pm_put(), so it is correct to wrap
- * only the pin/unpin/fence and not more.
- */
- intel_runtime_pm_get(dev_priv);
-
- /* Note that the w/a also requires 2 PTE of padding following
- * the bo. We currently fill all unused PTE with the shadow
- * page and so we should always have valid PTE following the
- * cursor preventing the VT-d warning.
- */
- alignment = 0;
- if (need_vtd_wa(dev))
- alignment = 64*1024;
-
- ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL);
- if (ret) {
- DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n");
- intel_runtime_pm_put(dev_priv);
- goto fail_locked;
- }
-
- ret = i915_gem_object_put_fence(obj);
- if (ret) {
- DRM_DEBUG_KMS("failed to release fence for cursor");
- intel_runtime_pm_put(dev_priv);
- goto fail_unpin;
- }
-
- addr = i915_gem_obj_ggtt_offset(obj);
-
- intel_runtime_pm_put(dev_priv);
- } else {
- int align = IS_I830(dev) ? 16 * 1024 : 256;
- ret = i915_gem_object_attach_phys(obj, align);
- if (ret) {
- DRM_DEBUG_KMS("failed to attach phys object\n");
- goto fail_locked;
- }
- addr = obj->phys_handle->busaddr;
- }
-
- finish:
- if (intel_crtc->cursor_bo) {
- if (!INTEL_INFO(dev)->cursor_needs_physical)
- i915_gem_object_unpin_from_display_plane(intel_crtc->cursor_bo);
- }
-
- i915_gem_track_fb(intel_crtc->cursor_bo, obj,
- INTEL_FRONTBUFFER_CURSOR(pipe));
- mutex_unlock(&dev->struct_mutex);
-
- old_width = intel_crtc->cursor_width;
-
- intel_crtc->cursor_addr = addr;
- intel_crtc->cursor_bo = obj;
- intel_crtc->cursor_width = width;
- intel_crtc->cursor_height = height;
-
- if (intel_crtc->active) {
- if (old_width != width)
- intel_update_watermarks(crtc);
- intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
-
- intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_CURSOR(pipe));
- }
-
- return 0;
-fail_unpin:
- i915_gem_object_unpin_from_display_plane(obj);
-fail_locked:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t start, uint32_t size)
{
@@ -8730,7 +8665,7 @@ retry:
intel_crtc = to_intel_crtc(crtc);
intel_crtc->new_enabled = true;
- intel_crtc->new_config = &intel_crtc->config;
+ intel_crtc->new_config = intel_crtc->config;
old->dpms_mode = connector->dpms;
old->load_detect_temp = true;
old->release_fb = NULL;
@@ -8771,7 +8706,7 @@ retry:
fail:
intel_crtc->new_enabled = crtc->enabled;
if (intel_crtc->new_enabled)
- intel_crtc->new_config = &intel_crtc->config;
+ intel_crtc->new_config = intel_crtc->config;
else
intel_crtc->new_config = NULL;
fail_unlock:
@@ -8817,7 +8752,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
}
static int i9xx_pll_refclk(struct drm_device *dev,
- const struct intel_crtc_config *pipe_config)
+ const struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll = pipe_config->dpll_hw_state.dpll;
@@ -8834,7 +8769,7 @@ static int i9xx_pll_refclk(struct drm_device *dev,
/* Returns the clock of the currently programmed mode of the given pipe. */
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -8941,7 +8876,7 @@ int intel_dotclock_calculate(int link_freq,
}
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
@@ -8954,7 +8889,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
* agree once we know their relationship in the encoder's
* get_config() function.
*/
- pipe_config->adjusted_mode.crtc_clock =
+ pipe_config->base.adjusted_mode.crtc_clock =
intel_dotclock_calculate(intel_fdi_link_freq(dev) * 10000,
&pipe_config->fdi_m_n);
}
@@ -8965,9 +8900,9 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
struct drm_display_mode *mode;
- struct intel_crtc_config pipe_config;
+ struct intel_crtc_state pipe_config;
int htot = I915_READ(HTOTAL(cpu_transcoder));
int hsync = I915_READ(HSYNC(cpu_transcoder));
int vtot = I915_READ(VTOTAL(cpu_transcoder));
@@ -9082,6 +9017,14 @@ out:
intel_runtime_pm_put(dev_priv);
}
+static void intel_crtc_set_state(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state)
+{
+ kfree(crtc->config);
+ crtc->config = crtc_state;
+ crtc->base.state = &crtc_state->base;
+}
+
static void intel_crtc_destroy(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -9098,6 +9041,7 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
kfree(work);
}
+ intel_crtc_set_state(intel_crtc, NULL);
drm_crtc_cleanup(crtc);
kfree(intel_crtc);
@@ -9115,7 +9059,10 @@ static void intel_unpin_work_fn(struct work_struct *__work)
drm_gem_object_unreference(&work->pending_flip_obj->base);
drm_gem_object_unreference(&work->old_fb_obj->base);
- intel_update_fbc(dev);
+ intel_fbc_update(dev);
+
+ if (work->flip_queued_req)
+ i915_gem_request_assign(&work->flip_queued_req, NULL);
mutex_unlock(&dev->struct_mutex);
intel_frontbuffer_flip_complete(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
@@ -9511,25 +9458,53 @@ static bool use_mmio_flip(struct intel_engine_cs *ring,
else if (i915.enable_execlists)
return true;
else
- return ring != obj->ring;
+ return ring != i915_gem_request_get_ring(obj->last_read_req);
}
-static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
+static void skl_do_mmio_flip(struct intel_crtc *intel_crtc)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
+ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+ struct drm_i915_gem_object *obj = intel_fb->obj;
+ const enum pipe pipe = intel_crtc->pipe;
+ u32 ctl, stride;
+
+ ctl = I915_READ(PLANE_CTL(pipe, 0));
+ ctl &= ~PLANE_CTL_TILED_MASK;
+ if (obj->tiling_mode == I915_TILING_X)
+ ctl |= PLANE_CTL_TILED_X;
+
+ /*
+ * The stride is either expressed as a multiple of 64 bytes chunks for
+ * linear buffers or in number of tiles for tiled buffers.
+ */
+ stride = fb->pitches[0] >> 6;
+ if (obj->tiling_mode == I915_TILING_X)
+ stride = fb->pitches[0] >> 9; /* X tiles are 512 bytes wide */
+
+ /*
+ * Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
+ * PLANE_SURF updates, the update is then guaranteed to be atomic.
+ */
+ I915_WRITE(PLANE_CTL(pipe, 0), ctl);
+ I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
+
+ I915_WRITE(PLANE_SURF(pipe, 0), intel_crtc->unpin_work->gtt_offset);
+ POSTING_READ(PLANE_SURF(pipe, 0));
+}
+
+static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_framebuffer *intel_fb =
to_intel_framebuffer(intel_crtc->base.primary->fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
- bool atomic_update;
- u32 start_vbl_count;
u32 dspcntr;
u32 reg;
- intel_mark_page_flip_active(intel_crtc);
-
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
-
reg = DSPCNTR(intel_crtc->plane);
dspcntr = I915_READ(reg);
@@ -9544,26 +9519,50 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
intel_crtc->unpin_work->gtt_offset);
POSTING_READ(DSPSURF(intel_crtc->plane));
+}
+
+/*
+ * XXX: This is the temporary way to update the plane registers until we get
+ * around to using the usual plane update functions for MMIO flips
+ */
+static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ bool atomic_update;
+ u32 start_vbl_count;
+
+ intel_mark_page_flip_active(intel_crtc);
+
+ atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
+
+ if (INTEL_INFO(dev)->gen >= 9)
+ skl_do_mmio_flip(intel_crtc);
+ else
+ /* use_mmio_flip() retricts MMIO flips to ilk+ */
+ ilk_do_mmio_flip(intel_crtc);
+
if (atomic_update)
intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void intel_mmio_flip_work_func(struct work_struct *work)
{
- struct intel_crtc *intel_crtc =
+ struct intel_crtc *crtc =
container_of(work, struct intel_crtc, mmio_flip.work);
- struct intel_engine_cs *ring;
- uint32_t seqno;
+ struct intel_mmio_flip *mmio_flip;
- seqno = intel_crtc->mmio_flip.seqno;
- ring = intel_crtc->mmio_flip.ring;
+ mmio_flip = &crtc->mmio_flip;
+ if (mmio_flip->req)
+ WARN_ON(__i915_wait_request(mmio_flip->req,
+ crtc->reset_counter,
+ false, NULL, NULL) != 0);
- if (seqno)
- WARN_ON(__i915_wait_seqno(ring, seqno,
- intel_crtc->reset_counter,
- false, NULL, NULL) != 0);
-
- intel_do_mmio_flip(intel_crtc);
+ intel_do_mmio_flip(crtc);
+ if (mmio_flip->req) {
+ mutex_lock(&crtc->base.dev->struct_mutex);
+ i915_gem_request_assign(&mmio_flip->req, NULL);
+ mutex_unlock(&crtc->base.dev->struct_mutex);
+ }
}
static int intel_queue_mmio_flip(struct drm_device *dev,
@@ -9575,8 +9574,8 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- intel_crtc->mmio_flip.seqno = obj->last_write_seqno;
- intel_crtc->mmio_flip.ring = obj->ring;
+ i915_gem_request_assign(&intel_crtc->mmio_flip.req,
+ obj->last_write_req);
schedule_work(&intel_crtc->mmio_flip.work);
@@ -9671,9 +9670,8 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
return false;
if (work->flip_ready_vblank == 0) {
- if (work->flip_queued_ring &&
- !i915_seqno_passed(work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
- work->flip_queued_seqno))
+ if (work->flip_queued_req &&
+ !i915_gem_request_completed(work->flip_queued_req, true))
return false;
work->flip_ready_vblank = drm_vblank_count(dev, intel_crtc->pipe);
@@ -9726,6 +9724,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb = crtc->primary->fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_plane *primary = crtc->primary;
enum pipe pipe = intel_crtc->pipe;
struct intel_unpin_work *work;
struct intel_engine_cs *ring;
@@ -9818,7 +9817,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
ring = &dev_priv->ring[BCS];
} else if (INTEL_INFO(dev)->gen >= 7) {
- ring = obj->ring;
+ ring = i915_gem_request_get_ring(obj->last_read_req);
if (ring == NULL || ring->id != RCS)
ring = &dev_priv->ring[BCS];
} else {
@@ -9838,16 +9837,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
if (ret)
goto cleanup_unpin;
- work->flip_queued_seqno = obj->last_write_seqno;
- work->flip_queued_ring = obj->ring;
+ i915_gem_request_assign(&work->flip_queued_req,
+ obj->last_write_req);
} else {
ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, ring,
page_flip_flags);
if (ret)
goto cleanup_unpin;
- work->flip_queued_seqno = intel_ring_get_seqno(ring);
- work->flip_queued_ring = ring;
+ i915_gem_request_assign(&work->flip_queued_req,
+ intel_ring_get_request(ring));
}
work->flip_queued_vblank = drm_vblank_count(dev, intel_crtc->pipe);
@@ -9856,7 +9855,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
i915_gem_track_fb(work->old_fb_obj, obj,
INTEL_FRONTBUFFER_PRIMARY(pipe));
- intel_disable_fbc(dev);
+ intel_fbc_disable(dev);
intel_frontbuffer_flip_prepare(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
mutex_unlock(&dev->struct_mutex);
@@ -9884,8 +9883,7 @@ free_work:
if (ret == -EIO) {
out_hang:
- intel_crtc_wait_for_pending_flips(crtc);
- ret = intel_pipe_set_base(crtc, crtc->x, crtc->y, fb);
+ ret = intel_plane_restore(primary);
if (ret == 0 && event) {
spin_lock_irq(&dev->event_lock);
drm_send_vblank_event(dev, pipe, event);
@@ -9898,6 +9896,8 @@ out_hang:
static struct drm_crtc_helper_funcs intel_helper_funcs = {
.mode_set_base_atomic = intel_pipe_set_base_atomic,
.load_lut = intel_crtc_load_lut,
+ .atomic_begin = intel_begin_crtc_commit,
+ .atomic_flush = intel_finish_crtc_commit,
};
/**
@@ -9927,7 +9927,7 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev)
crtc->new_enabled = crtc->base.enabled;
if (crtc->new_enabled)
- crtc->new_config = &crtc->config;
+ crtc->new_config = crtc->config;
else
crtc->new_config = NULL;
}
@@ -9960,7 +9960,7 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
static void
connected_sink_compute_bpp(struct intel_connector *connector,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
int bpp = pipe_config->pipe_bpp;
@@ -9987,7 +9987,7 @@ connected_sink_compute_bpp(struct intel_connector *connector,
static int
compute_baseline_pipe_bpp(struct intel_crtc *crtc,
struct drm_framebuffer *fb,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = crtc->base.dev;
struct intel_connector *connector;
@@ -10056,7 +10056,7 @@ static void intel_dump_crtc_timings(const struct drm_display_mode *mode)
}
static void intel_dump_pipe_config(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config,
+ struct intel_crtc_state *pipe_config,
const char *context)
{
DRM_DEBUG_KMS("[CRTC:%d]%s config for pipe %c\n", crtc->base.base.id,
@@ -10090,10 +10090,10 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
pipe_config->has_infoframe);
DRM_DEBUG_KMS("requested mode:\n");
- drm_mode_debug_printmodeline(&pipe_config->requested_mode);
+ drm_mode_debug_printmodeline(&pipe_config->base.mode);
DRM_DEBUG_KMS("adjusted mode:\n");
- drm_mode_debug_printmodeline(&pipe_config->adjusted_mode);
- intel_dump_crtc_timings(&pipe_config->adjusted_mode);
+ drm_mode_debug_printmodeline(&pipe_config->base.adjusted_mode);
+ intel_dump_crtc_timings(&pipe_config->base.adjusted_mode);
DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock);
DRM_DEBUG_KMS("pipe src size: %dx%d\n",
pipe_config->pipe_src_w, pipe_config->pipe_src_h);
@@ -10192,14 +10192,14 @@ static bool check_digital_port_conflicts(struct drm_device *dev)
return true;
}
-static struct intel_crtc_config *
+static struct intel_crtc_state *
intel_modeset_pipe_config(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_display_mode *mode)
{
struct drm_device *dev = crtc->dev;
struct intel_encoder *encoder;
- struct intel_crtc_config *pipe_config;
+ struct intel_crtc_state *pipe_config;
int plane_bpp, ret = -EINVAL;
bool retry = true;
@@ -10217,8 +10217,8 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
if (!pipe_config)
return ERR_PTR(-ENOMEM);
- drm_mode_copy(&pipe_config->adjusted_mode, mode);
- drm_mode_copy(&pipe_config->requested_mode, mode);
+ drm_mode_copy(&pipe_config->base.adjusted_mode, mode);
+ drm_mode_copy(&pipe_config->base.mode, mode);
pipe_config->cpu_transcoder =
(enum transcoder) to_intel_crtc(crtc)->pipe;
@@ -10229,13 +10229,13 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
* positive or negative polarity is requested, treat this as meaning
* negative polarity.
*/
- if (!(pipe_config->adjusted_mode.flags &
+ if (!(pipe_config->base.adjusted_mode.flags &
(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
- pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
+ pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
- if (!(pipe_config->adjusted_mode.flags &
+ if (!(pipe_config->base.adjusted_mode.flags &
(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
- pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
+ pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
/* Compute a starting value for pipe_config->pipe_bpp taking the source
* plane pixel format and any sink constraints into account. Returns the
@@ -10254,9 +10254,9 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
* computation to clearly distinguish it from the adjusted mode, which
* can be changed by the connectors in the below retry loop.
*/
- drm_mode_set_crtcinfo(&pipe_config->requested_mode, CRTC_STEREO_DOUBLE);
- pipe_config->pipe_src_w = pipe_config->requested_mode.crtc_hdisplay;
- pipe_config->pipe_src_h = pipe_config->requested_mode.crtc_vdisplay;
+ drm_crtc_get_hv_timing(&pipe_config->base.mode,
+ &pipe_config->pipe_src_w,
+ &pipe_config->pipe_src_h);
encoder_retry:
/* Ensure the port clock defaults are reset when retrying. */
@@ -10264,7 +10264,8 @@ encoder_retry:
pipe_config->pixel_multiplier = 1;
/* Fill in default crtc timings, allow encoders to overwrite them. */
- drm_mode_set_crtcinfo(&pipe_config->adjusted_mode, CRTC_STEREO_DOUBLE);
+ drm_mode_set_crtcinfo(&pipe_config->base.adjusted_mode,
+ CRTC_STEREO_DOUBLE);
/* Pass our mode to the connectors and the CRTC to give them a chance to
* adjust it according to limitations or connector properties, and also
@@ -10284,7 +10285,7 @@ encoder_retry:
/* Set default port clock if not overwritten by the encoder. Needs to be
* done afterwards in case the encoder adjusts the mode. */
if (!pipe_config->port_clock)
- pipe_config->port_clock = pipe_config->adjusted_mode.crtc_clock
+ pipe_config->port_clock = pipe_config->base.adjusted_mode.crtc_clock
* pipe_config->pixel_multiplier;
ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
@@ -10441,7 +10442,7 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
for_each_intel_crtc(dev, intel_crtc) {
WARN_ON(intel_crtc->base.enabled != intel_crtc_in_use(&intel_crtc->base));
WARN_ON(intel_crtc->new_config &&
- intel_crtc->new_config != &intel_crtc->config);
+ intel_crtc->new_config != intel_crtc->config);
WARN_ON(intel_crtc->base.enabled != !!intel_crtc->new_config);
}
@@ -10493,8 +10494,8 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
static bool
intel_pipe_config_compare(struct drm_device *dev,
- struct intel_crtc_config *current_config,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *current_config,
+ struct intel_crtc_state *pipe_config)
{
#define PIPE_CONF_CHECK_X(name) \
if (current_config->name != pipe_config->name) { \
@@ -10585,19 +10586,19 @@ intel_pipe_config_compare(struct drm_device *dev,
PIPE_CONF_CHECK_I_ALT(dp_m_n.tu, dp_m2_n2.tu);
}
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_hdisplay);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_htotal);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_start);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_end);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_start);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_end);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_start);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_end);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_start);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_end);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_vdisplay);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_vtotal);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_start);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_end);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start);
- PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vdisplay);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vtotal);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_start);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_end);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_start);
+ PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end);
PIPE_CONF_CHECK_I(pixel_multiplier);
PIPE_CONF_CHECK_I(has_hdmi_sink);
@@ -10608,17 +10609,17 @@ intel_pipe_config_compare(struct drm_device *dev,
PIPE_CONF_CHECK_I(has_audio);
- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+ PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_INTERLACE);
if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+ PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_PHSYNC);
- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+ PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_NHSYNC);
- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+ PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_PVSYNC);
- PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+ PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
DRM_MODE_FLAG_NVSYNC);
}
@@ -10668,7 +10669,7 @@ intel_pipe_config_compare(struct drm_device *dev,
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
PIPE_CONF_CHECK_I(pipe_bpp);
- PIPE_CONF_CHECK_CLOCK_FUZZY(adjusted_mode.crtc_clock);
+ PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
#undef PIPE_CONF_CHECK_X
@@ -10742,7 +10743,7 @@ check_connector_state(struct drm_device *dev)
* ->get_hw_state callbacks. */
intel_connector_check_state(connector);
- WARN(&connector->new_encoder->base != connector->base.encoder,
+ I915_STATE_WARN(&connector->new_encoder->base != connector->base.encoder,
"connector's staged encoder doesn't match current encoder\n");
}
}
@@ -10762,9 +10763,9 @@ check_encoder_state(struct drm_device *dev)
encoder->base.base.id,
encoder->base.name);
- WARN(&encoder->new_crtc->base != encoder->base.crtc,
+ I915_STATE_WARN(&encoder->new_crtc->base != encoder->base.crtc,
"encoder's stage crtc doesn't match current crtc\n");
- WARN(encoder->connectors_active && !encoder->base.crtc,
+ I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
"encoder's active_connectors set, but no crtc\n");
list_for_each_entry(connector, &dev->mode_config.connector_list,
@@ -10783,19 +10784,19 @@ check_encoder_state(struct drm_device *dev)
if (!enabled && encoder->base.encoder_type == DRM_MODE_ENCODER_DPMST)
continue;
- WARN(!!encoder->base.crtc != enabled,
+ I915_STATE_WARN(!!encoder->base.crtc != enabled,
"encoder's enabled state mismatch "
"(expected %i, found %i)\n",
!!encoder->base.crtc, enabled);
- WARN(active && !encoder->base.crtc,
+ I915_STATE_WARN(active && !encoder->base.crtc,
"active encoder with no crtc\n");
- WARN(encoder->connectors_active != active,
+ I915_STATE_WARN(encoder->connectors_active != active,
"encoder's computed active state doesn't match tracked active state "
"(expected %i, found %i)\n", active, encoder->connectors_active);
active = encoder->get_hw_state(encoder, &pipe);
- WARN(active != encoder->connectors_active,
+ I915_STATE_WARN(active != encoder->connectors_active,
"encoder's hw state doesn't match sw tracking "
"(expected %i, found %i)\n",
encoder->connectors_active, active);
@@ -10804,7 +10805,7 @@ check_encoder_state(struct drm_device *dev)
continue;
tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe;
- WARN(active && pipe != tracked_pipe,
+ I915_STATE_WARN(active && pipe != tracked_pipe,
"active encoder's pipe doesn't match"
"(expected %i, found %i)\n",
tracked_pipe, pipe);
@@ -10818,7 +10819,7 @@ check_crtc_state(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc;
struct intel_encoder *encoder;
- struct intel_crtc_config pipe_config;
+ struct intel_crtc_state pipe_config;
for_each_intel_crtc(dev, crtc) {
bool enabled = false;
@@ -10829,7 +10830,7 @@ check_crtc_state(struct drm_device *dev)
DRM_DEBUG_KMS("[CRTC:%d]\n",
crtc->base.base.id);
- WARN(crtc->active && !crtc->base.enabled,
+ I915_STATE_WARN(crtc->active && !crtc->base.enabled,
"active crtc, but not enabled in sw tracking\n");
for_each_intel_encoder(dev, encoder) {
@@ -10840,10 +10841,10 @@ check_crtc_state(struct drm_device *dev)
active = true;
}
- WARN(active != crtc->active,
+ I915_STATE_WARN(active != crtc->active,
"crtc's computed active state doesn't match tracked active state "
"(expected %i, found %i)\n", active, crtc->active);
- WARN(enabled != crtc->base.enabled,
+ I915_STATE_WARN(enabled != crtc->base.enabled,
"crtc's computed enabled state doesn't match tracked enabled state "
"(expected %i, found %i)\n", enabled, crtc->base.enabled);
@@ -10863,16 +10864,16 @@ check_crtc_state(struct drm_device *dev)
encoder->get_config(encoder, &pipe_config);
}
- WARN(crtc->active != active,
+ I915_STATE_WARN(crtc->active != active,
"crtc active state doesn't match with hw state "
"(expected %i, found %i)\n", crtc->active, active);
if (active &&
- !intel_pipe_config_compare(dev, &crtc->config, &pipe_config)) {
- WARN(1, "pipe state doesn't match!\n");
+ !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
+ I915_STATE_WARN(1, "pipe state doesn't match!\n");
intel_dump_pipe_config(crtc, &pipe_config,
"[hw state]");
- intel_dump_pipe_config(crtc, &crtc->config,
+ intel_dump_pipe_config(crtc, crtc->config,
"[sw state]");
}
}
@@ -10897,14 +10898,14 @@ check_shared_dpll_state(struct drm_device *dev)
active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state);
- WARN(pll->active > hweight32(pll->config.crtc_mask),
+ I915_STATE_WARN(pll->active > hweight32(pll->config.crtc_mask),
"more active pll users than references: %i vs %i\n",
pll->active, hweight32(pll->config.crtc_mask));
- WARN(pll->active && !pll->on,
+ I915_STATE_WARN(pll->active && !pll->on,
"pll in active use but not on in sw tracking\n");
- WARN(pll->on && !pll->active,
+ I915_STATE_WARN(pll->on && !pll->active,
"pll in on but not on in use in sw tracking\n");
- WARN(pll->on != active,
+ I915_STATE_WARN(pll->on != active,
"pll on state mismatch (expected %i, found %i)\n",
pll->on, active);
@@ -10914,14 +10915,14 @@ check_shared_dpll_state(struct drm_device *dev)
if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
active_crtcs++;
}
- WARN(pll->active != active_crtcs,
+ I915_STATE_WARN(pll->active != active_crtcs,
"pll active crtcs mismatch (expected %i, found %i)\n",
pll->active, active_crtcs);
- WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
+ I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
"pll enabled crtcs mismatch (expected %i, found %i)\n",
hweight32(pll->config.crtc_mask), enabled_crtcs);
- WARN(pll->on && memcmp(&pll->config.hw_state, &dpll_hw_state,
+ I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state, &dpll_hw_state,
sizeof(dpll_hw_state)),
"pll hw state mismatch\n");
}
@@ -10937,16 +10938,16 @@ intel_modeset_check_state(struct drm_device *dev)
check_shared_dpll_state(dev);
}
-void ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
+void ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config,
int dotclock)
{
/*
* FDI already provided one idea for the dotclock.
* Yell if the encoder disagrees.
*/
- WARN(!intel_fuzzy_clock_check(pipe_config->adjusted_mode.crtc_clock, dotclock),
+ WARN(!intel_fuzzy_clock_check(pipe_config->base.adjusted_mode.crtc_clock, dotclock),
"FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
- pipe_config->adjusted_mode.crtc_clock, dotclock);
+ pipe_config->base.adjusted_mode.crtc_clock, dotclock);
}
static void update_scanline_offset(struct intel_crtc *crtc)
@@ -10972,7 +10973,7 @@ static void update_scanline_offset(struct intel_crtc *crtc)
* one to the value.
*/
if (IS_GEN2(dev)) {
- const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
+ const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
int vtotal;
vtotal = mode->crtc_vtotal;
@@ -10987,7 +10988,7 @@ static void update_scanline_offset(struct intel_crtc *crtc)
crtc->scanline_offset = 1;
}
-static struct intel_crtc_config *
+static struct intel_crtc_state *
intel_modeset_compute_config(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_framebuffer *fb,
@@ -10995,7 +10996,7 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
unsigned *prepare_pipes,
unsigned *disable_pipes)
{
- struct intel_crtc_config *pipe_config = NULL;
+ struct intel_crtc_state *pipe_config = NULL;
intel_modeset_affected_pipes(crtc, modeset_pipes,
prepare_pipes, disable_pipes);
@@ -11020,10 +11021,40 @@ out:
return pipe_config;
}
+static int __intel_set_mode_setup_plls(struct drm_device *dev,
+ unsigned modeset_pipes,
+ unsigned disable_pipes)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ unsigned clear_pipes = modeset_pipes | disable_pipes;
+ struct intel_crtc *intel_crtc;
+ int ret = 0;
+
+ if (!dev_priv->display.crtc_compute_clock)
+ return 0;
+
+ ret = intel_shared_dpll_start_config(dev_priv, clear_pipes);
+ if (ret)
+ goto done;
+
+ for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
+ struct intel_crtc_state *state = intel_crtc->new_config;
+ ret = dev_priv->display.crtc_compute_clock(intel_crtc,
+ state);
+ if (ret) {
+ intel_shared_dpll_abort_config(dev_priv);
+ goto done;
+ }
+ }
+
+done:
+ return ret;
+}
+
static int __intel_set_mode(struct drm_crtc *crtc,
struct drm_display_mode *mode,
int x, int y, struct drm_framebuffer *fb,
- struct intel_crtc_config *pipe_config,
+ struct intel_crtc_state *pipe_config,
unsigned modeset_pipes,
unsigned prepare_pipes,
unsigned disable_pipes)
@@ -11057,21 +11088,9 @@ static int __intel_set_mode(struct drm_crtc *crtc,
prepare_pipes &= ~disable_pipes;
}
- if (dev_priv->display.crtc_compute_clock) {
- unsigned clear_pipes = modeset_pipes | disable_pipes;
-
- ret = intel_shared_dpll_start_config(dev_priv, clear_pipes);
- if (ret)
- goto done;
-
- for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
- ret = dev_priv->display.crtc_compute_clock(intel_crtc);
- if (ret) {
- intel_shared_dpll_abort_config(dev_priv);
- goto done;
- }
- }
- }
+ ret = __intel_set_mode_setup_plls(dev, modeset_pipes, disable_pipes);
+ if (ret)
+ goto done;
for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
intel_crtc_disable(&intel_crtc->base);
@@ -11092,8 +11111,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
crtc->mode = *mode;
/* mode_set/enable/disable functions rely on a correct pipe
* config. */
- to_intel_crtc(crtc)->config = *pipe_config;
- to_intel_crtc(crtc)->new_config = &to_intel_crtc(crtc)->config;
+ intel_crtc_set_state(to_intel_crtc(crtc), pipe_config);
/*
* Calculate and store various constants which
@@ -11101,7 +11119,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
* timestamping. They are derived from true hwmode.
*/
drm_calc_timestamping_constants(crtc,
- &pipe_config->adjusted_mode);
+ &pipe_config->base.adjusted_mode);
}
/* Only after disabling all output pipelines that will be changed can we
@@ -11114,26 +11132,15 @@ static int __intel_set_mode(struct drm_crtc *crtc,
* on the DPLL.
*/
for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
- struct drm_framebuffer *old_fb = crtc->primary->fb;
- struct drm_i915_gem_object *old_obj = intel_fb_obj(old_fb);
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-
- mutex_lock(&dev->struct_mutex);
- ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, NULL);
- if (ret != 0) {
- DRM_ERROR("pin & fence failed\n");
- mutex_unlock(&dev->struct_mutex);
- goto done;
- }
- if (old_fb)
- intel_unpin_fb_obj(old_obj);
- i915_gem_track_fb(old_obj, obj,
- INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe));
- mutex_unlock(&dev->struct_mutex);
+ struct drm_plane *primary = intel_crtc->base.primary;
+ int vdisplay, hdisplay;
- crtc->primary->fb = fb;
- crtc->x = x;
- crtc->y = y;
+ drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
+ ret = primary->funcs->update_plane(primary, &intel_crtc->base,
+ fb, 0, 0,
+ hdisplay, vdisplay,
+ x << 16, y << 16,
+ hdisplay << 16, vdisplay << 16);
}
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
@@ -11148,7 +11155,6 @@ done:
if (ret && crtc->enabled)
crtc->mode = *saved_mode;
- kfree(pipe_config);
kfree(saved_mode);
return ret;
}
@@ -11156,7 +11162,7 @@ done:
static int intel_set_mode_pipes(struct drm_crtc *crtc,
struct drm_display_mode *mode,
int x, int y, struct drm_framebuffer *fb,
- struct intel_crtc_config *pipe_config,
+ struct intel_crtc_state *pipe_config,
unsigned modeset_pipes,
unsigned prepare_pipes,
unsigned disable_pipes)
@@ -11176,7 +11182,7 @@ static int intel_set_mode(struct drm_crtc *crtc,
struct drm_display_mode *mode,
int x, int y, struct drm_framebuffer *fb)
{
- struct intel_crtc_config *pipe_config;
+ struct intel_crtc_state *pipe_config;
unsigned modeset_pipes, prepare_pipes, disable_pipes;
pipe_config = intel_modeset_compute_config(crtc, mode, fb,
@@ -11271,7 +11277,7 @@ static void intel_set_config_restore_state(struct drm_device *dev,
crtc->new_enabled = config->save_crtc_enabled[count++];
if (crtc->new_enabled)
- crtc->new_config = &crtc->config;
+ crtc->new_config = crtc->config;
else
crtc->new_config = NULL;
}
@@ -11483,7 +11489,7 @@ intel_modeset_stage_output_state(struct drm_device *dev,
}
if (crtc->new_enabled)
- crtc->new_config = &crtc->config;
+ crtc->new_config = crtc->config;
else
crtc->new_config = NULL;
}
@@ -11520,7 +11526,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
struct drm_device *dev;
struct drm_mode_set save_set;
struct intel_set_config *config;
- struct intel_crtc_config *pipe_config;
+ struct intel_crtc_state *pipe_config;
unsigned modeset_pipes, prepare_pipes, disable_pipes;
int ret;
@@ -11577,7 +11583,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
goto fail;
} else if (pipe_config) {
if (pipe_config->has_audio !=
- to_intel_crtc(set->crtc)->config.has_audio)
+ to_intel_crtc(set->crtc)->config->has_audio)
config->mode_changed = true;
/*
@@ -11601,11 +11607,14 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
disable_pipes);
} else if (config->fb_changed) {
struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
+ struct drm_plane *primary = set->crtc->primary;
+ int vdisplay, hdisplay;
- intel_crtc_wait_for_pending_flips(set->crtc);
-
- ret = intel_pipe_set_base(set->crtc,
- set->x, set->y, set->fb);
+ drm_crtc_get_hv_timing(set->mode, &hdisplay, &vdisplay);
+ ret = primary->funcs->update_plane(primary, set->crtc, set->fb,
+ 0, 0, hdisplay, vdisplay,
+ set->x << 16, set->y << 16,
+ hdisplay << 16, vdisplay << 16);
/*
* We need to make sure the primary plane is re-enabled if it
@@ -11660,6 +11669,8 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.set_config = intel_crtc_set_config,
.destroy = intel_crtc_destroy,
.page_flip = intel_crtc_page_flip,
+ .atomic_duplicate_state = intel_crtc_duplicate_state,
+ .atomic_destroy_state = intel_crtc_destroy_state,
};
static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
@@ -11762,93 +11773,149 @@ static void intel_shared_dpll_init(struct drm_device *dev)
BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
}
-static int
-intel_primary_plane_disable(struct drm_plane *plane)
+/**
+ * intel_prepare_plane_fb - Prepare fb for usage on plane
+ * @plane: drm plane to prepare for
+ * @fb: framebuffer to prepare for presentation
+ *
+ * Prepares a framebuffer for usage on a display plane. Generally this
+ * involves pinning the underlying object and updating the frontbuffer tracking
+ * bits. Some older platforms need special physical address handling for
+ * cursor planes.
+ *
+ * Returns 0 on success, negative error code on failure.
+ */
+int
+intel_prepare_plane_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb)
{
struct drm_device *dev = plane->dev;
- struct intel_crtc *intel_crtc;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ enum pipe pipe = intel_plane->pipe;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
+ unsigned frontbuffer_bits = 0;
+ int ret = 0;
- if (!plane->fb)
+ if (!obj)
return 0;
- BUG_ON(!plane->crtc);
+ switch (plane->type) {
+ case DRM_PLANE_TYPE_PRIMARY:
+ frontbuffer_bits = INTEL_FRONTBUFFER_PRIMARY(pipe);
+ break;
+ case DRM_PLANE_TYPE_CURSOR:
+ frontbuffer_bits = INTEL_FRONTBUFFER_CURSOR(pipe);
+ break;
+ case DRM_PLANE_TYPE_OVERLAY:
+ frontbuffer_bits = INTEL_FRONTBUFFER_SPRITE(pipe);
+ break;
+ }
- intel_crtc = to_intel_crtc(plane->crtc);
+ mutex_lock(&dev->struct_mutex);
- /*
- * Even though we checked plane->fb above, it's still possible that
- * the primary plane has been implicitly disabled because the crtc
- * coordinates given weren't visible, or because we detected
- * that it was 100% covered by a sprite plane. Or, the CRTC may be
- * off and we've set a fb, but haven't actually turned on the CRTC yet.
- * In either case, we need to unpin the FB and let the fb pointer get
- * updated, but otherwise we don't need to touch the hardware.
- */
- if (!intel_crtc->primary_enabled)
- goto disable_unpin;
+ if (plane->type == DRM_PLANE_TYPE_CURSOR &&
+ INTEL_INFO(dev)->cursor_needs_physical) {
+ int align = IS_I830(dev) ? 16 * 1024 : 256;
+ ret = i915_gem_object_attach_phys(obj, align);
+ if (ret)
+ DRM_DEBUG_KMS("failed to attach phys object\n");
+ } else {
+ ret = intel_pin_and_fence_fb_obj(plane, fb, NULL);
+ }
- intel_crtc_wait_for_pending_flips(plane->crtc);
- intel_disable_primary_hw_plane(plane, plane->crtc);
+ if (ret == 0)
+ i915_gem_track_fb(old_obj, obj, frontbuffer_bits);
-disable_unpin:
- mutex_lock(&dev->struct_mutex);
- i915_gem_track_fb(intel_fb_obj(plane->fb), NULL,
- INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe));
- intel_unpin_fb_obj(intel_fb_obj(plane->fb));
mutex_unlock(&dev->struct_mutex);
- plane->fb = NULL;
- return 0;
+ return ret;
+}
+
+/**
+ * intel_cleanup_plane_fb - Cleans up an fb after plane use
+ * @plane: drm plane to clean up for
+ * @fb: old framebuffer that was on plane
+ *
+ * Cleans up a framebuffer that has just been removed from a plane.
+ */
+void
+intel_cleanup_plane_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+
+ if (WARN_ON(!obj))
+ return;
+
+ if (plane->type != DRM_PLANE_TYPE_CURSOR ||
+ !INTEL_INFO(dev)->cursor_needs_physical) {
+ mutex_lock(&dev->struct_mutex);
+ intel_unpin_fb_obj(obj);
+ mutex_unlock(&dev->struct_mutex);
+ }
}
static int
intel_check_primary_plane(struct drm_plane *plane,
struct intel_plane_state *state)
{
- struct drm_crtc *crtc = state->crtc;
- struct drm_framebuffer *fb = state->fb;
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = state->base.crtc;
+ struct intel_crtc *intel_crtc;
+ struct drm_framebuffer *fb = state->base.fb;
struct drm_rect *dest = &state->dst;
struct drm_rect *src = &state->src;
const struct drm_rect *clip = &state->clip;
+ int ret;
- return drm_plane_helper_check_update(plane, crtc, fb,
- src, dest, clip,
- DRM_PLANE_HELPER_NO_SCALING,
- DRM_PLANE_HELPER_NO_SCALING,
- false, true, &state->visible);
-}
+ crtc = crtc ? crtc : plane->crtc;
+ intel_crtc = to_intel_crtc(crtc);
-static int
-intel_prepare_primary_plane(struct drm_plane *plane,
- struct intel_plane_state *state)
-{
- struct drm_crtc *crtc = state->crtc;
- struct drm_framebuffer *fb = state->fb;
- struct drm_device *dev = crtc->dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
- int ret;
+ ret = drm_plane_helper_check_update(plane, crtc, fb,
+ src, dest, clip,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ false, true, &state->visible);
+ if (ret)
+ return ret;
- intel_crtc_wait_for_pending_flips(crtc);
+ if (intel_crtc->active) {
+ intel_crtc->atomic.wait_for_flips = true;
- if (intel_crtc_has_pending_flip(crtc)) {
- DRM_ERROR("pipe is still busy with an old pageflip\n");
- return -EBUSY;
- }
+ /*
+ * FBC does not work on some platforms for rotated
+ * planes, so disable it when rotation is not 0 and
+ * update it when rotation is set back to 0.
+ *
+ * FIXME: This is redundant with the fbc update done in
+ * the primary plane enable function except that that
+ * one is done too late. We eventually need to unify
+ * this.
+ */
+ if (intel_crtc->primary_enabled &&
+ INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
+ dev_priv->fbc.plane == intel_crtc->plane &&
+ state->base.rotation != BIT(DRM_ROTATE_0)) {
+ intel_crtc->atomic.disable_fbc = true;
+ }
- if (old_obj != obj) {
- mutex_lock(&dev->struct_mutex);
- ret = intel_pin_and_fence_fb_obj(plane, fb, NULL);
- if (ret == 0)
- i915_gem_track_fb(old_obj, obj,
- INTEL_FRONTBUFFER_PRIMARY(pipe));
- mutex_unlock(&dev->struct_mutex);
- if (ret != 0) {
- DRM_DEBUG_KMS("pin & fence failed\n");
- return ret;
+ if (state->visible) {
+ /*
+ * BDW signals flip done immediately if the plane
+ * is disabled, even if the plane enable is already
+ * armed to occur at the next vblank :(
+ */
+ if (IS_BROADWELL(dev) && !intel_crtc->primary_enabled)
+ intel_crtc->atomic.wait_vblank = true;
}
+
+ intel_crtc->atomic.fb_bits |=
+ INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
+
+ intel_crtc->atomic.update_fbc = true;
}
return 0;
@@ -11858,53 +11925,26 @@ static void
intel_commit_primary_plane(struct drm_plane *plane,
struct intel_plane_state *state)
{
- struct drm_crtc *crtc = state->crtc;
- struct drm_framebuffer *fb = state->fb;
- struct drm_device *dev = crtc->dev;
+ struct drm_crtc *crtc = state->base.crtc;
+ struct drm_framebuffer *fb = state->base.fb;
+ struct drm_device *dev = plane->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
- struct drm_framebuffer *old_fb = plane->fb;
+ struct intel_crtc *intel_crtc;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
struct intel_plane *intel_plane = to_intel_plane(plane);
struct drm_rect *src = &state->src;
- crtc->primary->fb = fb;
+ crtc = crtc ? crtc : plane->crtc;
+ intel_crtc = to_intel_crtc(crtc);
+
+ plane->fb = fb;
crtc->x = src->x1 >> 16;
crtc->y = src->y1 >> 16;
- intel_plane->crtc_x = state->orig_dst.x1;
- intel_plane->crtc_y = state->orig_dst.y1;
- intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
- intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
- intel_plane->src_x = state->orig_src.x1;
- intel_plane->src_y = state->orig_src.y1;
- intel_plane->src_w = drm_rect_width(&state->orig_src);
- intel_plane->src_h = drm_rect_height(&state->orig_src);
intel_plane->obj = obj;
if (intel_crtc->active) {
- /*
- * FBC does not work on some platforms for rotated
- * planes, so disable it when rotation is not 0 and
- * update it when rotation is set back to 0.
- *
- * FIXME: This is redundant with the fbc update done in
- * the primary plane enable function except that that
- * one is done too late. We eventually need to unify
- * this.
- */
- if (intel_crtc->primary_enabled &&
- INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
- dev_priv->fbc.plane == intel_crtc->plane &&
- intel_plane->rotation != BIT(DRM_ROTATE_0)) {
- intel_disable_fbc(dev);
- }
-
if (state->visible) {
- bool was_enabled = intel_crtc->primary_enabled;
-
/* FIXME: kill this fastboot hack */
intel_update_pipe_size(intel_crtc);
@@ -11912,14 +11952,6 @@ intel_commit_primary_plane(struct drm_plane *plane,
dev_priv->display.update_primary_plane(crtc, plane->fb,
crtc->x, crtc->y);
-
- /*
- * BDW signals flip done immediately if the plane
- * is disabled, even if the plane enable is already
- * armed to occur at the next vblank :(
- */
- if (IS_BROADWELL(dev) && !was_enabled)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
} else {
/*
* If clipping results in a non-visible primary plane,
@@ -11930,90 +11962,129 @@ intel_commit_primary_plane(struct drm_plane *plane,
*/
intel_disable_primary_hw_plane(plane, crtc);
}
+ }
+}
- intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
+static void intel_begin_crtc_commit(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_plane *intel_plane;
+ struct drm_plane *p;
+ unsigned fb_bits = 0;
+
+ /* Track fb's for any planes being disabled */
+ list_for_each_entry(p, &dev->mode_config.plane_list, head) {
+ intel_plane = to_intel_plane(p);
+
+ if (intel_crtc->atomic.disabled_planes &
+ (1 << drm_plane_index(p))) {
+ switch (p->type) {
+ case DRM_PLANE_TYPE_PRIMARY:
+ fb_bits = INTEL_FRONTBUFFER_PRIMARY(intel_plane->pipe);
+ break;
+ case DRM_PLANE_TYPE_CURSOR:
+ fb_bits = INTEL_FRONTBUFFER_CURSOR(intel_plane->pipe);
+ break;
+ case DRM_PLANE_TYPE_OVERLAY:
+ fb_bits = INTEL_FRONTBUFFER_SPRITE(intel_plane->pipe);
+ break;
+ }
- mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
- mutex_unlock(&dev->struct_mutex);
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_track_fb(intel_fb_obj(p->fb), NULL, fb_bits);
+ mutex_unlock(&dev->struct_mutex);
+ }
}
- if (old_fb && old_fb != fb) {
- if (intel_crtc->active)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ if (intel_crtc->atomic.wait_for_flips)
+ intel_crtc_wait_for_pending_flips(crtc);
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(old_obj);
- mutex_unlock(&dev->struct_mutex);
- }
+ if (intel_crtc->atomic.disable_fbc)
+ intel_fbc_disable(dev);
+
+ if (intel_crtc->atomic.pre_disable_primary)
+ intel_pre_disable_primary(crtc);
+
+ if (intel_crtc->atomic.update_wm)
+ intel_update_watermarks(crtc);
+
+ intel_runtime_pm_get(dev_priv);
+
+ /* Perform vblank evasion around commit operation */
+ if (intel_crtc->active)
+ intel_crtc->atomic.evade =
+ intel_pipe_update_start(intel_crtc,
+ &intel_crtc->atomic.start_vbl_count);
}
-static int
-intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h)
+static void intel_finish_crtc_commit(struct drm_crtc *crtc)
{
- struct intel_plane_state state;
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int ret;
+ struct drm_plane *p;
- state.crtc = crtc;
- state.fb = fb;
+ if (intel_crtc->atomic.evade)
+ intel_pipe_update_end(intel_crtc,
+ intel_crtc->atomic.start_vbl_count);
- /* sample coordinates in 16.16 fixed point */
- state.src.x1 = src_x;
- state.src.x2 = src_x + src_w;
- state.src.y1 = src_y;
- state.src.y2 = src_y + src_h;
-
- /* integer pixels */
- state.dst.x1 = crtc_x;
- state.dst.x2 = crtc_x + crtc_w;
- state.dst.y1 = crtc_y;
- state.dst.y2 = crtc_y + crtc_h;
+ intel_runtime_pm_put(dev_priv);
- state.clip.x1 = 0;
- state.clip.y1 = 0;
- state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
- state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
+ if (intel_crtc->atomic.wait_vblank)
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
- state.orig_src = state.src;
- state.orig_dst = state.dst;
+ intel_frontbuffer_flip(dev, intel_crtc->atomic.fb_bits);
- ret = intel_check_primary_plane(plane, &state);
- if (ret)
- return ret;
+ if (intel_crtc->atomic.update_fbc) {
+ mutex_lock(&dev->struct_mutex);
+ intel_fbc_update(dev);
+ mutex_unlock(&dev->struct_mutex);
+ }
- ret = intel_prepare_primary_plane(plane, &state);
- if (ret)
- return ret;
+ if (intel_crtc->atomic.post_enable_primary)
+ intel_post_enable_primary(crtc);
- intel_commit_primary_plane(plane, &state);
+ drm_for_each_legacy_plane(p, &dev->mode_config.plane_list)
+ if (intel_crtc->atomic.update_sprite_watermarks & drm_plane_index(p))
+ intel_update_sprite_watermarks(p, crtc, 0, 0, 0,
+ false, false);
- return 0;
+ memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
}
-/* Common destruction function for both primary and cursor planes */
-static void intel_plane_destroy(struct drm_plane *plane)
+/**
+ * intel_plane_destroy - destroy a plane
+ * @plane: plane to destroy
+ *
+ * Common destruction function for all types of planes (primary, cursor,
+ * sprite).
+ */
+void intel_plane_destroy(struct drm_plane *plane)
{
struct intel_plane *intel_plane = to_intel_plane(plane);
drm_plane_cleanup(plane);
kfree(intel_plane);
}
-static const struct drm_plane_funcs intel_primary_plane_funcs = {
- .update_plane = intel_primary_plane_setplane,
- .disable_plane = intel_primary_plane_disable,
+const struct drm_plane_funcs intel_plane_funcs = {
+ .update_plane = drm_plane_helper_update,
+ .disable_plane = drm_plane_helper_disable,
.destroy = intel_plane_destroy,
- .set_property = intel_plane_set_property
+ .set_property = drm_atomic_helper_plane_set_property,
+ .atomic_get_property = intel_plane_atomic_get_property,
+ .atomic_set_property = intel_plane_atomic_set_property,
+ .atomic_duplicate_state = intel_plane_duplicate_state,
+ .atomic_destroy_state = intel_plane_destroy_state,
+
};
static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
int pipe)
{
struct intel_plane *primary;
+ struct intel_plane_state *state;
const uint32_t *intel_primary_formats;
int num_formats;
@@ -12021,11 +12092,19 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
if (primary == NULL)
return NULL;
+ state = intel_create_plane_state(&primary->base);
+ if (!state) {
+ kfree(primary);
+ return NULL;
+ }
+ primary->base.state = &state->base;
+
primary->can_scale = false;
primary->max_downscale = 1;
primary->pipe = pipe;
primary->plane = pipe;
- primary->rotation = BIT(DRM_ROTATE_0);
+ primary->check_plane = intel_check_primary_plane;
+ primary->commit_plane = intel_commit_primary_plane;
if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
primary->plane = !pipe;
@@ -12038,7 +12117,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
}
drm_universal_plane_init(dev, &primary->base, 0,
- &intel_primary_plane_funcs,
+ &intel_plane_funcs,
intel_primary_formats, num_formats,
DRM_PLANE_TYPE_PRIMARY);
@@ -12051,38 +12130,32 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
if (dev->mode_config.rotation_property)
drm_object_attach_property(&primary->base.base,
dev->mode_config.rotation_property,
- primary->rotation);
+ state->base.rotation);
}
- return &primary->base;
-}
-
-static int
-intel_cursor_plane_disable(struct drm_plane *plane)
-{
- if (!plane->fb)
- return 0;
-
- BUG_ON(!plane->crtc);
+ drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
- return intel_crtc_cursor_set_obj(plane->crtc, NULL, 0, 0);
+ return &primary->base;
}
static int
intel_check_cursor_plane(struct drm_plane *plane,
struct intel_plane_state *state)
{
- struct drm_crtc *crtc = state->crtc;
- struct drm_device *dev = crtc->dev;
- struct drm_framebuffer *fb = state->fb;
+ struct drm_crtc *crtc = state->base.crtc;
+ struct drm_device *dev = plane->dev;
+ struct drm_framebuffer *fb = state->base.fb;
struct drm_rect *dest = &state->dst;
struct drm_rect *src = &state->src;
const struct drm_rect *clip = &state->clip;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- int crtc_w, crtc_h;
+ struct intel_crtc *intel_crtc;
unsigned stride;
int ret;
+ crtc = crtc ? crtc : plane->crtc;
+ intel_crtc = to_intel_crtc(crtc);
+
ret = drm_plane_helper_check_update(plane, crtc, fb,
src, dest, clip,
DRM_PLANE_HELPER_NO_SCALING,
@@ -12094,18 +12167,17 @@ intel_check_cursor_plane(struct drm_plane *plane,
/* if we want to turn off the cursor ignore width and height */
if (!obj)
- return 0;
+ goto finish;
/* Check for which cursor types we support */
- crtc_w = drm_rect_width(&state->orig_dst);
- crtc_h = drm_rect_height(&state->orig_dst);
- if (!cursor_size_ok(dev, crtc_w, crtc_h)) {
- DRM_DEBUG("Cursor dimension not supported\n");
+ if (!cursor_size_ok(dev, state->base.crtc_w, state->base.crtc_h)) {
+ DRM_DEBUG("Cursor dimension %dx%d not supported\n",
+ state->base.crtc_w, state->base.crtc_h);
return -EINVAL;
}
- stride = roundup_pow_of_two(crtc_w) * 4;
- if (obj->base.size < stride * crtc_h) {
+ stride = roundup_pow_of_two(state->base.crtc_w) * 4;
+ if (obj->base.size < stride * state->base.crtc_h) {
DRM_DEBUG_KMS("buffer is too small\n");
return -ENOMEM;
}
@@ -12121,113 +12193,84 @@ intel_check_cursor_plane(struct drm_plane *plane,
}
mutex_unlock(&dev->struct_mutex);
+finish:
+ if (intel_crtc->active) {
+ if (intel_crtc->cursor_width != state->base.crtc_w)
+ intel_crtc->atomic.update_wm = true;
+
+ intel_crtc->atomic.fb_bits |=
+ INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe);
+ }
+
return ret;
}
-static int
+static void
intel_commit_cursor_plane(struct drm_plane *plane,
struct intel_plane_state *state)
{
- struct drm_crtc *crtc = state->crtc;
- struct drm_framebuffer *fb = state->fb;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_crtc *crtc = state->base.crtc;
+ struct drm_device *dev = plane->dev;
+ struct intel_crtc *intel_crtc;
struct intel_plane *intel_plane = to_intel_plane(plane);
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
- int crtc_w, crtc_h;
-
- crtc->cursor_x = state->orig_dst.x1;
- crtc->cursor_y = state->orig_dst.y1;
-
- intel_plane->crtc_x = state->orig_dst.x1;
- intel_plane->crtc_y = state->orig_dst.y1;
- intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
- intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
- intel_plane->src_x = state->orig_src.x1;
- intel_plane->src_y = state->orig_src.y1;
- intel_plane->src_w = drm_rect_width(&state->orig_src);
- intel_plane->src_h = drm_rect_height(&state->orig_src);
- intel_plane->obj = obj;
-
- if (fb != crtc->cursor->fb) {
- crtc_w = drm_rect_width(&state->orig_dst);
- crtc_h = drm_rect_height(&state->orig_dst);
- return intel_crtc_cursor_set_obj(crtc, obj, crtc_w, crtc_h);
- } else {
- intel_crtc_update_cursor(crtc, state->visible);
-
- intel_frontbuffer_flip(crtc->dev,
- INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe));
-
- return 0;
- }
-}
-
-static int
-intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_plane_state state;
- int ret;
+ struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+ uint32_t addr;
- state.crtc = crtc;
- state.fb = fb;
+ crtc = crtc ? crtc : plane->crtc;
+ intel_crtc = to_intel_crtc(crtc);
- /* sample coordinates in 16.16 fixed point */
- state.src.x1 = src_x;
- state.src.x2 = src_x + src_w;
- state.src.y1 = src_y;
- state.src.y2 = src_y + src_h;
+ plane->fb = state->base.fb;
+ crtc->cursor_x = state->base.crtc_x;
+ crtc->cursor_y = state->base.crtc_y;
- /* integer pixels */
- state.dst.x1 = crtc_x;
- state.dst.x2 = crtc_x + crtc_w;
- state.dst.y1 = crtc_y;
- state.dst.y2 = crtc_y + crtc_h;
+ intel_plane->obj = obj;
- state.clip.x1 = 0;
- state.clip.y1 = 0;
- state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
- state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
+ if (intel_crtc->cursor_bo == obj)
+ goto update;
- state.orig_src = state.src;
- state.orig_dst = state.dst;
+ if (!obj)
+ addr = 0;
+ else if (!INTEL_INFO(dev)->cursor_needs_physical)
+ addr = i915_gem_obj_ggtt_offset(obj);
+ else
+ addr = obj->phys_handle->busaddr;
- ret = intel_check_cursor_plane(plane, &state);
- if (ret)
- return ret;
+ intel_crtc->cursor_addr = addr;
+ intel_crtc->cursor_bo = obj;
+update:
+ intel_crtc->cursor_width = state->base.crtc_w;
+ intel_crtc->cursor_height = state->base.crtc_h;
- return intel_commit_cursor_plane(plane, &state);
+ if (intel_crtc->active)
+ intel_crtc_update_cursor(crtc, state->visible);
}
-static const struct drm_plane_funcs intel_cursor_plane_funcs = {
- .update_plane = intel_cursor_plane_update,
- .disable_plane = intel_cursor_plane_disable,
- .destroy = intel_plane_destroy,
- .set_property = intel_plane_set_property,
-};
-
static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
int pipe)
{
struct intel_plane *cursor;
+ struct intel_plane_state *state;
cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
if (cursor == NULL)
return NULL;
+ state = intel_create_plane_state(&cursor->base);
+ if (!state) {
+ kfree(cursor);
+ return NULL;
+ }
+ cursor->base.state = &state->base;
+
cursor->can_scale = false;
cursor->max_downscale = 1;
cursor->pipe = pipe;
cursor->plane = pipe;
- cursor->rotation = BIT(DRM_ROTATE_0);
+ cursor->check_plane = intel_check_cursor_plane;
+ cursor->commit_plane = intel_commit_cursor_plane;
drm_universal_plane_init(dev, &cursor->base, 0,
- &intel_cursor_plane_funcs,
+ &intel_plane_funcs,
intel_cursor_formats,
ARRAY_SIZE(intel_cursor_formats),
DRM_PLANE_TYPE_CURSOR);
@@ -12241,9 +12284,11 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
if (dev->mode_config.rotation_property)
drm_object_attach_property(&cursor->base.base,
dev->mode_config.rotation_property,
- cursor->rotation);
+ state->base.rotation);
}
+ drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
+
return &cursor->base;
}
@@ -12251,6 +12296,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc;
+ struct intel_crtc_state *crtc_state = NULL;
struct drm_plane *primary = NULL;
struct drm_plane *cursor = NULL;
int i, ret;
@@ -12259,6 +12305,11 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
if (intel_crtc == NULL)
return;
+ crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
+ if (!crtc_state)
+ goto fail;
+ intel_crtc_set_state(intel_crtc, crtc_state);
+
primary = intel_primary_plane_create(dev, pipe);
if (!primary)
goto fail;
@@ -12311,6 +12362,7 @@ fail:
drm_plane_cleanup(primary);
if (cursor)
drm_plane_cleanup(cursor);
+ kfree(crtc_state);
kfree(intel_crtc);
}
@@ -12383,28 +12435,6 @@ static bool has_edp_a(struct drm_device *dev)
return true;
}
-const char *intel_output_name(int output)
-{
- static const char *names[] = {
- [INTEL_OUTPUT_UNUSED] = "Unused",
- [INTEL_OUTPUT_ANALOG] = "Analog",
- [INTEL_OUTPUT_DVO] = "DVO",
- [INTEL_OUTPUT_SDVO] = "SDVO",
- [INTEL_OUTPUT_LVDS] = "LVDS",
- [INTEL_OUTPUT_TVOUT] = "TV",
- [INTEL_OUTPUT_HDMI] = "HDMI",
- [INTEL_OUTPUT_DISPLAYPORT] = "DisplayPort",
- [INTEL_OUTPUT_EDP] = "eDP",
- [INTEL_OUTPUT_DSI] = "DSI",
- [INTEL_OUTPUT_UNKNOWN] = "Unknown",
- };
-
- if (output < 0 || output >= ARRAY_SIZE(names) || !names[output])
- return "Invalid";
-
- return names[output];
-}
-
static bool intel_crt_present(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -12428,6 +12458,7 @@ static void intel_setup_outputs(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
+ struct drm_connector *connector;
bool dpd_is_edp = false;
intel_lvds_init(dev);
@@ -12491,14 +12522,16 @@ static void intel_setup_outputs(struct drm_device *dev)
* eDP ports. Consult the VBT as well as DP_DETECTED to
* detect eDP ports.
*/
- if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED)
+ if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED &&
+ !intel_dp_is_edp(dev, PORT_B))
intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB,
PORT_B);
if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED ||
intel_dp_is_edp(dev, PORT_B))
intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B);
- if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED)
+ if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED &&
+ !intel_dp_is_edp(dev, PORT_C))
intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC,
PORT_C);
if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED ||
@@ -12556,6 +12589,37 @@ static void intel_setup_outputs(struct drm_device *dev)
if (SUPPORTS_TV(dev))
intel_tv_init(dev);
+ /*
+ * FIXME: We don't have full atomic support yet, but we want to be
+ * able to enable/test plane updates via the atomic interface in the
+ * meantime. However as soon as we flip DRIVER_ATOMIC on, the DRM core
+ * will take some atomic codepaths to lookup properties during
+ * drmModeGetConnector() that unconditionally dereference
+ * connector->state.
+ *
+ * We create a dummy connector state here for each connector to ensure
+ * the DRM core doesn't try to dereference a NULL connector->state.
+ * The actual connector properties will never be updated or contain
+ * useful information, but since we're doing this specifically for
+ * testing/debug of the plane operations (and only when a specific
+ * kernel module option is given), that shouldn't really matter.
+ *
+ * Once atomic support for crtc's + connectors lands, this loop should
+ * be removed since we'll be setting up real connector state, which
+ * will contain Intel-specific properties.
+ */
+ if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
+ list_for_each_entry(connector,
+ &dev->mode_config.connector_list,
+ head) {
+ if (!WARN_ON(connector->state)) {
+ connector->state =
+ kzalloc(sizeof(*connector->state),
+ GFP_KERNEL);
+ }
+ }
+ }
+
intel_psr_init(dev);
for_each_intel_encoder(dev, encoder) {
@@ -12696,8 +12760,8 @@ static int intel_framebuffer_init(struct drm_device *dev,
if (mode_cmd->offsets[0] != 0)
return -EINVAL;
- aligned_height = intel_align_height(dev, mode_cmd->height,
- obj->tiling_mode);
+ aligned_height = intel_fb_align_height(dev, mode_cmd->height,
+ obj->tiling_mode);
/* FIXME drm helper for size checks (especially planar formats)? */
if (obj->base.size < aligned_height * mode_cmd->pitches[0])
return -EINVAL;
@@ -12739,6 +12803,8 @@ static inline void intel_fbdev_output_poll_changed(struct drm_device *dev)
static const struct drm_mode_config_funcs intel_mode_funcs = {
.fb_create = intel_user_framebuffer_create,
.output_poll_changed = intel_fbdev_output_poll_changed,
+ .atomic_check = intel_atomic_check,
+ .atomic_commit = intel_atomic_commit,
};
/* Set up chip specific display functions */
@@ -12757,23 +12823,32 @@ static void intel_init_display(struct drm_device *dev)
else
dev_priv->display.find_dpll = i9xx_find_best_dpll;
- if (HAS_DDI(dev)) {
+ if (INTEL_INFO(dev)->gen >= 9) {
dev_priv->display.get_pipe_config = haswell_get_pipe_config;
- dev_priv->display.get_plane_config = ironlake_get_plane_config;
+ dev_priv->display.get_initial_plane_config =
+ skylake_get_initial_plane_config;
dev_priv->display.crtc_compute_clock =
haswell_crtc_compute_clock;
dev_priv->display.crtc_enable = haswell_crtc_enable;
dev_priv->display.crtc_disable = haswell_crtc_disable;
dev_priv->display.off = ironlake_crtc_off;
- if (INTEL_INFO(dev)->gen >= 9)
- dev_priv->display.update_primary_plane =
- skylake_update_primary_plane;
- else
- dev_priv->display.update_primary_plane =
- ironlake_update_primary_plane;
+ dev_priv->display.update_primary_plane =
+ skylake_update_primary_plane;
+ } else if (HAS_DDI(dev)) {
+ dev_priv->display.get_pipe_config = haswell_get_pipe_config;
+ dev_priv->display.get_initial_plane_config =
+ ironlake_get_initial_plane_config;
+ dev_priv->display.crtc_compute_clock =
+ haswell_crtc_compute_clock;
+ dev_priv->display.crtc_enable = haswell_crtc_enable;
+ dev_priv->display.crtc_disable = haswell_crtc_disable;
+ dev_priv->display.off = ironlake_crtc_off;
+ dev_priv->display.update_primary_plane =
+ ironlake_update_primary_plane;
} else if (HAS_PCH_SPLIT(dev)) {
dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
- dev_priv->display.get_plane_config = ironlake_get_plane_config;
+ dev_priv->display.get_initial_plane_config =
+ ironlake_get_initial_plane_config;
dev_priv->display.crtc_compute_clock =
ironlake_crtc_compute_clock;
dev_priv->display.crtc_enable = ironlake_crtc_enable;
@@ -12783,7 +12858,8 @@ static void intel_init_display(struct drm_device *dev)
ironlake_update_primary_plane;
} else if (IS_VALLEYVIEW(dev)) {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
- dev_priv->display.get_plane_config = i9xx_get_plane_config;
+ dev_priv->display.get_initial_plane_config =
+ i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
dev_priv->display.crtc_enable = valleyview_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -12792,7 +12868,8 @@ static void intel_init_display(struct drm_device *dev)
i9xx_update_primary_plane;
} else {
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
- dev_priv->display.get_plane_config = i9xx_get_plane_config;
+ dev_priv->display.get_initial_plane_config =
+ i9xx_get_initial_plane_config;
dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
dev_priv->display.crtc_enable = i9xx_crtc_enable;
dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -13147,7 +13224,7 @@ void intel_modeset_init(struct drm_device *dev)
intel_setup_outputs(dev);
/* Just in case the BIOS is doing something questionable. */
- intel_disable_fbc(dev);
+ intel_fbc_disable(dev);
drm_modeset_lock_all(dev);
intel_modeset_setup_hw_state(dev, false);
@@ -13164,8 +13241,8 @@ void intel_modeset_init(struct drm_device *dev)
* can even allow for smooth boot transitions if the BIOS
* fb is large enough for the active pipe configuration.
*/
- if (dev_priv->display.get_plane_config) {
- dev_priv->display.get_plane_config(crtc,
+ if (dev_priv->display.get_initial_plane_config) {
+ dev_priv->display.get_initial_plane_config(crtc,
&crtc->plane_config);
/*
* If the fb is shared between multiple heads, we'll
@@ -13229,7 +13306,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
u32 reg;
/* Clear any frame start delays used for debugging left by the BIOS */
- reg = PIPECONF(crtc->config.cpu_transcoder);
+ reg = PIPECONF(crtc->config->cpu_transcoder);
I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
/* restore vblank interrupts to correct state */
@@ -13433,12 +13510,12 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
int i;
for_each_intel_crtc(dev, crtc) {
- memset(&crtc->config, 0, sizeof(crtc->config));
+ memset(crtc->config, 0, sizeof(*crtc->config));
- crtc->config.quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
+ crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
crtc->active = dev_priv->display.get_pipe_config(crtc,
- &crtc->config);
+ crtc->config);
crtc->base.enabled = crtc->active;
crtc->primary_enabled = primary_get_hw_state(crtc);
@@ -13475,7 +13552,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
if (encoder->get_hw_state(encoder, &pipe)) {
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
encoder->base.crtc = &crtc->base;
- encoder->get_config(encoder, &crtc->config);
+ encoder->get_config(encoder, crtc->config);
} else {
encoder->base.crtc = NULL;
}
@@ -13525,7 +13602,8 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
*/
for_each_intel_crtc(dev, crtc) {
if (crtc->active && i915.fastboot) {
- intel_mode_from_pipe_config(&crtc->base.mode, &crtc->config);
+ intel_mode_from_pipe_config(&crtc->base.mode,
+ crtc->config);
DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
crtc->base.base.id);
drm_mode_debug_printmodeline(&crtc->base.mode);
@@ -13540,7 +13618,8 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
for_each_pipe(dev_priv, pipe) {
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
intel_sanitize_crtc(crtc);
- intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]");
+ intel_dump_pipe_config(crtc, crtc->config,
+ "[setup_hw_state]");
}
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
@@ -13664,7 +13743,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
intel_unregister_dsm_handler();
- intel_disable_fbc(dev);
+ intel_fbc_disable(dev);
ironlake_teardown_rc6(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5cecc20efa71..a74aaf9242b9 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -31,6 +31,7 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
@@ -1074,7 +1075,7 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
}
static void
-skl_edp_set_pll_config(struct intel_crtc_config *pipe_config, int link_bw)
+skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_bw)
{
u32 ctrl1;
@@ -1101,7 +1102,7 @@ skl_edp_set_pll_config(struct intel_crtc_config *pipe_config, int link_bw)
}
static void
-hsw_dp_set_ddi_pll_sel(struct intel_crtc_config *pipe_config, int link_bw)
+hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config, int link_bw)
{
switch (link_bw) {
case DP_LINK_BW_1_62:
@@ -1118,7 +1119,7 @@ hsw_dp_set_ddi_pll_sel(struct intel_crtc_config *pipe_config, int link_bw)
static void
intel_dp_set_clock(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config, int link_bw)
+ struct intel_crtc_state *pipe_config, int link_bw)
{
struct drm_device *dev = encoder->base.dev;
const struct dp_link_dpll *divisor = NULL;
@@ -1151,11 +1152,11 @@ intel_dp_set_clock(struct intel_encoder *encoder,
bool
intel_dp_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
enum port port = dp_to_dig_port(intel_dp)->port;
struct intel_crtc *intel_crtc = encoder->new_crtc;
@@ -1269,7 +1270,7 @@ found:
&pipe_config->dp_m_n);
if (intel_connector->panel.downclock_mode != NULL &&
- intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) {
+ dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
pipe_config->has_drrs = true;
intel_link_compute_m_n(bpp, lane_count,
intel_connector->panel.downclock_mode->clock,
@@ -1295,11 +1296,12 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpa_ctl;
- DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock);
+ DRM_DEBUG_KMS("eDP PLL enable for clock %d\n",
+ crtc->config->port_clock);
dpa_ctl = I915_READ(DP_A);
dpa_ctl &= ~DP_PLL_FREQ_MASK;
- if (crtc->config.port_clock == 162000) {
+ if (crtc->config->port_clock == 162000) {
/* For a long time we've carried around a ILK-DevA w/a for the
* 160MHz clock. If we're really unlucky, it's still required.
*/
@@ -1324,7 +1326,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
enum port port = dp_to_dig_port(intel_dp)->port;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
- struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
/*
* There are four kinds of DP registers:
@@ -1352,7 +1354,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count);
- if (crtc->config.has_audio)
+ if (crtc->config->has_audio)
intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
/* Split out the IBX/CPU vs CPT settings */
@@ -1558,7 +1560,7 @@ void intel_edp_panel_vdd_on(struct intel_dp *intel_dp)
vdd = edp_panel_vdd_on(intel_dp);
pps_unlock(intel_dp);
- WARN(!vdd, "eDP port %c VDD already requested on\n",
+ I915_STATE_WARN(!vdd, "eDP port %c VDD already requested on\n",
port_name(dp_to_dig_port(intel_dp)->port));
}
@@ -1642,7 +1644,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
if (!is_edp(intel_dp))
return;
- WARN(!intel_dp->want_panel_vdd, "eDP port %c VDD not forced on",
+ I915_STATE_WARN(!intel_dp->want_panel_vdd, "eDP port %c VDD not forced on",
port_name(dp_to_dig_port(intel_dp)->port));
intel_dp->want_panel_vdd = false;
@@ -2013,7 +2015,7 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
}
static void intel_dp_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
u32 tmp, flags = 0;
@@ -2050,7 +2052,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
flags |= DRM_MODE_FLAG_NVSYNC;
}
- pipe_config->adjusted_mode.flags |= flags;
+ pipe_config->base.adjusted_mode.flags |= flags;
if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) &&
tmp & DP_COLOR_RANGE_16_235)
@@ -2073,7 +2075,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
if (HAS_PCH_SPLIT(dev_priv->dev) && port != PORT_A)
ironlake_check_encoder_dotclock(pipe_config, dotclock);
- pipe_config->adjusted_mode.crtc_clock = dotclock;
+ pipe_config->base.adjusted_mode.crtc_clock = dotclock;
if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp &&
pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
@@ -2102,9 +2104,12 @@ static void intel_disable_dp(struct intel_encoder *encoder)
struct drm_device *dev = encoder->base.dev;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
- if (crtc->config.has_audio)
+ if (crtc->config->has_audio)
intel_audio_codec_disable(encoder);
+ if (HAS_PSR(dev) && !HAS_DDI(dev))
+ intel_psr_disable(intel_dp);
+
/* Make sure the panel is off before trying to change the mode. But also
* ensure that we have vdd while we switch off the panel. */
intel_edp_panel_vdd_on(intel_dp);
@@ -2309,7 +2314,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
intel_dp_complete_link_train(intel_dp);
intel_dp_stop_link_train(intel_dp);
- if (crtc->config.has_audio) {
+ if (crtc->config->has_audio) {
DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
pipe_name(crtc->pipe));
intel_audio_codec_enable(encoder);
@@ -2329,6 +2334,7 @@ static void vlv_enable_dp(struct intel_encoder *encoder)
struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
intel_edp_backlight_on(intel_dp);
+ intel_psr_enable(intel_dp);
}
static void g4x_pre_enable_dp(struct intel_encoder *encoder)
@@ -3515,8 +3521,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
enum port port = intel_dig_port->port;
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc =
- to_intel_crtc(intel_dig_port->base.base.crtc);
uint32_t DP = intel_dp->DP;
if (WARN_ON(HAS_DDI(dev)))
@@ -3541,8 +3545,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
if (HAS_PCH_IBX(dev) &&
I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
- struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
-
/* Hardware workaround: leaving our transcoder select
* set to transcoder B while it's off will prevent the
* corresponding HDMI output on transcoder A.
@@ -3553,18 +3555,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
*/
DP &= ~DP_PIPEB_SELECT;
I915_WRITE(intel_dp->output_reg, DP);
-
- /* Changes to enable or select take place the vblank
- * after being written.
- */
- if (WARN_ON(crtc == NULL)) {
- /* We should never try to disable a port without a crtc
- * attached. For paranoia keep the code around for a
- * bit. */
- POSTING_READ(intel_dp->output_reg);
- msleep(50);
- } else
- intel_wait_for_vblank(dev, intel_crtc->pipe);
+ POSTING_READ(intel_dp->output_reg);
}
DP &= ~DP_AUDIO_OUTPUT_ENABLE;
@@ -3769,7 +3760,7 @@ go_again:
intel_dp_stop_link_train(intel_dp);
}
- DRM_DEBUG_KMS("got esi %02x %02x %02x\n", esi[0], esi[1], esi[2]);
+ DRM_DEBUG_KMS("got esi %3ph\n", esi);
ret = drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled);
if (handled) {
@@ -3785,7 +3776,7 @@ go_again:
bret = intel_dp_get_sink_irq_esi(intel_dp, esi);
if (bret == true) {
- DRM_DEBUG_KMS("got esi2 %02x %02x %02x\n", esi[0], esi[1], esi[2]);
+ DRM_DEBUG_KMS("got esi2 %3ph\n", esi);
goto go_again;
}
} else
@@ -4306,7 +4297,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
drm_dp_aux_unregister(&intel_dp->aux);
intel_dp_mst_encoder_cleanup(intel_dig_port);
- drm_encoder_cleanup(encoder);
if (is_edp(intel_dp)) {
cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
/*
@@ -4322,6 +4312,7 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
intel_dp->edp_notifier.notifier_call = NULL;
}
}
+ drm_encoder_cleanup(encoder);
kfree(intel_dig_port);
}
@@ -4396,7 +4387,9 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = {
.force = intel_dp_force,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_dp_set_property,
+ .atomic_get_property = intel_connector_atomic_get_property,
.destroy = intel_dp_connector_destroy,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = {
@@ -4416,7 +4409,7 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder)
return;
}
-bool
+enum irqreturn
intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
{
struct intel_dp *intel_dp = &intel_dig_port->dp;
@@ -4424,7 +4417,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum intel_display_power_domain power_domain;
- bool ret = true;
+ enum irqreturn ret = IRQ_NONE;
if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
@@ -4438,7 +4431,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
*/
DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n",
port_name(intel_dig_port->port));
- return false;
+ return IRQ_HANDLED;
}
DRM_DEBUG_KMS("got hpd irq on port %c - %s\n",
@@ -4483,7 +4476,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
drm_modeset_unlock(&dev->mode_config.connection_mutex);
}
}
- ret = false;
+
+ ret = IRQ_HANDLED;
+
goto put_power;
mst_fail:
/* if we were in MST mode, and device is not there get out of MST mode */
@@ -4741,39 +4736,34 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
I915_READ(pp_div_reg));
}
-void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
+static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
- struct intel_dp *intel_dp = NULL;
- struct intel_crtc_config *config = NULL;
+ struct intel_digital_port *dig_port = NULL;
+ struct intel_dp *intel_dp = dev_priv->drrs.dp;
+ struct intel_crtc_state *config = NULL;
struct intel_crtc *intel_crtc = NULL;
- struct intel_connector *intel_connector = dev_priv->drrs.connector;
u32 reg, val;
- enum edp_drrs_refresh_rate_type index = DRRS_HIGH_RR;
+ enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
if (refresh_rate <= 0) {
DRM_DEBUG_KMS("Refresh rate should be positive non-zero.\n");
return;
}
- if (intel_connector == NULL) {
- DRM_DEBUG_KMS("DRRS supported for eDP only.\n");
+ if (intel_dp == NULL) {
+ DRM_DEBUG_KMS("DRRS not supported.\n");
return;
}
/*
- * FIXME: This needs proper synchronization with psr state. But really
- * hard to tell without seeing the user of this function of this code.
- * Check locking and ordering once that lands.
+ * FIXME: This needs proper synchronization with psr state for some
+ * platforms that cannot have PSR and DRRS enabled at the same time.
*/
- if (INTEL_INFO(dev)->gen < 8 && intel_psr_is_enabled(dev)) {
- DRM_DEBUG_KMS("DRRS is disabled as PSR is enabled\n");
- return;
- }
- encoder = intel_attached_encoder(&intel_connector->base);
- intel_dp = enc_to_intel_dp(&encoder->base);
+ dig_port = dp_to_dig_port(intel_dp);
+ encoder = &dig_port->base;
intel_crtc = encoder->new_crtc;
if (!intel_crtc) {
@@ -4781,17 +4771,18 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
return;
}
- config = &intel_crtc->config;
+ config = intel_crtc->config;
- if (intel_dp->drrs_state.type < SEAMLESS_DRRS_SUPPORT) {
+ if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
DRM_DEBUG_KMS("Only Seamless DRRS supported.\n");
return;
}
- if (intel_connector->panel.downclock_mode->vrefresh == refresh_rate)
+ if (intel_dp->attached_connector->panel.downclock_mode->vrefresh ==
+ refresh_rate)
index = DRRS_LOW_RR;
- if (index == intel_dp->drrs_state.refresh_rate_type) {
+ if (index == dev_priv->drrs.refresh_rate_type) {
DRM_DEBUG_KMS(
"DRRS requested for previously set RR...ignoring\n");
return;
@@ -4803,7 +4794,7 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
}
if (INTEL_INFO(dev)->gen > 6 && INTEL_INFO(dev)->gen < 8) {
- reg = PIPECONF(intel_crtc->config.cpu_transcoder);
+ reg = PIPECONF(intel_crtc->config->cpu_transcoder);
val = I915_READ(reg);
if (index > DRRS_HIGH_RR) {
val |= PIPECONF_EDP_RR_MODE_SWITCH;
@@ -4814,30 +4805,154 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
I915_WRITE(reg, val);
}
+ dev_priv->drrs.refresh_rate_type = index;
+
+ DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
+}
+
+void intel_edp_drrs_enable(struct intel_dp *intel_dp)
+{
+ struct drm_device *dev = intel_dp_to_dev(intel_dp);
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct drm_crtc *crtc = dig_port->base.base.crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ if (!intel_crtc->config->has_drrs) {
+ DRM_DEBUG_KMS("Panel doesn't support DRRS\n");
+ return;
+ }
+
+ mutex_lock(&dev_priv->drrs.mutex);
+ if (WARN_ON(dev_priv->drrs.dp)) {
+ DRM_ERROR("DRRS already enabled\n");
+ goto unlock;
+ }
+
+ dev_priv->drrs.busy_frontbuffer_bits = 0;
+
+ dev_priv->drrs.dp = intel_dp;
+
+unlock:
+ mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+void intel_edp_drrs_disable(struct intel_dp *intel_dp)
+{
+ struct drm_device *dev = intel_dp_to_dev(intel_dp);
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct drm_crtc *crtc = dig_port->base.base.crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ if (!intel_crtc->config->has_drrs)
+ return;
+
+ mutex_lock(&dev_priv->drrs.mutex);
+ if (!dev_priv->drrs.dp) {
+ mutex_unlock(&dev_priv->drrs.mutex);
+ return;
+ }
+
+ if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR)
+ intel_dp_set_drrs_state(dev_priv->dev,
+ intel_dp->attached_connector->panel.
+ fixed_mode->vrefresh);
+
+ dev_priv->drrs.dp = NULL;
+ mutex_unlock(&dev_priv->drrs.mutex);
+
+ cancel_delayed_work_sync(&dev_priv->drrs.work);
+}
+
+static void intel_edp_drrs_downclock_work(struct work_struct *work)
+{
+ struct drm_i915_private *dev_priv =
+ container_of(work, typeof(*dev_priv), drrs.work.work);
+ struct intel_dp *intel_dp;
+
+ mutex_lock(&dev_priv->drrs.mutex);
+
+ intel_dp = dev_priv->drrs.dp;
+
+ if (!intel_dp)
+ goto unlock;
+
/*
- * mutex taken to ensure that there is no race between differnt
- * drrs calls trying to update refresh rate. This scenario may occur
- * in future when idleness detection based DRRS in kernel and
- * possible calls from user space to set differnt RR are made.
+ * The delayed work can race with an invalidate hence we need to
+ * recheck.
*/
- mutex_lock(&intel_dp->drrs_state.mutex);
+ if (dev_priv->drrs.busy_frontbuffer_bits)
+ goto unlock;
- intel_dp->drrs_state.refresh_rate_type = index;
+ if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR)
+ intel_dp_set_drrs_state(dev_priv->dev,
+ intel_dp->attached_connector->panel.
+ downclock_mode->vrefresh);
- mutex_unlock(&intel_dp->drrs_state.mutex);
+unlock:
- DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
+ mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+void intel_edp_drrs_invalidate(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc;
+ enum pipe pipe;
+
+ if (!dev_priv->drrs.dp)
+ return;
+
+ mutex_lock(&dev_priv->drrs.mutex);
+ crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
+ pipe = to_intel_crtc(crtc)->pipe;
+
+ if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) {
+ cancel_delayed_work_sync(&dev_priv->drrs.work);
+ intel_dp_set_drrs_state(dev_priv->dev,
+ dev_priv->drrs.dp->attached_connector->panel.
+ fixed_mode->vrefresh);
+ }
+
+ frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+
+ dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits;
+ mutex_unlock(&dev_priv->drrs.mutex);
+}
+
+void intel_edp_drrs_flush(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc;
+ enum pipe pipe;
+
+ if (!dev_priv->drrs.dp)
+ return;
+
+ mutex_lock(&dev_priv->drrs.mutex);
+ crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
+ pipe = to_intel_crtc(crtc)->pipe;
+ dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
+
+ cancel_delayed_work_sync(&dev_priv->drrs.work);
+
+ if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR &&
+ !dev_priv->drrs.busy_frontbuffer_bits)
+ schedule_delayed_work(&dev_priv->drrs.work,
+ msecs_to_jiffies(1000));
+ mutex_unlock(&dev_priv->drrs.mutex);
}
static struct drm_display_mode *
-intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
- struct intel_connector *intel_connector,
- struct drm_display_mode *fixed_mode)
+intel_dp_drrs_init(struct intel_connector *intel_connector,
+ struct drm_display_mode *fixed_mode)
{
struct drm_connector *connector = &intel_connector->base;
- struct intel_dp *intel_dp = &intel_dig_port->dp;
- struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_display_mode *downclock_mode = NULL;
@@ -4859,13 +4974,13 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
return NULL;
}
- dev_priv->drrs.connector = intel_connector;
+ INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
- mutex_init(&intel_dp->drrs_state.mutex);
+ mutex_init(&dev_priv->drrs.mutex);
- intel_dp->drrs_state.type = dev_priv->vbt.drrs_type;
+ dev_priv->drrs.type = dev_priv->vbt.drrs_type;
- intel_dp->drrs_state.refresh_rate_type = DRRS_HIGH_RR;
+ dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
DRM_DEBUG_KMS("seamless DRRS supported for eDP panel.\n");
return downclock_mode;
}
@@ -4885,7 +5000,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct edid *edid;
enum pipe pipe = INVALID_PIPE;
- intel_dp->drrs_state.type = DRRS_NOT_SUPPORTED;
+ dev_priv->drrs.type = DRRS_NOT_SUPPORTED;
if (!is_edp(intel_dp))
return true;
@@ -4934,7 +5049,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
fixed_mode = drm_mode_duplicate(dev, scan);
downclock_mode = intel_dp_drrs_init(
- intel_dig_port,
intel_connector, fixed_mode);
break;
}
@@ -5086,7 +5200,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
intel_dp_aux_init(intel_dp, intel_connector);
/* init MST on ports that can support it */
- if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
if (port == PORT_B || port == PORT_C || port == PORT_D) {
intel_dp_mst_encoder_init(intel_dig_port,
intel_connector->base.base.id);
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 7f8c6a66680a..9f67a379a9a5 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -26,11 +26,12 @@
#include <drm/drmP.h>
#include "i915_drv.h"
#include "intel_drv.h"
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
struct intel_digital_port *intel_dig_port = intel_mst->primary;
@@ -38,7 +39,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
struct drm_device *dev = encoder->base.dev;
int bpp;
int lane_count, slots;
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
struct intel_connector *found = NULL, *intel_connector;
int mst_pbn;
@@ -157,7 +158,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
if (intel_dp->active_mst_links == 0) {
enum port port = intel_ddi_get_encoder_port(encoder);
- I915_WRITE(PORT_CLK_SEL(port), intel_crtc->config.ddi_pll_sel);
+ I915_WRITE(PORT_CLK_SEL(port),
+ intel_crtc->config->ddi_pll_sel);
intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
@@ -170,7 +172,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
}
ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
- intel_mst->port, intel_crtc->config.pbn, &slots);
+ intel_mst->port,
+ intel_crtc->config->pbn, &slots);
if (ret == false) {
DRM_ERROR("failed to allocate vcpi\n");
return;
@@ -216,14 +219,14 @@ static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
}
static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
struct intel_digital_port *intel_dig_port = intel_mst->primary;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+ enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
u32 temp, flags = 0;
pipe_config->has_dp_encoder = true;
@@ -254,7 +257,7 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
default:
break;
}
- pipe_config->adjusted_mode.flags |= flags;
+ pipe_config->base.adjusted_mode.flags |= flags;
intel_dp_get_m_n(crtc, pipe_config);
intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
@@ -311,7 +314,9 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
.detect = intel_dp_mst_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_dp_mst_set_property,
+ .atomic_get_property = intel_connector_atomic_get_property,
.destroy = intel_dp_mst_connector_destroy,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static int intel_dp_mst_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 29ba962d15e3..eef79ccd0b7c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -143,7 +143,7 @@ struct intel_encoder {
bool connectors_active;
void (*hot_plug)(struct intel_encoder *);
bool (*compute_config)(struct intel_encoder *,
- struct intel_crtc_config *);
+ struct intel_crtc_state *);
void (*pre_pll_enable)(struct intel_encoder *);
void (*pre_enable)(struct intel_encoder *);
void (*enable)(struct intel_encoder *);
@@ -159,7 +159,7 @@ struct intel_encoder {
* pre-filled the pipe config. Note that intel_encoder->base.crtc must
* be set correctly before calling this function. */
void (*get_config)(struct intel_encoder *,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
/*
* Called during system suspend after all pending requests for the
* encoder are flushed (for example for DP AUX transactions) and
@@ -244,23 +244,28 @@ typedef struct dpll {
} intel_clock_t;
struct intel_plane_state {
- struct drm_crtc *crtc;
- struct drm_framebuffer *fb;
+ struct drm_plane_state base;
struct drm_rect src;
struct drm_rect dst;
struct drm_rect clip;
- struct drm_rect orig_src;
- struct drm_rect orig_dst;
bool visible;
+
+ /*
+ * used only for sprite planes to determine when to implicitly
+ * enable/disable the primary plane
+ */
+ bool hides_primary;
};
-struct intel_plane_config {
- bool tiled;
+struct intel_initial_plane_config {
+ unsigned int tiling;
int size;
u32 base;
};
-struct intel_crtc_config {
+struct intel_crtc_state {
+ struct drm_crtc_state base;
+
/**
* quirks - bitfield with hw state readout quirks
*
@@ -273,16 +278,6 @@ struct intel_crtc_config {
#define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */
unsigned long quirks;
- /* User requested mode, only valid as a starting point to
- * compute adjusted_mode, except in the case of (S)DVO where
- * it's also for the output timings of the (S)DVO chip.
- * adjusted_mode will then correspond to the S(DVO) chip's
- * preferred input timings. */
- struct drm_display_mode requested_mode;
- /* Actual pipe timings ie. what we program into the pipe timing
- * registers. adjusted_mode.crtc_clock is the pipe pixel clock. */
- struct drm_display_mode adjusted_mode;
-
/* Pipe source size (ie. panel fitter input size)
* All planes will be positioned inside this space,
* and get clipped at the edges. */
@@ -406,8 +401,7 @@ struct intel_pipe_wm {
};
struct intel_mmio_flip {
- u32 seqno;
- struct intel_engine_cs *ring;
+ struct drm_i915_gem_request *req;
struct work_struct work;
};
@@ -417,6 +411,32 @@ struct skl_pipe_wm {
uint32_t linetime;
};
+/*
+ * Tracking of operations that need to be performed at the beginning/end of an
+ * atomic commit, outside the atomic section where interrupts are disabled.
+ * These are generally operations that grab mutexes or might otherwise sleep
+ * and thus can't be run with interrupts disabled.
+ */
+struct intel_crtc_atomic_commit {
+ /* vblank evasion */
+ bool evade;
+ unsigned start_vbl_count;
+
+ /* Sleepable operations to perform before commit */
+ bool wait_for_flips;
+ bool disable_fbc;
+ bool pre_disable_primary;
+ bool update_wm;
+ unsigned disabled_planes;
+
+ /* Sleepable operations to perform after commit */
+ unsigned fb_bits;
+ bool wait_vblank;
+ bool update_fbc;
+ bool post_enable_primary;
+ unsigned update_sprite_watermarks;
+};
+
struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
@@ -448,9 +468,9 @@ struct intel_crtc {
uint32_t cursor_size;
uint32_t cursor_base;
- struct intel_plane_config plane_config;
- struct intel_crtc_config config;
- struct intel_crtc_config *new_config;
+ struct intel_initial_plane_config plane_config;
+ struct intel_crtc_state *config;
+ struct intel_crtc_state *new_config;
bool new_enabled;
/* reset counter value when the last flip was submitted */
@@ -470,6 +490,8 @@ struct intel_crtc {
int scanline_offset;
struct intel_mmio_flip mmio_flip;
+
+ struct intel_crtc_atomic_commit atomic;
};
struct intel_plane_wm_parameters {
@@ -487,11 +509,6 @@ struct intel_plane {
struct drm_i915_gem_object *obj;
bool can_scale;
int max_downscale;
- int crtc_x, crtc_y;
- unsigned int crtc_w, crtc_h;
- uint32_t src_x, src_y;
- uint32_t src_w, src_h;
- unsigned int rotation;
/* Since we need to change the watermarks before/after
* enabling/disabling the planes, we need to store the parameters here
@@ -500,6 +517,12 @@ struct intel_plane {
*/
struct intel_plane_wm_parameters wm;
+ /*
+ * NOTE: Do not place new plane state fields here (e.g., when adding
+ * new plane properties). New runtime state should now be placed in
+ * the intel_plane_state structure and accessed via drm_plane->state.
+ */
+
void (*update_plane)(struct drm_plane *plane,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
@@ -510,6 +533,10 @@ struct intel_plane {
uint32_t src_w, uint32_t src_h);
void (*disable_plane)(struct drm_plane *plane,
struct drm_crtc *crtc);
+ int (*check_plane)(struct drm_plane *plane,
+ struct intel_plane_state *state);
+ void (*commit_plane)(struct drm_plane *plane,
+ struct intel_plane_state *state);
int (*update_colorkey)(struct drm_plane *plane,
struct drm_intel_sprite_colorkey *key);
void (*get_colorkey)(struct drm_plane *plane,
@@ -540,6 +567,7 @@ struct cxsr_latency {
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
#define to_intel_plane(x) container_of(x, struct intel_plane, base)
+#define to_intel_plane_state(x) container_of(x, struct intel_plane_state, base)
#define intel_fb_obj(x) (x ? to_intel_framebuffer(x)->obj : NULL)
struct intel_hdmi {
@@ -564,17 +592,6 @@ struct intel_hdmi {
struct intel_dp_mst_encoder;
#define DP_MAX_DOWNSTREAM_PORTS 0x10
-/**
- * HIGH_RR is the highest eDP panel refresh rate read from EDID
- * LOW_RR is the lowest eDP panel refresh rate found from EDID
- * parsing for same resolution.
- */
-enum edp_drrs_refresh_rate_type {
- DRRS_HIGH_RR,
- DRRS_LOW_RR,
- DRRS_MAX_RR, /* RR count */
-};
-
struct intel_dp {
uint32_t output_reg;
uint32_t aux_ch_ctl_reg;
@@ -630,12 +647,6 @@ struct intel_dp {
bool has_aux_irq,
int send_bytes,
uint32_t aux_clock_divider);
- struct {
- enum drrs_support_type type;
- enum edp_drrs_refresh_rate_type refresh_rate_type;
- struct mutex mutex;
- } drrs_state;
-
};
struct intel_digital_port {
@@ -644,7 +655,7 @@ struct intel_digital_port {
u32 saved_port_bits;
struct intel_dp dp;
struct intel_hdmi hdmi;
- bool (*hpd_pulse)(struct intel_digital_port *, bool);
+ enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
};
struct intel_dp_mst_encoder {
@@ -708,8 +719,7 @@ struct intel_unpin_work {
#define INTEL_FLIP_COMPLETE 2
u32 flip_count;
u32 gtt_offset;
- struct intel_engine_cs *flip_queued_ring;
- u32 flip_queued_seqno;
+ struct drm_i915_gem_request *flip_queued_req;
int flip_queued_vblank;
int flip_ready_vblank;
bool enable_stall_check;
@@ -826,17 +836,18 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder);
void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
-bool intel_ddi_pll_select(struct intel_crtc *crtc);
+bool intel_ddi_pll_select(struct intel_crtc *crtc,
+ struct intel_crtc_state *crtc_state);
void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
void intel_ddi_fdi_disable(struct drm_crtc *crtc);
void intel_ddi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
void intel_ddi_clock_get(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
/* intel_frontbuffer.c */
@@ -866,6 +877,8 @@ void intel_frontbuffer_flip(struct drm_device *dev,
intel_frontbuffer_flush(dev, frontbuffer_bits);
}
+int intel_fb_align_height(struct drm_device *dev, int height,
+ unsigned int tiling);
void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire);
@@ -877,7 +890,7 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv);
void i915_audio_component_cleanup(struct drm_i915_private *dev_priv);
/* intel_display.c */
-const char *intel_output_name(int output);
+extern const struct drm_plane_funcs intel_plane_funcs;
bool intel_has_pending_fb_unpin(struct drm_device *dev);
int intel_pch_rawclk(struct drm_device *dev);
void intel_mark_busy(struct drm_device *dev);
@@ -928,6 +941,18 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane);
void intel_finish_page_flip(struct drm_device *dev, int pipe);
void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
void intel_check_page_flip(struct drm_device *dev, int pipe);
+int intel_prepare_plane_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb);
+void intel_cleanup_plane_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb);
+int intel_plane_atomic_get_property(struct drm_plane *plane,
+ const struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t *val);
+int intel_plane_atomic_set_property(struct drm_plane *plane,
+ struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t val);
/* shared dpll functions */
struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
@@ -936,7 +961,8 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
bool state);
#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
-struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc);
+struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
+ struct intel_crtc_state *state);
void intel_put_shared_dpll(struct intel_crtc *crtc);
void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
@@ -966,11 +992,11 @@ void intel_finish_reset(struct drm_device *dev);
void hsw_enable_pc8(struct drm_i915_private *dev_priv);
void hsw_disable_pc8(struct drm_i915_private *dev_priv);
void intel_dp_get_m_n(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
void intel_dp_set_m_n(struct intel_crtc *crtc);
int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
void
-ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
+ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config,
int dotclock);
bool intel_crtc_active(struct drm_crtc *crtc);
void hsw_enable_ips(struct intel_crtc *crtc);
@@ -978,8 +1004,7 @@ void hsw_disable_ips(struct intel_crtc *crtc);
enum intel_display_power_domain
intel_display_port_power_domain(struct intel_encoder *intel_encoder);
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
- struct intel_crtc_config *pipe_config);
-int intel_format_to_fourcc(int format);
+ struct intel_crtc_state *pipe_config);
void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc);
void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file);
@@ -995,16 +1020,15 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder);
void intel_dp_check_link_status(struct intel_dp *intel_dp);
int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc);
bool intel_dp_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
bool intel_dp_is_edp(struct drm_device *dev, enum port port);
-bool intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port,
- bool long_hpd);
+enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port,
+ bool long_hpd);
void intel_edp_backlight_on(struct intel_dp *intel_dp);
void intel_edp_backlight_off(struct intel_dp *intel_dp);
void intel_edp_panel_vdd_on(struct intel_dp *intel_dp);
void intel_edp_panel_on(struct intel_dp *intel_dp);
void intel_edp_panel_off(struct intel_dp *intel_dp);
-void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector);
void intel_dp_mst_suspend(struct drm_device *dev);
void intel_dp_mst_resume(struct drm_device *dev);
@@ -1013,6 +1037,18 @@ void intel_dp_hot_plug(struct intel_encoder *intel_encoder);
void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv);
uint32_t intel_dp_pack_aux(const uint8_t *src, int src_bytes);
void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes);
+int intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h);
+int intel_disable_plane(struct drm_plane *plane);
+void intel_plane_destroy(struct drm_plane *plane);
+void intel_edp_drrs_enable(struct intel_dp *intel_dp);
+void intel_edp_drrs_disable(struct intel_dp *intel_dp);
+void intel_edp_drrs_invalidate(struct drm_device *dev,
+ unsigned frontbuffer_bits);
+void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
/* intel_dp_mst.c */
int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
@@ -1056,13 +1092,20 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
}
#endif
+/* intel_fbc.c */
+bool intel_fbc_enabled(struct drm_device *dev);
+void intel_fbc_update(struct drm_device *dev);
+void intel_fbc_init(struct drm_i915_private *dev_priv);
+void intel_fbc_disable(struct drm_device *dev);
+void bdw_fbc_sw_flush(struct drm_device *dev, u32 value);
+
/* intel_hdmi.c */
void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port);
void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
struct intel_connector *intel_connector);
struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
bool intel_hdmi_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config);
+ struct intel_crtc_state *pipe_config);
/* intel_lvds.c */
@@ -1086,6 +1129,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int intel_overlay_attrs(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+void intel_overlay_reset(struct drm_i915_private *dev_priv);
/* intel_panel.c */
@@ -1096,10 +1140,10 @@ void intel_panel_fini(struct intel_panel *panel);
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
struct drm_display_mode *adjusted_mode);
void intel_pch_panel_fitting(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config,
+ struct intel_crtc_state *pipe_config,
int fitting_mode);
void intel_gmch_panel_fitting(struct intel_crtc *crtc,
- struct intel_crtc_config *pipe_config,
+ struct intel_crtc_state *pipe_config,
int fitting_mode);
void intel_panel_set_backlight_acpi(struct intel_connector *connector,
u32 level, u32 max);
@@ -1118,7 +1162,6 @@ void intel_backlight_unregister(struct drm_device *dev);
/* intel_psr.c */
-bool intel_psr_is_enabled(struct drm_device *dev);
void intel_psr_enable(struct intel_dp *intel_dp);
void intel_psr_disable(struct intel_dp *intel_dp);
void intel_psr_invalidate(struct drm_device *dev,
@@ -1162,8 +1205,6 @@ void intel_update_sprite_watermarks(struct drm_plane *plane,
bool enabled, bool scaled);
void intel_init_pm(struct drm_device *dev);
void intel_pm_setup(struct drm_device *dev);
-bool intel_fbc_enabled(struct drm_device *dev);
-void intel_update_fbc(struct drm_device *dev);
void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
void intel_gpu_ips_teardown(void);
void intel_init_gt_powersave(struct drm_device *dev);
@@ -1194,7 +1235,6 @@ int intel_plane_set_property(struct drm_plane *plane,
struct drm_property *prop,
uint64_t val);
int intel_plane_restore(struct drm_plane *plane);
-void intel_plane_disable(struct drm_plane *plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
@@ -1202,8 +1242,31 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
bool intel_pipe_update_start(struct intel_crtc *crtc,
uint32_t *start_vbl_count);
void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count);
+void intel_post_enable_primary(struct drm_crtc *crtc);
+void intel_pre_disable_primary(struct drm_crtc *crtc);
/* intel_tv.c */
void intel_tv_init(struct drm_device *dev);
+/* intel_atomic.c */
+int intel_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state);
+int intel_atomic_commit(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ bool async);
+int intel_connector_atomic_get_property(struct drm_connector *connector,
+ const struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t *val);
+struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
+void intel_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state);
+
+/* intel_atomic_plane.c */
+struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
+struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
+void intel_plane_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state);
+extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
+
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 0b184079de14..10ab68457ca8 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -24,24 +24,219 @@
*/
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/i915_drm.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_mipi_dsi.h>
#include <linux/slab.h>
#include "i915_drv.h"
#include "intel_drv.h"
#include "intel_dsi.h"
-#include "intel_dsi_cmd.h"
-/* the sub-encoders aka panel drivers */
-static const struct intel_dsi_device intel_dsi_devices[] = {
+static const struct {
+ u16 panel_id;
+ struct drm_panel * (*init)(struct intel_dsi *intel_dsi, u16 panel_id);
+} intel_dsi_drivers[] = {
{
.panel_id = MIPI_DSI_GENERIC_PANEL_ID,
- .name = "vbt-generic-dsi-vid-mode-display",
- .dev_ops = &vbt_generic_dsi_display_ops,
+ .init = vbt_panel_init,
},
};
+static void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
+{
+ struct drm_encoder *encoder = &intel_dsi->base.base;
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 mask;
+
+ mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY |
+ LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY;
+
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == mask, 100))
+ DRM_ERROR("DPI FIFOs are not empty\n");
+}
+
+static void write_data(struct drm_i915_private *dev_priv, u32 reg,
+ const u8 *data, u32 len)
+{
+ u32 i, j;
+
+ for (i = 0; i < len; i += 4) {
+ u32 val = 0;
+
+ for (j = 0; j < min_t(u32, len - i, 4); j++)
+ val |= *data++ << 8 * j;
+
+ I915_WRITE(reg, val);
+ }
+}
+
+static void read_data(struct drm_i915_private *dev_priv, u32 reg,
+ u8 *data, u32 len)
+{
+ u32 i, j;
+
+ for (i = 0; i < len; i += 4) {
+ u32 val = I915_READ(reg);
+
+ for (j = 0; j < min_t(u32, len - i, 4); j++)
+ *data++ = val >> 8 * j;
+ }
+}
+
+static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host,
+ const struct mipi_dsi_msg *msg)
+{
+ struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host);
+ struct drm_device *dev = intel_dsi_host->intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum port port = intel_dsi_host->port;
+ struct mipi_dsi_packet packet;
+ ssize_t ret;
+ const u8 *header, *data;
+ u32 data_reg, data_mask, ctrl_reg, ctrl_mask;
+
+ ret = mipi_dsi_create_packet(&packet, msg);
+ if (ret < 0)
+ return ret;
+
+ header = packet.header;
+ data = packet.payload;
+
+ if (msg->flags & MIPI_DSI_MSG_USE_LPM) {
+ data_reg = MIPI_LP_GEN_DATA(port);
+ data_mask = LP_DATA_FIFO_FULL;
+ ctrl_reg = MIPI_LP_GEN_CTRL(port);
+ ctrl_mask = LP_CTRL_FIFO_FULL;
+ } else {
+ data_reg = MIPI_HS_GEN_DATA(port);
+ data_mask = HS_DATA_FIFO_FULL;
+ ctrl_reg = MIPI_HS_GEN_CTRL(port);
+ ctrl_mask = HS_CTRL_FIFO_FULL;
+ }
+
+ /* note: this is never true for reads */
+ if (packet.payload_length) {
+
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & data_mask) == 0, 50))
+ DRM_ERROR("Timeout waiting for HS/LP DATA FIFO !full\n");
+
+ write_data(dev_priv, data_reg, packet.payload,
+ packet.payload_length);
+ }
+
+ if (msg->rx_len) {
+ I915_WRITE(MIPI_INTR_STAT(port), GEN_READ_DATA_AVAIL);
+ }
+
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & ctrl_mask) == 0, 50)) {
+ DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n");
+ }
+
+ I915_WRITE(ctrl_reg, header[2] << 16 | header[1] << 8 | header[0]);
+
+ /* ->rx_len is set only for reads */
+ if (msg->rx_len) {
+ data_mask = GEN_READ_DATA_AVAIL;
+ if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & data_mask) == data_mask, 50))
+ DRM_ERROR("Timeout waiting for read data.\n");
+
+ read_data(dev_priv, data_reg, msg->rx_buf, msg->rx_len);
+ }
+
+ /* XXX: fix for reads and writes */
+ return 4 + packet.payload_length;
+}
+
+static int intel_dsi_host_attach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *dsi)
+{
+ return 0;
+}
+
+static int intel_dsi_host_detach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *dsi)
+{
+ return 0;
+}
+
+static const struct mipi_dsi_host_ops intel_dsi_host_ops = {
+ .attach = intel_dsi_host_attach,
+ .detach = intel_dsi_host_detach,
+ .transfer = intel_dsi_host_transfer,
+};
+
+static struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
+ enum port port)
+{
+ struct intel_dsi_host *host;
+ struct mipi_dsi_device *device;
+
+ host = kzalloc(sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return NULL;
+
+ host->base.ops = &intel_dsi_host_ops;
+ host->intel_dsi = intel_dsi;
+ host->port = port;
+
+ /*
+ * We should call mipi_dsi_host_register(&host->base) here, but we don't
+ * have a host->dev, and we don't have OF stuff either. So just use the
+ * dsi framework as a library and hope for the best. Create the dsi
+ * devices by ourselves here too. Need to be careful though, because we
+ * don't initialize any of the driver model devices here.
+ */
+ device = kzalloc(sizeof(*device), GFP_KERNEL);
+ if (!device) {
+ kfree(host);
+ return NULL;
+ }
+
+ device->host = &host->base;
+ host->device = device;
+
+ return host;
+}
+
+/*
+ * send a video mode command
+ *
+ * XXX: commands with data in MIPI_DPI_DATA?
+ */
+static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs,
+ enum port port)
+{
+ struct drm_encoder *encoder = &intel_dsi->base.base;
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 mask;
+
+ /* XXX: pipe, hs */
+ if (hs)
+ cmd &= ~DPI_LP_MODE;
+ else
+ cmd |= DPI_LP_MODE;
+
+ /* clear bit */
+ I915_WRITE(MIPI_INTR_STAT(port), SPL_PKT_SENT_INTERRUPT);
+
+ /* XXX: old code skips write if control unchanged */
+ if (cmd == I915_READ(MIPI_DPI_CONTROL(port)))
+ DRM_ERROR("Same special packet %02x twice in a row.\n", cmd);
+
+ I915_WRITE(MIPI_DPI_CONTROL(port), cmd);
+
+ mask = SPL_PKT_SENT_INTERRUPT;
+ if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, 100))
+ DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd);
+
+ return 0;
+}
+
static void band_gap_reset(struct drm_i915_private *dev_priv)
{
mutex_lock(&dev_priv->dpio_lock);
@@ -56,12 +251,6 @@ static void band_gap_reset(struct drm_i915_private *dev_priv)
mutex_unlock(&dev_priv->dpio_lock);
}
-static struct intel_dsi *intel_attached_dsi(struct drm_connector *connector)
-{
- return container_of(intel_attached_encoder(connector),
- struct intel_dsi, base);
-}
-
static inline bool is_vid_mode(struct intel_dsi *intel_dsi)
{
return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE;
@@ -78,14 +267,13 @@ static void intel_dsi_hot_plug(struct intel_encoder *encoder)
}
static bool intel_dsi_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *config)
+ struct intel_crtc_state *config)
{
struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
base);
struct intel_connector *intel_connector = intel_dsi->attached_connector;
struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
- struct drm_display_mode *adjusted_mode = &config->adjusted_mode;
- struct drm_display_mode *mode = &config->requested_mode;
+ struct drm_display_mode *adjusted_mode = &config->base.adjusted_mode;
DRM_DEBUG_KMS("\n");
@@ -95,18 +283,65 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
/* DSI uses short packets for sync events, so clear mode flags for DSI */
adjusted_mode->flags = 0;
- if (intel_dsi->dev.dev_ops->mode_fixup)
- return intel_dsi->dev.dev_ops->mode_fixup(&intel_dsi->dev,
- mode, adjusted_mode);
-
return true;
}
+static void intel_dsi_port_enable(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+ enum port port;
+ u32 temp;
+
+ if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
+ temp = I915_READ(VLV_CHICKEN_3);
+ temp &= ~PIXEL_OVERLAP_CNT_MASK |
+ intel_dsi->pixel_overlap <<
+ PIXEL_OVERLAP_CNT_SHIFT;
+ I915_WRITE(VLV_CHICKEN_3, temp);
+ }
+
+ for_each_dsi_port(port, intel_dsi->ports) {
+ temp = I915_READ(MIPI_PORT_CTRL(port));
+ temp &= ~LANE_CONFIGURATION_MASK;
+ temp &= ~DUAL_LINK_MODE_MASK;
+
+ if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) {
+ temp |= (intel_dsi->dual_link - 1)
+ << DUAL_LINK_MODE_SHIFT;
+ temp |= intel_crtc->pipe ?
+ LANE_CONFIGURATION_DUAL_LINK_B :
+ LANE_CONFIGURATION_DUAL_LINK_A;
+ }
+ /* assert ip_tg_enable signal */
+ I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE);
+ POSTING_READ(MIPI_PORT_CTRL(port));
+ }
+}
+
+static void intel_dsi_port_disable(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+ enum port port;
+ u32 temp;
+
+ for_each_dsi_port(port, intel_dsi->ports) {
+ /* de-assert ip_tg_enable signal */
+ temp = I915_READ(MIPI_PORT_CTRL(port));
+ I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE);
+ POSTING_READ(MIPI_PORT_CTRL(port));
+ }
+}
+
static void intel_dsi_device_ready(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
- int pipe = intel_crtc->pipe;
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+ enum port port;
u32 val;
DRM_DEBUG_KMS("\n");
@@ -120,48 +355,51 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
/* bandgap reset is needed after everytime we do power gate */
band_gap_reset(dev_priv);
- I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
- usleep_range(2500, 3000);
+ for_each_dsi_port(port, intel_dsi->ports) {
+
+ I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER);
+ usleep_range(2500, 3000);
- val = I915_READ(MIPI_PORT_CTRL(pipe));
- I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
- usleep_range(1000, 1500);
+ /* Enable MIPI PHY transparent latch
+ * Common bit for both MIPI Port A & MIPI Port C
+ * No similar bit in MIPI Port C reg
+ */
+ val = I915_READ(MIPI_PORT_CTRL(PORT_A));
+ I915_WRITE(MIPI_PORT_CTRL(PORT_A), val | LP_OUTPUT_HOLD);
+ usleep_range(1000, 1500);
- I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT);
- usleep_range(2500, 3000);
+ I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT);
+ usleep_range(2500, 3000);
- I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
- usleep_range(2500, 3000);
+ I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY);
+ usleep_range(2500, 3000);
+ }
}
static void intel_dsi_enable(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
- int pipe = intel_crtc->pipe;
- u32 temp;
+ enum port port;
DRM_DEBUG_KMS("\n");
- if (is_cmd_mode(intel_dsi))
- I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
- else {
+ if (is_cmd_mode(intel_dsi)) {
+ for_each_dsi_port(port, intel_dsi->ports)
+ I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(port), 8 * 4);
+ } else {
msleep(20); /* XXX */
- dpi_send_cmd(intel_dsi, TURN_ON, DPI_LP_MODE_EN);
+ for_each_dsi_port(port, intel_dsi->ports)
+ dpi_send_cmd(intel_dsi, TURN_ON, false, port);
msleep(100);
- if (intel_dsi->dev.dev_ops->enable)
- intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
+ drm_panel_enable(intel_dsi->panel);
- wait_for_dsi_fifo_empty(intel_dsi);
+ for_each_dsi_port(port, intel_dsi->ports)
+ wait_for_dsi_fifo_empty(intel_dsi, port);
- /* assert ip_tg_enable signal */
- temp = I915_READ(MIPI_PORT_CTRL(pipe)) & ~LANE_CONFIGURATION_MASK;
- temp = temp | intel_dsi->port_bits;
- I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE);
- POSTING_READ(MIPI_PORT_CTRL(pipe));
+ intel_dsi_port_enable(encoder);
}
}
@@ -172,6 +410,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
enum pipe pipe = intel_crtc->pipe;
+ enum port port;
u32 tmp;
DRM_DEBUG_KMS("\n");
@@ -183,7 +422,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
I915_WRITE(DPLL(pipe), tmp);
/* update the hw state for DPLL */
- intel_crtc->config.dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV |
+ intel_crtc->config->dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV |
DPLL_REFA_CLK_ENABLE_VLV;
tmp = I915_READ(DSPCLK_GATE_D);
@@ -195,13 +434,10 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
msleep(intel_dsi->panel_on_delay);
- if (intel_dsi->dev.dev_ops->panel_reset)
- intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev);
+ drm_panel_prepare(intel_dsi->panel);
- if (intel_dsi->dev.dev_ops->send_otp_cmds)
- intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
-
- wait_for_dsi_fifo_empty(intel_dsi);
+ for_each_dsi_port(port, intel_dsi->ports)
+ wait_for_dsi_fifo_empty(intel_dsi, port);
/* Enable port in pre-enable phase itself because as per hw team
* recommendation, port should be enabled befor plane & pipe */
@@ -221,12 +457,14 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder)
static void intel_dsi_pre_disable(struct intel_encoder *encoder)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+ enum port port;
DRM_DEBUG_KMS("\n");
if (is_vid_mode(intel_dsi)) {
/* Send Shutdown command to the panel in LP mode */
- dpi_send_cmd(intel_dsi, SHUTDOWN, DPI_LP_MODE_EN);
+ for_each_dsi_port(port, intel_dsi->ports)
+ dpi_send_cmd(intel_dsi, SHUTDOWN, false, port);
msleep(10);
}
}
@@ -235,77 +473,85 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
- int pipe = intel_crtc->pipe;
+ enum port port;
u32 temp;
DRM_DEBUG_KMS("\n");
if (is_vid_mode(intel_dsi)) {
- wait_for_dsi_fifo_empty(intel_dsi);
-
- /* de-assert ip_tg_enable signal */
- temp = I915_READ(MIPI_PORT_CTRL(pipe));
- I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE);
- POSTING_READ(MIPI_PORT_CTRL(pipe));
+ for_each_dsi_port(port, intel_dsi->ports)
+ wait_for_dsi_fifo_empty(intel_dsi, port);
+ intel_dsi_port_disable(encoder);
msleep(2);
}
- /* Panel commands can be sent when clock is in LP11 */
- I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0);
-
- temp = I915_READ(MIPI_CTRL(pipe));
- temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
- I915_WRITE(MIPI_CTRL(pipe), temp |
- intel_dsi->escape_clk_div <<
- ESCAPE_CLOCK_DIVIDER_SHIFT);
+ for_each_dsi_port(port, intel_dsi->ports) {
+ /* Panel commands can be sent when clock is in LP11 */
+ I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
- I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP);
+ temp = I915_READ(MIPI_CTRL(port));
+ temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
+ I915_WRITE(MIPI_CTRL(port), temp |
+ intel_dsi->escape_clk_div <<
+ ESCAPE_CLOCK_DIVIDER_SHIFT);
- temp = I915_READ(MIPI_DSI_FUNC_PRG(pipe));
- temp &= ~VID_MODE_FORMAT_MASK;
- I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), temp);
+ I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
- I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1);
+ temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
+ temp &= ~VID_MODE_FORMAT_MASK;
+ I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp);
+ I915_WRITE(MIPI_DEVICE_READY(port), 0x1);
+ }
/* if disable packets are sent before sending shutdown packet then in
* some next enable sequence send turn on packet error is observed */
- if (intel_dsi->dev.dev_ops->disable)
- intel_dsi->dev.dev_ops->disable(&intel_dsi->dev);
+ drm_panel_disable(intel_dsi->panel);
- wait_for_dsi_fifo_empty(intel_dsi);
+ for_each_dsi_port(port, intel_dsi->ports)
+ wait_for_dsi_fifo_empty(intel_dsi, port);
}
static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
- int pipe = intel_crtc->pipe;
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+ enum port port;
u32 val;
DRM_DEBUG_KMS("\n");
-
- I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER);
- usleep_range(2000, 2500);
-
- I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
- usleep_range(2000, 2500);
-
- I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER);
- usleep_range(2000, 2500);
-
- if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT)
- == 0x00000), 30))
- DRM_ERROR("DSI LP not going Low\n");
-
- val = I915_READ(MIPI_PORT_CTRL(pipe));
- I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD);
- usleep_range(1000, 1500);
-
- I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
- usleep_range(2000, 2500);
+ for_each_dsi_port(port, intel_dsi->ports) {
+
+ I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+ ULPS_STATE_ENTER);
+ usleep_range(2000, 2500);
+
+ I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+ ULPS_STATE_EXIT);
+ usleep_range(2000, 2500);
+
+ I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
+ ULPS_STATE_ENTER);
+ usleep_range(2000, 2500);
+
+ /* Wait till Clock lanes are in LP-00 state for MIPI Port A
+ * only. MIPI Port C has no similar bit for checking
+ */
+ if (wait_for(((I915_READ(MIPI_PORT_CTRL(PORT_A)) & AFE_LATCHOUT)
+ == 0x00000), 30))
+ DRM_ERROR("DSI LP not going Low\n");
+
+ /* Disable MIPI PHY transparent latch
+ * Common bit for both MIPI Port A & MIPI Port C
+ */
+ val = I915_READ(MIPI_PORT_CTRL(PORT_A));
+ I915_WRITE(MIPI_PORT_CTRL(PORT_A), val & ~LP_OUTPUT_HOLD);
+ usleep_range(1000, 1500);
+
+ I915_WRITE(MIPI_DEVICE_READY(port), 0x00);
+ usleep_range(2000, 2500);
+ }
vlv_disable_dsi_pll(encoder);
}
@@ -326,8 +572,7 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder)
val &= ~DPOUNIT_CLOCK_GATE_DISABLE;
I915_WRITE(DSPCLK_GATE_D, val);
- if (intel_dsi->dev.dev_ops->disable_panel_power)
- intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev);
+ drm_panel_unprepare(intel_dsi->panel);
msleep(intel_dsi->panel_off_delay);
msleep(intel_dsi->panel_pwr_cycle_delay);
@@ -337,9 +582,11 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
enum pipe *pipe)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+ struct drm_device *dev = encoder->base.dev;
enum intel_display_power_domain power_domain;
- u32 port, func;
- enum pipe p;
+ u32 dpi_enabled, func;
+ enum port port;
DRM_DEBUG_KMS("\n");
@@ -348,13 +595,23 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
return false;
/* XXX: this only works for one DSI output */
- for (p = PIPE_A; p <= PIPE_B; p++) {
- port = I915_READ(MIPI_PORT_CTRL(p));
- func = I915_READ(MIPI_DSI_FUNC_PRG(p));
-
- if ((port & DPI_ENABLE) || (func & CMD_MODE_DATA_WIDTH_MASK)) {
- if (I915_READ(MIPI_DEVICE_READY(p)) & DEVICE_READY) {
- *pipe = p;
+ for_each_dsi_port(port, intel_dsi->ports) {
+ func = I915_READ(MIPI_DSI_FUNC_PRG(port));
+ dpi_enabled = I915_READ(MIPI_PORT_CTRL(port)) &
+ DPI_ENABLE;
+
+ /* Due to some hardware limitations on BYT, MIPI Port C DPI
+ * Enable bit does not get set. To check whether DSI Port C
+ * was enabled in BIOS, check the Pipe B enable bit
+ */
+ if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) &&
+ (port == PORT_C))
+ dpi_enabled = I915_READ(PIPECONF(PIPE_B)) &
+ PIPECONF_ENABLE;
+
+ if (dpi_enabled || (func & CMD_MODE_DATA_WIDTH_MASK)) {
+ if (I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY) {
+ *pipe = port == PORT_A ? PIPE_A : PIPE_B;
return true;
}
}
@@ -364,7 +621,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
}
static void intel_dsi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
u32 pclk;
DRM_DEBUG_KMS("\n");
@@ -379,7 +636,7 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
if (!pclk)
return;
- pipe_config->adjusted_mode.crtc_clock = pclk;
+ pipe_config->base.adjusted_mode.crtc_clock = pclk;
pipe_config->port_clock = pclk;
}
@@ -389,7 +646,6 @@ intel_dsi_mode_valid(struct drm_connector *connector,
{
struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
- struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
DRM_DEBUG_KMS("\n");
@@ -405,7 +661,7 @@ intel_dsi_mode_valid(struct drm_connector *connector,
return MODE_PANEL;
}
- return intel_dsi->dev.dev_ops->mode_valid(&intel_dsi->dev, mode);
+ return MODE_OK;
}
/* return txclkesc cycles in terms of divider and duration in us */
@@ -437,8 +693,8 @@ static void set_dsi_timings(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
- int pipe = intel_crtc->pipe;
- unsigned int bpp = intel_crtc->config.pipe_bpp;
+ enum port port;
+ unsigned int bpp = intel_crtc->config->pipe_bpp;
unsigned int lane_count = intel_dsi->lane_count;
u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp;
@@ -448,6 +704,15 @@ static void set_dsi_timings(struct drm_encoder *encoder,
hsync = mode->hsync_end - mode->hsync_start;
hbp = mode->htotal - mode->hsync_end;
+ if (intel_dsi->dual_link) {
+ hactive /= 2;
+ if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
+ hactive += intel_dsi->pixel_overlap;
+ hfp /= 2;
+ hsync /= 2;
+ hbp /= 2;
+ }
+
vfp = mode->vsync_start - mode->vdisplay;
vsync = mode->vsync_end - mode->vsync_start;
vbp = mode->vtotal - mode->vsync_end;
@@ -460,18 +725,20 @@ static void set_dsi_timings(struct drm_encoder *encoder,
intel_dsi->burst_mode_ratio);
hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
- I915_WRITE(MIPI_HACTIVE_AREA_COUNT(pipe), hactive);
- I915_WRITE(MIPI_HFP_COUNT(pipe), hfp);
+ for_each_dsi_port(port, intel_dsi->ports) {
+ I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive);
+ I915_WRITE(MIPI_HFP_COUNT(port), hfp);
- /* meaningful for video mode non-burst sync pulse mode only, can be zero
- * for non-burst sync events and burst modes */
- I915_WRITE(MIPI_HSYNC_PADDING_COUNT(pipe), hsync);
- I915_WRITE(MIPI_HBP_COUNT(pipe), hbp);
+ /* meaningful for video mode non-burst sync pulse mode only,
+ * can be zero for non-burst sync events and burst modes */
+ I915_WRITE(MIPI_HSYNC_PADDING_COUNT(port), hsync);
+ I915_WRITE(MIPI_HBP_COUNT(port), hbp);
- /* vertical values are in terms of lines */
- I915_WRITE(MIPI_VFP_COUNT(pipe), vfp);
- I915_WRITE(MIPI_VSYNC_PADDING_COUNT(pipe), vsync);
- I915_WRITE(MIPI_VBP_COUNT(pipe), vbp);
+ /* vertical values are in terms of lines */
+ I915_WRITE(MIPI_VFP_COUNT(port), vfp);
+ I915_WRITE(MIPI_VSYNC_PADDING_COUNT(port), vsync);
+ I915_WRITE(MIPI_VBP_COUNT(port), vbp);
+ }
}
static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
@@ -482,33 +749,44 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
struct drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
- int pipe = intel_crtc->pipe;
- unsigned int bpp = intel_crtc->config.pipe_bpp;
+ &intel_crtc->config->base.adjusted_mode;
+ enum port port;
+ unsigned int bpp = intel_crtc->config->pipe_bpp;
u32 val, tmp;
+ u16 mode_hdisplay;
- DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
+ DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe));
- /* escape clock divider, 20MHz, shared for A and C. device ready must be
- * off when doing this! txclkesc? */
- tmp = I915_READ(MIPI_CTRL(0));
- tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
- I915_WRITE(MIPI_CTRL(0), tmp | ESCAPE_CLOCK_DIVIDER_1);
+ mode_hdisplay = adjusted_mode->hdisplay;
- /* read request priority is per pipe */
- tmp = I915_READ(MIPI_CTRL(pipe));
- tmp &= ~READ_REQUEST_PRIORITY_MASK;
- I915_WRITE(MIPI_CTRL(pipe), tmp | READ_REQUEST_PRIORITY_HIGH);
+ if (intel_dsi->dual_link) {
+ mode_hdisplay /= 2;
+ if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
+ mode_hdisplay += intel_dsi->pixel_overlap;
+ }
- /* XXX: why here, why like this? handling in irq handler?! */
- I915_WRITE(MIPI_INTR_STAT(pipe), 0xffffffff);
- I915_WRITE(MIPI_INTR_EN(pipe), 0xffffffff);
+ for_each_dsi_port(port, intel_dsi->ports) {
+ /* escape clock divider, 20MHz, shared for A and C.
+ * device ready must be off when doing this! txclkesc? */
+ tmp = I915_READ(MIPI_CTRL(PORT_A));
+ tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
+ I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1);
- I915_WRITE(MIPI_DPHY_PARAM(pipe), intel_dsi->dphy_reg);
+ /* read request priority is per pipe */
+ tmp = I915_READ(MIPI_CTRL(port));
+ tmp &= ~READ_REQUEST_PRIORITY_MASK;
+ I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH);
- I915_WRITE(MIPI_DPI_RESOLUTION(pipe),
- adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT |
- adjusted_mode->hdisplay << HORIZONTAL_ADDRESS_SHIFT);
+ /* XXX: why here, why like this? handling in irq handler?! */
+ I915_WRITE(MIPI_INTR_STAT(port), 0xffffffff);
+ I915_WRITE(MIPI_INTR_EN(port), 0xffffffff);
+
+ I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg);
+
+ I915_WRITE(MIPI_DPI_RESOLUTION(port),
+ adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT |
+ mode_hdisplay << HORIZONTAL_ADDRESS_SHIFT);
+ }
set_dsi_timings(encoder, adjusted_mode);
@@ -522,95 +800,102 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
/* XXX: cross-check bpp vs. pixel format? */
val |= intel_dsi->pixel_format;
}
- I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), val);
-
- /* timeouts for recovery. one frame IIUC. if counter expires, EOT and
- * stop state. */
-
- /*
- * In burst mode, value greater than one DPI line Time in byte clock
- * (txbyteclkhs) To timeout this timer 1+ of the above said value is
- * recommended.
- *
- * In non-burst mode, Value greater than one DPI frame time in byte
- * clock(txbyteclkhs) To timeout this timer 1+ of the above said value
- * is recommended.
- *
- * In DBI only mode, value greater than one DBI frame time in byte
- * clock(txbyteclkhs) To timeout this timer 1+ of the above said value
- * is recommended.
- */
-
- if (is_vid_mode(intel_dsi) &&
- intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
- I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
- txbyteclkhs(adjusted_mode->htotal, bpp,
- intel_dsi->lane_count,
- intel_dsi->burst_mode_ratio) + 1);
- } else {
- I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe),
- txbyteclkhs(adjusted_mode->vtotal *
- adjusted_mode->htotal,
- bpp, intel_dsi->lane_count,
- intel_dsi->burst_mode_ratio) + 1);
- }
- I915_WRITE(MIPI_LP_RX_TIMEOUT(pipe), intel_dsi->lp_rx_timeout);
- I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), intel_dsi->turn_arnd_val);
- I915_WRITE(MIPI_DEVICE_RESET_TIMER(pipe), intel_dsi->rst_timer_val);
-
- /* dphy stuff */
- /* in terms of low power clock */
- I915_WRITE(MIPI_INIT_COUNT(pipe), txclkesc(intel_dsi->escape_clk_div, 100));
-
- val = 0;
+ tmp = 0;
if (intel_dsi->eotp_pkt == 0)
- val |= EOT_DISABLE;
-
+ tmp |= EOT_DISABLE;
if (intel_dsi->clock_stop)
- val |= CLOCKSTOP;
-
- /* recovery disables */
- I915_WRITE(MIPI_EOT_DISABLE(pipe), val);
-
- /* in terms of low power clock */
- I915_WRITE(MIPI_INIT_COUNT(pipe), intel_dsi->init_count);
-
- /* in terms of txbyteclkhs. actual high to low switch +
- * MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK.
- *
- * XXX: write MIPI_STOP_STATE_STALL?
- */
- I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(pipe),
- intel_dsi->hs_to_lp_count);
-
- /* XXX: low power clock equivalence in terms of byte clock. the number
- * of byte clocks occupied in one low power clock. based on txbyteclkhs
- * and txclkesc. txclkesc time / txbyteclk time * (105 +
- * MIPI_STOP_STATE_STALL) / 105.???
- */
- I915_WRITE(MIPI_LP_BYTECLK(pipe), intel_dsi->lp_byte_clk);
-
- /* the bw essential for transmitting 16 long packets containing 252
- * bytes meant for dcs write memory command is programmed in this
- * register in terms of byte clocks. based on dsi transfer rate and the
- * number of lanes configured the time taken to transmit 16 long packets
- * in a dsi stream varies. */
- I915_WRITE(MIPI_DBI_BW_CTRL(pipe), intel_dsi->bw_timer);
-
- I915_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe),
- intel_dsi->clk_lp_to_hs_count << LP_HS_SSW_CNT_SHIFT |
- intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT);
-
- if (is_vid_mode(intel_dsi))
- /* Some panels might have resolution which is not a multiple of
- * 64 like 1366 x 768. Enable RANDOM resolution support for such
- * panels by default */
- I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe),
- intel_dsi->video_frmt_cfg_bits |
- intel_dsi->video_mode_format |
- IP_TG_CONFIG |
- RANDOM_DPI_DISPLAY_RESOLUTION);
+ tmp |= CLOCKSTOP;
+
+ for_each_dsi_port(port, intel_dsi->ports) {
+ I915_WRITE(MIPI_DSI_FUNC_PRG(port), val);
+
+ /* timeouts for recovery. one frame IIUC. if counter expires,
+ * EOT and stop state. */
+
+ /*
+ * In burst mode, value greater than one DPI line Time in byte
+ * clock (txbyteclkhs) To timeout this timer 1+ of the above
+ * said value is recommended.
+ *
+ * In non-burst mode, Value greater than one DPI frame time in
+ * byte clock(txbyteclkhs) To timeout this timer 1+ of the above
+ * said value is recommended.
+ *
+ * In DBI only mode, value greater than one DBI frame time in
+ * byte clock(txbyteclkhs) To timeout this timer 1+ of the above
+ * said value is recommended.
+ */
+
+ if (is_vid_mode(intel_dsi) &&
+ intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
+ I915_WRITE(MIPI_HS_TX_TIMEOUT(port),
+ txbyteclkhs(adjusted_mode->htotal, bpp,
+ intel_dsi->lane_count,
+ intel_dsi->burst_mode_ratio) + 1);
+ } else {
+ I915_WRITE(MIPI_HS_TX_TIMEOUT(port),
+ txbyteclkhs(adjusted_mode->vtotal *
+ adjusted_mode->htotal,
+ bpp, intel_dsi->lane_count,
+ intel_dsi->burst_mode_ratio) + 1);
+ }
+ I915_WRITE(MIPI_LP_RX_TIMEOUT(port), intel_dsi->lp_rx_timeout);
+ I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(port),
+ intel_dsi->turn_arnd_val);
+ I915_WRITE(MIPI_DEVICE_RESET_TIMER(port),
+ intel_dsi->rst_timer_val);
+
+ /* dphy stuff */
+
+ /* in terms of low power clock */
+ I915_WRITE(MIPI_INIT_COUNT(port),
+ txclkesc(intel_dsi->escape_clk_div, 100));
+
+
+ /* recovery disables */
+ I915_WRITE(MIPI_EOT_DISABLE(port), val);
+
+ /* in terms of low power clock */
+ I915_WRITE(MIPI_INIT_COUNT(port), intel_dsi->init_count);
+
+ /* in terms of txbyteclkhs. actual high to low switch +
+ * MIPI_STOP_STATE_STALL * MIPI_LP_BYTECLK.
+ *
+ * XXX: write MIPI_STOP_STATE_STALL?
+ */
+ I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(port),
+ intel_dsi->hs_to_lp_count);
+
+ /* XXX: low power clock equivalence in terms of byte clock.
+ * the number of byte clocks occupied in one low power clock.
+ * based on txbyteclkhs and txclkesc.
+ * txclkesc time / txbyteclk time * (105 + MIPI_STOP_STATE_STALL
+ * ) / 105.???
+ */
+ I915_WRITE(MIPI_LP_BYTECLK(port), intel_dsi->lp_byte_clk);
+
+ /* the bw essential for transmitting 16 long packets containing
+ * 252 bytes meant for dcs write memory command is programmed in
+ * this register in terms of byte clocks. based on dsi transfer
+ * rate and the number of lanes configured the time taken to
+ * transmit 16 long packets in a dsi stream varies. */
+ I915_WRITE(MIPI_DBI_BW_CTRL(port), intel_dsi->bw_timer);
+
+ I915_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT(port),
+ intel_dsi->clk_lp_to_hs_count << LP_HS_SSW_CNT_SHIFT |
+ intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT);
+
+ if (is_vid_mode(intel_dsi))
+ /* Some panels might have resolution which is not a
+ * multiple of 64 like 1366 x 768. Enable RANDOM
+ * resolution support for such panels by default */
+ I915_WRITE(MIPI_VIDEO_MODE_FORMAT(port),
+ intel_dsi->video_frmt_cfg_bits |
+ intel_dsi->video_mode_format |
+ IP_TG_CONFIG |
+ RANDOM_DPI_DISPLAY_RESOLUTION);
+ }
}
static void intel_dsi_pre_pll_enable(struct intel_encoder *encoder)
@@ -625,20 +910,7 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder *encoder)
static enum drm_connector_status
intel_dsi_detect(struct drm_connector *connector, bool force)
{
- struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
- struct intel_encoder *intel_encoder = &intel_dsi->base;
- enum intel_display_power_domain power_domain;
- enum drm_connector_status connector_status;
- struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private;
-
- DRM_DEBUG_KMS("\n");
- power_domain = intel_display_port_power_domain(intel_encoder);
-
- intel_display_power_get(dev_priv, power_domain);
- connector_status = intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
- intel_display_power_put(dev_priv, power_domain);
-
- return connector_status;
+ return connector_status_connected;
}
static int intel_dsi_get_modes(struct drm_connector *connector)
@@ -664,7 +936,7 @@ static int intel_dsi_get_modes(struct drm_connector *connector)
return 1;
}
-static void intel_dsi_destroy(struct drm_connector *connector)
+static void intel_dsi_connector_destroy(struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
@@ -674,8 +946,20 @@ static void intel_dsi_destroy(struct drm_connector *connector)
kfree(connector);
}
+static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
+{
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+
+ if (intel_dsi->panel) {
+ drm_panel_detach(intel_dsi->panel);
+ /* XXX: Logically this call belongs in the panel driver. */
+ drm_panel_remove(intel_dsi->panel);
+ }
+ intel_encoder_destroy(encoder);
+}
+
static const struct drm_encoder_funcs intel_dsi_funcs = {
- .destroy = intel_encoder_destroy,
+ .destroy = intel_dsi_encoder_destroy,
};
static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = {
@@ -687,8 +971,10 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
static const struct drm_connector_funcs intel_dsi_connector_funcs = {
.dpms = intel_connector_dpms,
.detect = intel_dsi_detect,
- .destroy = intel_dsi_destroy,
+ .destroy = intel_dsi_connector_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
+ .atomic_get_property = intel_connector_atomic_get_property,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
void intel_dsi_init(struct drm_device *dev)
@@ -698,9 +984,9 @@ void intel_dsi_init(struct drm_device *dev)
struct drm_encoder *encoder;
struct intel_connector *intel_connector;
struct drm_connector *connector;
- struct drm_display_mode *fixed_mode = NULL;
+ struct drm_display_mode *scan, *fixed_mode = NULL;
struct drm_i915_private *dev_priv = dev->dev_private;
- const struct intel_dsi_device *dsi;
+ enum port port;
unsigned int i;
DRM_DEBUG_KMS("\n");
@@ -748,22 +1034,43 @@ void intel_dsi_init(struct drm_device *dev)
intel_connector->get_hw_state = intel_connector_get_hw_state;
intel_connector->unregister = intel_connector_unregister;
- for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) {
- dsi = &intel_dsi_devices[i];
- intel_dsi->dev = *dsi;
+ /* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */
+ if (dev_priv->vbt.dsi.config->dual_link) {
+ /* XXX: does dual link work on either pipe? */
+ intel_encoder->crtc_mask = (1 << PIPE_A);
+ intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C));
+ } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) {
+ intel_encoder->crtc_mask = (1 << PIPE_A);
+ intel_dsi->ports = (1 << PORT_A);
+ } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIC) {
+ intel_encoder->crtc_mask = (1 << PIPE_B);
+ intel_dsi->ports = (1 << PORT_C);
+ }
- if (dsi->dev_ops->init(&intel_dsi->dev))
+ /* Create a DSI host (and a device) for each port. */
+ for_each_dsi_port(port, intel_dsi->ports) {
+ struct intel_dsi_host *host;
+
+ host = intel_dsi_host_init(intel_dsi, port);
+ if (!host)
+ goto err;
+
+ intel_dsi->dsi_hosts[port] = host;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(intel_dsi_drivers); i++) {
+ intel_dsi->panel = intel_dsi_drivers[i].init(intel_dsi,
+ intel_dsi_drivers[i].panel_id);
+ if (intel_dsi->panel)
break;
}
- if (i == ARRAY_SIZE(intel_dsi_devices)) {
+ if (!intel_dsi->panel) {
DRM_DEBUG_KMS("no device found\n");
goto err;
}
intel_encoder->type = INTEL_OUTPUT_DSI;
- intel_encoder->crtc_mask = (1 << 0); /* XXX */
-
intel_encoder->cloneable = 0;
drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
DRM_MODE_CONNECTOR_DSI);
@@ -778,13 +1085,23 @@ void intel_dsi_init(struct drm_device *dev)
drm_connector_register(connector);
- fixed_mode = dsi->dev_ops->get_modes(&intel_dsi->dev);
+ drm_panel_attach(intel_dsi->panel, connector);
+
+ mutex_lock(&dev->mode_config.mutex);
+ drm_panel_get_modes(intel_dsi->panel);
+ list_for_each_entry(scan, &connector->probed_modes, head) {
+ if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
+ fixed_mode = drm_mode_duplicate(dev, scan);
+ break;
+ }
+ }
+ mutex_unlock(&dev->mode_config.mutex);
+
if (!fixed_mode) {
DRM_DEBUG_KMS("no fixed mode\n");
goto err;
}
- fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
return;
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 657eb5c1b9d8..2784ac442368 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -26,58 +26,27 @@
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
#include "intel_drv.h"
-struct intel_dsi_device {
- unsigned int panel_id;
- const char *name;
- const struct intel_dsi_dev_ops *dev_ops;
- void *dev_priv;
-};
-
-struct intel_dsi_dev_ops {
- bool (*init)(struct intel_dsi_device *dsi);
-
- void (*panel_reset)(struct intel_dsi_device *dsi);
-
- void (*disable_panel_power)(struct intel_dsi_device *dsi);
-
- /* one time programmable commands if needed */
- void (*send_otp_cmds)(struct intel_dsi_device *dsi);
-
- /* This callback must be able to assume DSI commands can be sent */
- void (*enable)(struct intel_dsi_device *dsi);
-
- /* This callback must be able to assume DSI commands can be sent */
- void (*disable)(struct intel_dsi_device *dsi);
-
- int (*mode_valid)(struct intel_dsi_device *dsi,
- struct drm_display_mode *mode);
-
- bool (*mode_fixup)(struct intel_dsi_device *dsi,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-
- void (*mode_set)(struct intel_dsi_device *dsi,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
-
- enum drm_connector_status (*detect)(struct intel_dsi_device *dsi);
+/* Dual Link support */
+#define DSI_DUAL_LINK_NONE 0
+#define DSI_DUAL_LINK_FRONT_BACK 1
+#define DSI_DUAL_LINK_PIXEL_ALT 2
- bool (*get_hw_state)(struct intel_dsi_device *dev);
-
- struct drm_display_mode *(*get_modes)(struct intel_dsi_device *dsi);
-
- void (*destroy) (struct intel_dsi_device *dsi);
-};
+struct intel_dsi_host;
struct intel_dsi {
struct intel_encoder base;
- struct intel_dsi_device dev;
+ struct drm_panel *panel;
+ struct intel_dsi_host *dsi_hosts[I915_MAX_PORTS];
struct intel_connector *attached_connector;
+ /* bit mask of ports being driven */
+ u16 ports;
+
/* if true, use HS mode, otherwise LP */
bool hs;
@@ -101,6 +70,8 @@ struct intel_dsi {
u8 clock_stop;
u8 escape_clk_div;
+ u8 dual_link;
+ u8 pixel_overlap;
u32 port_bits;
u32 bw_timer;
u32 dphy_reg;
@@ -127,6 +98,24 @@ struct intel_dsi {
u16 panel_pwr_cycle_delay;
};
+struct intel_dsi_host {
+ struct mipi_dsi_host base;
+ struct intel_dsi *intel_dsi;
+ enum port port;
+
+ /* our little hack */
+ struct mipi_dsi_device *device;
+};
+
+static inline struct intel_dsi_host *to_intel_dsi_host(struct mipi_dsi_host *h)
+{
+ return container_of(h, struct intel_dsi_host, base);
+}
+
+#define for_each_dsi_port(__port, __ports_mask) \
+ for ((__port) = PORT_A; (__port) < I915_MAX_PORTS; (__port)++) \
+ if ((__ports_mask) & (1 << (__port)))
+
static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
{
return container_of(encoder, struct intel_dsi, base.base);
@@ -136,6 +125,6 @@ extern void vlv_enable_dsi_pll(struct intel_encoder *encoder);
extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
-extern struct intel_dsi_dev_ops vbt_generic_dsi_display_ops;
+struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id);
#endif /* _INTEL_DSI_H */
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c
deleted file mode 100644
index f4767fd2ebeb..000000000000
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright © 2013 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Author: Jani Nikula <jani.nikula@intel.com>
- */
-
-#include <linux/export.h>
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-#include <video/mipi_display.h>
-#include "i915_drv.h"
-#include "intel_drv.h"
-#include "intel_dsi.h"
-#include "intel_dsi_cmd.h"
-
-/*
- * XXX: MIPI_DATA_ADDRESS, MIPI_DATA_LENGTH, MIPI_COMMAND_LENGTH, and
- * MIPI_COMMAND_ADDRESS registers.
- *
- * Apparently these registers provide a MIPI adapter level way to send (lots of)
- * commands and data to the receiver, without having to write the commands and
- * data to MIPI_{HS,LP}_GEN_{CTRL,DATA} registers word by word.
- *
- * Presumably for anything other than MIPI_DCS_WRITE_MEMORY_START and
- * MIPI_DCS_WRITE_MEMORY_CONTINUE (which are used to update the external
- * framebuffer in command mode displays) these are just an optimization that can
- * come later.
- *
- * For memory writes, these should probably be used for performance.
- */
-
-static void print_stat(struct intel_dsi *intel_dsi)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 val;
-
- val = I915_READ(MIPI_INTR_STAT(pipe));
-
-#define STAT_BIT(val, bit) (val) & (bit) ? " " #bit : ""
- DRM_DEBUG_KMS("MIPI_INTR_STAT(%d) = %08x"
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
- "\n", pipe, val,
- STAT_BIT(val, TEARING_EFFECT),
- STAT_BIT(val, SPL_PKT_SENT_INTERRUPT),
- STAT_BIT(val, GEN_READ_DATA_AVAIL),
- STAT_BIT(val, LP_GENERIC_WR_FIFO_FULL),
- STAT_BIT(val, HS_GENERIC_WR_FIFO_FULL),
- STAT_BIT(val, RX_PROT_VIOLATION),
- STAT_BIT(val, RX_INVALID_TX_LENGTH),
- STAT_BIT(val, ACK_WITH_NO_ERROR),
- STAT_BIT(val, TURN_AROUND_ACK_TIMEOUT),
- STAT_BIT(val, LP_RX_TIMEOUT),
- STAT_BIT(val, HS_TX_TIMEOUT),
- STAT_BIT(val, DPI_FIFO_UNDERRUN),
- STAT_BIT(val, LOW_CONTENTION),
- STAT_BIT(val, HIGH_CONTENTION),
- STAT_BIT(val, TXDSI_VC_ID_INVALID),
- STAT_BIT(val, TXDSI_DATA_TYPE_NOT_RECOGNISED),
- STAT_BIT(val, TXCHECKSUM_ERROR),
- STAT_BIT(val, TXECC_MULTIBIT_ERROR),
- STAT_BIT(val, TXECC_SINGLE_BIT_ERROR),
- STAT_BIT(val, TXFALSE_CONTROL_ERROR),
- STAT_BIT(val, RXDSI_VC_ID_INVALID),
- STAT_BIT(val, RXDSI_DATA_TYPE_NOT_REGOGNISED),
- STAT_BIT(val, RXCHECKSUM_ERROR),
- STAT_BIT(val, RXECC_MULTIBIT_ERROR),
- STAT_BIT(val, RXECC_SINGLE_BIT_ERROR),
- STAT_BIT(val, RXFALSE_CONTROL_ERROR),
- STAT_BIT(val, RXHS_RECEIVE_TIMEOUT_ERROR),
- STAT_BIT(val, RX_LP_TX_SYNC_ERROR),
- STAT_BIT(val, RXEXCAPE_MODE_ENTRY_ERROR),
- STAT_BIT(val, RXEOT_SYNC_ERROR),
- STAT_BIT(val, RXSOT_SYNC_ERROR),
- STAT_BIT(val, RXSOT_ERROR));
-#undef STAT_BIT
-}
-
-enum dsi_type {
- DSI_DCS,
- DSI_GENERIC,
-};
-
-/* enable or disable command mode hs transmissions */
-void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 temp;
- u32 mask = DBI_FIFO_EMPTY;
-
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
-
- temp = I915_READ(MIPI_HS_LP_DBI_ENABLE(pipe));
- temp &= DBI_HS_LP_MODE_MASK;
- I915_WRITE(MIPI_HS_LP_DBI_ENABLE(pipe), enable ? DBI_HS_MODE : DBI_LP_MODE);
-
- intel_dsi->hs = enable;
-}
-
-static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel,
- u8 data_type, u16 data)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 ctrl_reg;
- u32 ctrl;
- u32 mask;
-
- DRM_DEBUG_KMS("channel %d, data_type %d, data %04x\n",
- channel, data_type, data);
-
- if (intel_dsi->hs) {
- ctrl_reg = MIPI_HS_GEN_CTRL(pipe);
- mask = HS_CTRL_FIFO_FULL;
- } else {
- ctrl_reg = MIPI_LP_GEN_CTRL(pipe);
- mask = LP_CTRL_FIFO_FULL;
- }
-
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50)) {
- DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n");
- print_stat(intel_dsi);
- }
-
- /*
- * Note: This function is also used for long packets, with length passed
- * as data, since SHORT_PACKET_PARAM_SHIFT ==
- * LONG_PACKET_WORD_COUNT_SHIFT.
- */
- ctrl = data << SHORT_PACKET_PARAM_SHIFT |
- channel << VIRTUAL_CHANNEL_SHIFT |
- data_type << DATA_TYPE_SHIFT;
-
- I915_WRITE(ctrl_reg, ctrl);
-
- return 0;
-}
-
-static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel,
- u8 data_type, const u8 *data, int len)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 data_reg;
- int i, j, n;
- u32 mask;
-
- DRM_DEBUG_KMS("channel %d, data_type %d, len %04x\n",
- channel, data_type, len);
-
- if (intel_dsi->hs) {
- data_reg = MIPI_HS_GEN_DATA(pipe);
- mask = HS_DATA_FIFO_FULL;
- } else {
- data_reg = MIPI_LP_GEN_DATA(pipe);
- mask = LP_DATA_FIFO_FULL;
- }
-
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == 0, 50))
- DRM_ERROR("Timeout waiting for HS/LP DATA FIFO !full\n");
-
- for (i = 0; i < len; i += n) {
- u32 val = 0;
- n = min_t(int, len - i, 4);
-
- for (j = 0; j < n; j++)
- val |= *data++ << 8 * j;
-
- I915_WRITE(data_reg, val);
- /* XXX: check for data fifo full, once that is set, write 4
- * dwords, then wait for not set, then continue. */
- }
-
- return dsi_vc_send_short(intel_dsi, channel, data_type, len);
-}
-
-static int dsi_vc_write_common(struct intel_dsi *intel_dsi,
- int channel, const u8 *data, int len,
- enum dsi_type type)
-{
- int ret;
-
- if (len == 0) {
- BUG_ON(type == DSI_GENERIC);
- ret = dsi_vc_send_short(intel_dsi, channel,
- MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM,
- 0);
- } else if (len == 1) {
- ret = dsi_vc_send_short(intel_dsi, channel,
- type == DSI_GENERIC ?
- MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM :
- MIPI_DSI_DCS_SHORT_WRITE, data[0]);
- } else if (len == 2) {
- ret = dsi_vc_send_short(intel_dsi, channel,
- type == DSI_GENERIC ?
- MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM :
- MIPI_DSI_DCS_SHORT_WRITE_PARAM,
- (data[1] << 8) | data[0]);
- } else {
- ret = dsi_vc_send_long(intel_dsi, channel,
- type == DSI_GENERIC ?
- MIPI_DSI_GENERIC_LONG_WRITE :
- MIPI_DSI_DCS_LONG_WRITE, data, len);
- }
-
- return ret;
-}
-
-int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len)
-{
- return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_DCS);
-}
-
-int dsi_vc_generic_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len)
-{
- return dsi_vc_write_common(intel_dsi, channel, data, len, DSI_GENERIC);
-}
-
-static int dsi_vc_dcs_send_read_request(struct intel_dsi *intel_dsi,
- int channel, u8 dcs_cmd)
-{
- return dsi_vc_send_short(intel_dsi, channel, MIPI_DSI_DCS_READ,
- dcs_cmd);
-}
-
-static int dsi_vc_generic_send_read_request(struct intel_dsi *intel_dsi,
- int channel, u8 *reqdata,
- int reqlen)
-{
- u16 data;
- u8 data_type;
-
- switch (reqlen) {
- case 0:
- data_type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
- data = 0;
- break;
- case 1:
- data_type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
- data = reqdata[0];
- break;
- case 2:
- data_type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
- data = (reqdata[1] << 8) | reqdata[0];
- break;
- default:
- BUG();
- }
-
- return dsi_vc_send_short(intel_dsi, channel, data_type, data);
-}
-
-static int dsi_read_data_return(struct intel_dsi *intel_dsi,
- u8 *buf, int buflen)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- int i, len = 0;
- u32 data_reg, val;
-
- if (intel_dsi->hs) {
- data_reg = MIPI_HS_GEN_DATA(pipe);
- } else {
- data_reg = MIPI_LP_GEN_DATA(pipe);
- }
-
- while (len < buflen) {
- val = I915_READ(data_reg);
- for (i = 0; i < 4 && len < buflen; i++, len++)
- buf[len] = val >> 8 * i;
- }
-
- return len;
-}
-
-int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
- u8 *buf, int buflen)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 mask;
- int ret;
-
- /*
- * XXX: should issue multiple read requests and reads if request is
- * longer than MIPI_MAX_RETURN_PKT_SIZE
- */
-
- I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL);
-
- ret = dsi_vc_dcs_send_read_request(intel_dsi, channel, dcs_cmd);
- if (ret)
- return ret;
-
- mask = GEN_READ_DATA_AVAIL;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for read data.\n");
-
- ret = dsi_read_data_return(intel_dsi, buf, buflen);
- if (ret < 0)
- return ret;
-
- if (ret != buflen)
- return -EIO;
-
- return 0;
-}
-
-int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
- u8 *reqdata, int reqlen, u8 *buf, int buflen)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 mask;
- int ret;
-
- /*
- * XXX: should issue multiple read requests and reads if request is
- * longer than MIPI_MAX_RETURN_PKT_SIZE
- */
-
- I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL);
-
- ret = dsi_vc_generic_send_read_request(intel_dsi, channel, reqdata,
- reqlen);
- if (ret)
- return ret;
-
- mask = GEN_READ_DATA_AVAIL;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for read data.\n");
-
- ret = dsi_read_data_return(intel_dsi, buf, buflen);
- if (ret < 0)
- return ret;
-
- if (ret != buflen)
- return -EIO;
-
- return 0;
-}
-
-/*
- * send a video mode command
- *
- * XXX: commands with data in MIPI_DPI_DATA?
- */
-int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 mask;
-
- /* XXX: pipe, hs */
- if (hs)
- cmd &= ~DPI_LP_MODE;
- else
- cmd |= DPI_LP_MODE;
-
- /* clear bit */
- I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT);
-
- /* XXX: old code skips write if control unchanged */
- if (cmd == I915_READ(MIPI_DPI_CONTROL(pipe)))
- DRM_ERROR("Same special packet %02x twice in a row.\n", cmd);
-
- I915_WRITE(MIPI_DPI_CONTROL(pipe), cmd);
-
- mask = SPL_PKT_SENT_INTERRUPT;
- if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 100))
- DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd);
-
- return 0;
-}
-
-void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi)
-{
- struct drm_encoder *encoder = &intel_dsi->base.base;
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- enum pipe pipe = intel_crtc->pipe;
- u32 mask;
-
- mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY |
- LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY;
-
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 100))
- DRM_ERROR("DPI FIFOs are not empty\n");
-}
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.h b/drivers/gpu/drm/i915/intel_dsi_cmd.h
index 46aa1acc00eb..886779030f1a 100644
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.h
+++ b/drivers/gpu/drm/i915/intel_dsi_cmd.h
@@ -33,81 +33,7 @@
#include "intel_drv.h"
#include "intel_dsi.h"
-#define DPI_LP_MODE_EN false
-#define DPI_HS_MODE_EN true
-
-void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable);
-
-int dsi_vc_dcs_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len);
-
-int dsi_vc_generic_write(struct intel_dsi *intel_dsi, int channel,
- const u8 *data, int len);
-
-int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
- u8 *buf, int buflen);
-
-int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
- u8 *reqdata, int reqlen, u8 *buf, int buflen);
-
-int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs);
-void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi);
-
-/* XXX: questionable write helpers */
-static inline int dsi_vc_dcs_write_0(struct intel_dsi *intel_dsi,
- int channel, u8 dcs_cmd)
-{
- return dsi_vc_dcs_write(intel_dsi, channel, &dcs_cmd, 1);
-}
-
-static inline int dsi_vc_dcs_write_1(struct intel_dsi *intel_dsi,
- int channel, u8 dcs_cmd, u8 param)
-{
- u8 buf[2] = { dcs_cmd, param };
- return dsi_vc_dcs_write(intel_dsi, channel, buf, 2);
-}
-
-static inline int dsi_vc_generic_write_0(struct intel_dsi *intel_dsi,
- int channel)
-{
- return dsi_vc_generic_write(intel_dsi, channel, NULL, 0);
-}
-
-static inline int dsi_vc_generic_write_1(struct intel_dsi *intel_dsi,
- int channel, u8 param)
-{
- return dsi_vc_generic_write(intel_dsi, channel, &param, 1);
-}
-
-static inline int dsi_vc_generic_write_2(struct intel_dsi *intel_dsi,
- int channel, u8 param1, u8 param2)
-{
- u8 buf[2] = { param1, param2 };
- return dsi_vc_generic_write(intel_dsi, channel, buf, 2);
-}
-
-/* XXX: questionable read helpers */
-static inline int dsi_vc_generic_read_0(struct intel_dsi *intel_dsi,
- int channel, u8 *buf, int buflen)
-{
- return dsi_vc_generic_read(intel_dsi, channel, NULL, 0, buf, buflen);
-}
-
-static inline int dsi_vc_generic_read_1(struct intel_dsi *intel_dsi,
- int channel, u8 param, u8 *buf,
- int buflen)
-{
- return dsi_vc_generic_read(intel_dsi, channel, &param, 1, buf, buflen);
-}
-
-static inline int dsi_vc_generic_read_2(struct intel_dsi *intel_dsi,
- int channel, u8 param1, u8 param2,
- u8 *buf, int buflen)
-{
- u8 req[2] = { param1, param2 };
-
- return dsi_vc_generic_read(intel_dsi, channel, req, 2, buf, buflen);
-}
-
+void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable,
+ enum port port);
#endif /* _INTEL_DSI_DSI_H */
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index f6bdd44069ce..d2cd8d5b27a1 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -28,6 +28,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/i915_drm.h>
+#include <drm/drm_panel.h>
#include <linux/slab.h>
#include <video/mipi_display.h>
#include <asm/intel-mid.h>
@@ -35,7 +36,16 @@
#include "i915_drv.h"
#include "intel_drv.h"
#include "intel_dsi.h"
-#include "intel_dsi_cmd.h"
+
+struct vbt_panel {
+ struct drm_panel panel;
+ struct intel_dsi *intel_dsi;
+};
+
+static inline struct vbt_panel *to_vbt_panel(struct drm_panel *panel)
+{
+ return container_of(panel, struct vbt_panel, panel);
+}
#define MIPI_TRANSFER_MODE_SHIFT 0
#define MIPI_VIRTUAL_CHANNEL_SHIFT 1
@@ -94,34 +104,59 @@ static struct gpio_table gtable[] = {
{ GPIO_NC_11_PCONF0, GPIO_NC_11_PAD, 0}
};
-static u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, u8 *data)
+static inline enum port intel_dsi_seq_port_to_port(u8 port)
{
- u8 type, byte, mode, vc, port;
- u16 len;
-
- byte = *data++;
- mode = (byte >> MIPI_TRANSFER_MODE_SHIFT) & 0x1;
- vc = (byte >> MIPI_VIRTUAL_CHANNEL_SHIFT) & 0x3;
- port = (byte >> MIPI_PORT_SHIFT) & 0x3;
+ return port ? PORT_C : PORT_A;
+}
- /* LP or HS mode */
- intel_dsi->hs = mode;
+static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi,
+ const u8 *data)
+{
+ struct mipi_dsi_device *dsi_device;
+ u8 type, flags, seq_port;
+ u16 len;
+ enum port port;
- /* get packet type and increment the pointer */
+ flags = *data++;
type = *data++;
len = *((u16 *) data);
data += 2;
+ seq_port = (flags >> MIPI_PORT_SHIFT) & 3;
+
+ /* For DSI single link on Port A & C, the seq_port value which is
+ * parsed from Sequence Block#53 of VBT has been set to 0
+ * Now, read/write of packets for the DSI single link on Port A and
+ * Port C will based on the DVO port from VBT block 2.
+ */
+ if (intel_dsi->ports == (1 << PORT_C))
+ port = PORT_C;
+ else
+ port = intel_dsi_seq_port_to_port(seq_port);
+
+ dsi_device = intel_dsi->dsi_hosts[port]->device;
+ if (!dsi_device) {
+ DRM_DEBUG_KMS("no dsi device for port %c\n", port_name(port));
+ goto out;
+ }
+
+ if ((flags >> MIPI_TRANSFER_MODE_SHIFT) & 1)
+ dsi_device->mode_flags &= ~MIPI_DSI_MODE_LPM;
+ else
+ dsi_device->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ dsi_device->channel = (flags >> MIPI_VIRTUAL_CHANNEL_SHIFT) & 3;
+
switch (type) {
case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
- dsi_vc_generic_write_0(intel_dsi, vc);
+ mipi_dsi_generic_write(dsi_device, NULL, 0);
break;
case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
- dsi_vc_generic_write_1(intel_dsi, vc, *data);
+ mipi_dsi_generic_write(dsi_device, data, 1);
break;
case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
- dsi_vc_generic_write_2(intel_dsi, vc, *data, *(data + 1));
+ mipi_dsi_generic_write(dsi_device, data, 2);
break;
case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
@@ -129,30 +164,31 @@ static u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, u8 *data)
DRM_DEBUG_DRIVER("Generic Read not yet implemented or used\n");
break;
case MIPI_DSI_GENERIC_LONG_WRITE:
- dsi_vc_generic_write(intel_dsi, vc, data, len);
+ mipi_dsi_generic_write(dsi_device, data, len);
break;
case MIPI_DSI_DCS_SHORT_WRITE:
- dsi_vc_dcs_write_0(intel_dsi, vc, *data);
+ mipi_dsi_dcs_write_buffer(dsi_device, data, 1);
break;
case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
- dsi_vc_dcs_write_1(intel_dsi, vc, *data, *(data + 1));
+ mipi_dsi_dcs_write_buffer(dsi_device, data, 2);
break;
case MIPI_DSI_DCS_READ:
DRM_DEBUG_DRIVER("DCS Read not yet implemented or used\n");
break;
case MIPI_DSI_DCS_LONG_WRITE:
- dsi_vc_dcs_write(intel_dsi, vc, data, len);
+ mipi_dsi_dcs_write_buffer(dsi_device, data, len);
break;
}
+out:
data += len;
return data;
}
-static u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, u8 *data)
+static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data)
{
- u32 delay = *((u32 *) data);
+ u32 delay = *((const u32 *) data);
usleep_range(delay, delay + 10);
data += 4;
@@ -160,7 +196,7 @@ static u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, u8 *data)
return data;
}
-static u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, u8 *data)
+static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
{
u8 gpio, action;
u16 function, pad;
@@ -193,7 +229,8 @@ static u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, u8 *data)
return data;
}
-typedef u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi, u8 *data);
+typedef const u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi,
+ const u8 *data);
static const fn_mipi_elem_exec exec_elem[] = {
NULL, /* reserved */
mipi_exec_send_packet,
@@ -217,13 +254,12 @@ static const char * const seq_name[] = {
"MIPI_SEQ_DEASSERT_RESET"
};
-static void generic_exec_sequence(struct intel_dsi *intel_dsi, char *sequence)
+static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data)
{
- u8 *data = sequence;
fn_mipi_elem_exec mipi_elem_exec;
int index;
- if (!sequence)
+ if (!data)
return;
DRM_DEBUG_DRIVER("Starting MIPI sequence - %s\n", seq_name[*data]);
@@ -256,14 +292,103 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, char *sequence)
}
}
-static bool generic_init(struct intel_dsi_device *dsi)
+static int vbt_panel_prepare(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_unprepare(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_enable(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_disable(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const u8 *sequence;
+
+ sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_OFF];
+ generic_exec_sequence(intel_dsi, sequence);
+
+ return 0;
+}
+
+static int vbt_panel_get_modes(struct drm_panel *panel)
+{
+ struct vbt_panel *vbt_panel = to_vbt_panel(panel);
+ struct intel_dsi *intel_dsi = vbt_panel->intel_dsi;
+ struct drm_device *dev = intel_dsi->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_display_mode *mode;
+
+ if (!panel->connector)
+ return 0;
+
+ mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
+ if (!mode)
+ return 0;
+
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_probed_add(panel->connector, mode);
+
+ return 1;
+}
+
+static const struct drm_panel_funcs vbt_panel_funcs = {
+ .disable = vbt_panel_disable,
+ .unprepare = vbt_panel_unprepare,
+ .prepare = vbt_panel_prepare,
+ .enable = vbt_panel_enable,
+ .get_modes = vbt_panel_get_modes,
+};
+
+struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id)
{
- struct intel_dsi *intel_dsi = container_of(dsi, struct intel_dsi, dev);
struct drm_device *dev = intel_dsi->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps;
struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode;
+ struct vbt_panel *vbt_panel;
u32 bits_per_pixel = 24;
u32 tlpx_ns, extra_byte_count, bitrate, tlpx_ui;
u32 ui_num, ui_den;
@@ -273,6 +398,7 @@ static bool generic_init(struct intel_dsi_device *dsi)
u32 lp_to_hs_switch, hs_to_lp_switch;
u32 pclk, computed_ddr;
u16 burst_mode_ratio;
+ enum port port;
DRM_DEBUG_KMS("\n");
@@ -280,6 +406,8 @@ static bool generic_init(struct intel_dsi_device *dsi)
intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0;
intel_dsi->lane_count = mipi_config->lane_cnt + 1;
intel_dsi->pixel_format = mipi_config->videomode_color_format << 7;
+ intel_dsi->dual_link = mipi_config->dual_link;
+ intel_dsi->pixel_overlap = mipi_config->pixel_overlap;
if (intel_dsi->pixel_format == VID_MODE_FORMAT_RGB666)
bits_per_pixel = 18;
@@ -299,6 +427,20 @@ static bool generic_init(struct intel_dsi_device *dsi)
pclk = mode->clock;
+ /* In dual link mode each port needs half of pixel clock */
+ if (intel_dsi->dual_link) {
+ pclk = pclk / 2;
+
+ /* we can enable pixel_overlap if needed by panel. In this
+ * case we need to increase the pixelclock for extra pixels
+ */
+ if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
+ pclk += DIV_ROUND_UP(mode->vtotal *
+ intel_dsi->pixel_overlap *
+ 60, 1000);
+ }
+ }
+
/* Burst Mode Ratio
* Target ddr frequency from VBT / non burst ddr freq
* multiply by 100 to preserve remainder
@@ -311,7 +453,7 @@ static bool generic_init(struct intel_dsi_device *dsi)
if (mipi_config->target_burst_mode_freq <
computed_ddr) {
DRM_ERROR("Burst mode freq is less than computed\n");
- return false;
+ return NULL;
}
burst_mode_ratio = DIV_ROUND_UP(
@@ -321,7 +463,7 @@ static bool generic_init(struct intel_dsi_device *dsi)
pclk = DIV_ROUND_UP(pclk * burst_mode_ratio, 100);
} else {
DRM_ERROR("Burst mode target is not set\n");
- return false;
+ return NULL;
}
} else
burst_mode_ratio = 100;
@@ -493,6 +635,12 @@ static bool generic_init(struct intel_dsi_device *dsi)
DRM_DEBUG_KMS("Clockstop %s\n", intel_dsi->clock_stop ?
"disabled" : "enabled");
DRM_DEBUG_KMS("Mode %s\n", intel_dsi->operation_mode ? "command" : "video");
+ if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
+ DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_FRONT_BACK\n");
+ else if (intel_dsi->dual_link == DSI_DUAL_LINK_PIXEL_ALT)
+ DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_PIXEL_ALT\n");
+ else
+ DRM_DEBUG_KMS("Dual link: NONE\n");
DRM_DEBUG_KMS("Pixel Format %d\n", intel_dsi->pixel_format);
DRM_DEBUG_KMS("TLPX %d\n", intel_dsi->escape_clk_div);
DRM_DEBUG_KMS("LP RX Timeout 0x%x\n", intel_dsi->lp_rx_timeout);
@@ -516,110 +664,18 @@ static bool generic_init(struct intel_dsi_device *dsi)
intel_dsi->panel_off_delay = pps->panel_off_delay / 10;
intel_dsi->panel_pwr_cycle_delay = pps->panel_power_cycle_delay / 10;
- return true;
-}
-
-static int generic_mode_valid(struct intel_dsi_device *dsi,
- struct drm_display_mode *mode)
-{
- return MODE_OK;
-}
-
-static bool generic_mode_fixup(struct intel_dsi_device *dsi,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode) {
- return true;
-}
-
-static void generic_panel_reset(struct intel_dsi_device *dsi)
-{
- struct intel_dsi *intel_dsi = container_of(dsi, struct intel_dsi, dev);
- struct drm_device *dev = intel_dsi->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- char *sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET];
-
- generic_exec_sequence(intel_dsi, sequence);
-}
-
-static void generic_disable_panel_power(struct intel_dsi_device *dsi)
-{
- struct intel_dsi *intel_dsi = container_of(dsi, struct intel_dsi, dev);
- struct drm_device *dev = intel_dsi->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- char *sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET];
-
- generic_exec_sequence(intel_dsi, sequence);
-}
-
-static void generic_send_otp_cmds(struct intel_dsi_device *dsi)
-{
- struct intel_dsi *intel_dsi = container_of(dsi, struct intel_dsi, dev);
- struct drm_device *dev = intel_dsi->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- char *sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP];
-
- generic_exec_sequence(intel_dsi, sequence);
-}
-
-static void generic_enable(struct intel_dsi_device *dsi)
-{
- struct intel_dsi *intel_dsi = container_of(dsi, struct intel_dsi, dev);
- struct drm_device *dev = intel_dsi->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- char *sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON];
-
- generic_exec_sequence(intel_dsi, sequence);
-}
-
-static void generic_disable(struct intel_dsi_device *dsi)
-{
- struct intel_dsi *intel_dsi = container_of(dsi, struct intel_dsi, dev);
- struct drm_device *dev = intel_dsi->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ /* This is cheating a bit with the cleanup. */
+ vbt_panel = devm_kzalloc(dev->dev, sizeof(*vbt_panel), GFP_KERNEL);
- char *sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_OFF];
+ vbt_panel->intel_dsi = intel_dsi;
+ drm_panel_init(&vbt_panel->panel);
+ vbt_panel->panel.funcs = &vbt_panel_funcs;
+ drm_panel_add(&vbt_panel->panel);
- generic_exec_sequence(intel_dsi, sequence);
-}
-
-static enum drm_connector_status generic_detect(struct intel_dsi_device *dsi)
-{
- return connector_status_connected;
-}
-
-static bool generic_get_hw_state(struct intel_dsi_device *dev)
-{
- return true;
-}
-
-static struct drm_display_mode *generic_get_modes(struct intel_dsi_device *dsi)
-{
- struct intel_dsi *intel_dsi = container_of(dsi, struct intel_dsi, dev);
- struct drm_device *dev = intel_dsi->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
+ /* a regular driver would get the device in probe */
+ for_each_dsi_port(port, intel_dsi->ports) {
+ mipi_dsi_attach(intel_dsi->dsi_hosts[port]->device);
+ }
- dev_priv->vbt.lfp_lvds_vbt_mode->type |= DRM_MODE_TYPE_PREFERRED;
- return dev_priv->vbt.lfp_lvds_vbt_mode;
+ return &vbt_panel->panel;
}
-
-static void generic_destroy(struct intel_dsi_device *dsi) { }
-
-/* Callbacks. We might not need them all. */
-struct intel_dsi_dev_ops vbt_generic_dsi_display_ops = {
- .init = generic_init,
- .mode_valid = generic_mode_valid,
- .mode_fixup = generic_mode_fixup,
- .panel_reset = generic_panel_reset,
- .disable_panel_power = generic_disable_panel_power,
- .send_otp_cmds = generic_send_otp_cmds,
- .enable = generic_enable,
- .disable = generic_disable,
- .detect = generic_detect,
- .get_hw_state = generic_get_hw_state,
- .get_modes = generic_get_modes,
- .destroy = generic_destroy,
-};
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
index fa7a6ca34cd6..3622d0bafdf8 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -241,7 +241,11 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
return;
}
- dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
+ if (intel_dsi->ports & (1 << PORT_A))
+ dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
+
+ if (intel_dsi->ports & (1 << PORT_C))
+ dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n",
dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl);
@@ -269,12 +273,14 @@ void vlv_enable_dsi_pll(struct intel_encoder *encoder)
tmp |= DSI_PLL_VCO_EN;
vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
- mutex_unlock(&dev_priv->dpio_lock);
+ if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
+ DSI_PLL_LOCK, 20)) {
- if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED, 20)) {
+ mutex_unlock(&dev_priv->dpio_lock);
DRM_ERROR("DSI PLL lock failed\n");
return;
}
+ mutex_unlock(&dev_priv->dpio_lock);
DRM_DEBUG_KMS("DSI PLL locked\n");
}
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index e40e3df33517..d8579510beb0 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -27,6 +27,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include "intel_drv.h"
#include <drm/i915_drm.h>
@@ -144,7 +145,7 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
}
static void intel_dvo_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
@@ -160,9 +161,9 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
else
flags |= DRM_MODE_FLAG_NVSYNC;
- pipe_config->adjusted_mode.flags |= flags;
+ pipe_config->base.adjusted_mode.flags |= flags;
- pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
+ pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
}
static void intel_disable_dvo(struct intel_encoder *encoder)
@@ -186,8 +187,8 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
u32 temp = I915_READ(dvo_reg);
intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
- &crtc->config.requested_mode,
- &crtc->config.adjusted_mode);
+ &crtc->config->base.mode,
+ &crtc->config->base.adjusted_mode);
I915_WRITE(dvo_reg, temp | DVO_ENABLE);
I915_READ(dvo_reg);
@@ -200,7 +201,7 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
{
struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
struct drm_crtc *crtc;
- struct intel_crtc_config *config;
+ struct intel_crtc_state *config;
/* dvo supports only 2 dpms states. */
if (mode != DRM_MODE_DPMS_ON)
@@ -221,7 +222,7 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
/* We call connector dpms manually below in case pipe dpms doesn't
* change due to cloning. */
if (mode == DRM_MODE_DPMS_ON) {
- config = &to_intel_crtc(crtc)->config;
+ config = to_intel_crtc(crtc)->config;
intel_dvo->base.connectors_active = true;
@@ -261,10 +262,10 @@ intel_dvo_mode_valid(struct drm_connector *connector,
}
static bool intel_dvo_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
/* If we have timings from the BIOS for the panel, put them in
* to the adjusted mode. The CRTC will be set up for this mode,
@@ -295,7 +296,7 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder)
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
- struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
int pipe = crtc->pipe;
u32 dvo_val;
@@ -390,6 +391,8 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = {
.detect = intel_dvo_detect,
.destroy = intel_dvo_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
+ .atomic_get_property = intel_connector_atomic_get_property,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
new file mode 100644
index 000000000000..624d1d92d284
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -0,0 +1,701 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * DOC: Frame Buffer Compression (FBC)
+ *
+ * FBC tries to save memory bandwidth (and so power consumption) by
+ * compressing the amount of memory used by the display. It is total
+ * transparent to user space and completely handled in the kernel.
+ *
+ * The benefits of FBC are mostly visible with solid backgrounds and
+ * variation-less patterns. It comes from keeping the memory footprint small
+ * and having fewer memory pages opened and accessed for refreshing the display.
+ *
+ * i915 is responsible to reserve stolen memory for FBC and configure its
+ * offset on proper registers. The hardware takes care of all
+ * compress/decompress. However there are many known cases where we have to
+ * forcibly disable it to allow proper screen updates.
+ */
+
+#include "intel_drv.h"
+#include "i915_drv.h"
+
+static void i8xx_fbc_disable(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 fbc_ctl;
+
+ dev_priv->fbc.enabled = false;
+
+ /* Disable compression */
+ fbc_ctl = I915_READ(FBC_CONTROL);
+ if ((fbc_ctl & FBC_CTL_EN) == 0)
+ return;
+
+ fbc_ctl &= ~FBC_CTL_EN;
+ I915_WRITE(FBC_CONTROL, fbc_ctl);
+
+ /* Wait for compressing bit to clear */
+ if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) {
+ DRM_DEBUG_KMS("FBC idle timed out\n");
+ return;
+ }
+
+ DRM_DEBUG_KMS("disabled FBC\n");
+}
+
+static void i8xx_fbc_enable(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_framebuffer *fb = crtc->primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int cfb_pitch;
+ int i;
+ u32 fbc_ctl;
+
+ dev_priv->fbc.enabled = true;
+
+ cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE;
+ if (fb->pitches[0] < cfb_pitch)
+ cfb_pitch = fb->pitches[0];
+
+ /* FBC_CTL wants 32B or 64B units */
+ if (IS_GEN2(dev))
+ cfb_pitch = (cfb_pitch / 32) - 1;
+ else
+ cfb_pitch = (cfb_pitch / 64) - 1;
+
+ /* Clear old tags */
+ for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
+ I915_WRITE(FBC_TAG + (i * 4), 0);
+
+ if (IS_GEN4(dev)) {
+ u32 fbc_ctl2;
+
+ /* Set it up... */
+ fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE;
+ fbc_ctl2 |= FBC_CTL_PLANE(intel_crtc->plane);
+ I915_WRITE(FBC_CONTROL2, fbc_ctl2);
+ I915_WRITE(FBC_FENCE_OFF, crtc->y);
+ }
+
+ /* enable it... */
+ fbc_ctl = I915_READ(FBC_CONTROL);
+ fbc_ctl &= 0x3fff << FBC_CTL_INTERVAL_SHIFT;
+ fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
+ if (IS_I945GM(dev))
+ fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
+ fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
+ fbc_ctl |= obj->fence_reg;
+ I915_WRITE(FBC_CONTROL, fbc_ctl);
+
+ DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c\n",
+ cfb_pitch, crtc->y, plane_name(intel_crtc->plane));
+}
+
+static bool i8xx_fbc_enabled(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ return I915_READ(FBC_CONTROL) & FBC_CTL_EN;
+}
+
+static void g4x_fbc_enable(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_framebuffer *fb = crtc->primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ u32 dpfc_ctl;
+
+ dev_priv->fbc.enabled = true;
+
+ dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane) | DPFC_SR_EN;
+ if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+ dpfc_ctl |= DPFC_CTL_LIMIT_2X;
+ else
+ dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+ dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg;
+
+ I915_WRITE(DPFC_FENCE_YOFF, crtc->y);
+
+ /* enable it... */
+ I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
+
+ DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
+}
+
+static void g4x_fbc_disable(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 dpfc_ctl;
+
+ dev_priv->fbc.enabled = false;
+
+ /* Disable compression */
+ dpfc_ctl = I915_READ(DPFC_CONTROL);
+ if (dpfc_ctl & DPFC_CTL_EN) {
+ dpfc_ctl &= ~DPFC_CTL_EN;
+ I915_WRITE(DPFC_CONTROL, dpfc_ctl);
+
+ DRM_DEBUG_KMS("disabled FBC\n");
+ }
+}
+
+static bool g4x_fbc_enabled(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
+}
+
+static void snb_fbc_blit_update(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 blt_ecoskpd;
+
+ /* Make sure blitter notifies FBC of writes */
+
+ /* Blitter is part of Media powerwell on VLV. No impact of
+ * his param in other platforms for now */
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_MEDIA);
+
+ blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
+ blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
+ GEN6_BLITTER_LOCK_SHIFT;
+ I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+ blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY;
+ I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+ blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY <<
+ GEN6_BLITTER_LOCK_SHIFT);
+ I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+ POSTING_READ(GEN6_BLITTER_ECOSKPD);
+
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_MEDIA);
+}
+
+static void ilk_fbc_enable(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_framebuffer *fb = crtc->primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ u32 dpfc_ctl;
+
+ dev_priv->fbc.enabled = true;
+
+ dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane);
+ if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+ dev_priv->fbc.threshold++;
+
+ switch (dev_priv->fbc.threshold) {
+ case 4:
+ case 3:
+ dpfc_ctl |= DPFC_CTL_LIMIT_4X;
+ break;
+ case 2:
+ dpfc_ctl |= DPFC_CTL_LIMIT_2X;
+ break;
+ case 1:
+ dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+ break;
+ }
+ dpfc_ctl |= DPFC_CTL_FENCE_EN;
+ if (IS_GEN5(dev))
+ dpfc_ctl |= obj->fence_reg;
+
+ I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y);
+ I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj) | ILK_FBC_RT_VALID);
+ /* enable it... */
+ I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
+
+ if (IS_GEN6(dev)) {
+ I915_WRITE(SNB_DPFC_CTL_SA,
+ SNB_CPU_FENCE_ENABLE | obj->fence_reg);
+ I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
+ snb_fbc_blit_update(dev);
+ }
+
+ DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
+}
+
+static void ilk_fbc_disable(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 dpfc_ctl;
+
+ dev_priv->fbc.enabled = false;
+
+ /* Disable compression */
+ dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
+ if (dpfc_ctl & DPFC_CTL_EN) {
+ dpfc_ctl &= ~DPFC_CTL_EN;
+ I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
+
+ DRM_DEBUG_KMS("disabled FBC\n");
+ }
+}
+
+static bool ilk_fbc_enabled(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
+}
+
+static void gen7_fbc_enable(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_framebuffer *fb = crtc->primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ u32 dpfc_ctl;
+
+ dev_priv->fbc.enabled = true;
+
+ dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane);
+ if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+ dev_priv->fbc.threshold++;
+
+ switch (dev_priv->fbc.threshold) {
+ case 4:
+ case 3:
+ dpfc_ctl |= DPFC_CTL_LIMIT_4X;
+ break;
+ case 2:
+ dpfc_ctl |= DPFC_CTL_LIMIT_2X;
+ break;
+ case 1:
+ dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+ break;
+ }
+
+ dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;
+
+ if (dev_priv->fbc.false_color)
+ dpfc_ctl |= FBC_CTL_FALSE_COLOR;
+
+ I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
+
+ if (IS_IVYBRIDGE(dev)) {
+ /* WaFbcAsynchFlipDisableFbcQueue:ivb */
+ I915_WRITE(ILK_DISPLAY_CHICKEN1,
+ I915_READ(ILK_DISPLAY_CHICKEN1) |
+ ILK_FBCQ_DIS);
+ } else {
+ /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
+ I915_WRITE(CHICKEN_PIPESL_1(intel_crtc->pipe),
+ I915_READ(CHICKEN_PIPESL_1(intel_crtc->pipe)) |
+ HSW_FBCQ_DIS);
+ }
+
+ I915_WRITE(SNB_DPFC_CTL_SA,
+ SNB_CPU_FENCE_ENABLE | obj->fence_reg);
+ I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
+
+ snb_fbc_blit_update(dev);
+
+ DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
+}
+
+/**
+ * intel_fbc_enabled - Is FBC enabled?
+ * @dev: the drm_device
+ *
+ * This function is used to verify the current state of FBC.
+ * FIXME: This should be tracked in the plane config eventually
+ * instead of queried at runtime for most callers.
+ */
+bool intel_fbc_enabled(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ return dev_priv->fbc.enabled;
+}
+
+void bdw_fbc_sw_flush(struct drm_device *dev, u32 value)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (!IS_GEN8(dev))
+ return;
+
+ if (!intel_fbc_enabled(dev))
+ return;
+
+ I915_WRITE(MSG_FBC_REND_STATE, value);
+}
+
+static void intel_fbc_work_fn(struct work_struct *__work)
+{
+ struct intel_fbc_work *work =
+ container_of(to_delayed_work(__work),
+ struct intel_fbc_work, work);
+ struct drm_device *dev = work->crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev->struct_mutex);
+ if (work == dev_priv->fbc.fbc_work) {
+ /* Double check that we haven't switched fb without cancelling
+ * the prior work.
+ */
+ if (work->crtc->primary->fb == work->fb) {
+ dev_priv->display.enable_fbc(work->crtc);
+
+ dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane;
+ dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id;
+ dev_priv->fbc.y = work->crtc->y;
+ }
+
+ dev_priv->fbc.fbc_work = NULL;
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+ kfree(work);
+}
+
+static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv)
+{
+ if (dev_priv->fbc.fbc_work == NULL)
+ return;
+
+ DRM_DEBUG_KMS("cancelling pending FBC enable\n");
+
+ /* Synchronisation is provided by struct_mutex and checking of
+ * dev_priv->fbc.fbc_work, so we can perform the cancellation
+ * entirely asynchronously.
+ */
+ if (cancel_delayed_work(&dev_priv->fbc.fbc_work->work))
+ /* tasklet was killed before being run, clean up */
+ kfree(dev_priv->fbc.fbc_work);
+
+ /* Mark the work as no longer wanted so that if it does
+ * wake-up (because the work was already running and waiting
+ * for our mutex), it will discover that is no longer
+ * necessary to run.
+ */
+ dev_priv->fbc.fbc_work = NULL;
+}
+
+static void intel_fbc_enable(struct drm_crtc *crtc)
+{
+ struct intel_fbc_work *work;
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (!dev_priv->display.enable_fbc)
+ return;
+
+ intel_fbc_cancel_work(dev_priv);
+
+ work = kzalloc(sizeof(*work), GFP_KERNEL);
+ if (work == NULL) {
+ DRM_ERROR("Failed to allocate FBC work structure\n");
+ dev_priv->display.enable_fbc(crtc);
+ return;
+ }
+
+ work->crtc = crtc;
+ work->fb = crtc->primary->fb;
+ INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn);
+
+ dev_priv->fbc.fbc_work = work;
+
+ /* Delay the actual enabling to let pageflipping cease and the
+ * display to settle before starting the compression. Note that
+ * this delay also serves a second purpose: it allows for a
+ * vblank to pass after disabling the FBC before we attempt
+ * to modify the control registers.
+ *
+ * A more complicated solution would involve tracking vblanks
+ * following the termination of the page-flipping sequence
+ * and indeed performing the enable as a co-routine and not
+ * waiting synchronously upon the vblank.
+ *
+ * WaFbcWaitForVBlankBeforeEnable:ilk,snb
+ */
+ schedule_delayed_work(&work->work, msecs_to_jiffies(50));
+}
+
+/**
+ * intel_fbc_disable - disable FBC
+ * @dev: the drm_device
+ *
+ * This function disables FBC.
+ */
+void intel_fbc_disable(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ intel_fbc_cancel_work(dev_priv);
+
+ if (!dev_priv->display.disable_fbc)
+ return;
+
+ dev_priv->display.disable_fbc(dev);
+ dev_priv->fbc.plane = -1;
+}
+
+static bool set_no_fbc_reason(struct drm_i915_private *dev_priv,
+ enum no_fbc_reason reason)
+{
+ if (dev_priv->fbc.no_fbc_reason == reason)
+ return false;
+
+ dev_priv->fbc.no_fbc_reason = reason;
+ return true;
+}
+
+/**
+ * intel_fbc_update - enable/disable FBC as needed
+ * @dev: the drm_device
+ *
+ * Set up the framebuffer compression hardware at mode set time. We
+ * enable it if possible:
+ * - plane A only (on pre-965)
+ * - no pixel mulitply/line duplication
+ * - no alpha buffer discard
+ * - no dual wide
+ * - framebuffer <= max_hdisplay in width, max_vdisplay in height
+ *
+ * We can't assume that any compression will take place (worst case),
+ * so the compressed buffer has to be the same size as the uncompressed
+ * one. It also must reside (along with the line length buffer) in
+ * stolen memory.
+ *
+ * We need to enable/disable FBC on a global basis.
+ */
+void intel_fbc_update(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = NULL, *tmp_crtc;
+ struct intel_crtc *intel_crtc;
+ struct drm_framebuffer *fb;
+ struct drm_i915_gem_object *obj;
+ const struct drm_display_mode *adjusted_mode;
+ unsigned int max_width, max_height;
+
+ if (!HAS_FBC(dev)) {
+ set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED);
+ return;
+ }
+
+ if (!i915.powersave) {
+ if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM))
+ DRM_DEBUG_KMS("fbc disabled per module param\n");
+ return;
+ }
+
+ /*
+ * If FBC is already on, we just have to verify that we can
+ * keep it that way...
+ * Need to disable if:
+ * - more than one pipe is active
+ * - changing FBC params (stride, fence, mode)
+ * - new fb is too large to fit in compressed buffer
+ * - going to an unsupported config (interlace, pixel multiply, etc.)
+ */
+ for_each_crtc(dev, tmp_crtc) {
+ if (intel_crtc_active(tmp_crtc) &&
+ to_intel_crtc(tmp_crtc)->primary_enabled) {
+ if (crtc) {
+ if (set_no_fbc_reason(dev_priv, FBC_MULTIPLE_PIPES))
+ DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
+ goto out_disable;
+ }
+ crtc = tmp_crtc;
+ }
+ }
+
+ if (!crtc || crtc->primary->fb == NULL) {
+ if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT))
+ DRM_DEBUG_KMS("no output, disabling\n");
+ goto out_disable;
+ }
+
+ intel_crtc = to_intel_crtc(crtc);
+ fb = crtc->primary->fb;
+ obj = intel_fb_obj(fb);
+ adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+
+ if (i915.enable_fbc < 0) {
+ if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT))
+ DRM_DEBUG_KMS("disabled per chip default\n");
+ goto out_disable;
+ }
+ if (!i915.enable_fbc) {
+ if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM))
+ DRM_DEBUG_KMS("fbc disabled per module param\n");
+ goto out_disable;
+ }
+ if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
+ (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
+ if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
+ DRM_DEBUG_KMS("mode incompatible with compression, "
+ "disabling\n");
+ goto out_disable;
+ }
+
+ if (INTEL_INFO(dev)->gen >= 8 || IS_HASWELL(dev)) {
+ max_width = 4096;
+ max_height = 4096;
+ } else if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+ max_width = 4096;
+ max_height = 2048;
+ } else {
+ max_width = 2048;
+ max_height = 1536;
+ }
+ if (intel_crtc->config->pipe_src_w > max_width ||
+ intel_crtc->config->pipe_src_h > max_height) {
+ if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE))
+ DRM_DEBUG_KMS("mode too large for compression, disabling\n");
+ goto out_disable;
+ }
+ if ((INTEL_INFO(dev)->gen < 4 || HAS_DDI(dev)) &&
+ intel_crtc->plane != PLANE_A) {
+ if (set_no_fbc_reason(dev_priv, FBC_BAD_PLANE))
+ DRM_DEBUG_KMS("plane not A, disabling compression\n");
+ goto out_disable;
+ }
+
+ /* The use of a CPU fence is mandatory in order to detect writes
+ * by the CPU to the scanout and trigger updates to the FBC.
+ */
+ if (obj->tiling_mode != I915_TILING_X ||
+ obj->fence_reg == I915_FENCE_REG_NONE) {
+ if (set_no_fbc_reason(dev_priv, FBC_NOT_TILED))
+ DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n");
+ goto out_disable;
+ }
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
+ crtc->primary->state->rotation != BIT(DRM_ROTATE_0)) {
+ if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
+ DRM_DEBUG_KMS("Rotation unsupported, disabling\n");
+ goto out_disable;
+ }
+
+ /* If the kernel debugger is active, always disable compression */
+ if (in_dbg_master())
+ goto out_disable;
+
+ if (i915_gem_stolen_setup_compression(dev, obj->base.size,
+ drm_format_plane_cpp(fb->pixel_format, 0))) {
+ if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL))
+ DRM_DEBUG_KMS("framebuffer too large, disabling compression\n");
+ goto out_disable;
+ }
+
+ /* If the scanout has not changed, don't modify the FBC settings.
+ * Note that we make the fundamental assumption that the fb->obj
+ * cannot be unpinned (and have its GTT offset and fence revoked)
+ * without first being decoupled from the scanout and FBC disabled.
+ */
+ if (dev_priv->fbc.plane == intel_crtc->plane &&
+ dev_priv->fbc.fb_id == fb->base.id &&
+ dev_priv->fbc.y == crtc->y)
+ return;
+
+ if (intel_fbc_enabled(dev)) {
+ /* We update FBC along two paths, after changing fb/crtc
+ * configuration (modeswitching) and after page-flipping
+ * finishes. For the latter, we know that not only did
+ * we disable the FBC at the start of the page-flip
+ * sequence, but also more than one vblank has passed.
+ *
+ * For the former case of modeswitching, it is possible
+ * to switch between two FBC valid configurations
+ * instantaneously so we do need to disable the FBC
+ * before we can modify its control registers. We also
+ * have to wait for the next vblank for that to take
+ * effect. However, since we delay enabling FBC we can
+ * assume that a vblank has passed since disabling and
+ * that we can safely alter the registers in the deferred
+ * callback.
+ *
+ * In the scenario that we go from a valid to invalid
+ * and then back to valid FBC configuration we have
+ * no strict enforcement that a vblank occurred since
+ * disabling the FBC. However, along all current pipe
+ * disabling paths we do need to wait for a vblank at
+ * some point. And we wait before enabling FBC anyway.
+ */
+ DRM_DEBUG_KMS("disabling active FBC for update\n");
+ intel_fbc_disable(dev);
+ }
+
+ intel_fbc_enable(crtc);
+ dev_priv->fbc.no_fbc_reason = FBC_OK;
+ return;
+
+out_disable:
+ /* Multiple disables should be harmless */
+ if (intel_fbc_enabled(dev)) {
+ DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
+ intel_fbc_disable(dev);
+ }
+ i915_gem_stolen_cleanup_compression(dev);
+}
+
+/**
+ * intel_fbc_init - Initialize FBC
+ * @dev_priv: the i915 device
+ *
+ * This function might be called during PM init process.
+ */
+void intel_fbc_init(struct drm_i915_private *dev_priv)
+{
+ if (!HAS_FBC(dev_priv)) {
+ dev_priv->fbc.enabled = false;
+ return;
+ }
+
+ if (INTEL_INFO(dev_priv)->gen >= 7) {
+ dev_priv->display.fbc_enabled = ilk_fbc_enabled;
+ dev_priv->display.enable_fbc = gen7_fbc_enable;
+ dev_priv->display.disable_fbc = ilk_fbc_disable;
+ } else if (INTEL_INFO(dev_priv)->gen >= 5) {
+ dev_priv->display.fbc_enabled = ilk_fbc_enabled;
+ dev_priv->display.enable_fbc = ilk_fbc_enable;
+ dev_priv->display.disable_fbc = ilk_fbc_disable;
+ } else if (IS_GM45(dev_priv)) {
+ dev_priv->display.fbc_enabled = g4x_fbc_enabled;
+ dev_priv->display.enable_fbc = g4x_fbc_enable;
+ dev_priv->display.disable_fbc = g4x_fbc_disable;
+ } else {
+ dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
+ dev_priv->display.enable_fbc = i8xx_fbc_enable;
+ dev_priv->display.disable_fbc = i8xx_fbc_disable;
+
+ /* This value was pulled out of someone's hat */
+ I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
+ }
+
+ dev_priv->fbc.enabled = dev_priv->display.fbc_enabled(dev_priv->dev);
+}
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 850cf7d6578c..3001a8674611 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -443,7 +443,7 @@ retry:
DRM_DEBUG_KMS("looking for current mode on connector %s\n",
connector->name);
intel_mode_from_pipe_config(&encoder->crtc->hwmode,
- &to_intel_crtc(encoder->crtc)->config);
+ to_intel_crtc(encoder->crtc)->config);
modes[i] = &encoder->crtc->hwmode;
}
crtcs[i] = new_crtc;
@@ -531,7 +531,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
struct intel_framebuffer *fb = NULL;
struct drm_crtc *crtc;
struct intel_crtc *intel_crtc;
- struct intel_plane_config *plane_config = NULL;
+ struct intel_initial_plane_config *plane_config = NULL;
unsigned int max_size = 0;
if (!i915.fastboot)
@@ -581,7 +581,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
* pipe. Note we need to use the selected fb's pitch and bpp
* rather than the current pipe's, since they differ.
*/
- cur_size = intel_crtc->config.adjusted_mode.crtc_hdisplay;
+ cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
cur_size = cur_size * fb->base.bits_per_pixel / 8;
if (fb->base.pitches[0] < cur_size) {
DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
@@ -592,13 +592,14 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
break;
}
- cur_size = intel_crtc->config.adjusted_mode.crtc_vdisplay;
- cur_size = ALIGN(cur_size, plane_config->tiled ? (IS_GEN2(dev) ? 16 : 8) : 1);
+ cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
+ cur_size = intel_fb_align_height(dev, cur_size,
+ plane_config->tiling);
cur_size *= fb->base.pitches[0];
DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
pipe_name(intel_crtc->pipe),
- intel_crtc->config.adjusted_mode.crtc_hdisplay,
- intel_crtc->config.adjusted_mode.crtc_vdisplay,
+ intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
+ intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
fb->base.bits_per_pixel,
cur_size);
diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c
index 77af512d2d35..04e248dd2259 100644
--- a/drivers/gpu/drm/i915/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c
@@ -341,7 +341,7 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
}
/**
- * intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt
+ * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
* @dev_priv: i915 device instance
* @pipe: (CPU) pipe to set state for
*
diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
index 79f6d72179c5..73cb6e036445 100644
--- a/drivers/gpu/drm/i915/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
@@ -157,6 +157,7 @@ void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring);
intel_psr_invalidate(dev, obj->frontbuffer_bits);
+ intel_edp_drrs_invalidate(dev, obj->frontbuffer_bits);
}
/**
@@ -182,6 +183,7 @@ void intel_frontbuffer_flush(struct drm_device *dev,
intel_mark_fb_busy(dev, frontbuffer_bits, NULL);
+ intel_edp_drrs_flush(dev, frontbuffer_bits);
intel_psr_flush(dev, frontbuffer_bits);
/*
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 3abc2000fce9..995c5b261f4f 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -31,6 +31,7 @@
#include <linux/delay.h>
#include <linux/hdmi.h>
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include "intel_drv.h"
@@ -337,13 +338,13 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder);
+ u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
u32 data_reg;
int i;
u32 val = I915_READ(ctl_reg);
data_reg = hsw_infoframe_data_reg(type,
- intel_crtc->config.cpu_transcoder,
+ intel_crtc->config->cpu_transcoder,
dev_priv);
if (data_reg == 0)
return;
@@ -371,7 +372,7 @@ static bool hsw_infoframe_enabled(struct drm_encoder *encoder)
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
- u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder);
+ u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
u32 val = I915_READ(ctl_reg);
return val & (VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_SPD_HSW |
@@ -436,7 +437,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
}
if (intel_hdmi->rgb_quant_range_selectable) {
- if (intel_crtc->config.limited_color_range)
+ if (intel_crtc->config->limited_color_range)
frame.avi.quantization_range =
HDMI_QUANTIZATION_RANGE_LIMITED;
else
@@ -672,7 +673,7 @@ static void hsw_set_infoframes(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = encoder->dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
- u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder);
+ u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
u32 val = I915_READ(reg);
assert_hdmi_port_disabled(intel_hdmi);
@@ -700,7 +701,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
- struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
u32 hdmi_val;
hdmi_val = SDVO_ENCODING_HDMI;
@@ -711,12 +712,12 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
- if (crtc->config.pipe_bpp > 24)
+ if (crtc->config->pipe_bpp > 24)
hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
else
hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
- if (crtc->config.has_hdmi_sink)
+ if (crtc->config->has_hdmi_sink)
hdmi_val |= HDMI_MODE_SELECT_HDMI;
if (HAS_PCH_CPT(dev))
@@ -759,7 +760,7 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
}
static void intel_hdmi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_device *dev = encoder->base.dev;
@@ -792,7 +793,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
tmp & HDMI_COLOR_RANGE_16_235)
pipe_config->limited_color_range = true;
- pipe_config->adjusted_mode.flags |= flags;
+ pipe_config->base.adjusted_mode.flags |= flags;
if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
dotclock = pipe_config->port_clock * 2 / 3;
@@ -802,7 +803,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
if (HAS_PCH_SPLIT(dev_priv->dev))
ironlake_check_encoder_dotclock(pipe_config, dotclock);
- pipe_config->adjusted_mode.crtc_clock = dotclock;
+ pipe_config->base.adjusted_mode.crtc_clock = dotclock;
}
static void intel_enable_hdmi(struct intel_encoder *encoder)
@@ -814,7 +815,7 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)
u32 temp;
u32 enable_bits = SDVO_ENABLE;
- if (intel_crtc->config.has_audio)
+ if (intel_crtc->config->has_audio)
enable_bits |= SDVO_AUDIO_ENABLE;
temp = I915_READ(intel_hdmi->hdmi_reg);
@@ -845,8 +846,8 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)
POSTING_READ(intel_hdmi->hdmi_reg);
}
- if (intel_crtc->config.has_audio) {
- WARN_ON(!intel_crtc->config.has_hdmi_sink);
+ if (intel_crtc->config->has_audio) {
+ WARN_ON(!intel_crtc->config->has_hdmi_sink);
DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
pipe_name(intel_crtc->pipe));
intel_audio_codec_enable(encoder);
@@ -866,7 +867,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
u32 temp;
u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
- if (crtc->config.has_audio)
+ if (crtc->config->has_audio)
intel_audio_codec_disable(encoder);
temp = I915_READ(intel_hdmi->hdmi_reg);
@@ -975,12 +976,12 @@ static bool hdmi_12bpc_possible(struct intel_crtc *crtc)
}
bool intel_hdmi_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_device *dev = encoder->base.dev;
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
- int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+ int clock_12bpc = pipe_config->base.adjusted_mode.crtc_clock * 3 / 2;
int portclock_limit = hdmi_portclock_limit(intel_hdmi, false);
int desired_bpp;
@@ -1252,12 +1253,12 @@ static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
+ &intel_crtc->config->base.adjusted_mode;
intel_hdmi_prepare(encoder);
intel_hdmi->set_infoframes(&encoder->base,
- intel_crtc->config.has_hdmi_sink,
+ intel_crtc->config->has_hdmi_sink,
adjusted_mode);
}
@@ -1270,7 +1271,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
struct intel_crtc *intel_crtc =
to_intel_crtc(encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
+ &intel_crtc->config->base.adjusted_mode;
enum dpio_channel port = vlv_dport_to_channel(dport);
int pipe = intel_crtc->pipe;
u32 val;
@@ -1302,7 +1303,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock);
intel_hdmi->set_infoframes(&encoder->base,
- intel_crtc->config.has_hdmi_sink,
+ intel_crtc->config->has_hdmi_sink,
adjusted_mode);
intel_enable_hdmi(encoder);
@@ -1467,7 +1468,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
struct intel_crtc *intel_crtc =
to_intel_crtc(encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
- &intel_crtc->config.adjusted_mode;
+ &intel_crtc->config->base.adjusted_mode;
enum dpio_channel ch = vlv_dport_to_channel(dport);
int pipe = intel_crtc->pipe;
int data, i;
@@ -1593,7 +1594,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock);
intel_hdmi->set_infoframes(&encoder->base,
- intel_crtc->config.has_hdmi_sink,
+ intel_crtc->config->has_hdmi_sink,
adjusted_mode);
intel_enable_hdmi(encoder);
@@ -1614,7 +1615,9 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
.force = intel_hdmi_force,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_hdmi_set_property,
+ .atomic_get_property = intel_connector_atomic_get_property,
.destroy = intel_hdmi_destroy,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index e588376227ea..0f358c5999ec 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -212,8 +212,7 @@ static int intel_lr_context_pin(struct intel_engine_cs *ring,
* @enable_execlists: value of i915.enable_execlists module parameter.
*
* Only certain platforms support Execlists (the prerequisites being
- * support for Logical Ring Contexts and Aliasing PPGTT or better),
- * and only when enabled via module parameter.
+ * support for Logical Ring Contexts and Aliasing PPGTT or better).
*
* Return: 1 if Execlists is supported and has to be enabled.
*/
@@ -284,7 +283,6 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
struct drm_i915_private *dev_priv = dev->dev_private;
uint64_t temp = 0;
uint32_t desc[4];
- unsigned long flags;
/* XXX: You must always write both descriptors in the order below. */
if (ctx_obj1)
@@ -298,63 +296,17 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
desc[3] = (u32)(temp >> 32);
desc[2] = (u32)temp;
- /* Set Force Wakeup bit to prevent GT from entering C6 while ELSP writes
- * are in progress.
- *
- * The other problem is that we can't just call gen6_gt_force_wake_get()
- * because that function calls intel_runtime_pm_get(), which might sleep.
- * Instead, we do the runtime_pm_get/put when creating/destroying requests.
- */
- spin_lock_irqsave(&dev_priv->uncore.lock, flags);
- if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) {
- if (dev_priv->uncore.fw_rendercount++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv,
- FORCEWAKE_RENDER);
- if (dev_priv->uncore.fw_mediacount++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv,
- FORCEWAKE_MEDIA);
- if (INTEL_INFO(dev)->gen >= 9) {
- if (dev_priv->uncore.fw_blittercount++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv,
- FORCEWAKE_BLITTER);
- }
- } else {
- if (dev_priv->uncore.forcewake_count++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv,
- FORCEWAKE_ALL);
- }
- spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
-
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
I915_WRITE(RING_ELSP(ring), desc[1]);
I915_WRITE(RING_ELSP(ring), desc[0]);
I915_WRITE(RING_ELSP(ring), desc[3]);
+
/* The context is automatically loaded after the following */
I915_WRITE(RING_ELSP(ring), desc[2]);
/* ELSP is a wo register, so use another nearby reg for posting instead */
POSTING_READ(RING_EXECLIST_STATUS(ring));
-
- /* Release Force Wakeup (see the big comment above). */
- spin_lock_irqsave(&dev_priv->uncore.lock, flags);
- if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) {
- if (--dev_priv->uncore.fw_rendercount == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv,
- FORCEWAKE_RENDER);
- if (--dev_priv->uncore.fw_mediacount == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv,
- FORCEWAKE_MEDIA);
- if (INTEL_INFO(dev)->gen >= 9) {
- if (--dev_priv->uncore.fw_blittercount == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv,
- FORCEWAKE_BLITTER);
- }
- } else {
- if (--dev_priv->uncore.forcewake_count == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv,
- FORCEWAKE_ALL);
- }
-
- spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
static int execlists_update_context(struct drm_i915_gem_object *ctx_obj,
@@ -405,8 +357,8 @@ static void execlists_submit_contexts(struct intel_engine_cs *ring,
static void execlists_context_unqueue(struct intel_engine_cs *ring)
{
- struct intel_ctx_submit_request *req0 = NULL, *req1 = NULL;
- struct intel_ctx_submit_request *cursor = NULL, *tmp = NULL;
+ struct drm_i915_gem_request *req0 = NULL, *req1 = NULL;
+ struct drm_i915_gem_request *cursor = NULL, *tmp = NULL;
assert_spin_locked(&ring->execlist_lock);
@@ -446,12 +398,12 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
static bool execlists_check_remove_request(struct intel_engine_cs *ring,
u32 request_id)
{
- struct intel_ctx_submit_request *head_req;
+ struct drm_i915_gem_request *head_req;
assert_spin_locked(&ring->execlist_lock);
head_req = list_first_entry_or_null(&ring->execlist_queue,
- struct intel_ctx_submit_request,
+ struct drm_i915_gem_request,
execlist_link);
if (head_req != NULL) {
@@ -474,13 +426,13 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring,
}
/**
- * intel_execlists_handle_ctx_events() - handle Context Switch interrupts
+ * intel_lrc_irq_handler() - handle Context Switch interrupts
* @ring: Engine Command Streamer to handle.
*
* Check the unread Context Status Buffers and manage the submission of new
* contexts to the ELSP accordingly.
*/
-void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring)
+void intel_lrc_irq_handler(struct intel_engine_cs *ring)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
u32 status_pointer;
@@ -535,24 +487,34 @@ void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring)
static int execlists_context_queue(struct intel_engine_cs *ring,
struct intel_context *to,
- u32 tail)
+ u32 tail,
+ struct drm_i915_gem_request *request)
{
- struct intel_ctx_submit_request *req = NULL, *cursor;
+ struct drm_i915_gem_request *cursor;
struct drm_i915_private *dev_priv = ring->dev->dev_private;
unsigned long flags;
int num_elements = 0;
- req = kzalloc(sizeof(*req), GFP_KERNEL);
- if (req == NULL)
- return -ENOMEM;
- req->ctx = to;
- i915_gem_context_reference(req->ctx);
-
if (to != ring->default_context)
intel_lr_context_pin(ring, to);
- req->ring = ring;
- req->tail = tail;
+ if (!request) {
+ /*
+ * If there isn't a request associated with this submission,
+ * create one as a temporary holder.
+ */
+ WARN(1, "execlist context submission without request");
+ request = kzalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
+ request->ring = ring;
+ request->ctx = to;
+ } else {
+ WARN_ON(to != request->ctx);
+ }
+ request->tail = tail;
+ i915_gem_request_reference(request);
+ i915_gem_context_reference(request->ctx);
intel_runtime_pm_get(dev_priv);
@@ -563,10 +525,10 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
break;
if (num_elements > 2) {
- struct intel_ctx_submit_request *tail_req;
+ struct drm_i915_gem_request *tail_req;
tail_req = list_last_entry(&ring->execlist_queue,
- struct intel_ctx_submit_request,
+ struct drm_i915_gem_request,
execlist_link);
if (to == tail_req->ctx) {
@@ -578,7 +540,7 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
}
}
- list_add_tail(&req->execlist_link, &ring->execlist_queue);
+ list_add_tail(&request->execlist_link, &ring->execlist_queue);
if (num_elements == 0)
execlists_context_unqueue(ring);
@@ -587,7 +549,8 @@ static int execlists_context_queue(struct intel_engine_cs *ring,
return 0;
}
-static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf)
+static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx)
{
struct intel_engine_cs *ring = ringbuf->ring;
uint32_t flush_domains;
@@ -597,7 +560,8 @@ static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf)
if (ring->gpu_caches_dirty)
flush_domains = I915_GEM_GPU_DOMAINS;
- ret = ring->emit_flush(ringbuf, I915_GEM_GPU_DOMAINS, flush_domains);
+ ret = ring->emit_flush(ringbuf, ctx,
+ I915_GEM_GPU_DOMAINS, flush_domains);
if (ret)
return ret;
@@ -606,6 +570,7 @@ static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf)
}
static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
struct list_head *vmas)
{
struct intel_engine_cs *ring = ringbuf->ring;
@@ -633,7 +598,7 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
/* Unconditionally invalidate gpu caches and ensure that we do flush
* any residual writes from the previous batch.
*/
- return logical_ring_invalidate_all_caches(ringbuf);
+ return logical_ring_invalidate_all_caches(ringbuf, ctx);
}
/**
@@ -713,13 +678,13 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
return -EINVAL;
}
- ret = execlists_move_to_gpu(ringbuf, vmas);
+ ret = execlists_move_to_gpu(ringbuf, ctx, vmas);
if (ret)
return ret;
if (ring == &dev_priv->ring[RCS] &&
instp_mode != dev_priv->relative_constants_mode) {
- ret = intel_logical_ring_begin(ringbuf, 4);
+ ret = intel_logical_ring_begin(ringbuf, ctx, 4);
if (ret)
return ret;
@@ -732,7 +697,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
dev_priv->relative_constants_mode = instp_mode;
}
- ret = ring->emit_bb_start(ringbuf, exec_start, flags);
+ ret = ring->emit_bb_start(ringbuf, ctx, exec_start, flags);
if (ret)
return ret;
@@ -744,7 +709,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
void intel_execlists_retire_requests(struct intel_engine_cs *ring)
{
- struct intel_ctx_submit_request *req, *tmp;
+ struct drm_i915_gem_request *req, *tmp;
struct drm_i915_private *dev_priv = ring->dev->dev_private;
unsigned long flags;
struct list_head retired_list;
@@ -766,9 +731,9 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring)
if (ctx_obj && (ctx != ring->default_context))
intel_lr_context_unpin(ring, ctx);
intel_runtime_pm_put(dev_priv);
- i915_gem_context_unreference(req->ctx);
+ i915_gem_context_unreference(ctx);
list_del(&req->execlist_link);
- kfree(req);
+ i915_gem_request_unreference(req);
}
}
@@ -794,7 +759,8 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring)
I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING));
}
-int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf)
+int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx)
{
struct intel_engine_cs *ring = ringbuf->ring;
int ret;
@@ -802,7 +768,7 @@ int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf)
if (!ring->gpu_caches_dirty)
return 0;
- ret = ring->emit_flush(ringbuf, 0, I915_GEM_GPU_DOMAINS);
+ ret = ring->emit_flush(ringbuf, ctx, 0, I915_GEM_GPU_DOMAINS);
if (ret)
return ret;
@@ -819,17 +785,18 @@ int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf)
* on a queue waiting for the ELSP to be ready to accept a new context submission. At that
* point, the tail *inside* the context is updated and the ELSP written to.
*/
-void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf)
+void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
+ struct drm_i915_gem_request *request)
{
struct intel_engine_cs *ring = ringbuf->ring;
- struct intel_context *ctx = ringbuf->FIXME_lrc_ctx;
intel_logical_ring_advance(ringbuf);
if (intel_ring_stopped(ring))
return;
- execlists_context_queue(ring, ctx, ringbuf->tail);
+ execlists_context_queue(ring, ctx, ringbuf->tail, request);
}
static int intel_lr_context_pin(struct intel_engine_cs *ring,
@@ -840,11 +807,11 @@ static int intel_lr_context_pin(struct intel_engine_cs *ring,
int ret = 0;
WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex));
- if (ctx->engine[ring->id].unpin_count++ == 0) {
+ if (ctx->engine[ring->id].pin_count++ == 0) {
ret = i915_gem_obj_ggtt_pin(ctx_obj,
GEN8_LR_CONTEXT_ALIGN, 0);
if (ret)
- goto reset_unpin_count;
+ goto reset_pin_count;
ret = intel_pin_and_map_ringbuffer_obj(ring->dev, ringbuf);
if (ret)
@@ -855,8 +822,8 @@ static int intel_lr_context_pin(struct intel_engine_cs *ring,
unpin_ctx_obj:
i915_gem_object_ggtt_unpin(ctx_obj);
-reset_unpin_count:
- ctx->engine[ring->id].unpin_count = 0;
+reset_pin_count:
+ ctx->engine[ring->id].pin_count = 0;
return ret;
}
@@ -869,47 +836,55 @@ void intel_lr_context_unpin(struct intel_engine_cs *ring,
if (ctx_obj) {
WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex));
- if (--ctx->engine[ring->id].unpin_count == 0) {
+ if (--ctx->engine[ring->id].pin_count == 0) {
intel_unpin_ringbuffer_obj(ringbuf);
i915_gem_object_ggtt_unpin(ctx_obj);
}
}
}
-static int logical_ring_alloc_seqno(struct intel_engine_cs *ring,
- struct intel_context *ctx)
+static int logical_ring_alloc_request(struct intel_engine_cs *ring,
+ struct intel_context *ctx)
{
+ struct drm_i915_gem_request *request;
+ struct drm_i915_private *dev_private = ring->dev->dev_private;
int ret;
- if (ring->outstanding_lazy_seqno)
+ if (ring->outstanding_lazy_request)
return 0;
- if (ring->preallocated_lazy_request == NULL) {
- struct drm_i915_gem_request *request;
-
- request = kmalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
+ request = kzalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
- if (ctx != ring->default_context) {
- ret = intel_lr_context_pin(ring, ctx);
- if (ret) {
- kfree(request);
- return ret;
- }
+ if (ctx != ring->default_context) {
+ ret = intel_lr_context_pin(ring, ctx);
+ if (ret) {
+ kfree(request);
+ return ret;
}
+ }
- /* Hold a reference to the context this request belongs to
- * (we will need it when the time comes to emit/retire the
- * request).
- */
- request->ctx = ctx;
- i915_gem_context_reference(request->ctx);
+ kref_init(&request->ref);
+ request->ring = ring;
+ request->uniq = dev_private->request_uniq++;
- ring->preallocated_lazy_request = request;
+ ret = i915_gem_get_seqno(ring->dev, &request->seqno);
+ if (ret) {
+ intel_lr_context_unpin(ring, ctx);
+ kfree(request);
+ return ret;
}
- return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+ /* Hold a reference to the context this request belongs to
+ * (we will need it when the time comes to emit/retire the
+ * request).
+ */
+ request->ctx = ctx;
+ i915_gem_context_reference(request->ctx);
+
+ ring->outstanding_lazy_request = request;
+ return 0;
}
static int logical_ring_wait_request(struct intel_ringbuffer *ringbuf,
@@ -917,42 +892,42 @@ static int logical_ring_wait_request(struct intel_ringbuffer *ringbuf,
{
struct intel_engine_cs *ring = ringbuf->ring;
struct drm_i915_gem_request *request;
- u32 seqno = 0;
int ret;
- if (ringbuf->last_retired_head != -1) {
- ringbuf->head = ringbuf->last_retired_head;
- ringbuf->last_retired_head = -1;
-
- ringbuf->space = intel_ring_space(ringbuf);
- if (ringbuf->space >= bytes)
- return 0;
- }
+ if (intel_ring_space(ringbuf) >= bytes)
+ return 0;
list_for_each_entry(request, &ring->request_list, list) {
+ /*
+ * The request queue is per-engine, so can contain requests
+ * from multiple ringbuffers. Here, we must ignore any that
+ * aren't from the ringbuffer we're considering.
+ */
+ struct intel_context *ctx = request->ctx;
+ if (ctx->engine[ring->id].ringbuf != ringbuf)
+ continue;
+
+ /* Would completion of this request free enough space? */
if (__intel_ring_space(request->tail, ringbuf->tail,
ringbuf->size) >= bytes) {
- seqno = request->seqno;
break;
}
}
- if (seqno == 0)
+ if (&request->list == &ring->request_list)
return -ENOSPC;
- ret = i915_wait_seqno(ring, seqno);
+ ret = i915_wait_request(request);
if (ret)
return ret;
i915_gem_retire_requests_ring(ring);
- ringbuf->head = ringbuf->last_retired_head;
- ringbuf->last_retired_head = -1;
- ringbuf->space = intel_ring_space(ringbuf);
- return 0;
+ return intel_ring_space(ringbuf) >= bytes ? 0 : -ENOSPC;
}
static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
int bytes)
{
struct intel_engine_cs *ring = ringbuf->ring;
@@ -966,7 +941,7 @@ static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf,
return ret;
/* Force the context submission in case we have been skipping it */
- intel_logical_ring_advance_and_submit(ringbuf);
+ intel_logical_ring_advance_and_submit(ringbuf, ctx, NULL);
/* With GEM the hangcheck timer should kick us out of the loop,
* leaving it early runs the risk of corrupting GEM state (due
@@ -975,13 +950,10 @@ static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf,
* case by choosing an insanely large timeout. */
end = jiffies + 60 * HZ;
+ ret = 0;
do {
- ringbuf->head = I915_READ_HEAD(ring);
- ringbuf->space = intel_ring_space(ringbuf);
- if (ringbuf->space >= bytes) {
- ret = 0;
+ if (intel_ring_space(ringbuf) >= bytes)
break;
- }
msleep(1);
@@ -1004,13 +976,14 @@ static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf,
return ret;
}
-static int logical_ring_wrap_buffer(struct intel_ringbuffer *ringbuf)
+static int logical_ring_wrap_buffer(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx)
{
uint32_t __iomem *virt;
int rem = ringbuf->size - ringbuf->tail;
if (ringbuf->space < rem) {
- int ret = logical_ring_wait_for_space(ringbuf, rem);
+ int ret = logical_ring_wait_for_space(ringbuf, ctx, rem);
if (ret)
return ret;
@@ -1022,23 +995,24 @@ static int logical_ring_wrap_buffer(struct intel_ringbuffer *ringbuf)
iowrite32(MI_NOOP, virt++);
ringbuf->tail = 0;
- ringbuf->space = intel_ring_space(ringbuf);
+ intel_ring_update_space(ringbuf);
return 0;
}
-static int logical_ring_prepare(struct intel_ringbuffer *ringbuf, int bytes)
+static int logical_ring_prepare(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx, int bytes)
{
int ret;
if (unlikely(ringbuf->tail + bytes > ringbuf->effective_size)) {
- ret = logical_ring_wrap_buffer(ringbuf);
+ ret = logical_ring_wrap_buffer(ringbuf, ctx);
if (unlikely(ret))
return ret;
}
if (unlikely(ringbuf->space < bytes)) {
- ret = logical_ring_wait_for_space(ringbuf, bytes);
+ ret = logical_ring_wait_for_space(ringbuf, ctx, bytes);
if (unlikely(ret))
return ret;
}
@@ -1059,7 +1033,8 @@ static int logical_ring_prepare(struct intel_ringbuffer *ringbuf, int bytes)
*
* Return: non-zero if the ringbuffer is not ready to be written to.
*/
-int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords)
+int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx, int num_dwords)
{
struct intel_engine_cs *ring = ringbuf->ring;
struct drm_device *dev = ring->dev;
@@ -1071,12 +1046,12 @@ int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords)
if (ret)
return ret;
- ret = logical_ring_prepare(ringbuf, num_dwords * sizeof(uint32_t));
+ ret = logical_ring_prepare(ringbuf, ctx, num_dwords * sizeof(uint32_t));
if (ret)
return ret;
/* Preallocate the olr before touching the ring */
- ret = logical_ring_alloc_seqno(ring, ringbuf->FIXME_lrc_ctx);
+ ret = logical_ring_alloc_request(ring, ctx);
if (ret)
return ret;
@@ -1093,15 +1068,15 @@ static int intel_logical_ring_workarounds_emit(struct intel_engine_cs *ring,
struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_workarounds *w = &dev_priv->workarounds;
- if (WARN_ON(w->count == 0))
+ if (WARN_ON_ONCE(w->count == 0))
return 0;
ring->gpu_caches_dirty = true;
- ret = logical_ring_flush_all_caches(ringbuf);
+ ret = logical_ring_flush_all_caches(ringbuf, ctx);
if (ret)
return ret;
- ret = intel_logical_ring_begin(ringbuf, w->count * 2 + 2);
+ ret = intel_logical_ring_begin(ringbuf, ctx, w->count * 2 + 2);
if (ret)
return ret;
@@ -1115,7 +1090,7 @@ static int intel_logical_ring_workarounds_emit(struct intel_engine_cs *ring,
intel_logical_ring_advance(ringbuf);
ring->gpu_caches_dirty = true;
- ret = logical_ring_flush_all_caches(ringbuf);
+ ret = logical_ring_flush_all_caches(ringbuf, ctx);
if (ret)
return ret;
@@ -1134,6 +1109,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring)
_MASKED_BIT_DISABLE(GFX_REPLAY_MODE) |
_MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE));
POSTING_READ(RING_MODE_GEN7(ring));
+ ring->next_context_status_buffer = 0;
DRM_DEBUG_DRIVER("Execlists enabled for %s\n", ring->name);
memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
@@ -1159,22 +1135,19 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring)
*/
I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
- ret = intel_init_pipe_control(ring);
- if (ret)
- return ret;
-
I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
return init_workarounds_ring(ring);
}
static int gen8_emit_bb_start(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
u64 offset, unsigned flags)
{
bool ppgtt = !(flags & I915_DISPATCH_SECURE);
int ret;
- ret = intel_logical_ring_begin(ringbuf, 4);
+ ret = intel_logical_ring_begin(ringbuf, ctx, 4);
if (ret)
return ret;
@@ -1222,6 +1195,7 @@ static void gen8_logical_ring_put_irq(struct intel_engine_cs *ring)
}
static int gen8_emit_flush(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
u32 invalidate_domains,
u32 unused)
{
@@ -1231,21 +1205,23 @@ static int gen8_emit_flush(struct intel_ringbuffer *ringbuf,
uint32_t cmd;
int ret;
- ret = intel_logical_ring_begin(ringbuf, 4);
+ ret = intel_logical_ring_begin(ringbuf, ctx, 4);
if (ret)
return ret;
cmd = MI_FLUSH_DW + 1;
- if (ring == &dev_priv->ring[VCS]) {
- if (invalidate_domains & I915_GEM_GPU_DOMAINS)
- cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD |
- MI_FLUSH_DW_STORE_INDEX |
- MI_FLUSH_DW_OP_STOREDW;
- } else {
- if (invalidate_domains & I915_GEM_DOMAIN_RENDER)
- cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX |
- MI_FLUSH_DW_OP_STOREDW;
+ /* We always require a command barrier so that subsequent
+ * commands, such as breadcrumb interrupts, are strictly ordered
+ * wrt the contents of the write cache being flushed to memory
+ * (and thus being coherent from the CPU).
+ */
+ cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
+ if (invalidate_domains & I915_GEM_GPU_DOMAINS) {
+ cmd |= MI_INVALIDATE_TLB;
+ if (ring == &dev_priv->ring[VCS])
+ cmd |= MI_INVALIDATE_BSD;
}
intel_logical_ring_emit(ringbuf, cmd);
@@ -1260,6 +1236,7 @@ static int gen8_emit_flush(struct intel_ringbuffer *ringbuf,
}
static int gen8_emit_flush_render(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
u32 invalidate_domains,
u32 flush_domains)
{
@@ -1286,7 +1263,7 @@ static int gen8_emit_flush_render(struct intel_ringbuffer *ringbuf,
flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
}
- ret = intel_logical_ring_begin(ringbuf, 6);
+ ret = intel_logical_ring_begin(ringbuf, ctx, 6);
if (ret)
return ret;
@@ -1311,17 +1288,18 @@ static void gen8_set_seqno(struct intel_engine_cs *ring, u32 seqno)
intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno);
}
-static int gen8_emit_request(struct intel_ringbuffer *ringbuf)
+static int gen8_emit_request(struct intel_ringbuffer *ringbuf,
+ struct drm_i915_gem_request *request)
{
struct intel_engine_cs *ring = ringbuf->ring;
u32 cmd;
int ret;
- ret = intel_logical_ring_begin(ringbuf, 6);
+ ret = intel_logical_ring_begin(ringbuf, request->ctx, 6);
if (ret)
return ret;
- cmd = MI_STORE_DWORD_IMM_GEN8;
+ cmd = MI_STORE_DWORD_IMM_GEN4;
cmd |= MI_GLOBAL_GTT;
intel_logical_ring_emit(ringbuf, cmd);
@@ -1329,14 +1307,27 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf)
(ring->status_page.gfx_addr +
(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT)));
intel_logical_ring_emit(ringbuf, 0);
- intel_logical_ring_emit(ringbuf, ring->outstanding_lazy_seqno);
+ intel_logical_ring_emit(ringbuf,
+ i915_gem_request_get_seqno(ring->outstanding_lazy_request));
intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
intel_logical_ring_emit(ringbuf, MI_NOOP);
- intel_logical_ring_advance_and_submit(ringbuf);
+ intel_logical_ring_advance_and_submit(ringbuf, request->ctx, request);
return 0;
}
+static int gen8_init_rcs_context(struct intel_engine_cs *ring,
+ struct intel_context *ctx)
+{
+ int ret;
+
+ ret = intel_logical_ring_workarounds_emit(ring, ctx);
+ if (ret)
+ return ret;
+
+ return intel_lr_context_render_state_init(ring, ctx);
+}
+
/**
* intel_logical_ring_cleanup() - deallocate the Engine Command Streamer
*
@@ -1354,8 +1345,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
intel_logical_ring_stop(ring);
WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0);
- ring->preallocated_lazy_request = NULL;
- ring->outstanding_lazy_seqno = 0;
+ i915_gem_request_assign(&ring->outstanding_lazy_request, NULL);
if (ring->cleanup)
ring->cleanup(ring);
@@ -1383,18 +1373,11 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
INIT_LIST_HEAD(&ring->execlist_queue);
INIT_LIST_HEAD(&ring->execlist_retired_req_list);
spin_lock_init(&ring->execlist_lock);
- ring->next_context_status_buffer = 0;
ret = i915_cmd_parser_init_ring(ring);
if (ret)
return ret;
- if (ring->init) {
- ret = ring->init(ring);
- if (ret)
- return ret;
- }
-
ret = intel_lr_context_deferred_create(ring->default_context, ring);
return ret;
@@ -1404,6 +1387,7 @@ static int logical_render_ring_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring = &dev_priv->ring[RCS];
+ int ret;
ring->name = "render ring";
ring->id = RCS;
@@ -1415,8 +1399,8 @@ static int logical_render_ring_init(struct drm_device *dev)
if (HAS_L3_DPF(dev))
ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
- ring->init = gen8_init_render_ring;
- ring->init_context = intel_logical_ring_workarounds_emit;
+ ring->init_hw = gen8_init_render_ring;
+ ring->init_context = gen8_init_rcs_context;
ring->cleanup = intel_fini_pipe_control;
ring->get_seqno = gen8_get_seqno;
ring->set_seqno = gen8_set_seqno;
@@ -1426,7 +1410,12 @@ static int logical_render_ring_init(struct drm_device *dev)
ring->irq_put = gen8_logical_ring_put_irq;
ring->emit_bb_start = gen8_emit_bb_start;
- return logical_ring_init(dev, ring);
+ ring->dev = dev;
+ ret = logical_ring_init(dev, ring);
+ if (ret)
+ return ret;
+
+ return intel_init_pipe_control(ring);
}
static int logical_bsd_ring_init(struct drm_device *dev)
@@ -1442,7 +1431,7 @@ static int logical_bsd_ring_init(struct drm_device *dev)
ring->irq_keep_mask =
GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT;
- ring->init = gen8_init_common_ring;
+ ring->init_hw = gen8_init_common_ring;
ring->get_seqno = gen8_get_seqno;
ring->set_seqno = gen8_set_seqno;
ring->emit_request = gen8_emit_request;
@@ -1467,7 +1456,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev)
ring->irq_keep_mask =
GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT;
- ring->init = gen8_init_common_ring;
+ ring->init_hw = gen8_init_common_ring;
ring->get_seqno = gen8_get_seqno;
ring->set_seqno = gen8_set_seqno;
ring->emit_request = gen8_emit_request;
@@ -1492,7 +1481,7 @@ static int logical_blt_ring_init(struct drm_device *dev)
ring->irq_keep_mask =
GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT;
- ring->init = gen8_init_common_ring;
+ ring->init_hw = gen8_init_common_ring;
ring->get_seqno = gen8_get_seqno;
ring->set_seqno = gen8_set_seqno;
ring->emit_request = gen8_emit_request;
@@ -1517,7 +1506,7 @@ static int logical_vebox_ring_init(struct drm_device *dev)
ring->irq_keep_mask =
GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT;
- ring->init = gen8_init_common_ring;
+ ring->init_hw = gen8_init_common_ring;
ring->get_seqno = gen8_get_seqno;
ring->set_seqno = gen8_set_seqno;
ring->emit_request = gen8_emit_request;
@@ -1609,6 +1598,7 @@ int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
return 0;
ret = ring->emit_bb_start(ringbuf,
+ ctx,
so.ggtt_offset,
I915_DISPATCH_SECURE);
if (ret)
@@ -1616,7 +1606,7 @@ int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
- ret = __i915_add_request(ring, file, so.obj, NULL);
+ ret = __i915_add_request(ring, file, so.obj);
/* intel_logical_ring_add_request moves object to inactive if it
* fails */
out:
@@ -1763,6 +1753,7 @@ void intel_lr_context_free(struct intel_context *ctx)
intel_unpin_ringbuffer_obj(ringbuf);
i915_gem_object_ggtt_unpin(ctx_obj);
}
+ WARN_ON(ctx->engine[ring->id].pin_count);
intel_destroy_ringbuffer_obj(ringbuf);
kfree(ringbuf);
drm_gem_object_unreference(&ctx_obj->base);
@@ -1835,8 +1826,7 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
int ret;
WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL);
- if (ctx->engine[ring->id].state)
- return 0;
+ WARN_ON(ctx->engine[ring->id].state);
context_size = round_up(get_lr_context_size(ring), 4096);
@@ -1866,14 +1856,13 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
}
ringbuf->ring = ring;
- ringbuf->FIXME_lrc_ctx = ctx;
ringbuf->size = 32 * PAGE_SIZE;
ringbuf->effective_size = ringbuf->size;
ringbuf->head = 0;
ringbuf->tail = 0;
- ringbuf->space = ringbuf->size;
ringbuf->last_retired_head = -1;
+ intel_ring_update_space(ringbuf);
if (ringbuf->obj == NULL) {
ret = intel_alloc_ringbuffer_obj(dev, ringbuf);
@@ -1907,21 +1896,17 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
if (ctx == ring->default_context)
lrc_setup_hardware_status_page(ring, ctx_obj);
-
- if (ring->id == RCS && !ctx->rcs_initialized) {
+ else if (ring->id == RCS && !ctx->rcs_initialized) {
if (ring->init_context) {
ret = ring->init_context(ring, ctx);
- if (ret)
+ if (ret) {
DRM_ERROR("ring init context: %d\n", ret);
+ ctx->engine[ring->id].ringbuf = NULL;
+ ctx->engine[ring->id].state = NULL;
+ goto error;
+ }
}
- ret = intel_lr_context_render_state_init(ring, ctx);
- if (ret) {
- DRM_ERROR("Init render state failed: %d\n", ret);
- ctx->engine[ring->id].ringbuf = NULL;
- ctx->engine[ring->id].state = NULL;
- goto error;
- }
ctx->rcs_initialized = true;
}
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 14b216b9be7f..6f2d7da594f6 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -38,8 +38,12 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring);
void intel_logical_ring_cleanup(struct intel_engine_cs *ring);
int intel_logical_rings_init(struct drm_device *dev);
-int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf);
-void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf);
+int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx);
+void intel_logical_ring_advance_and_submit(
+ struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
+ struct drm_i915_gem_request *request);
/**
* intel_logical_ring_advance() - advance the ringbuffer tail
* @ringbuf: Ringbuffer to advance.
@@ -61,7 +65,9 @@ static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf,
iowrite32(data, ringbuf->virtual_start + ringbuf->tail);
ringbuf->tail += 4;
}
-int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords);
+int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
+ int num_dwords);
/* Logical Ring Contexts */
int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
@@ -83,36 +89,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
u64 exec_start, u32 flags);
u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj);
-/**
- * struct intel_ctx_submit_request - queued context submission request
- * @ctx: Context to submit to the ELSP.
- * @ring: Engine to submit it to.
- * @tail: how far in the context's ringbuffer this request goes to.
- * @execlist_link: link in the submission queue.
- * @work: workqueue for processing this request in a bottom half.
- * @elsp_submitted: no. of times this request has been sent to the ELSP.
- *
- * The ELSP only accepts two elements at a time, so we queue context/tail
- * pairs on a given queue (ring->execlist_queue) until the hardware is
- * available. The queue serves a double purpose: we also use it to keep track
- * of the up to 2 contexts currently in the hardware (usually one in execution
- * and the other queued up by the GPU): We only remove elements from the head
- * of the queue when the hardware informs us that an element has been
- * completed.
- *
- * All accesses to the queue are mediated by a spinlock (ring->execlist_lock).
- */
-struct intel_ctx_submit_request {
- struct intel_context *ctx;
- struct intel_engine_cs *ring;
- u32 tail;
-
- struct list_head execlist_link;
-
- int elsp_submitted;
-};
-
-void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring);
+void intel_lrc_irq_handler(struct intel_engine_cs *ring);
void intel_execlists_retire_requests(struct intel_engine_cs *ring);
#endif /* _INTEL_LRC_H_ */
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 14654d628ca4..071b96d6e146 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -32,6 +32,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include "intel_drv.h"
@@ -93,7 +94,7 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
}
static void intel_lvds_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -115,7 +116,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
else
flags |= DRM_MODE_FLAG_PVSYNC;
- pipe_config->adjusted_mode.flags |= flags;
+ pipe_config->base.adjusted_mode.flags |= flags;
/* gen2/3 store dither state in pfit control, needs to match */
if (INTEL_INFO(dev)->gen < 4) {
@@ -129,7 +130,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
if (HAS_PCH_SPLIT(dev_priv->dev))
ironlake_check_encoder_dotclock(pipe_config, dotclock);
- pipe_config->adjusted_mode.crtc_clock = dotclock;
+ pipe_config->base.adjusted_mode.crtc_clock = dotclock;
}
static void intel_pre_enable_lvds(struct intel_encoder *encoder)
@@ -139,7 +140,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
const struct drm_display_mode *adjusted_mode =
- &crtc->config.adjusted_mode;
+ &crtc->config->base.adjusted_mode;
int pipe = crtc->pipe;
u32 temp;
@@ -167,7 +168,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
/* set the corresponsding LVDS_BORDER bit */
temp &= ~LVDS_BORDER_ENABLE;
- temp |= crtc->config.gmch_pfit.lvds_border_bits;
+ temp |= crtc->config->gmch_pfit.lvds_border_bits;
/* Set the B0-B3 data pairs corresponding to whether we're going to
* set the DPLLs for dual-channel mode or not.
*/
@@ -190,7 +191,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
if (INTEL_INFO(dev)->gen == 4) {
/* Bspec wording suggests that LVDS port dithering only exists
* for 18bpp panels. */
- if (crtc->config.dither && crtc->config.pipe_bpp == 18)
+ if (crtc->config->dither && crtc->config->pipe_bpp == 18)
temp |= LVDS_ENABLE_DITHER;
else
temp &= ~LVDS_ENABLE_DITHER;
@@ -277,14 +278,14 @@ intel_lvds_mode_valid(struct drm_connector *connector,
}
static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = intel_encoder->base.dev;
struct intel_lvds_encoder *lvds_encoder =
to_lvds_encoder(&intel_encoder->base);
struct intel_connector *intel_connector =
&lvds_encoder->attached_connector->base;
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
unsigned int lvds_bpp;
@@ -531,7 +532,9 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_lvds_set_property,
+ .atomic_get_property = intel_connector_atomic_get_property,
.destroy = intel_lvds_destroy,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index dc2f4f26c961..f93dfc174495 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -182,7 +182,7 @@ struct intel_overlay {
u32 flip_addr;
struct drm_i915_gem_object *reg_bo;
/* flip handling */
- uint32_t last_flip_req;
+ struct drm_i915_gem_request *last_flip_req;
void (*flip_tail)(struct intel_overlay *);
};
@@ -217,17 +217,19 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
int ret;
BUG_ON(overlay->last_flip_req);
- ret = i915_add_request(ring, &overlay->last_flip_req);
+ i915_gem_request_assign(&overlay->last_flip_req,
+ ring->outstanding_lazy_request);
+ ret = i915_add_request(ring);
if (ret)
return ret;
overlay->flip_tail = tail;
- ret = i915_wait_seqno(ring, overlay->last_flip_req);
+ ret = i915_wait_request(overlay->last_flip_req);
if (ret)
return ret;
i915_gem_retire_requests(dev);
- overlay->last_flip_req = 0;
+ i915_gem_request_assign(&overlay->last_flip_req, NULL);
return 0;
}
@@ -286,7 +288,10 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
intel_ring_emit(ring, flip_addr);
intel_ring_advance(ring);
- return i915_add_request(ring, &overlay->last_flip_req);
+ WARN_ON(overlay->last_flip_req);
+ i915_gem_request_assign(&overlay->last_flip_req,
+ ring->outstanding_lazy_request);
+ return i915_add_request(ring);
}
static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@ -361,23 +366,20 @@ static int intel_overlay_off(struct intel_overlay *overlay)
* We have to be careful not to repeat work forever an make forward progess. */
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
{
- struct drm_device *dev = overlay->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_engine_cs *ring = &dev_priv->ring[RCS];
int ret;
- if (overlay->last_flip_req == 0)
+ if (overlay->last_flip_req == NULL)
return 0;
- ret = i915_wait_seqno(ring, overlay->last_flip_req);
+ ret = i915_wait_request(overlay->last_flip_req);
if (ret)
return ret;
- i915_gem_retire_requests(dev);
+ i915_gem_retire_requests(overlay->dev);
if (overlay->flip_tail)
overlay->flip_tail(overlay);
- overlay->last_flip_req = 0;
+ i915_gem_request_assign(&overlay->last_flip_req, NULL);
return 0;
}
@@ -392,6 +394,8 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
struct intel_engine_cs *ring = &dev_priv->ring[RCS];
int ret;
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
/* Only wait if there is actually an old frame to release to
* guarantee forward progress.
*/
@@ -422,6 +426,22 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
return 0;
}
+void intel_overlay_reset(struct drm_i915_private *dev_priv)
+{
+ struct intel_overlay *overlay = dev_priv->overlay;
+
+ if (!overlay)
+ return;
+
+ intel_overlay_release_old_vid(overlay);
+
+ overlay->last_flip_req = NULL;
+ overlay->old_xscale = 0;
+ overlay->old_yscale = 0;
+ overlay->crtc = NULL;
+ overlay->active = false;
+}
+
struct put_image_params {
int format;
short dst_x;
@@ -836,7 +856,7 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
return -EINVAL;
/* can't use the overlay with double wide pipe */
- if (crtc->config.double_wide)
+ if (crtc->config->double_wide)
return -EINVAL;
return 0;
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index dfb783a8f2c3..d8686ce89160 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -98,13 +98,13 @@ intel_find_panel_downclock(struct drm_device *dev,
/* adjusted_mode has been preset to be the panel's fixed mode */
void
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
- struct intel_crtc_config *pipe_config,
+ struct intel_crtc_state *pipe_config,
int fitting_mode)
{
struct drm_display_mode *adjusted_mode;
int x, y, width, height;
- adjusted_mode = &pipe_config->adjusted_mode;
+ adjusted_mode = &pipe_config->base.adjusted_mode;
x = y = width = height = 0;
@@ -223,10 +223,10 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
return (FACTOR * ratio + FACTOR/2) / FACTOR;
}
-static void i965_scale_aspect(struct intel_crtc_config *pipe_config,
+static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
u32 *pfit_control)
{
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
u32 scaled_width = adjusted_mode->hdisplay *
pipe_config->pipe_src_h;
u32 scaled_height = pipe_config->pipe_src_w *
@@ -243,11 +243,11 @@ static void i965_scale_aspect(struct intel_crtc_config *pipe_config,
*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
}
-static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
+static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
u32 *pfit_control, u32 *pfit_pgm_ratios,
u32 *border)
{
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
u32 scaled_width = adjusted_mode->hdisplay *
pipe_config->pipe_src_h;
u32 scaled_height = pipe_config->pipe_src_w *
@@ -301,14 +301,14 @@ static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
}
void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
- struct intel_crtc_config *pipe_config,
+ struct intel_crtc_state *pipe_config,
int fitting_mode)
{
struct drm_device *dev = intel_crtc->base.dev;
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
struct drm_display_mode *adjusted_mode;
- adjusted_mode = &pipe_config->adjusted_mode;
+ adjusted_mode = &pipe_config->base.adjusted_mode;
/* Native modes don't need fitting */
if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index bf814a64582a..24d77ddcc5f4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -52,17 +52,6 @@
#define INTEL_RC6p_ENABLE (1<<1)
#define INTEL_RC6pp_ENABLE (1<<2)
-/* FBC, or Frame Buffer Compression, is a technique employed to compress the
- * framebuffer contents in-memory, aiming at reducing the required bandwidth
- * during in-memory transfers and, therefore, reduce the power packet.
- *
- * The benefits of FBC are mostly visible with solid backgrounds and
- * variation-less patterns.
- *
- * FBC-related functionality can be enabled by the means of the
- * i915.i915_enable_fbc parameter
- */
-
static void gen9_init_clock_gating(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -87,614 +76,6 @@ static void gen9_init_clock_gating(struct drm_device *dev)
_MASKED_BIT_ENABLE(GEN8_4x4_STC_OPTIMIZATION_DISABLE));
}
-static void i8xx_disable_fbc(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 fbc_ctl;
-
- dev_priv->fbc.enabled = false;
-
- /* Disable compression */
- fbc_ctl = I915_READ(FBC_CONTROL);
- if ((fbc_ctl & FBC_CTL_EN) == 0)
- return;
-
- fbc_ctl &= ~FBC_CTL_EN;
- I915_WRITE(FBC_CONTROL, fbc_ctl);
-
- /* Wait for compressing bit to clear */
- if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) {
- DRM_DEBUG_KMS("FBC idle timed out\n");
- return;
- }
-
- DRM_DEBUG_KMS("disabled FBC\n");
-}
-
-static void i8xx_enable_fbc(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int cfb_pitch;
- int i;
- u32 fbc_ctl;
-
- dev_priv->fbc.enabled = true;
-
- cfb_pitch = dev_priv->fbc.size / FBC_LL_SIZE;
- if (fb->pitches[0] < cfb_pitch)
- cfb_pitch = fb->pitches[0];
-
- /* FBC_CTL wants 32B or 64B units */
- if (IS_GEN2(dev))
- cfb_pitch = (cfb_pitch / 32) - 1;
- else
- cfb_pitch = (cfb_pitch / 64) - 1;
-
- /* Clear old tags */
- for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
- I915_WRITE(FBC_TAG + (i * 4), 0);
-
- if (IS_GEN4(dev)) {
- u32 fbc_ctl2;
-
- /* Set it up... */
- fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE;
- fbc_ctl2 |= FBC_CTL_PLANE(intel_crtc->plane);
- I915_WRITE(FBC_CONTROL2, fbc_ctl2);
- I915_WRITE(FBC_FENCE_OFF, crtc->y);
- }
-
- /* enable it... */
- fbc_ctl = I915_READ(FBC_CONTROL);
- fbc_ctl &= 0x3fff << FBC_CTL_INTERVAL_SHIFT;
- fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
- if (IS_I945GM(dev))
- fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */
- fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
- fbc_ctl |= obj->fence_reg;
- I915_WRITE(FBC_CONTROL, fbc_ctl);
-
- DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c\n",
- cfb_pitch, crtc->y, plane_name(intel_crtc->plane));
-}
-
-static bool i8xx_fbc_enabled(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- return I915_READ(FBC_CONTROL) & FBC_CTL_EN;
-}
-
-static void g4x_enable_fbc(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 dpfc_ctl;
-
- dev_priv->fbc.enabled = true;
-
- dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane) | DPFC_SR_EN;
- if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
- dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- else
- dpfc_ctl |= DPFC_CTL_LIMIT_1X;
- dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg;
-
- I915_WRITE(DPFC_FENCE_YOFF, crtc->y);
-
- /* enable it... */
- I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
-
- DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
-}
-
-static void g4x_disable_fbc(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 dpfc_ctl;
-
- dev_priv->fbc.enabled = false;
-
- /* Disable compression */
- dpfc_ctl = I915_READ(DPFC_CONTROL);
- if (dpfc_ctl & DPFC_CTL_EN) {
- dpfc_ctl &= ~DPFC_CTL_EN;
- I915_WRITE(DPFC_CONTROL, dpfc_ctl);
-
- DRM_DEBUG_KMS("disabled FBC\n");
- }
-}
-
-static bool g4x_fbc_enabled(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
-}
-
-static void sandybridge_blit_fbc_update(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 blt_ecoskpd;
-
- /* Make sure blitter notifies FBC of writes */
-
- /* Blitter is part of Media powerwell on VLV. No impact of
- * his param in other platforms for now */
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_MEDIA);
-
- blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
- blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
- GEN6_BLITTER_LOCK_SHIFT;
- I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
- blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY;
- I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
- blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY <<
- GEN6_BLITTER_LOCK_SHIFT);
- I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
- POSTING_READ(GEN6_BLITTER_ECOSKPD);
-
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_MEDIA);
-}
-
-static void ironlake_enable_fbc(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 dpfc_ctl;
-
- dev_priv->fbc.enabled = true;
-
- dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane);
- if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
- dev_priv->fbc.threshold++;
-
- switch (dev_priv->fbc.threshold) {
- case 4:
- case 3:
- dpfc_ctl |= DPFC_CTL_LIMIT_4X;
- break;
- case 2:
- dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- break;
- case 1:
- dpfc_ctl |= DPFC_CTL_LIMIT_1X;
- break;
- }
- dpfc_ctl |= DPFC_CTL_FENCE_EN;
- if (IS_GEN5(dev))
- dpfc_ctl |= obj->fence_reg;
-
- I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y);
- I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj) | ILK_FBC_RT_VALID);
- /* enable it... */
- I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
-
- if (IS_GEN6(dev)) {
- I915_WRITE(SNB_DPFC_CTL_SA,
- SNB_CPU_FENCE_ENABLE | obj->fence_reg);
- I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
- sandybridge_blit_fbc_update(dev);
- }
-
- DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
-}
-
-static void ironlake_disable_fbc(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 dpfc_ctl;
-
- dev_priv->fbc.enabled = false;
-
- /* Disable compression */
- dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
- if (dpfc_ctl & DPFC_CTL_EN) {
- dpfc_ctl &= ~DPFC_CTL_EN;
- I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
-
- DRM_DEBUG_KMS("disabled FBC\n");
- }
-}
-
-static bool ironlake_fbc_enabled(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
-}
-
-static void gen7_enable_fbc(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_framebuffer *fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 dpfc_ctl;
-
- dev_priv->fbc.enabled = true;
-
- dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane);
- if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
- dev_priv->fbc.threshold++;
-
- switch (dev_priv->fbc.threshold) {
- case 4:
- case 3:
- dpfc_ctl |= DPFC_CTL_LIMIT_4X;
- break;
- case 2:
- dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- break;
- case 1:
- dpfc_ctl |= DPFC_CTL_LIMIT_1X;
- break;
- }
-
- dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;
-
- if (dev_priv->fbc.false_color)
- dpfc_ctl |= FBC_CTL_FALSE_COLOR;
-
- I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
-
- if (IS_IVYBRIDGE(dev)) {
- /* WaFbcAsynchFlipDisableFbcQueue:ivb */
- I915_WRITE(ILK_DISPLAY_CHICKEN1,
- I915_READ(ILK_DISPLAY_CHICKEN1) |
- ILK_FBCQ_DIS);
- } else {
- /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */
- I915_WRITE(CHICKEN_PIPESL_1(intel_crtc->pipe),
- I915_READ(CHICKEN_PIPESL_1(intel_crtc->pipe)) |
- HSW_FBCQ_DIS);
- }
-
- I915_WRITE(SNB_DPFC_CTL_SA,
- SNB_CPU_FENCE_ENABLE | obj->fence_reg);
- I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
-
- sandybridge_blit_fbc_update(dev);
-
- DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
-}
-
-bool intel_fbc_enabled(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- return dev_priv->fbc.enabled;
-}
-
-void bdw_fbc_sw_flush(struct drm_device *dev, u32 value)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (!IS_GEN8(dev))
- return;
-
- if (!intel_fbc_enabled(dev))
- return;
-
- I915_WRITE(MSG_FBC_REND_STATE, value);
-}
-
-static void intel_fbc_work_fn(struct work_struct *__work)
-{
- struct intel_fbc_work *work =
- container_of(to_delayed_work(__work),
- struct intel_fbc_work, work);
- struct drm_device *dev = work->crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- mutex_lock(&dev->struct_mutex);
- if (work == dev_priv->fbc.fbc_work) {
- /* Double check that we haven't switched fb without cancelling
- * the prior work.
- */
- if (work->crtc->primary->fb == work->fb) {
- dev_priv->display.enable_fbc(work->crtc);
-
- dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane;
- dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id;
- dev_priv->fbc.y = work->crtc->y;
- }
-
- dev_priv->fbc.fbc_work = NULL;
- }
- mutex_unlock(&dev->struct_mutex);
-
- kfree(work);
-}
-
-static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv)
-{
- if (dev_priv->fbc.fbc_work == NULL)
- return;
-
- DRM_DEBUG_KMS("cancelling pending FBC enable\n");
-
- /* Synchronisation is provided by struct_mutex and checking of
- * dev_priv->fbc.fbc_work, so we can perform the cancellation
- * entirely asynchronously.
- */
- if (cancel_delayed_work(&dev_priv->fbc.fbc_work->work))
- /* tasklet was killed before being run, clean up */
- kfree(dev_priv->fbc.fbc_work);
-
- /* Mark the work as no longer wanted so that if it does
- * wake-up (because the work was already running and waiting
- * for our mutex), it will discover that is no longer
- * necessary to run.
- */
- dev_priv->fbc.fbc_work = NULL;
-}
-
-static void intel_enable_fbc(struct drm_crtc *crtc)
-{
- struct intel_fbc_work *work;
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (!dev_priv->display.enable_fbc)
- return;
-
- intel_cancel_fbc_work(dev_priv);
-
- work = kzalloc(sizeof(*work), GFP_KERNEL);
- if (work == NULL) {
- DRM_ERROR("Failed to allocate FBC work structure\n");
- dev_priv->display.enable_fbc(crtc);
- return;
- }
-
- work->crtc = crtc;
- work->fb = crtc->primary->fb;
- INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn);
-
- dev_priv->fbc.fbc_work = work;
-
- /* Delay the actual enabling to let pageflipping cease and the
- * display to settle before starting the compression. Note that
- * this delay also serves a second purpose: it allows for a
- * vblank to pass after disabling the FBC before we attempt
- * to modify the control registers.
- *
- * A more complicated solution would involve tracking vblanks
- * following the termination of the page-flipping sequence
- * and indeed performing the enable as a co-routine and not
- * waiting synchronously upon the vblank.
- *
- * WaFbcWaitForVBlankBeforeEnable:ilk,snb
- */
- schedule_delayed_work(&work->work, msecs_to_jiffies(50));
-}
-
-void intel_disable_fbc(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- intel_cancel_fbc_work(dev_priv);
-
- if (!dev_priv->display.disable_fbc)
- return;
-
- dev_priv->display.disable_fbc(dev);
- dev_priv->fbc.plane = -1;
-}
-
-static bool set_no_fbc_reason(struct drm_i915_private *dev_priv,
- enum no_fbc_reason reason)
-{
- if (dev_priv->fbc.no_fbc_reason == reason)
- return false;
-
- dev_priv->fbc.no_fbc_reason = reason;
- return true;
-}
-
-/**
- * intel_update_fbc - enable/disable FBC as needed
- * @dev: the drm_device
- *
- * Set up the framebuffer compression hardware at mode set time. We
- * enable it if possible:
- * - plane A only (on pre-965)
- * - no pixel mulitply/line duplication
- * - no alpha buffer discard
- * - no dual wide
- * - framebuffer <= max_hdisplay in width, max_vdisplay in height
- *
- * We can't assume that any compression will take place (worst case),
- * so the compressed buffer has to be the same size as the uncompressed
- * one. It also must reside (along with the line length buffer) in
- * stolen memory.
- *
- * We need to enable/disable FBC on a global basis.
- */
-void intel_update_fbc(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = NULL, *tmp_crtc;
- struct intel_crtc *intel_crtc;
- struct drm_framebuffer *fb;
- struct drm_i915_gem_object *obj;
- const struct drm_display_mode *adjusted_mode;
- unsigned int max_width, max_height;
-
- if (!HAS_FBC(dev)) {
- set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED);
- return;
- }
-
- if (!i915.powersave) {
- if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM))
- DRM_DEBUG_KMS("fbc disabled per module param\n");
- return;
- }
-
- /*
- * If FBC is already on, we just have to verify that we can
- * keep it that way...
- * Need to disable if:
- * - more than one pipe is active
- * - changing FBC params (stride, fence, mode)
- * - new fb is too large to fit in compressed buffer
- * - going to an unsupported config (interlace, pixel multiply, etc.)
- */
- for_each_crtc(dev, tmp_crtc) {
- if (intel_crtc_active(tmp_crtc) &&
- to_intel_crtc(tmp_crtc)->primary_enabled) {
- if (crtc) {
- if (set_no_fbc_reason(dev_priv, FBC_MULTIPLE_PIPES))
- DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
- goto out_disable;
- }
- crtc = tmp_crtc;
- }
- }
-
- if (!crtc || crtc->primary->fb == NULL) {
- if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT))
- DRM_DEBUG_KMS("no output, disabling\n");
- goto out_disable;
- }
-
- intel_crtc = to_intel_crtc(crtc);
- fb = crtc->primary->fb;
- obj = intel_fb_obj(fb);
- adjusted_mode = &intel_crtc->config.adjusted_mode;
-
- if (i915.enable_fbc < 0) {
- if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT))
- DRM_DEBUG_KMS("disabled per chip default\n");
- goto out_disable;
- }
- if (!i915.enable_fbc) {
- if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM))
- DRM_DEBUG_KMS("fbc disabled per module param\n");
- goto out_disable;
- }
- if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
- (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
- if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
- DRM_DEBUG_KMS("mode incompatible with compression, "
- "disabling\n");
- goto out_disable;
- }
-
- if (INTEL_INFO(dev)->gen >= 8 || IS_HASWELL(dev)) {
- max_width = 4096;
- max_height = 4096;
- } else if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
- max_width = 4096;
- max_height = 2048;
- } else {
- max_width = 2048;
- max_height = 1536;
- }
- if (intel_crtc->config.pipe_src_w > max_width ||
- intel_crtc->config.pipe_src_h > max_height) {
- if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE))
- DRM_DEBUG_KMS("mode too large for compression, disabling\n");
- goto out_disable;
- }
- if ((INTEL_INFO(dev)->gen < 4 || HAS_DDI(dev)) &&
- intel_crtc->plane != PLANE_A) {
- if (set_no_fbc_reason(dev_priv, FBC_BAD_PLANE))
- DRM_DEBUG_KMS("plane not A, disabling compression\n");
- goto out_disable;
- }
-
- /* The use of a CPU fence is mandatory in order to detect writes
- * by the CPU to the scanout and trigger updates to the FBC.
- */
- if (obj->tiling_mode != I915_TILING_X ||
- obj->fence_reg == I915_FENCE_REG_NONE) {
- if (set_no_fbc_reason(dev_priv, FBC_NOT_TILED))
- DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n");
- goto out_disable;
- }
- if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
- to_intel_plane(crtc->primary)->rotation != BIT(DRM_ROTATE_0)) {
- if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
- DRM_DEBUG_KMS("Rotation unsupported, disabling\n");
- goto out_disable;
- }
-
- /* If the kernel debugger is active, always disable compression */
- if (in_dbg_master())
- goto out_disable;
-
- if (i915_gem_stolen_setup_compression(dev, obj->base.size,
- drm_format_plane_cpp(fb->pixel_format, 0))) {
- if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL))
- DRM_DEBUG_KMS("framebuffer too large, disabling compression\n");
- goto out_disable;
- }
-
- /* If the scanout has not changed, don't modify the FBC settings.
- * Note that we make the fundamental assumption that the fb->obj
- * cannot be unpinned (and have its GTT offset and fence revoked)
- * without first being decoupled from the scanout and FBC disabled.
- */
- if (dev_priv->fbc.plane == intel_crtc->plane &&
- dev_priv->fbc.fb_id == fb->base.id &&
- dev_priv->fbc.y == crtc->y)
- return;
-
- if (intel_fbc_enabled(dev)) {
- /* We update FBC along two paths, after changing fb/crtc
- * configuration (modeswitching) and after page-flipping
- * finishes. For the latter, we know that not only did
- * we disable the FBC at the start of the page-flip
- * sequence, but also more than one vblank has passed.
- *
- * For the former case of modeswitching, it is possible
- * to switch between two FBC valid configurations
- * instantaneously so we do need to disable the FBC
- * before we can modify its control registers. We also
- * have to wait for the next vblank for that to take
- * effect. However, since we delay enabling FBC we can
- * assume that a vblank has passed since disabling and
- * that we can safely alter the registers in the deferred
- * callback.
- *
- * In the scenario that we go from a valid to invalid
- * and then back to valid FBC configuration we have
- * no strict enforcement that a vblank occurred since
- * disabling the FBC. However, along all current pipe
- * disabling paths we do need to wait for a vblank at
- * some point. And we wait before enabling FBC anyway.
- */
- DRM_DEBUG_KMS("disabling active FBC for update\n");
- intel_disable_fbc(dev);
- }
-
- intel_enable_fbc(crtc);
- dev_priv->fbc.no_fbc_reason = FBC_OK;
- return;
-
-out_disable:
- /* Multiple disables should be harmless */
- if (intel_fbc_enabled(dev)) {
- DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
- intel_disable_fbc(dev);
- }
- i915_gem_stolen_cleanup_compression(dev);
-}
-
static void i915_pineview_get_mem_freq(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1157,7 +538,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
int pixel_size = crtc->primary->fb->bits_per_pixel / 8;
int clock;
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+ adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
clock = adjusted_mode->crtc_clock;
/* Display SR */
@@ -1226,10 +607,10 @@ static bool g4x_compute_wm0(struct drm_device *dev,
return false;
}
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+ adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
clock = adjusted_mode->crtc_clock;
htotal = adjusted_mode->crtc_htotal;
- hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+ hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
pixel_size = crtc->primary->fb->bits_per_pixel / 8;
/* Use the small buffer method to calculate plane watermark */
@@ -1313,10 +694,10 @@ static bool g4x_compute_srwm(struct drm_device *dev,
}
crtc = intel_get_crtc_for_plane(dev, plane);
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+ adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
clock = adjusted_mode->crtc_clock;
htotal = adjusted_mode->crtc_htotal;
- hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+ hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
pixel_size = crtc->primary->fb->bits_per_pixel / 8;
line_time_us = max(htotal * 1000 / clock, 1);
@@ -1347,7 +728,7 @@ static bool vlv_compute_drain_latency(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
int entries;
- int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
+ int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
if (WARN(clock == 0, "Pixel clock is zero!\n"))
return false;
@@ -1677,10 +1058,10 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
/* self-refresh has much higher latency */
static const int sr_latency_ns = 12000;
const struct drm_display_mode *adjusted_mode =
- &to_intel_crtc(crtc)->config.adjusted_mode;
+ &to_intel_crtc(crtc)->config->base.adjusted_mode;
int clock = adjusted_mode->crtc_clock;
int htotal = adjusted_mode->crtc_htotal;
- int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+ int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
int pixel_size = crtc->primary->fb->bits_per_pixel / 8;
unsigned long line_time_us;
int entries;
@@ -1762,7 +1143,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
if (IS_GEN2(dev))
cpp = 4;
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+ adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
wm_info, fifo_size, cpp,
pessimal_latency_ns);
@@ -1784,7 +1165,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
if (IS_GEN2(dev))
cpp = 4;
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+ adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
wm_info, fifo_size, cpp,
pessimal_latency_ns);
@@ -1823,10 +1204,10 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
/* self-refresh has much higher latency */
static const int sr_latency_ns = 6000;
const struct drm_display_mode *adjusted_mode =
- &to_intel_crtc(enabled)->config.adjusted_mode;
+ &to_intel_crtc(enabled)->config->base.adjusted_mode;
int clock = adjusted_mode->crtc_clock;
int htotal = adjusted_mode->crtc_htotal;
- int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w;
+ int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w;
int pixel_size = enabled->primary->fb->bits_per_pixel / 8;
unsigned long line_time_us;
int entries;
@@ -1879,7 +1260,7 @@ static void i845_update_wm(struct drm_crtc *unused_crtc)
if (crtc == NULL)
return;
- adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+ adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
&i845_wm_info,
dev_priv->display.get_fifo_size(dev, 0),
@@ -1898,17 +1279,17 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t pixel_rate;
- pixel_rate = intel_crtc->config.adjusted_mode.crtc_clock;
+ pixel_rate = intel_crtc->config->base.adjusted_mode.crtc_clock;
/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
* adjust the pixel_rate here. */
- if (intel_crtc->config.pch_pfit.enabled) {
+ if (intel_crtc->config->pch_pfit.enabled) {
uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
- uint32_t pfit_size = intel_crtc->config.pch_pfit.size;
+ uint32_t pfit_size = intel_crtc->config->pch_pfit.size;
- pipe_w = intel_crtc->config.pipe_src_w;
- pipe_h = intel_crtc->config.pipe_src_h;
+ pipe_w = intel_crtc->config->pipe_src_w;
+ pipe_h = intel_crtc->config->pipe_src_h;
pfit_w = (pfit_size >> 16) & 0xFFFF;
pfit_h = pfit_size & 0xFFFF;
if (pipe_w < pfit_w)
@@ -2261,7 +1642,7 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
+ struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode;
u32 linetime, ips_linetime;
if (!intel_crtc_active(crtc))
@@ -2521,11 +1902,11 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
return;
p->active = true;
- p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
+ p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8;
p->cur.bytes_per_pixel = 4;
- p->pri.horiz_pixels = intel_crtc->config.pipe_src_w;
+ p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
p->cur.horiz_pixels = intel_crtc->cursor_width;
/* TODO: for now, assume primary and cursor planes are always enabled. */
p->pri.enabled = true;
@@ -3174,10 +2555,10 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
}
-static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
+static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_state *config)
{
/* TODO: Take into account the scalers once we support them */
- return config->adjusted_mode.crtc_clock;
+ return config->base.adjusted_mode.crtc_clock;
}
/*
@@ -3265,8 +2646,8 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
p->active = intel_crtc_active(crtc);
if (p->active) {
- p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
- p->pixel_rate = skl_pipe_pixel_rate(&intel_crtc->config);
+ p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
+ p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
/*
* For now, assume primary and cursor planes are always enabled.
@@ -3274,8 +2655,8 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
p->plane[0].enabled = true;
p->plane[0].bytes_per_pixel =
crtc->primary->fb->bits_per_pixel / 8;
- p->plane[0].horiz_pixels = intel_crtc->config.pipe_src_w;
- p->plane[0].vert_pixels = intel_crtc->config.pipe_src_h;
+ p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
+ p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
p->cursor.enabled = true;
p->cursor.bytes_per_pixel = 4;
@@ -3286,7 +2667,8 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
struct intel_plane *intel_plane = to_intel_plane(plane);
- if (intel_plane->pipe == pipe)
+ if (intel_plane->pipe == pipe &&
+ plane->type == DRM_PLANE_TYPE_OVERLAY)
p->plane[i++] = intel_plane->wm;
}
}
@@ -3621,9 +3003,8 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
skl_ddb_entry_size(&cur_ddb->pipe[pipe])) {
skl_wm_flush_pipe(dev_priv, pipe, 2);
intel_wait_for_vblank(dev, pipe);
+ reallocated[pipe] = true;
}
-
- reallocated[pipe] = true;
}
/*
@@ -4418,8 +3799,8 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
- /* Latest VLV doesn't need to force the gfx clock */
- if (dev->pdev->revision >= 0xd) {
+ /* CHV and latest VLV don't need to force the gfx clock */
+ if (IS_CHERRYVIEW(dev) || dev->pdev->revision >= 0xd) {
valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
return;
}
@@ -4458,9 +3839,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
mutex_lock(&dev_priv->rps.hw_lock);
if (dev_priv->rps.enabled) {
- if (IS_CHERRYVIEW(dev))
- valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
- else if (IS_VALLEYVIEW(dev))
+ if (IS_VALLEYVIEW(dev))
vlv_set_rps_idle(dev_priv);
else
gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
@@ -4502,7 +3881,7 @@ void valleyview_set_rps(struct drm_device *dev, u8 val)
I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
dev_priv->rps.cur_freq = val;
- trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv, val));
+ trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
}
static void gen9_disable_rps(struct drm_device *dev)
@@ -4510,6 +3889,7 @@ static void gen9_disable_rps(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(GEN6_RC_CONTROL, 0);
+ I915_WRITE(GEN9_PG_ENABLE, 0);
}
static void gen6_disable_rps(struct drm_device *dev)
@@ -4533,11 +3913,11 @@ static void valleyview_disable_rps(struct drm_device *dev)
/* we're doing forcewake before Disabling RC6,
* This what the BIOS expects when going into suspend */
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
I915_WRITE(GEN6_RC_CONTROL, 0);
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
@@ -4625,7 +4005,10 @@ static void gen6_init_rps_frequencies(struct drm_device *dev)
&ddcc_status);
if (0 == ret)
dev_priv->rps.efficient_freq =
- (ddcc_status >> 8) & 0xff;
+ clamp_t(u8,
+ ((ddcc_status >> 8) & 0xff),
+ dev_priv->rps.min_freq,
+ dev_priv->rps.max_freq);
}
/* Preserve min/max settings in case of re-init */
@@ -4643,9 +4026,39 @@ static void gen6_init_rps_frequencies(struct drm_device *dev)
}
}
+/* See the Gen9_GT_PM_Programming_Guide doc for the below */
static void gen9_enable_rps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+ gen6_init_rps_frequencies(dev);
+
+ I915_WRITE(GEN6_RPNSWREQ, 0xc800000);
+ I915_WRITE(GEN6_RC_VIDEO_FREQ, 0xc800000);
+
+ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 0xf4240);
+ I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, 0x12060000);
+ I915_WRITE(GEN6_RP_UP_THRESHOLD, 0xe808);
+ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 0x3bd08);
+ I915_WRITE(GEN6_RP_UP_EI, 0x101d0);
+ I915_WRITE(GEN6_RP_DOWN_EI, 0x55730);
+ I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 0xa);
+ I915_WRITE(GEN6_PMINTRMSK, 0x6);
+ I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_TURBO |
+ GEN6_RP_MEDIA_HW_MODE | GEN6_RP_MEDIA_IS_GFX |
+ GEN6_RP_ENABLE | GEN6_RP_UP_BUSY_AVG |
+ GEN6_RP_DOWN_IDLE_AVG);
+
+ gen6_enable_rps_interrupts(dev);
+
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+}
+
+static void gen9_enable_rc6(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring;
uint32_t rc6_mask = 0;
int unused;
@@ -4655,7 +4068,7 @@ static void gen9_enable_rps(struct drm_device *dev)
/* 1b: Get forcewake during program sequence. Although the driver
* hasn't enabled a state yet where we need forcewake, BIOS may have.*/
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
/* 2a: Disable RC states. */
I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -4669,6 +4082,10 @@ static void gen9_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RC_SLEEP, 0);
I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
+ /* 2c: Program Coarse Power Gating Policies. */
+ I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 25);
+ I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 25);
+
/* 3a: Enable RC6 */
if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
@@ -4678,7 +4095,10 @@ static void gen9_enable_rps(struct drm_device *dev)
GEN6_RC_CTL_EI_MODE(1) |
rc6_mask);
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ /* 3b: Enable Coarse Power Gating only when RC6 is enabled */
+ I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? 3 : 0);
+
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
@@ -4694,7 +4114,7 @@ static void gen8_enable_rps(struct drm_device *dev)
/* 1c & 1d: Get forcewake during program sequence. Although the driver
* hasn't enabled a state yet where we need forcewake, BIOS may have.*/
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
/* 2a: Disable RC states. */
I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -4761,7 +4181,7 @@ static void gen8_enable_rps(struct drm_device *dev)
dev_priv->rps.power = HIGH_POWER; /* force a reset */
gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
static void gen6_enable_rps(struct drm_device *dev)
@@ -4789,7 +4209,7 @@ static void gen6_enable_rps(struct drm_device *dev)
I915_WRITE(GTFIFODBG, gtfifodbg);
}
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
/* Initialize rps frequencies */
gen6_init_rps_frequencies(dev);
@@ -4869,7 +4289,7 @@ static void gen6_enable_rps(struct drm_device *dev)
DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
}
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
static void __gen6_update_ring_freq(struct drm_device *dev)
@@ -4956,11 +4376,35 @@ void gen6_update_ring_freq(struct drm_device *dev)
static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)
{
+ struct drm_device *dev = dev_priv->dev;
u32 val, rp0;
- val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG);
- rp0 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & PUNIT_GPU_STATUS_MAX_FREQ_MASK;
+ if (dev->pdev->revision >= 0x20) {
+ val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
+ switch (INTEL_INFO(dev)->eu_total) {
+ case 8:
+ /* (2 * 4) config */
+ rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT);
+ break;
+ case 12:
+ /* (2 * 6) config */
+ rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT);
+ break;
+ case 16:
+ /* (2 * 8) config */
+ default:
+ /* Setting (2 * 8) Min RP0 for any other combination */
+ rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT);
+ break;
+ }
+ rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK);
+ } else {
+ /* For pre-production hardware */
+ val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG);
+ rp0 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) &
+ PUNIT_GPU_STATUS_MAX_FREQ_MASK;
+ }
return rp0;
}
@@ -4976,20 +4420,36 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv)
static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv)
{
+ struct drm_device *dev = dev_priv->dev;
u32 val, rp1;
- val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
- rp1 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & PUNIT_GPU_STATUS_MAX_FREQ_MASK;
-
+ if (dev->pdev->revision >= 0x20) {
+ val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
+ rp1 = (val & FB_GFX_FREQ_FUSE_MASK);
+ } else {
+ /* For pre-production hardware */
+ val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+ rp1 = ((val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) &
+ PUNIT_GPU_STATUS_MAX_FREQ_MASK);
+ }
return rp1;
}
static int cherryview_rps_min_freq(struct drm_i915_private *dev_priv)
{
+ struct drm_device *dev = dev_priv->dev;
u32 val, rpn;
- val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG);
- rpn = (val >> PUNIT_GPU_STATIS_GFX_MIN_FREQ_SHIFT) & PUNIT_GPU_STATUS_GFX_MIN_FREQ_MASK;
+ if (dev->pdev->revision >= 0x20) {
+ val = vlv_punit_read(dev_priv, FB_GFX_FMIN_AT_VMIN_FUSE);
+ rpn = ((val >> FB_GFX_FMIN_AT_VMIN_FUSE_SHIFT) &
+ FB_GFX_FREQ_FUSE_MASK);
+ } else { /* For pre-production hardware */
+ val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG);
+ rpn = ((val >> PUNIT_GPU_STATIS_GFX_MIN_FREQ_SHIFT) &
+ PUNIT_GPU_STATUS_GFX_MIN_FREQ_MASK);
+ }
+
return rpn;
}
@@ -5160,22 +4620,22 @@ static void valleyview_init_gt_powersave(struct drm_device *dev)
dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv);
dev_priv->rps.rp0_freq = dev_priv->rps.max_freq;
DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.max_freq),
dev_priv->rps.max_freq);
dev_priv->rps.efficient_freq = valleyview_rps_rpe_freq(dev_priv);
DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
dev_priv->rps.efficient_freq);
dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv);
DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
dev_priv->rps.rp1_freq);
dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv);
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
dev_priv->rps.min_freq);
/* Preserve min/max settings in case of re-init */
@@ -5229,22 +4689,22 @@ static void cherryview_init_gt_powersave(struct drm_device *dev)
dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv);
dev_priv->rps.rp0_freq = dev_priv->rps.max_freq;
DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.max_freq),
dev_priv->rps.max_freq);
dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv);
DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
dev_priv->rps.efficient_freq);
dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv);
DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
dev_priv->rps.rp1_freq);
dev_priv->rps.min_freq = cherryview_rps_min_freq(dev_priv);
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.min_freq),
dev_priv->rps.min_freq);
WARN_ONCE((dev_priv->rps.max_freq |
@@ -5288,7 +4748,10 @@ static void cherryview_enable_rps(struct drm_device *dev)
/* 1a & 1b: Get forcewake during program sequence. Although the driver
* hasn't enabled a state yet where we need forcewake, BIOS may have.*/
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+ /* Disable RC states. */
+ I915_WRITE(GEN6_RC_CONTROL, 0);
/* 2a: Program RC6 thresholds.*/
I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
@@ -5299,7 +4762,8 @@ static void cherryview_enable_rps(struct drm_device *dev)
I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
I915_WRITE(GEN6_RC_SLEEP, 0);
- I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
+ /* TO threshold set to 1750 us ( 0x557 * 1.28 us) */
+ I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
/* allows RC6 residency counter to work */
I915_WRITE(VLV_COUNTER_CONTROL,
@@ -5313,11 +4777,12 @@ static void cherryview_enable_rps(struct drm_device *dev)
/* 3: Enable RC6 */
if ((intel_enable_rc6(dev) & INTEL_RC6_ENABLE) &&
(pcbr >> VLV_PCBR_ADDR_SHIFT))
- rc6_mode = GEN6_RC_CTL_EI_MODE(1);
+ rc6_mode = GEN7_RC_CTL_TO_MODE;
I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
/* 4 Program defaults and thresholds for RPS*/
+ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
I915_WRITE(GEN6_RP_UP_EI, 66000);
@@ -5325,14 +4790,10 @@ static void cherryview_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
- /* WaDisablePwrmtrEvent:chv (pre-production hw) */
- I915_WRITE(0xA80C, I915_READ(0xA80C) & 0x00ffffff);
- I915_WRITE(0xA810, I915_READ(0xA810) & 0xffffff00);
-
/* 5: Enable RPS */
I915_WRITE(GEN6_RP_CONTROL,
GEN6_RP_MEDIA_HW_NORMAL_MODE |
- GEN6_RP_MEDIA_IS_GFX | /* WaSetMaskForGfxBusyness:chv (pre-production hw ?) */
+ GEN6_RP_MEDIA_IS_GFX |
GEN6_RP_ENABLE |
GEN6_RP_UP_BUSY_AVG |
GEN6_RP_DOWN_IDLE_AVG);
@@ -5347,16 +4808,16 @@ static void cherryview_enable_rps(struct drm_device *dev)
dev_priv->rps.cur_freq = (val >> 8) & 0xff;
DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
dev_priv->rps.cur_freq);
DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
dev_priv->rps.efficient_freq);
valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
static void valleyview_enable_rps(struct drm_device *dev)
@@ -5377,15 +4838,18 @@ static void valleyview_enable_rps(struct drm_device *dev)
}
/* If VLV, Forcewake all wells, else re-direct to regular path */
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+ /* Disable RC states. */
+ I915_WRITE(GEN6_RC_CONTROL, 0);
+
+ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
I915_WRITE(GEN6_RP_UP_EI, 66000);
I915_WRITE(GEN6_RP_DOWN_EI, 350000);
I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
- I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 0xf4240);
I915_WRITE(GEN6_RP_CONTROL,
GEN6_RP_MEDIA_TURBO |
@@ -5428,16 +4892,16 @@ static void valleyview_enable_rps(struct drm_device *dev)
dev_priv->rps.cur_freq = (val >> 8) & 0xff;
DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
dev_priv->rps.cur_freq);
DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
- vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+ intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
dev_priv->rps.efficient_freq);
valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
void ironlake_teardown_rc6(struct drm_device *dev)
@@ -5673,146 +5137,27 @@ unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
return ((m * x) / 127) - b;
}
-static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
+static int _pxvid_to_vd(u8 pxvid)
+{
+ if (pxvid == 0)
+ return 0;
+
+ if (pxvid >= 8 && pxvid < 31)
+ pxvid = 31;
+
+ return (pxvid + 2) * 125;
+}
+
+static u32 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
{
struct drm_device *dev = dev_priv->dev;
- static const struct v_table {
- u16 vd; /* in .1 mil */
- u16 vm; /* in .1 mil */
- } v_table[] = {
- { 0, 0, },
- { 375, 0, },
- { 500, 0, },
- { 625, 0, },
- { 750, 0, },
- { 875, 0, },
- { 1000, 0, },
- { 1125, 0, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4125, 3000, },
- { 4250, 3125, },
- { 4375, 3250, },
- { 4500, 3375, },
- { 4625, 3500, },
- { 4750, 3625, },
- { 4875, 3750, },
- { 5000, 3875, },
- { 5125, 4000, },
- { 5250, 4125, },
- { 5375, 4250, },
- { 5500, 4375, },
- { 5625, 4500, },
- { 5750, 4625, },
- { 5875, 4750, },
- { 6000, 4875, },
- { 6125, 5000, },
- { 6250, 5125, },
- { 6375, 5250, },
- { 6500, 5375, },
- { 6625, 5500, },
- { 6750, 5625, },
- { 6875, 5750, },
- { 7000, 5875, },
- { 7125, 6000, },
- { 7250, 6125, },
- { 7375, 6250, },
- { 7500, 6375, },
- { 7625, 6500, },
- { 7750, 6625, },
- { 7875, 6750, },
- { 8000, 6875, },
- { 8125, 7000, },
- { 8250, 7125, },
- { 8375, 7250, },
- { 8500, 7375, },
- { 8625, 7500, },
- { 8750, 7625, },
- { 8875, 7750, },
- { 9000, 7875, },
- { 9125, 8000, },
- { 9250, 8125, },
- { 9375, 8250, },
- { 9500, 8375, },
- { 9625, 8500, },
- { 9750, 8625, },
- { 9875, 8750, },
- { 10000, 8875, },
- { 10125, 9000, },
- { 10250, 9125, },
- { 10375, 9250, },
- { 10500, 9375, },
- { 10625, 9500, },
- { 10750, 9625, },
- { 10875, 9750, },
- { 11000, 9875, },
- { 11125, 10000, },
- { 11250, 10125, },
- { 11375, 10250, },
- { 11500, 10375, },
- { 11625, 10500, },
- { 11750, 10625, },
- { 11875, 10750, },
- { 12000, 10875, },
- { 12125, 11000, },
- { 12250, 11125, },
- { 12375, 11250, },
- { 12500, 11375, },
- { 12625, 11500, },
- { 12750, 11625, },
- { 12875, 11750, },
- { 13000, 11875, },
- { 13125, 12000, },
- { 13250, 12125, },
- { 13375, 12250, },
- { 13500, 12375, },
- { 13625, 12500, },
- { 13750, 12625, },
- { 13875, 12750, },
- { 14000, 12875, },
- { 14125, 13000, },
- { 14250, 13125, },
- { 14375, 13250, },
- { 14500, 13375, },
- { 14625, 13500, },
- { 14750, 13625, },
- { 14875, 13750, },
- { 15000, 13875, },
- { 15125, 14000, },
- { 15250, 14125, },
- { 15375, 14250, },
- { 15500, 14375, },
- { 15625, 14500, },
- { 15750, 14625, },
- { 15875, 14750, },
- { 16000, 14875, },
- { 16125, 15000, },
- };
+ const int vd = _pxvid_to_vd(pxvid);
+ const int vm = vd - 1125;
+
if (INTEL_INFO(dev)->is_mobile)
- return v_table[pxvid].vm;
- else
- return v_table[pxvid].vd;
+ return vm > 0 ? vm : 0;
+
+ return vd;
}
static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
@@ -6264,7 +5609,9 @@ static void intel_gen6_powersave_work(struct work_struct *work)
} else if (IS_VALLEYVIEW(dev)) {
valleyview_enable_rps(dev);
} else if (INTEL_INFO(dev)->gen >= 9) {
+ gen9_enable_rc6(dev);
gen9_enable_rps(dev);
+ __gen6_update_ring_freq(dev);
} else if (IS_BROADWELL(dev)) {
gen8_enable_rps(dev);
__gen6_update_ring_freq(dev);
@@ -6710,6 +6057,10 @@ static void haswell_init_clock_gating(struct drm_device *dev)
I915_WRITE(GEN7_GT_MODE,
_MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
+ /* WaSampleCChickenBitEnable:hsw */
+ I915_WRITE(HALF_SLICE_CHICKEN3,
+ _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE));
+
/* WaSwitchSolVfFArbitrationPriority:hsw */
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
@@ -6880,6 +6231,17 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
_MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
/*
+ * BSpec recommends 8x4 when MSAA is used,
+ * however in practice 16x4 seems fastest.
+ *
+ * Note that PS/WM thread counts depend on the WIZ hashing
+ * disable bit, which we don't touch here, but it's good
+ * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+ */
+ I915_WRITE(GEN7_GT_MODE,
+ _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
+
+ /*
* WaIncreaseL3CreditsForVLVB0:vlv
* This is the hardware default actually.
*/
@@ -7043,43 +6405,12 @@ void intel_suspend_hw(struct drm_device *dev)
lpt_suspend_hw(dev);
}
-static void intel_init_fbc(struct drm_i915_private *dev_priv)
-{
- if (!HAS_FBC(dev_priv)) {
- dev_priv->fbc.enabled = false;
- return;
- }
-
- if (INTEL_INFO(dev_priv)->gen >= 7) {
- dev_priv->display.fbc_enabled = ironlake_fbc_enabled;
- dev_priv->display.enable_fbc = gen7_enable_fbc;
- dev_priv->display.disable_fbc = ironlake_disable_fbc;
- } else if (INTEL_INFO(dev_priv)->gen >= 5) {
- dev_priv->display.fbc_enabled = ironlake_fbc_enabled;
- dev_priv->display.enable_fbc = ironlake_enable_fbc;
- dev_priv->display.disable_fbc = ironlake_disable_fbc;
- } else if (IS_GM45(dev_priv)) {
- dev_priv->display.fbc_enabled = g4x_fbc_enabled;
- dev_priv->display.enable_fbc = g4x_enable_fbc;
- dev_priv->display.disable_fbc = g4x_disable_fbc;
- } else {
- dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
- dev_priv->display.enable_fbc = i8xx_enable_fbc;
- dev_priv->display.disable_fbc = i8xx_disable_fbc;
-
- /* This value was pulled out of someone's hat */
- I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
- }
-
- dev_priv->fbc.enabled = dev_priv->display.fbc_enabled(dev_priv->dev);
-}
-
/* Set up chip specific power management-related functions */
void intel_init_pm(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- intel_init_fbc(dev_priv);
+ intel_fbc_init(dev_priv);
/* For cxsr */
if (IS_PINEVIEW(dev))
@@ -7285,28 +6616,24 @@ static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2;
}
-int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
+int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
- int ret = -1;
-
if (IS_CHERRYVIEW(dev_priv->dev))
- ret = chv_gpu_freq(dev_priv, val);
+ return chv_gpu_freq(dev_priv, val);
else if (IS_VALLEYVIEW(dev_priv->dev))
- ret = byt_gpu_freq(dev_priv, val);
-
- return ret;
+ return byt_gpu_freq(dev_priv, val);
+ else
+ return val * GT_FREQUENCY_MULTIPLIER;
}
-int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
+int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
- int ret = -1;
-
if (IS_CHERRYVIEW(dev_priv->dev))
- ret = chv_freq_opcode(dev_priv, val);
+ return chv_freq_opcode(dev_priv, val);
else if (IS_VALLEYVIEW(dev_priv->dev))
- ret = byt_freq_opcode(dev_priv, val);
-
- return ret;
+ return byt_freq_opcode(dev_priv, val);
+ else
+ return val / GT_FREQUENCY_MULTIPLIER;
}
void intel_pm_setup(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 716b8a961eea..b9f40c2e0af7 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -61,14 +61,15 @@ static bool is_edp_psr(struct intel_dp *intel_dp)
return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
}
-bool intel_psr_is_enabled(struct drm_device *dev)
+static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t val;
- if (!HAS_PSR(dev))
- return false;
-
- return I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE;
+ val = I915_READ(VLV_PSRSTAT(pipe)) &
+ VLV_EDP_PSR_CURR_STATE_MASK;
+ return (val == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
+ (val == VLV_EDP_PSR_ACTIVE_SF_UPDATE);
}
static void intel_psr_write_vsc(struct intel_dp *intel_dp,
@@ -78,8 +79,8 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp,
struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
- u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder);
- u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder);
+ u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config->cpu_transcoder);
+ u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config->cpu_transcoder);
uint32_t *data = (uint32_t *) vsc_psr;
unsigned int i;
@@ -100,7 +101,23 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp,
POSTING_READ(ctl_reg);
}
-static void intel_psr_setup_vsc(struct intel_dp *intel_dp)
+static void vlv_psr_setup_vsc(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ uint32_t val;
+
+ /* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
+ val = I915_READ(VLV_VSCSDP(pipe));
+ val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
+ val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
+ I915_WRITE(VLV_VSCSDP(pipe), val);
+}
+
+static void hsw_psr_setup_vsc(struct intel_dp *intel_dp)
{
struct edp_vsc_psr psr_vsc;
@@ -113,14 +130,20 @@ static void intel_psr_setup_vsc(struct intel_dp *intel_dp)
intel_psr_write_vsc(intel_dp, &psr_vsc);
}
-static void intel_psr_enable_sink(struct intel_dp *intel_dp)
+static void vlv_psr_enable_sink(struct intel_dp *intel_dp)
+{
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
+ DP_PSR_ENABLE);
+}
+
+static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t aux_clock_divider;
+ uint32_t aux_data_reg, aux_ctl_reg;
int precharge = 0x3;
- bool only_standby = false;
static const uint8_t aux_msg[] = {
[0] = DP_AUX_NATIVE_WRITE << 4,
[1] = DP_SET_POWER >> 8,
@@ -134,49 +157,96 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
- if (IS_BROADWELL(dev) && dig_port->port != PORT_A)
- only_standby = true;
-
/* Enable PSR in sink */
- if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby)
+ if (dev_priv->psr.link_standby)
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
- DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE);
+ DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
else
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
- DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
+ DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE);
+
+ aux_data_reg = (INTEL_INFO(dev)->gen >= 9) ?
+ DPA_AUX_CH_DATA1 : EDP_PSR_AUX_DATA1(dev);
+ aux_ctl_reg = (INTEL_INFO(dev)->gen >= 9) ?
+ DPA_AUX_CH_CTL : EDP_PSR_AUX_CTL(dev);
/* Setup AUX registers */
for (i = 0; i < sizeof(aux_msg); i += 4)
- I915_WRITE(EDP_PSR_AUX_DATA1(dev) + i,
+ I915_WRITE(aux_data_reg + i,
intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
- I915_WRITE(EDP_PSR_AUX_CTL(dev),
+ if (INTEL_INFO(dev)->gen >= 9) {
+ uint32_t val;
+
+ val = I915_READ(aux_ctl_reg);
+ val &= ~DP_AUX_CH_CTL_TIME_OUT_MASK;
+ val |= DP_AUX_CH_CTL_TIME_OUT_1600us;
+ val &= ~DP_AUX_CH_CTL_MESSAGE_SIZE_MASK;
+ val |= (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
+ /* Use hardcoded data values for PSR */
+ val &= ~DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL;
+ I915_WRITE(aux_ctl_reg, val);
+ } else {
+ I915_WRITE(aux_ctl_reg,
DP_AUX_CH_CTL_TIME_OUT_400us |
(sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
(precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
(aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT));
+ }
}
-static void intel_psr_enable_source(struct intel_dp *intel_dp)
+static void vlv_psr_enable_source(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = dig_port->base.base.crtc;
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+
+ /* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */
+ I915_WRITE(VLV_PSRCTL(pipe),
+ VLV_EDP_PSR_MODE_SW_TIMER |
+ VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
+ VLV_EDP_PSR_ENABLE);
+}
+
+static void vlv_psr_activate(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = dig_port->base.base.crtc;
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+
+ /* Let's do the transition from PSR_state 1 to PSR_state 2
+ * that is PSR transition to active - static frame transmission.
+ * Then Hardware is responsible for the transition to PSR_state 3
+ * that is PSR active - no Remote Frame Buffer (RFB) update.
+ */
+ I915_WRITE(VLV_PSRCTL(pipe), I915_READ(VLV_PSRCTL(pipe)) |
+ VLV_EDP_PSR_ACTIVE_ENTRY);
+}
+
+static void hsw_psr_enable_source(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t max_sleep_time = 0x1f;
- uint32_t idle_frames = 1;
+ /* Lately it was identified that depending on panel idle frame count
+ * calculated at HW can be off by 1. So let's use what came
+ * from VBT + 1 and at minimum 2 to be on the safe side.
+ */
+ uint32_t idle_frames = dev_priv->vbt.psr.idle_frames ?
+ dev_priv->vbt.psr.idle_frames + 1 : 2;
uint32_t val = 0x0;
const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
- bool only_standby = false;
-
- if (IS_BROADWELL(dev) && dig_port->port != PORT_A)
- only_standby = true;
- if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby) {
+ if (dev_priv->psr.link_standby) {
val |= EDP_PSR_LINK_STANDBY;
val |= EDP_PSR_TP2_TP3_TIME_0us;
val |= EDP_PSR_TP1_TIME_0us;
val |= EDP_PSR_SKIP_AUX_EXIT;
- val |= IS_BROADWELL(dev) ? BDW_PSR_SINGLE_FRAME : 0;
} else
val |= EDP_PSR_LINK_DISABLE;
@@ -211,27 +281,24 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
return false;
}
- /* Below limitations aren't valid for Broadwell */
- if (IS_BROADWELL(dev))
- goto out;
-
- if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) &
- S3D_ENABLE) {
+ if (IS_HASWELL(dev) &&
+ I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config->cpu_transcoder)) &
+ S3D_ENABLE) {
DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
return false;
}
- if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+ if (IS_HASWELL(dev) &&
+ intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
return false;
}
- out:
dev_priv->psr.source_ok = true;
return true;
}
-static void intel_psr_do_enable(struct intel_dp *intel_dp)
+static void intel_psr_activate(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -242,7 +309,14 @@ static void intel_psr_do_enable(struct intel_dp *intel_dp)
lockdep_assert_held(&dev_priv->psr.lock);
/* Enable/Re-enable PSR on the host */
- intel_psr_enable_source(intel_dp);
+ if (HAS_DDI(dev))
+ /* On HSW+ after we enable PSR on source it will activate it
+ * as soon as it match configure idle_frame count. So
+ * we just actually enable it here on activation time.
+ */
+ hsw_psr_enable_source(intel_dp);
+ else
+ vlv_psr_activate(intel_dp);
dev_priv->psr.active = true;
}
@@ -278,39 +352,79 @@ void intel_psr_enable(struct intel_dp *intel_dp)
if (!intel_psr_match_conditions(intel_dp))
goto unlock;
+ /* First we check VBT, but we must respect sink and source
+ * known restrictions */
+ dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link;
+ if ((intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) ||
+ (IS_BROADWELL(dev) && intel_dig_port->port != PORT_A))
+ dev_priv->psr.link_standby = true;
+
dev_priv->psr.busy_frontbuffer_bits = 0;
- intel_psr_setup_vsc(intel_dp);
+ if (HAS_DDI(dev)) {
+ hsw_psr_setup_vsc(intel_dp);
+
+ /* Avoid continuous PSR exit by masking memup and hpd */
+ I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP |
+ EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
- /* Avoid continuous PSR exit by masking memup and hpd */
- I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP |
- EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
+ /* Enable PSR on the panel */
+ hsw_psr_enable_sink(intel_dp);
- /* Enable PSR on the panel */
- intel_psr_enable_sink(intel_dp);
+ if (INTEL_INFO(dev)->gen >= 9)
+ intel_psr_activate(intel_dp);
+ } else {
+ vlv_psr_setup_vsc(intel_dp);
+
+ /* Enable PSR on the panel */
+ vlv_psr_enable_sink(intel_dp);
+
+ /* On HSW+ enable_source also means go to PSR entry/active
+ * state as soon as idle_frame achieved and here would be
+ * to soon. However on VLV enable_source just enable PSR
+ * but let it on inactive state. So we might do this prior
+ * to active transition, i.e. here.
+ */
+ vlv_psr_enable_source(intel_dp);
+ }
dev_priv->psr.enabled = intel_dp;
unlock:
mutex_unlock(&dev_priv->psr.lock);
}
-/**
- * intel_psr_disable - Disable PSR
- * @intel_dp: Intel DP
- *
- * This function needs to be called before disabling pipe.
- */
-void intel_psr_disable(struct intel_dp *intel_dp)
+static void vlv_psr_disable(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc =
+ to_intel_crtc(intel_dig_port->base.base.crtc);
+ uint32_t val;
- mutex_lock(&dev_priv->psr.lock);
- if (!dev_priv->psr.enabled) {
- mutex_unlock(&dev_priv->psr.lock);
- return;
+ if (dev_priv->psr.active) {
+ /* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */
+ if (wait_for((I915_READ(VLV_PSRSTAT(intel_crtc->pipe)) &
+ VLV_EDP_PSR_IN_TRANS) == 0, 1))
+ WARN(1, "PSR transition took longer than expected\n");
+
+ val = I915_READ(VLV_PSRCTL(intel_crtc->pipe));
+ val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
+ val &= ~VLV_EDP_PSR_ENABLE;
+ val &= ~VLV_EDP_PSR_MODE_MASK;
+ I915_WRITE(VLV_PSRCTL(intel_crtc->pipe), val);
+
+ dev_priv->psr.active = false;
+ } else {
+ WARN_ON(vlv_is_psr_active_on_pipe(dev, intel_crtc->pipe));
}
+}
+
+static void hsw_psr_disable(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
if (dev_priv->psr.active) {
I915_WRITE(EDP_PSR_CTL(dev),
@@ -325,6 +439,30 @@ void intel_psr_disable(struct intel_dp *intel_dp)
} else {
WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE);
}
+}
+
+/**
+ * intel_psr_disable - Disable PSR
+ * @intel_dp: Intel DP
+ *
+ * This function needs to be called before disabling pipe.
+ */
+void intel_psr_disable(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev_priv->psr.lock);
+ if (!dev_priv->psr.enabled) {
+ mutex_unlock(&dev_priv->psr.lock);
+ return;
+ }
+
+ if (HAS_DDI(dev))
+ hsw_psr_disable(intel_dp);
+ else
+ vlv_psr_disable(intel_dp);
dev_priv->psr.enabled = NULL;
mutex_unlock(&dev_priv->psr.lock);
@@ -337,18 +475,27 @@ static void intel_psr_work(struct work_struct *work)
struct drm_i915_private *dev_priv =
container_of(work, typeof(*dev_priv), psr.work.work);
struct intel_dp *intel_dp = dev_priv->psr.enabled;
+ struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
/* We have to make sure PSR is ready for re-enable
* otherwise it keeps disabled until next full enable/disable cycle.
* PSR might take some time to get fully disabled
* and be ready for re-enable.
*/
- if (wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev_priv->dev)) &
- EDP_PSR_STATUS_STATE_MASK) == 0, 50)) {
- DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
- return;
+ if (HAS_DDI(dev_priv->dev)) {
+ if (wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev_priv->dev)) &
+ EDP_PSR_STATUS_STATE_MASK) == 0, 50)) {
+ DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
+ return;
+ }
+ } else {
+ if (wait_for((I915_READ(VLV_PSRSTAT(pipe)) &
+ VLV_EDP_PSR_IN_TRANS) == 0, 1)) {
+ DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
+ return;
+ }
}
-
mutex_lock(&dev_priv->psr.lock);
intel_dp = dev_priv->psr.enabled;
@@ -363,7 +510,7 @@ static void intel_psr_work(struct work_struct *work)
if (dev_priv->psr.busy_frontbuffer_bits)
goto unlock;
- intel_psr_do_enable(intel_dp);
+ intel_psr_activate(intel_dp);
unlock:
mutex_unlock(&dev_priv->psr.lock);
}
@@ -371,17 +518,47 @@ unlock:
static void intel_psr_exit(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp *intel_dp = dev_priv->psr.enabled;
+ struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ u32 val;
- if (dev_priv->psr.active) {
- u32 val = I915_READ(EDP_PSR_CTL(dev));
+ if (!dev_priv->psr.active)
+ return;
+
+ if (HAS_DDI(dev)) {
+ val = I915_READ(EDP_PSR_CTL(dev));
WARN_ON(!(val & EDP_PSR_ENABLE));
I915_WRITE(EDP_PSR_CTL(dev), val & ~EDP_PSR_ENABLE);
dev_priv->psr.active = false;
+ } else {
+ val = I915_READ(VLV_PSRCTL(pipe));
+
+ /* Here we do the transition from PSR_state 3 to PSR_state 5
+ * directly once PSR State 4 that is active with single frame
+ * update can be skipped. PSR_state 5 that is PSR exit then
+ * Hardware is responsible to transition back to PSR_state 1
+ * that is PSR inactive. Same state after
+ * vlv_edp_psr_enable_source.
+ */
+ val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
+ I915_WRITE(VLV_PSRCTL(pipe), val);
+
+ /* Send AUX wake up - Spec says after transitioning to PSR
+ * active we have to send AUX wake up by writing 01h in DPCD
+ * 600h of sink device.
+ * XXX: This might slow down the transition, but without this
+ * HW doesn't complete the transition to PSR_state 1 and we
+ * never get the screen updated.
+ */
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
+ DP_SET_POWER_D0);
}
+ dev_priv->psr.active = false;
}
/**
@@ -459,6 +636,15 @@ void intel_psr_flush(struct drm_device *dev,
(frontbuffer_bits & INTEL_FRONTBUFFER_SPRITE(pipe)))
intel_psr_exit(dev);
+ /*
+ * On Valleyview and Cherryview we don't use hardware tracking so
+ * any plane updates or cursor moves don't result in a PSR
+ * invalidating. Which means we need to manually fake this in
+ * software for all flushes, not just when we've seen a preceding
+ * invalidation through frontbuffer rendering. */
+ if (!HAS_DDI(dev))
+ intel_psr_exit(dev);
+
if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
schedule_delayed_work(&dev_priv->psr.work,
msecs_to_jiffies(100));
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen6.c b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
index 56c1429d8a60..11c8e7b3dd7c 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen6.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
@@ -1,3 +1,28 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
#include "intel_renderstate.h"
static const u32 gen6_null_state_relocs[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.c b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
index 419e35a7b0ff..655180646152 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen7.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
@@ -1,3 +1,28 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
#include "intel_renderstate.h"
static const u32 gen7_null_state_relocs[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
index 78011d73fa9f..95288a34c15d 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
@@ -1,3 +1,28 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
#include "intel_renderstate.h"
static const u32 gen8_null_state_relocs[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen9.c b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
index 875075373807..16a7ec273bd9 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen9.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
@@ -1,3 +1,28 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ */
+
#include "intel_renderstate.h"
static const u32 gen9_null_state_relocs[] = {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index c7bc93d28d84..e5b3c6dbd467 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -52,16 +52,27 @@ intel_ring_initialized(struct intel_engine_cs *ring)
int __intel_ring_space(int head, int tail, int size)
{
- int space = head - (tail + I915_RING_FREE_SPACE);
- if (space < 0)
+ int space = head - tail;
+ if (space <= 0)
space += size;
- return space;
+ return space - I915_RING_FREE_SPACE;
+}
+
+void intel_ring_update_space(struct intel_ringbuffer *ringbuf)
+{
+ if (ringbuf->last_retired_head != -1) {
+ ringbuf->head = ringbuf->last_retired_head;
+ ringbuf->last_retired_head = -1;
+ }
+
+ ringbuf->space = __intel_ring_space(ringbuf->head & HEAD_ADDR,
+ ringbuf->tail, ringbuf->size);
}
int intel_ring_space(struct intel_ringbuffer *ringbuf)
{
- return __intel_ring_space(ringbuf->head & HEAD_ADDR,
- ringbuf->tail, ringbuf->size);
+ intel_ring_update_space(ringbuf);
+ return ringbuf->space;
}
bool intel_ring_stopped(struct intel_engine_cs *ring)
@@ -528,7 +539,7 @@ static int init_ring_common(struct intel_engine_cs *ring)
struct drm_i915_gem_object *obj = ringbuf->obj;
int ret = 0;
- gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
if (!stop_ring(ring)) {
/* G45 ring initialization often fails to reset head to zero */
@@ -592,15 +603,15 @@ static int init_ring_common(struct intel_engine_cs *ring)
goto out;
}
+ ringbuf->last_retired_head = -1;
ringbuf->head = I915_READ_HEAD(ring);
ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
- ringbuf->space = intel_ring_space(ringbuf);
- ringbuf->last_retired_head = -1;
+ intel_ring_update_space(ringbuf);
memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
out:
- gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
return ret;
}
@@ -627,8 +638,7 @@ intel_init_pipe_control(struct intel_engine_cs *ring)
{
int ret;
- if (ring->scratch.obj)
- return 0;
+ WARN_ON(ring->scratch.obj);
ring->scratch.obj = i915_gem_alloc_object(ring->dev, 4096);
if (ring->scratch.obj == NULL) {
@@ -672,7 +682,7 @@ static int intel_ring_workarounds_emit(struct intel_engine_cs *ring,
struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_workarounds *w = &dev_priv->workarounds;
- if (WARN_ON(w->count == 0))
+ if (WARN_ON_ONCE(w->count == 0))
return 0;
ring->gpu_caches_dirty = true;
@@ -703,6 +713,22 @@ static int intel_ring_workarounds_emit(struct intel_engine_cs *ring,
return 0;
}
+static int intel_rcs_ctx_init(struct intel_engine_cs *ring,
+ struct intel_context *ctx)
+{
+ int ret;
+
+ ret = intel_ring_workarounds_emit(ring, ctx);
+ if (ret != 0)
+ return ret;
+
+ ret = i915_gem_render_state_init(ring);
+ if (ret)
+ DRM_ERROR("init render state: %d\n", ret);
+
+ return ret;
+}
+
static int wa_add(struct drm_i915_private *dev_priv,
const u32 addr, const u32 mask, const u32 val)
{
@@ -762,11 +788,24 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring)
* workaround for for a possible hang in the unlikely event a TLB
* invalidation occurs during a PSD flush.
*/
+ /* WaForceEnableNonCoherent:bdw */
+ /* WaHdcDisableFetchWhenMasked:bdw */
/* WaDisableFenceDestinationToSLM:bdw (GT3 pre-production) */
WA_SET_BIT_MASKED(HDC_CHICKEN0,
HDC_FORCE_NON_COHERENT |
+ HDC_DONOT_FETCH_MEM_WHEN_MASKED |
(IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
+ /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
+ * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
+ * polygons in the same 8x4 pixel/sample area to be processed without
+ * stalling waiting for the earlier ones to write to Hierarchical Z
+ * buffer."
+ *
+ * This optimization is off by default for Broadwell; turn it on.
+ */
+ WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
+
/* Wa4x4STCOptimizationDisable:bdw */
WA_SET_BIT_MASKED(CACHE_MODE_1,
GEN8_4x4_STC_OPTIMIZATION_DISABLE);
@@ -807,6 +846,30 @@ static int chv_init_workarounds(struct intel_engine_cs *ring)
HDC_FORCE_NON_COHERENT |
HDC_DONOT_FETCH_MEM_WHEN_MASKED);
+ /* According to the CACHE_MODE_0 default value documentation, some
+ * CHV platforms disable this optimization by default. Turn it on.
+ */
+ WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
+
+ /* Wa4x4STCOptimizationDisable:chv */
+ WA_SET_BIT_MASKED(CACHE_MODE_1,
+ GEN8_4x4_STC_OPTIMIZATION_DISABLE);
+
+ /* Improve HiZ throughput on CHV. */
+ WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
+
+ /*
+ * BSpec recommends 8x4 when MSAA is used,
+ * however in practice 16x4 seems fastest.
+ *
+ * Note that PS/WM thread counts depend on the WIZ hashing
+ * disable bit, which we don't touch here, but it's good
+ * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+ */
+ WA_SET_FIELD_MASKED(GEN7_GT_MODE,
+ GEN6_WIZ_HASHING_MASK,
+ GEN6_WIZ_HASHING_16x4);
+
return 0;
}
@@ -861,12 +924,6 @@ static int init_render_ring(struct intel_engine_cs *ring)
_MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_EXPLICIT) |
_MASKED_BIT_ENABLE(GFX_REPLAY_MODE));
- if (INTEL_INFO(dev)->gen >= 5) {
- ret = intel_init_pipe_control(ring);
- if (ret)
- return ret;
- }
-
if (IS_GEN6(dev)) {
/* From the Sandybridge PRM, volume 1 part 3, page 24:
* "If this bit is set, STCunit will have LRA as replacement
@@ -918,17 +975,20 @@ static int gen8_rcs_signal(struct intel_engine_cs *signaller,
return ret;
for_each_ring(waiter, dev_priv, i) {
+ u32 seqno;
u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
continue;
+ seqno = i915_gem_request_get_seqno(
+ signaller->outstanding_lazy_request);
intel_ring_emit(signaller, GFX_OP_PIPE_CONTROL(6));
intel_ring_emit(signaller, PIPE_CONTROL_GLOBAL_GTT_IVB |
PIPE_CONTROL_QW_WRITE |
PIPE_CONTROL_FLUSH_ENABLE);
intel_ring_emit(signaller, lower_32_bits(gtt_offset));
intel_ring_emit(signaller, upper_32_bits(gtt_offset));
- intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, seqno);
intel_ring_emit(signaller, 0);
intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
MI_SEMAPHORE_TARGET(waiter->id));
@@ -956,16 +1016,19 @@ static int gen8_xcs_signal(struct intel_engine_cs *signaller,
return ret;
for_each_ring(waiter, dev_priv, i) {
+ u32 seqno;
u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
continue;
+ seqno = i915_gem_request_get_seqno(
+ signaller->outstanding_lazy_request);
intel_ring_emit(signaller, (MI_FLUSH_DW + 1) |
MI_FLUSH_DW_OP_STOREDW);
intel_ring_emit(signaller, lower_32_bits(gtt_offset) |
MI_FLUSH_DW_USE_GTT);
intel_ring_emit(signaller, upper_32_bits(gtt_offset));
- intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, seqno);
intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
MI_SEMAPHORE_TARGET(waiter->id));
intel_ring_emit(signaller, 0);
@@ -994,9 +1057,11 @@ static int gen6_signal(struct intel_engine_cs *signaller,
for_each_ring(useless, dev_priv, i) {
u32 mbox_reg = signaller->semaphore.mbox.signal[i];
if (mbox_reg != GEN6_NOSYNC) {
+ u32 seqno = i915_gem_request_get_seqno(
+ signaller->outstanding_lazy_request);
intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(signaller, mbox_reg);
- intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, seqno);
}
}
@@ -1031,7 +1096,8 @@ gen6_add_request(struct intel_engine_cs *ring)
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring,
+ i915_gem_request_get_seqno(ring->outstanding_lazy_request));
intel_ring_emit(ring, MI_USER_INTERRUPT);
__intel_ring_advance(ring);
@@ -1149,7 +1215,8 @@ pc_render_add_request(struct intel_engine_cs *ring)
PIPE_CONTROL_WRITE_FLUSH |
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring,
+ i915_gem_request_get_seqno(ring->outstanding_lazy_request));
intel_ring_emit(ring, 0);
PIPE_CONTROL_FLUSH(ring, scratch_addr);
scratch_addr += 2 * CACHELINE_BYTES; /* write to separate cachelines */
@@ -1168,7 +1235,8 @@ pc_render_add_request(struct intel_engine_cs *ring)
PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
PIPE_CONTROL_NOTIFY);
intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring,
+ i915_gem_request_get_seqno(ring->outstanding_lazy_request));
intel_ring_emit(ring, 0);
__intel_ring_advance(ring);
@@ -1408,7 +1476,8 @@ i9xx_add_request(struct intel_engine_cs *ring)
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+ intel_ring_emit(ring,
+ i915_gem_request_get_seqno(ring->outstanding_lazy_request));
intel_ring_emit(ring, MI_USER_INTERRUPT);
__intel_ring_advance(ring);
@@ -1789,15 +1858,15 @@ int intel_alloc_ringbuffer_obj(struct drm_device *dev,
static int intel_init_ring_buffer(struct drm_device *dev,
struct intel_engine_cs *ring)
{
- struct intel_ringbuffer *ringbuf = ring->buffer;
+ struct intel_ringbuffer *ringbuf;
int ret;
- if (ringbuf == NULL) {
- ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL);
- if (!ringbuf)
- return -ENOMEM;
- ring->buffer = ringbuf;
- }
+ WARN_ON(ring->buffer);
+
+ ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL);
+ if (!ringbuf)
+ return -ENOMEM;
+ ring->buffer = ringbuf;
ring->dev = dev;
INIT_LIST_HEAD(&ring->active_list);
@@ -1820,21 +1889,21 @@ static int intel_init_ring_buffer(struct drm_device *dev,
goto error;
}
- if (ringbuf->obj == NULL) {
- ret = intel_alloc_ringbuffer_obj(dev, ringbuf);
- if (ret) {
- DRM_ERROR("Failed to allocate ringbuffer %s: %d\n",
- ring->name, ret);
- goto error;
- }
+ WARN_ON(ringbuf->obj);
- ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf);
- if (ret) {
- DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n",
- ring->name, ret);
- intel_destroy_ringbuffer_obj(ringbuf);
- goto error;
- }
+ ret = intel_alloc_ringbuffer_obj(dev, ringbuf);
+ if (ret) {
+ DRM_ERROR("Failed to allocate ringbuffer %s: %d\n",
+ ring->name, ret);
+ goto error;
+ }
+
+ ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf);
+ if (ret) {
+ DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n",
+ ring->name, ret);
+ intel_destroy_ringbuffer_obj(ringbuf);
+ goto error;
}
/* Workaround an erratum on the i830 which causes a hang if
@@ -1849,10 +1918,6 @@ static int intel_init_ring_buffer(struct drm_device *dev,
if (ret)
goto error;
- ret = ring->init(ring);
- if (ret)
- goto error;
-
return 0;
error:
@@ -1877,8 +1942,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
intel_unpin_ringbuffer_obj(ringbuf);
intel_destroy_ringbuffer_obj(ringbuf);
- ring->preallocated_lazy_request = NULL;
- ring->outstanding_lazy_seqno = 0;
+ i915_gem_request_assign(&ring->outstanding_lazy_request, NULL);
if (ring->cleanup)
ring->cleanup(ring);
@@ -1895,38 +1959,27 @@ static int intel_ring_wait_request(struct intel_engine_cs *ring, int n)
{
struct intel_ringbuffer *ringbuf = ring->buffer;
struct drm_i915_gem_request *request;
- u32 seqno = 0;
int ret;
- if (ringbuf->last_retired_head != -1) {
- ringbuf->head = ringbuf->last_retired_head;
- ringbuf->last_retired_head = -1;
-
- ringbuf->space = intel_ring_space(ringbuf);
- if (ringbuf->space >= n)
- return 0;
- }
+ if (intel_ring_space(ringbuf) >= n)
+ return 0;
list_for_each_entry(request, &ring->request_list, list) {
- if (__intel_ring_space(request->tail, ringbuf->tail,
+ if (__intel_ring_space(request->postfix, ringbuf->tail,
ringbuf->size) >= n) {
- seqno = request->seqno;
break;
}
}
- if (seqno == 0)
+ if (&request->list == &ring->request_list)
return -ENOSPC;
- ret = i915_wait_seqno(ring, seqno);
+ ret = i915_wait_request(request);
if (ret)
return ret;
i915_gem_retire_requests_ring(ring);
- ringbuf->head = ringbuf->last_retired_head;
- ringbuf->last_retired_head = -1;
- ringbuf->space = intel_ring_space(ringbuf);
return 0;
}
@@ -1952,14 +2005,14 @@ static int ring_wait_for_space(struct intel_engine_cs *ring, int n)
* case by choosing an insanely large timeout. */
end = jiffies + 60 * HZ;
+ ret = 0;
trace_i915_ring_wait_begin(ring);
do {
+ if (intel_ring_space(ringbuf) >= n)
+ break;
ringbuf->head = I915_READ_HEAD(ring);
- ringbuf->space = intel_ring_space(ringbuf);
- if (ringbuf->space >= n) {
- ret = 0;
+ if (intel_ring_space(ringbuf) >= n)
break;
- }
msleep(1);
@@ -2000,19 +2053,19 @@ static int intel_wrap_ring_buffer(struct intel_engine_cs *ring)
iowrite32(MI_NOOP, virt++);
ringbuf->tail = 0;
- ringbuf->space = intel_ring_space(ringbuf);
+ intel_ring_update_space(ringbuf);
return 0;
}
int intel_ring_idle(struct intel_engine_cs *ring)
{
- u32 seqno;
+ struct drm_i915_gem_request *req;
int ret;
/* We need to add any requests required to flush the objects and ring */
- if (ring->outstanding_lazy_seqno) {
- ret = i915_add_request(ring, NULL);
+ if (ring->outstanding_lazy_request) {
+ ret = i915_add_request(ring);
if (ret)
return ret;
}
@@ -2021,30 +2074,39 @@ int intel_ring_idle(struct intel_engine_cs *ring)
if (list_empty(&ring->request_list))
return 0;
- seqno = list_entry(ring->request_list.prev,
+ req = list_entry(ring->request_list.prev,
struct drm_i915_gem_request,
- list)->seqno;
+ list);
- return i915_wait_seqno(ring, seqno);
+ return i915_wait_request(req);
}
static int
-intel_ring_alloc_seqno(struct intel_engine_cs *ring)
+intel_ring_alloc_request(struct intel_engine_cs *ring)
{
- if (ring->outstanding_lazy_seqno)
+ int ret;
+ struct drm_i915_gem_request *request;
+ struct drm_i915_private *dev_private = ring->dev->dev_private;
+
+ if (ring->outstanding_lazy_request)
return 0;
- if (ring->preallocated_lazy_request == NULL) {
- struct drm_i915_gem_request *request;
+ request = kzalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
- request = kmalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
+ kref_init(&request->ref);
+ request->ring = ring;
+ request->uniq = dev_private->request_uniq++;
- ring->preallocated_lazy_request = request;
+ ret = i915_gem_get_seqno(ring->dev, &request->seqno);
+ if (ret) {
+ kfree(request);
+ return ret;
}
- return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+ ring->outstanding_lazy_request = request;
+ return 0;
}
static int __intel_ring_prepare(struct intel_engine_cs *ring,
@@ -2084,7 +2146,7 @@ int intel_ring_begin(struct intel_engine_cs *ring,
return ret;
/* Preallocate the olr before touching the ring */
- ret = intel_ring_alloc_seqno(ring);
+ ret = intel_ring_alloc_request(ring);
if (ret)
return ret;
@@ -2119,7 +2181,7 @@ void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno)
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- BUG_ON(ring->outstanding_lazy_seqno);
+ BUG_ON(ring->outstanding_lazy_request);
if (INTEL_INFO(dev)->gen == 6 || INTEL_INFO(dev)->gen == 7) {
I915_WRITE(RING_SYNC_0(ring->mmio_base), 0);
@@ -2178,6 +2240,14 @@ static int gen6_bsd_ring_flush(struct intel_engine_cs *ring,
cmd = MI_FLUSH_DW;
if (INTEL_INFO(ring->dev)->gen >= 8)
cmd += 1;
+
+ /* We always require a command barrier so that subsequent
+ * commands, such as breadcrumb interrupts, are strictly ordered
+ * wrt the contents of the write cache being flushed to memory
+ * (and thus being coherent from the CPU).
+ */
+ cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
/*
* Bspec vol 1c.5 - video engine command streamer:
* "If ENABLED, all TLBs will be invalidated once the flush
@@ -2185,8 +2255,8 @@ static int gen6_bsd_ring_flush(struct intel_engine_cs *ring,
* Post-Sync Operation field is a value of 1h or 3h."
*/
if (invalidate & I915_GEM_GPU_DOMAINS)
- cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD |
- MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+ cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD;
+
intel_ring_emit(ring, cmd);
intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
if (INTEL_INFO(ring->dev)->gen >= 8) {
@@ -2282,6 +2352,14 @@ static int gen6_ring_flush(struct intel_engine_cs *ring,
cmd = MI_FLUSH_DW;
if (INTEL_INFO(ring->dev)->gen >= 8)
cmd += 1;
+
+ /* We always require a command barrier so that subsequent
+ * commands, such as breadcrumb interrupts, are strictly ordered
+ * wrt the contents of the write cache being flushed to memory
+ * (and thus being coherent from the CPU).
+ */
+ cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
+
/*
* Bspec vol 1c.3 - blitter engine command streamer:
* "If ENABLED, all TLBs will be invalidated once the flush
@@ -2289,8 +2367,7 @@ static int gen6_ring_flush(struct intel_engine_cs *ring,
* Post-Sync Operation field is a value of 1h or 3h."
*/
if (invalidate & I915_GEM_DOMAIN_RENDER)
- cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX |
- MI_FLUSH_DW_OP_STOREDW;
+ cmd |= MI_INVALIDATE_TLB;
intel_ring_emit(ring, cmd);
intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT);
if (INTEL_INFO(ring->dev)->gen >= 8) {
@@ -2341,7 +2418,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
}
}
- ring->init_context = intel_ring_workarounds_emit;
+ ring->init_context = intel_rcs_ctx_init;
ring->add_request = gen6_add_request;
ring->flush = gen8_render_ring_flush;
ring->irq_get = gen8_ring_get_irq;
@@ -2426,7 +2503,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = i830_dispatch_execbuffer;
else
ring->dispatch_execbuffer = i915_dispatch_execbuffer;
- ring->init = init_render_ring;
+ ring->init_hw = init_render_ring;
ring->cleanup = render_ring_cleanup;
/* Workaround batchbuffer to combat CS tlb bug. */
@@ -2448,7 +2525,17 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj);
}
- return intel_init_ring_buffer(dev, ring);
+ ret = intel_init_ring_buffer(dev, ring);
+ if (ret)
+ return ret;
+
+ if (INTEL_INFO(dev)->gen >= 5) {
+ ret = intel_init_pipe_control(ring);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
int intel_init_bsd_ring_buffer(struct drm_device *dev)
@@ -2519,7 +2606,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
}
ring->dispatch_execbuffer = i965_dispatch_execbuffer;
}
- ring->init = init_ring_common;
+ ring->init_hw = init_ring_common;
return intel_init_ring_buffer(dev, ring);
}
@@ -2558,7 +2645,7 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev)
ring->semaphore.signal = gen8_xcs_signal;
GEN8_RING_SEMAPHORE_INIT;
}
- ring->init = init_ring_common;
+ ring->init_hw = init_ring_common;
return intel_init_ring_buffer(dev, ring);
}
@@ -2615,7 +2702,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
}
}
- ring->init = init_ring_common;
+ ring->init_hw = init_ring_common;
return intel_init_ring_buffer(dev, ring);
}
@@ -2666,7 +2753,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
}
}
- ring->init = init_ring_common;
+ ring->init_hw = init_ring_common;
return intel_init_ring_buffer(dev, ring);
}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index fe426cff598b..714f3fdd57d2 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -99,13 +99,6 @@ struct intel_ringbuffer {
struct intel_engine_cs *ring;
- /*
- * FIXME: This backpointer is an artifact of the history of how the
- * execlist patches came into being. It will get removed once the basic
- * code has landed.
- */
- struct intel_context *FIXME_lrc_ctx;
-
u32 head;
u32 tail;
int space;
@@ -123,6 +116,8 @@ struct intel_ringbuffer {
u32 last_retired_head;
};
+struct intel_context;
+
struct intel_engine_cs {
const char *name;
enum intel_ring_id {
@@ -142,11 +137,11 @@ struct intel_engine_cs {
unsigned irq_refcount; /* protected by dev_priv->irq_lock */
u32 irq_enable_mask; /* bitmask to enable ring interrupt */
- u32 trace_irq_seqno;
+ struct drm_i915_gem_request *trace_irq_req;
bool __must_check (*irq_get)(struct intel_engine_cs *ring);
void (*irq_put)(struct intel_engine_cs *ring);
- int (*init)(struct intel_engine_cs *ring);
+ int (*init_hw)(struct intel_engine_cs *ring);
int (*init_context)(struct intel_engine_cs *ring,
struct intel_context *ctx);
@@ -239,11 +234,14 @@ struct intel_engine_cs {
struct list_head execlist_retired_req_list;
u8 next_context_status_buffer;
u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */
- int (*emit_request)(struct intel_ringbuffer *ringbuf);
+ int (*emit_request)(struct intel_ringbuffer *ringbuf,
+ struct drm_i915_gem_request *request);
int (*emit_flush)(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
u32 invalidate_domains,
u32 flush_domains);
int (*emit_bb_start)(struct intel_ringbuffer *ringbuf,
+ struct intel_context *ctx,
u64 offset, unsigned flags);
/**
@@ -251,7 +249,7 @@ struct intel_engine_cs {
* ringbuffer.
*
* Includes buffers having the contents of their GPU caches
- * flushed, not necessarily primitives. last_rendering_seqno
+ * flushed, not necessarily primitives. last_read_req
* represents when the rendering involved will be completed.
*
* A reference is held on the buffer while on this list.
@@ -267,8 +265,7 @@ struct intel_engine_cs {
/**
* Do we have some not yet emitted requests outstanding?
*/
- struct drm_i915_gem_request *preallocated_lazy_request;
- u32 outstanding_lazy_seqno;
+ struct drm_i915_gem_request *outstanding_lazy_request;
bool gpu_caches_dirty;
bool fbc_dirty;
@@ -408,6 +405,7 @@ static inline void intel_ring_advance(struct intel_engine_cs *ring)
ringbuf->tail &= ringbuf->size - 1;
}
int __intel_ring_space(int head, int tail, int size);
+void intel_ring_update_space(struct intel_ringbuffer *ringbuf);
int intel_ring_space(struct intel_ringbuffer *ringbuf);
bool intel_ring_stopped(struct intel_engine_cs *ring);
void __intel_ring_advance(struct intel_engine_cs *ring);
@@ -436,16 +434,11 @@ static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf)
return ringbuf->tail;
}
-static inline u32 intel_ring_get_seqno(struct intel_engine_cs *ring)
-{
- BUG_ON(ring->outstanding_lazy_seqno == 0);
- return ring->outstanding_lazy_seqno;
-}
-
-static inline void i915_trace_irq_get(struct intel_engine_cs *ring, u32 seqno)
+static inline struct drm_i915_gem_request *
+intel_ring_get_request(struct intel_engine_cs *ring)
{
- if (ring->trace_irq_seqno == 0 && ring->irq_get(ring))
- ring->trace_irq_seqno = seqno;
+ BUG_ON(ring->outstanding_lazy_request == NULL);
+ return ring->outstanding_lazy_request;
}
#endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 39ddf40171bf..49695d7d51e3 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -115,7 +115,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
}
/**
- * intel_display_power_is_enabled - unlocked check for a power domain
+ * intel_display_power_is_enabled - check for a power domain
* @dev_priv: i915 device instance
* @domain: power domain to check
*
@@ -703,6 +703,10 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \
BIT(POWER_DOMAIN_PORT_CRT) | \
BIT(POWER_DOMAIN_PLLS) | \
+ BIT(POWER_DOMAIN_AUX_A) | \
+ BIT(POWER_DOMAIN_AUX_B) | \
+ BIT(POWER_DOMAIN_AUX_C) | \
+ BIT(POWER_DOMAIN_AUX_D) | \
BIT(POWER_DOMAIN_INIT))
#define HSW_DISPLAY_POWER_DOMAINS ( \
(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
@@ -724,24 +728,30 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
BIT(POWER_DOMAIN_PORT_CRT) | \
+ BIT(POWER_DOMAIN_AUX_B) | \
+ BIT(POWER_DOMAIN_AUX_C) | \
BIT(POWER_DOMAIN_INIT))
#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_B) | \
BIT(POWER_DOMAIN_INIT))
#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_B) | \
BIT(POWER_DOMAIN_INIT))
#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_C) | \
BIT(POWER_DOMAIN_INIT))
#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_C) | \
BIT(POWER_DOMAIN_INIT))
#define CHV_PIPE_A_POWER_DOMAINS ( \
@@ -761,20 +771,25 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_B) | \
+ BIT(POWER_DOMAIN_AUX_C) | \
BIT(POWER_DOMAIN_INIT))
#define CHV_DPIO_CMN_D_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_D) | \
BIT(POWER_DOMAIN_INIT))
#define CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_D) | \
BIT(POWER_DOMAIN_INIT))
#define CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \
+ BIT(POWER_DOMAIN_AUX_D) | \
BIT(POWER_DOMAIN_INIT))
static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 6d7a277458b5..64ad2b40179f 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -30,6 +30,7 @@
#include <linux/delay.h>
#include <linux/export.h>
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include "intel_drv.h"
@@ -1007,7 +1008,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
}
if (intel_sdvo->rgb_quant_range_selectable) {
- if (intel_crtc->config.limited_color_range)
+ if (intel_crtc->config->limited_color_range)
frame.avi.quantization_range =
HDMI_QUANTIZATION_RANGE_LIMITED;
else
@@ -1085,7 +1086,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
return true;
}
-static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config)
+static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)
{
unsigned dotclock = pipe_config->port_clock;
struct dpll *clock = &pipe_config->dpll;
@@ -1112,11 +1113,11 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config)
}
static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
- struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
- struct drm_display_mode *mode = &pipe_config->requested_mode;
+ struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+ struct drm_display_mode *mode = &pipe_config->base.mode;
DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
pipe_config->pipe_bpp = 8*3;
@@ -1181,8 +1182,8 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
- &crtc->config.adjusted_mode;
- struct drm_display_mode *mode = &crtc->config.requested_mode;
+ &crtc->config->base.adjusted_mode;
+ struct drm_display_mode *mode = &crtc->config->base.mode;
struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
u32 sdvox;
struct intel_sdvo_in_out_map in_out;
@@ -1224,7 +1225,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
if (!intel_sdvo_set_target_input(intel_sdvo))
return;
- if (crtc->config.has_hdmi_sink) {
+ if (crtc->config->has_hdmi_sink) {
intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
intel_sdvo_set_colorimetry(intel_sdvo,
SDVO_COLORIMETRY_RGB256);
@@ -1244,7 +1245,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
DRM_INFO("Setting input timings on %s failed\n",
SDVO_NAME(intel_sdvo));
- switch (crtc->config.pixel_multiplier) {
+ switch (crtc->config->pixel_multiplier) {
default:
WARN(1, "unknown pixel mutlipler specified\n");
case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
@@ -1259,7 +1260,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
/* The real mode polarity is set by the SDVO commands, using
* struct intel_sdvo_dtd. */
sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
- if (!HAS_PCH_SPLIT(dev) && crtc->config.limited_color_range)
+ if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
sdvox |= HDMI_COLOR_RANGE_16_235;
if (INTEL_INFO(dev)->gen < 5)
sdvox |= SDVO_BORDER_ENABLE;
@@ -1289,7 +1290,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
/* done in crtc_mode_set as it lives inside the dpll register */
} else {
- sdvox |= (crtc->config.pixel_multiplier - 1)
+ sdvox |= (crtc->config->pixel_multiplier - 1)
<< SDVO_PORT_MULTIPLY_SHIFT;
}
@@ -1338,7 +1339,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
}
static void intel_sdvo_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1370,7 +1371,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
flags |= DRM_MODE_FLAG_NVSYNC;
}
- pipe_config->adjusted_mode.flags |= flags;
+ pipe_config->base.adjusted_mode.flags |= flags;
/*
* pixel multiplier readout is tricky: Only on i915g/gm it is stored in
@@ -1392,7 +1393,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
if (HAS_PCH_SPLIT(dev))
ironlake_check_encoder_dotclock(pipe_config, dotclock);
- pipe_config->adjusted_mode.crtc_clock = dotclock;
+ pipe_config->base.adjusted_mode.crtc_clock = dotclock;
/* Cross check the port pixel multiplier with the sdvo encoder state. */
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
@@ -1617,6 +1618,9 @@ static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo)
struct drm_device *dev = intel_sdvo->base.base.dev;
uint16_t hotplug;
+ if (!I915_HAS_HOTPLUG(dev))
+ return 0;
+
/* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
* on the line. */
if (IS_I945G(dev) || IS_I945GM(dev))
@@ -2187,7 +2191,9 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
.detect = intel_sdvo_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_sdvo_set_property,
+ .atomic_get_property = intel_connector_atomic_get_property,
.destroy = intel_sdvo_destroy,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 01d841ea3140..693ce8281970 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -75,26 +75,26 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
return 0;
}
-u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr)
+u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
{
u32 val = 0;
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
mutex_lock(&dev_priv->dpio_lock);
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
SB_CRRDDA_NP, addr, &val);
mutex_unlock(&dev_priv->dpio_lock);
return val;
}
-void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
+void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
{
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
mutex_lock(&dev_priv->dpio_lock);
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
SB_CRWRDA_NP, addr, &val);
mutex_unlock(&dev_priv->dpio_lock);
}
@@ -103,7 +103,7 @@ u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
{
u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
SB_CRRDDA_NP, reg, &val);
return val;
@@ -111,7 +111,7 @@ u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_BUNIT,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_BUNIT,
SB_CRWRDA_NP, reg, &val);
}
@@ -122,7 +122,7 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
mutex_lock(&dev_priv->dpio_lock);
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
SB_CRRDDA_NP, addr, &val);
mutex_unlock(&dev_priv->dpio_lock);
@@ -132,56 +132,56 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg)
{
u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC,
SB_CRRDDA_NP, reg, &val);
return val;
}
void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPIO_NC,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC,
SB_CRWRDA_NP, reg, &val);
}
u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg)
{
u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
SB_CRRDDA_NP, reg, &val);
return val;
}
void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCK,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCK,
SB_CRWRDA_NP, reg, &val);
}
u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
{
u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
SB_CRRDDA_NP, reg, &val);
return val;
}
void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_CCU,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_CCU,
SB_CRWRDA_NP, reg, &val);
}
u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg)
{
u32 val = 0;
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPS_CORE,
SB_CRRDDA_NP, reg, &val);
return val;
}
void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
{
- vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_GPS_CORE,
+ vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPS_CORE,
SB_CRWRDA_NP, reg, &val);
}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 7d9c340f7693..0a52c44ad03d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -33,6 +33,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_rect.h>
+#include <drm/drm_plane_helper.h>
#include "intel_drv.h"
#include <drm/i915_drm.h>
#include "i915_drv.h"
@@ -79,7 +80,7 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
{
struct drm_device *dev = crtc->base.dev;
- const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
+ const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
enum pipe pipe = crtc->pipe;
long timeout = msecs_to_jiffies_timeout(1);
int scanline, min, max, vblank_start;
@@ -255,7 +256,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
default:
BUG();
}
- if (intel_plane->rotation == BIT(DRM_ROTATE_180))
+ if (drm_plane->state->rotation == BIT(DRM_ROTATE_180))
plane_ctl |= PLANE_CTL_ROTATE_180;
plane_ctl |= PLANE_CTL_ENABLE;
@@ -412,8 +413,6 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
u32 sprctl;
unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
- u32 start_vbl_count;
- bool atomic_update;
sprctl = I915_READ(SPCNTR(pipe, plane));
@@ -494,7 +493,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
fb->pitches[0]);
linear_offset -= sprsurf_offset;
- if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+ if (dplane->state->rotation == BIT(DRM_ROTATE_180)) {
sprctl |= SP_ROTATE_180;
x += src_w;
@@ -502,8 +501,6 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
}
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
-
intel_update_primary_plane(intel_crtc);
if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
@@ -525,9 +522,6 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
sprsurf_offset);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
-
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void
@@ -539,10 +533,6 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_plane->pipe;
int plane = intel_plane->plane;
- u32 start_vbl_count;
- bool atomic_update;
-
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -553,9 +543,6 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
-
intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
}
@@ -626,8 +613,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
u32 sprctl, sprscale = 0;
unsigned long sprsurf_offset, linear_offset;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
- u32 start_vbl_count;
- bool atomic_update;
sprctl = I915_READ(SPRCTL(pipe));
@@ -699,7 +684,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
pixel_size, fb->pitches[0]);
linear_offset -= sprsurf_offset;
- if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+ if (plane->state->rotation == BIT(DRM_ROTATE_180)) {
sprctl |= SPRITE_ROTATE_180;
/* HSW and BDW does this automagically in hardware */
@@ -711,8 +696,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
}
}
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
-
intel_update_primary_plane(intel_crtc);
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
@@ -735,9 +718,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
-
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void
@@ -748,10 +728,6 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
struct intel_plane *intel_plane = to_intel_plane(plane);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_plane->pipe;
- u32 start_vbl_count;
- bool atomic_update;
-
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -764,16 +740,12 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
-
/*
* Avoid underruns when disabling the sprite.
* FIXME remove once watermark updates are done properly.
*/
- intel_wait_for_vblank(dev, pipe);
-
- intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
+ intel_crtc->atomic.wait_vblank = true;
+ intel_crtc->atomic.update_sprite_watermarks |= (1 << drm_plane_index(plane));
}
static int
@@ -846,8 +818,6 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
unsigned long dvssurf_offset, linear_offset;
u32 dvscntr, dvsscale;
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
- u32 start_vbl_count;
- bool atomic_update;
dvscntr = I915_READ(DVSCNTR(pipe));
@@ -914,7 +884,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
pixel_size, fb->pitches[0]);
linear_offset -= dvssurf_offset;
- if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+ if (plane->state->rotation == BIT(DRM_ROTATE_180)) {
dvscntr |= DVS_ROTATE_180;
x += src_w;
@@ -922,8 +892,6 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
}
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
-
intel_update_primary_plane(intel_crtc);
I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
@@ -941,9 +909,6 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
-
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void
@@ -954,10 +919,6 @@ ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
struct intel_plane *intel_plane = to_intel_plane(plane);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_plane->pipe;
- u32 start_vbl_count;
- bool atomic_update;
-
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
intel_update_primary_plane(intel_crtc);
@@ -969,19 +930,25 @@ ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
intel_flush_primary_plane(dev_priv, intel_crtc->plane);
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
-
/*
* Avoid underruns when disabling the sprite.
* FIXME remove once watermark updates are done properly.
*/
- intel_wait_for_vblank(dev, pipe);
-
- intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
+ intel_crtc->atomic.wait_vblank = true;
+ intel_crtc->atomic.update_sprite_watermarks |= (1 << drm_plane_index(plane));
}
-static void
+/**
+ * intel_post_enable_primary - Perform operations after enabling primary plane
+ * @crtc: the CRTC whose primary plane was just enabled
+ *
+ * Performs potentially sleeping operations that must be done after the primary
+ * plane is enabled, such as updating FBC and IPS. Note that this may be
+ * called due to an explicit primary plane update, or due to an implicit
+ * re-enable that is caused when a sprite plane is updated to no longer
+ * completely hide the primary plane.
+ */
+void
intel_post_enable_primary(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -1004,11 +971,21 @@ intel_post_enable_primary(struct drm_crtc *crtc)
hsw_enable_ips(intel_crtc);
mutex_lock(&dev->struct_mutex);
- intel_update_fbc(dev);
+ intel_fbc_update(dev);
mutex_unlock(&dev->struct_mutex);
}
-static void
+/**
+ * intel_pre_disable_primary - Perform operations before disabling primary plane
+ * @crtc: the CRTC whose primary plane is to be disabled
+ *
+ * Performs potentially sleeping operations that must be done before the
+ * primary plane is enabled, such as updating FBC and IPS. Note that this may
+ * be called due to an explicit primary plane update, or due to an implicit
+ * disable that is caused when a sprite plane completely hides the primary
+ * plane.
+ */
+void
intel_pre_disable_primary(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -1017,7 +994,7 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
if (dev_priv->fbc.plane == intel_crtc->plane)
- intel_disable_fbc(dev);
+ intel_fbc_disable(dev);
mutex_unlock(&dev->struct_mutex);
/*
@@ -1096,20 +1073,26 @@ static int
intel_check_sprite_plane(struct drm_plane *plane,
struct intel_plane_state *state)
{
- struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
+ struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
struct intel_plane *intel_plane = to_intel_plane(plane);
- struct drm_framebuffer *fb = state->fb;
+ struct drm_framebuffer *fb = state->base.fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
int crtc_x, crtc_y;
unsigned int crtc_w, crtc_h;
uint32_t src_x, src_y, src_w, src_h;
struct drm_rect *src = &state->src;
struct drm_rect *dst = &state->dst;
- struct drm_rect *orig_src = &state->orig_src;
const struct drm_rect *clip = &state->clip;
int hscale, vscale;
int max_scale, min_scale;
- int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
+ int pixel_size;
+
+ intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
+
+ if (!fb) {
+ state->visible = false;
+ goto finish;
+ }
/* Don't modify another pipe's plane */
if (intel_plane->pipe != intel_crtc->pipe) {
@@ -1142,7 +1125,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
min_scale = intel_plane->can_scale ? 1 : (1 << 16);
drm_rect_rotate(src, fb->width << 16, fb->height << 16,
- intel_plane->rotation);
+ state->base.rotation);
hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
BUG_ON(hscale < 0);
@@ -1183,13 +1166,13 @@ intel_check_sprite_plane(struct drm_plane *plane,
drm_rect_height(dst) * vscale - drm_rect_height(src));
drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
- intel_plane->rotation);
+ state->base.rotation);
/* sanity check to make sure the src viewport wasn't enlarged */
- WARN_ON(src->x1 < (int) orig_src->x1 ||
- src->y1 < (int) orig_src->y1 ||
- src->x2 > (int) orig_src->x2 ||
- src->y2 > (int) orig_src->y2);
+ WARN_ON(src->x1 < (int) state->base.src_x ||
+ src->y1 < (int) state->base.src_y ||
+ src->x2 > (int) state->base.src_x + state->base.src_w ||
+ src->y2 > (int) state->base.src_y + state->base.src_h);
/*
* Hardware doesn't handle subpixel coordinates.
@@ -1232,6 +1215,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
if (src_w < 3 || src_h < 3)
state->visible = false;
+ pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
width_bytes = ((src_x * pixel_size) & 63) +
src_w * pixel_size;
@@ -1254,39 +1238,27 @@ intel_check_sprite_plane(struct drm_plane *plane,
dst->y1 = crtc_y;
dst->y2 = crtc_y + crtc_h;
- return 0;
-}
+finish:
+ /*
+ * If the sprite is completely covering the primary plane,
+ * we can disable the primary and save power.
+ */
+ state->hides_primary = fb != NULL && drm_rect_equals(dst, clip) &&
+ !colorkey_enabled(intel_plane);
+ WARN_ON(state->hides_primary && !state->visible && intel_crtc->active);
-static int
-intel_prepare_sprite_plane(struct drm_plane *plane,
- struct intel_plane_state *state)
-{
- struct drm_device *dev = plane->dev;
- struct drm_crtc *crtc = state->crtc;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_plane *intel_plane = to_intel_plane(plane);
- enum pipe pipe = intel_crtc->pipe;
- struct drm_framebuffer *fb = state->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct drm_i915_gem_object *old_obj = intel_plane->obj;
- int ret;
+ if (intel_crtc->active) {
+ if (intel_crtc->primary_enabled == state->hides_primary)
+ intel_crtc->atomic.wait_for_flips = true;
- if (old_obj != obj) {
- mutex_lock(&dev->struct_mutex);
+ if (intel_crtc->primary_enabled && state->hides_primary)
+ intel_crtc->atomic.pre_disable_primary = true;
- /* Note that this will apply the VT-d workaround for scanouts,
- * which is more restrictive than required for sprites. (The
- * primary plane requires 256KiB alignment with 64 PTE padding,
- * the sprite planes only require 128KiB alignment and 32 PTE
- * padding.
- */
- ret = intel_pin_and_fence_fb_obj(plane, fb, NULL);
- if (ret == 0)
- i915_gem_track_fb(old_obj, obj,
- INTEL_FRONTBUFFER_SPRITE(pipe));
- mutex_unlock(&dev->struct_mutex);
- if (ret)
- return ret;
+ intel_crtc->atomic.fb_bits |=
+ INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe);
+
+ if (!intel_crtc->primary_enabled && !state->hides_primary)
+ intel_crtc->atomic.post_enable_primary = true;
}
return 0;
@@ -1296,48 +1268,23 @@ static void
intel_commit_sprite_plane(struct drm_plane *plane,
struct intel_plane_state *state)
{
- struct drm_device *dev = plane->dev;
- struct drm_crtc *crtc = state->crtc;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_crtc *crtc = state->base.crtc;
+ struct intel_crtc *intel_crtc;
struct intel_plane *intel_plane = to_intel_plane(plane);
- enum pipe pipe = intel_crtc->pipe;
- struct drm_framebuffer *fb = state->fb;
+ struct drm_framebuffer *fb = state->base.fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct drm_i915_gem_object *old_obj = intel_plane->obj;
int crtc_x, crtc_y;
unsigned int crtc_w, crtc_h;
uint32_t src_x, src_y, src_w, src_h;
- struct drm_rect *dst = &state->dst;
- const struct drm_rect *clip = &state->clip;
- bool primary_enabled;
- /*
- * If the sprite is completely covering the primary plane,
- * we can disable the primary and save power.
- */
- primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane);
- WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
-
- intel_plane->crtc_x = state->orig_dst.x1;
- intel_plane->crtc_y = state->orig_dst.y1;
- intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
- intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
- intel_plane->src_x = state->orig_src.x1;
- intel_plane->src_y = state->orig_src.y1;
- intel_plane->src_w = drm_rect_width(&state->orig_src);
- intel_plane->src_h = drm_rect_height(&state->orig_src);
+ crtc = crtc ? crtc : plane->crtc;
+ intel_crtc = to_intel_crtc(crtc);
+
+ plane->fb = state->base.fb;
intel_plane->obj = obj;
if (intel_crtc->active) {
- bool primary_was_enabled = intel_crtc->primary_enabled;
-
- intel_crtc->primary_enabled = primary_enabled;
-
- if (primary_was_enabled != primary_enabled)
- intel_crtc_wait_for_pending_flips(crtc);
-
- if (primary_was_enabled && !primary_enabled)
- intel_pre_disable_primary(crtc);
+ intel_crtc->primary_enabled = !state->hides_primary;
if (state->visible) {
crtc_x = state->dst.x1;
@@ -1354,129 +1301,9 @@ intel_commit_sprite_plane(struct drm_plane *plane,
} else {
intel_plane->disable_plane(plane, crtc);
}
-
-
- intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
-
- if (!primary_was_enabled && primary_enabled)
- intel_post_enable_primary(crtc);
- }
-
- /* Unpin old obj after new one is active to avoid ugliness */
- if (old_obj && old_obj != obj) {
-
- /*
- * It's fairly common to simply update the position of
- * an existing object. In that case, we don't need to
- * wait for vblank to avoid ugliness, we only need to
- * do the pin & ref bookkeeping.
- */
- if (intel_crtc->active)
- intel_wait_for_vblank(dev, intel_crtc->pipe);
-
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(old_obj);
- mutex_unlock(&dev->struct_mutex);
}
}
-static int
-intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h)
-{
- struct intel_plane_state state;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int ret;
-
- state.crtc = crtc;
- state.fb = fb;
-
- /* sample coordinates in 16.16 fixed point */
- state.src.x1 = src_x;
- state.src.x2 = src_x + src_w;
- state.src.y1 = src_y;
- state.src.y2 = src_y + src_h;
-
- /* integer pixels */
- state.dst.x1 = crtc_x;
- state.dst.x2 = crtc_x + crtc_w;
- state.dst.y1 = crtc_y;
- state.dst.y2 = crtc_y + crtc_h;
-
- state.clip.x1 = 0;
- state.clip.y1 = 0;
- state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
- state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
- state.orig_src = state.src;
- state.orig_dst = state.dst;
-
- ret = intel_check_sprite_plane(plane, &state);
- if (ret)
- return ret;
-
- ret = intel_prepare_sprite_plane(plane, &state);
- if (ret)
- return ret;
-
- intel_commit_sprite_plane(plane, &state);
- return 0;
-}
-
-static int
-intel_disable_plane(struct drm_plane *plane)
-{
- struct drm_device *dev = plane->dev;
- struct intel_plane *intel_plane = to_intel_plane(plane);
- struct intel_crtc *intel_crtc;
- enum pipe pipe;
-
- if (!plane->fb)
- return 0;
-
- if (WARN_ON(!plane->crtc))
- return -EINVAL;
-
- intel_crtc = to_intel_crtc(plane->crtc);
- pipe = intel_crtc->pipe;
-
- if (intel_crtc->active) {
- bool primary_was_enabled = intel_crtc->primary_enabled;
-
- intel_crtc->primary_enabled = true;
-
- intel_plane->disable_plane(plane, plane->crtc);
-
- if (!primary_was_enabled && intel_crtc->primary_enabled)
- intel_post_enable_primary(plane->crtc);
- }
-
- if (intel_plane->obj) {
- if (intel_crtc->active)
- intel_wait_for_vblank(dev, intel_plane->pipe);
-
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(intel_plane->obj);
- i915_gem_track_fb(intel_plane->obj, NULL,
- INTEL_FRONTBUFFER_SPRITE(pipe));
- mutex_unlock(&dev->struct_mutex);
-
- intel_plane->obj = NULL;
- }
-
- return 0;
-}
-
-static void intel_destroy_plane(struct drm_plane *plane)
-{
- struct intel_plane *intel_plane = to_intel_plane(plane);
- intel_disable_plane(plane);
- drm_plane_cleanup(plane);
- kfree(intel_plane);
-}
-
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -1535,62 +1362,18 @@ out_unlock:
return ret;
}
-int intel_plane_set_property(struct drm_plane *plane,
- struct drm_property *prop,
- uint64_t val)
-{
- struct drm_device *dev = plane->dev;
- struct intel_plane *intel_plane = to_intel_plane(plane);
- uint64_t old_val;
- int ret = -ENOENT;
-
- if (prop == dev->mode_config.rotation_property) {
- /* exactly one rotation angle please */
- if (hweight32(val & 0xf) != 1)
- return -EINVAL;
-
- if (intel_plane->rotation == val)
- return 0;
-
- old_val = intel_plane->rotation;
- intel_plane->rotation = val;
- ret = intel_plane_restore(plane);
- if (ret)
- intel_plane->rotation = old_val;
- }
-
- return ret;
-}
-
int intel_plane_restore(struct drm_plane *plane)
{
- struct intel_plane *intel_plane = to_intel_plane(plane);
-
if (!plane->crtc || !plane->fb)
return 0;
return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
- intel_plane->crtc_x, intel_plane->crtc_y,
- intel_plane->crtc_w, intel_plane->crtc_h,
- intel_plane->src_x, intel_plane->src_y,
- intel_plane->src_w, intel_plane->src_h);
-}
-
-void intel_plane_disable(struct drm_plane *plane)
-{
- if (!plane->crtc || !plane->fb)
- return;
-
- intel_disable_plane(plane);
+ plane->state->crtc_x, plane->state->crtc_y,
+ plane->state->crtc_w, plane->state->crtc_h,
+ plane->state->src_x, plane->state->src_y,
+ plane->state->src_w, plane->state->src_h);
}
-static const struct drm_plane_funcs intel_plane_funcs = {
- .update_plane = intel_update_plane,
- .disable_plane = intel_disable_plane,
- .destroy = intel_destroy_plane,
- .set_property = intel_plane_set_property,
-};
-
static uint32_t ilk_plane_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_YUYV,
@@ -1638,6 +1421,7 @@ int
intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
{
struct intel_plane *intel_plane;
+ struct intel_plane_state *state;
unsigned long possible_crtcs;
const uint32_t *plane_formats;
int num_plane_formats;
@@ -1650,6 +1434,13 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
if (!intel_plane)
return -ENOMEM;
+ state = intel_create_plane_state(&intel_plane->base);
+ if (!state) {
+ kfree(intel_plane);
+ return -ENOMEM;
+ }
+ intel_plane->base.state = &state->base;
+
switch (INTEL_INFO(dev)->gen) {
case 5:
case 6:
@@ -1719,7 +1510,8 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
intel_plane->pipe = pipe;
intel_plane->plane = plane;
- intel_plane->rotation = BIT(DRM_ROTATE_0);
+ intel_plane->check_plane = intel_check_sprite_plane;
+ intel_plane->commit_plane = intel_commit_sprite_plane;
possible_crtcs = (1 << pipe);
ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
&intel_plane_funcs,
@@ -1739,7 +1531,9 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
if (dev->mode_config.rotation_property)
drm_object_attach_property(&intel_plane->base.base,
dev->mode_config.rotation_property,
- intel_plane->rotation);
+ state->base.rotation);
+
+ drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
out:
return ret;
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 6f5f59b880f5..892d23c8479d 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -31,6 +31,7 @@
*/
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include "intel_drv.h"
@@ -908,14 +909,14 @@ intel_tv_mode_valid(struct drm_connector *connector,
static void
intel_tv_get_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
- pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock;
+ pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
}
static bool
intel_tv_compute_config(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+ struct intel_crtc_state *pipe_config)
{
struct intel_tv *intel_tv = enc_to_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
@@ -923,12 +924,12 @@ intel_tv_compute_config(struct intel_encoder *encoder,
if (!tv_mode)
return false;
- pipe_config->adjusted_mode.crtc_clock = tv_mode->clock;
+ pipe_config->base.adjusted_mode.crtc_clock = tv_mode->clock;
DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
pipe_config->pipe_bpp = 8*3;
/* TV has it's own notion of sync and other mode flags, so clear them. */
- pipe_config->adjusted_mode.flags = 0;
+ pipe_config->base.adjusted_mode.flags = 0;
/*
* FIXME: We don't check whether the input mode is actually what we want
@@ -1512,7 +1513,9 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = {
.detect = intel_tv_detect,
.destroy = intel_tv_destroy,
.set_property = intel_tv_set_property,
+ .atomic_get_property = intel_connector_atomic_get_property,
.fill_modes = drm_helper_probe_single_connector_modes,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 46de8d75b4bf..c47a3baa53d5 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -24,6 +24,8 @@
#include "i915_drv.h"
#include "intel_drv.h"
+#include <linux/pm_runtime.h>
+
#define FORCEWAKE_ACK_TIMEOUT_MS 2
#define __raw_i915_read8(dev_priv__, reg__) readb((dev_priv__)->regs + (reg__))
@@ -40,6 +42,26 @@
#define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__)
+static const char * const forcewake_domain_names[] = {
+ "render",
+ "blitter",
+ "media",
+};
+
+const char *
+intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id)
+{
+ BUILD_BUG_ON((sizeof(forcewake_domain_names)/sizeof(const char *)) !=
+ FW_DOMAIN_ID_COUNT);
+
+ if (id >= 0 && id < FW_DOMAIN_ID_COUNT)
+ return forcewake_domain_names[id];
+
+ WARN_ON(id);
+
+ return "unknown";
+}
+
static void
assert_device_not_suspended(struct drm_i915_private *dev_priv)
{
@@ -47,73 +69,128 @@ assert_device_not_suspended(struct drm_i915_private *dev_priv)
"Device suspended\n");
}
-static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
+static inline void
+fw_domain_reset(const struct intel_uncore_forcewake_domain *d)
{
- /* w/a for a sporadic read returning 0 by waiting for the GT
- * thread to wake up.
- */
- if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) &
- GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500))
- DRM_ERROR("GT thread status wait timed out\n");
+ WARN_ON(d->reg_set == 0);
+ __raw_i915_write32(d->i915, d->reg_set, d->val_reset);
}
-static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv)
+static inline void
+fw_domain_arm_timer(struct intel_uncore_forcewake_domain *d)
{
- __raw_i915_write32(dev_priv, FORCEWAKE, 0);
- /* something from same cacheline, but !FORCEWAKE */
- __raw_posting_read(dev_priv, ECOBUS);
+ mod_timer_pinned(&d->timer, jiffies + 1);
}
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
- int fw_engine)
+static inline void
+fw_domain_wait_ack_clear(const struct intel_uncore_forcewake_domain *d)
{
- if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0,
+ if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
+ FORCEWAKE_KERNEL) == 0,
FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
+ DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n",
+ intel_uncore_forcewake_domain_to_str(d->id));
+}
- __raw_i915_write32(dev_priv, FORCEWAKE, 1);
- /* something from same cacheline, but !FORCEWAKE */
- __raw_posting_read(dev_priv, ECOBUS);
+static inline void
+fw_domain_get(const struct intel_uncore_forcewake_domain *d)
+{
+ __raw_i915_write32(d->i915, d->reg_set, d->val_set);
+}
- if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1),
+static inline void
+fw_domain_wait_ack(const struct intel_uncore_forcewake_domain *d)
+{
+ if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
+ FORCEWAKE_KERNEL),
FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
+ DRM_ERROR("%s: timed out waiting for forcewake ack request.\n",
+ intel_uncore_forcewake_domain_to_str(d->id));
+}
- /* WaRsForcewakeWaitTC0:snb */
- __gen6_gt_wait_for_thread_c0(dev_priv);
+static inline void
+fw_domain_put(const struct intel_uncore_forcewake_domain *d)
+{
+ __raw_i915_write32(d->i915, d->reg_set, d->val_clear);
}
-static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
+static inline void
+fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
{
- __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff));
- /* something from same cacheline, but !FORCEWAKE_MT */
- __raw_posting_read(dev_priv, ECOBUS);
+ /* something from same cacheline, but not from the set register */
+ if (d->reg_post)
+ __raw_posting_read(d->i915, d->reg_post);
}
-static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv,
- int fw_engine)
+static void
+fw_domains_get(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
{
- u32 forcewake_ack;
+ struct intel_uncore_forcewake_domain *d;
+ enum forcewake_domain_id id;
- if (IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev))
- forcewake_ack = FORCEWAKE_ACK_HSW;
- else
- forcewake_ack = FORCEWAKE_MT_ACK;
+ for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
+ fw_domain_wait_ack_clear(d);
+ fw_domain_get(d);
+ fw_domain_wait_ack(d);
+ }
+}
- if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL) == 0,
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
+static void
+fw_domains_put(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
+{
+ struct intel_uncore_forcewake_domain *d;
+ enum forcewake_domain_id id;
- __raw_i915_write32(dev_priv, FORCEWAKE_MT,
- _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
- /* something from same cacheline, but !FORCEWAKE_MT */
- __raw_posting_read(dev_priv, ECOBUS);
+ for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
+ fw_domain_put(d);
+ fw_domain_posting_read(d);
+ }
+}
- if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL),
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
+static void
+fw_domains_posting_read(struct drm_i915_private *dev_priv)
+{
+ struct intel_uncore_forcewake_domain *d;
+ enum forcewake_domain_id id;
- /* WaRsForcewakeWaitTC0:ivb,hsw */
+ /* No need to do for all, just do for first found */
+ for_each_fw_domain(d, dev_priv, id) {
+ fw_domain_posting_read(d);
+ break;
+ }
+}
+
+static void
+fw_domains_reset(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
+{
+ struct intel_uncore_forcewake_domain *d;
+ enum forcewake_domain_id id;
+
+ if (dev_priv->uncore.fw_domains == 0)
+ return;
+
+ for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
+ fw_domain_reset(d);
+
+ fw_domains_posting_read(dev_priv);
+}
+
+static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
+{
+ /* w/a for a sporadic read returning 0 by waiting for the GT
+ * thread to wake up.
+ */
+ if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) &
+ GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500))
+ DRM_ERROR("GT thread status wait timed out\n");
+}
+
+static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
+ enum forcewake_domains fw_domains)
+{
+ fw_domains_get(dev_priv, fw_domains);
+
+ /* WaRsForcewakeWaitTC0:snb,ivb,hsw,bdw,vlv */
__gen6_gt_wait_for_thread_c0(dev_priv);
}
@@ -126,27 +203,13 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
__raw_i915_write32(dev_priv, GTFIFODBG, gtfifodbg);
}
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
- int fw_engine)
+static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
+ enum forcewake_domains fw_domains)
{
- __raw_i915_write32(dev_priv, FORCEWAKE, 0);
- /* something from same cacheline, but !FORCEWAKE */
- __raw_posting_read(dev_priv, ECOBUS);
+ fw_domains_put(dev_priv, fw_domains);
gen6_gt_check_fifodbg(dev_priv);
}
-static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv,
- int fw_engine)
-{
- __raw_i915_write32(dev_priv, FORCEWAKE_MT,
- _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
- /* something from same cacheline, but !FORCEWAKE_MT */
- __raw_posting_read(dev_priv, ECOBUS);
-
- if (IS_GEN7(dev_priv->dev))
- gen6_gt_check_fifodbg(dev_priv);
-}
-
static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
{
int ret = 0;
@@ -174,332 +237,78 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
return ret;
}
-static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
-{
- __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
- _MASKED_BIT_DISABLE(0xffff));
- __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
- _MASKED_BIT_DISABLE(0xffff));
- /* something from same cacheline, but !FORCEWAKE_VLV */
- __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
-}
-
-static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
- int fw_engine)
-{
- /* Check for Render Engine */
- if (FORCEWAKE_RENDER & fw_engine) {
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_VLV) &
- FORCEWAKE_KERNEL) == 0,
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
-
- __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
- _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_VLV) &
- FORCEWAKE_KERNEL),
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: waiting for Render to ack.\n");
- }
-
- /* Check for Media Engine */
- if (FORCEWAKE_MEDIA & fw_engine) {
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_MEDIA_VLV) &
- FORCEWAKE_KERNEL) == 0,
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
-
- __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
- _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_MEDIA_VLV) &
- FORCEWAKE_KERNEL),
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: waiting for media to ack.\n");
- }
-}
-
-static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
- int fw_engine)
-{
-
- /* Check for Render Engine */
- if (FORCEWAKE_RENDER & fw_engine)
- __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
- _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-
-
- /* Check for Media Engine */
- if (FORCEWAKE_MEDIA & fw_engine)
- __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
- _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-
- /* something from same cacheline, but !FORCEWAKE_VLV */
- __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
- if (!IS_CHERRYVIEW(dev_priv->dev))
- gen6_gt_check_fifodbg(dev_priv);
-}
-
-static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+static void intel_uncore_fw_release_timer(unsigned long arg)
{
+ struct intel_uncore_forcewake_domain *domain = (void *)arg;
unsigned long irqflags;
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
- if (fw_engine & FORCEWAKE_RENDER &&
- dev_priv->uncore.fw_rendercount++ != 0)
- fw_engine &= ~FORCEWAKE_RENDER;
- if (fw_engine & FORCEWAKE_MEDIA &&
- dev_priv->uncore.fw_mediacount++ != 0)
- fw_engine &= ~FORCEWAKE_MEDIA;
-
- if (fw_engine)
- dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine);
-
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-}
-
-static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
-{
- unsigned long irqflags;
-
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
- if (fw_engine & FORCEWAKE_RENDER) {
- WARN_ON(!dev_priv->uncore.fw_rendercount);
- if (--dev_priv->uncore.fw_rendercount != 0)
- fw_engine &= ~FORCEWAKE_RENDER;
- }
-
- if (fw_engine & FORCEWAKE_MEDIA) {
- WARN_ON(!dev_priv->uncore.fw_mediacount);
- if (--dev_priv->uncore.fw_mediacount != 0)
- fw_engine &= ~FORCEWAKE_MEDIA;
- }
-
- if (fw_engine)
- dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine);
-
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-}
-
-static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
-{
- __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
- _MASKED_BIT_DISABLE(0xffff));
-
- __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
- _MASKED_BIT_DISABLE(0xffff));
-
- __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
- _MASKED_BIT_DISABLE(0xffff));
-}
-
-static void
-__gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
-{
- /* Check for Render Engine */
- if (FORCEWAKE_RENDER & fw_engine) {
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_RENDER_GEN9) &
- FORCEWAKE_KERNEL) == 0,
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
-
- __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
- _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_RENDER_GEN9) &
- FORCEWAKE_KERNEL),
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: waiting for Render to ack.\n");
- }
+ assert_device_not_suspended(domain->i915);
- /* Check for Media Engine */
- if (FORCEWAKE_MEDIA & fw_engine) {
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_MEDIA_GEN9) &
- FORCEWAKE_KERNEL) == 0,
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
-
- __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
- _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_MEDIA_GEN9) &
- FORCEWAKE_KERNEL),
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: waiting for Media to ack.\n");
- }
+ spin_lock_irqsave(&domain->i915->uncore.lock, irqflags);
+ if (WARN_ON(domain->wake_count == 0))
+ domain->wake_count++;
- /* Check for Blitter Engine */
- if (FORCEWAKE_BLITTER & fw_engine) {
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_BLITTER_GEN9) &
- FORCEWAKE_KERNEL) == 0,
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");
-
- __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
- _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
- if (wait_for_atomic((__raw_i915_read32(dev_priv,
- FORCEWAKE_ACK_BLITTER_GEN9) &
- FORCEWAKE_KERNEL),
- FORCEWAKE_ACK_TIMEOUT_MS))
- DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
- }
-}
+ if (--domain->wake_count == 0)
+ domain->i915->uncore.funcs.force_wake_put(domain->i915,
+ 1 << domain->id);
-static void
-__gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
-{
- /* Check for Render Engine */
- if (FORCEWAKE_RENDER & fw_engine)
- __raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
- _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-
- /* Check for Media Engine */
- if (FORCEWAKE_MEDIA & fw_engine)
- __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
- _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-
- /* Check for Blitter Engine */
- if (FORCEWAKE_BLITTER & fw_engine)
- __raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
- _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+ spin_unlock_irqrestore(&domain->i915->uncore.lock, irqflags);
}
-static void
-gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
+ struct intel_uncore_forcewake_domain *domain;
+ int retry_count = 100;
+ enum forcewake_domain_id id;
+ enum forcewake_domains fw = 0, active_domains;
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
- if (FORCEWAKE_RENDER & fw_engine) {
- if (dev_priv->uncore.fw_rendercount++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv,
- FORCEWAKE_RENDER);
- }
-
- if (FORCEWAKE_MEDIA & fw_engine) {
- if (dev_priv->uncore.fw_mediacount++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv,
- FORCEWAKE_MEDIA);
- }
+ /* Hold uncore.lock across reset to prevent any register access
+ * with forcewake not set correctly. Wait until all pending
+ * timers are run before holding.
+ */
+ while (1) {
+ active_domains = 0;
- if (FORCEWAKE_BLITTER & fw_engine) {
- if (dev_priv->uncore.fw_blittercount++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv,
- FORCEWAKE_BLITTER);
- }
+ for_each_fw_domain(domain, dev_priv, id) {
+ if (del_timer_sync(&domain->timer) == 0)
+ continue;
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-}
+ intel_uncore_fw_release_timer((unsigned long)domain);
+ }
-static void
-gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
-{
- unsigned long irqflags;
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+ for_each_fw_domain(domain, dev_priv, id) {
+ if (timer_pending(&domain->timer))
+ active_domains |= (1 << id);
+ }
- if (FORCEWAKE_RENDER & fw_engine) {
- WARN_ON(dev_priv->uncore.fw_rendercount == 0);
- if (--dev_priv->uncore.fw_rendercount == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv,
- FORCEWAKE_RENDER);
- }
+ if (active_domains == 0)
+ break;
- if (FORCEWAKE_MEDIA & fw_engine) {
- WARN_ON(dev_priv->uncore.fw_mediacount == 0);
- if (--dev_priv->uncore.fw_mediacount == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv,
- FORCEWAKE_MEDIA);
- }
+ if (--retry_count == 0) {
+ DRM_ERROR("Timed out waiting for forcewake timers to finish\n");
+ break;
+ }
- if (FORCEWAKE_BLITTER & fw_engine) {
- WARN_ON(dev_priv->uncore.fw_blittercount == 0);
- if (--dev_priv->uncore.fw_blittercount == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv,
- FORCEWAKE_BLITTER);
+ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+ cond_resched();
}
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-}
-
-static void gen6_force_wake_timer(unsigned long arg)
-{
- struct drm_i915_private *dev_priv = (void *)arg;
- unsigned long irqflags;
-
- assert_device_not_suspended(dev_priv);
-
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- WARN_ON(!dev_priv->uncore.forcewake_count);
-
- if (--dev_priv->uncore.forcewake_count == 0)
- dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-
- intel_runtime_pm_put(dev_priv);
-}
-
-void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long irqflags;
-
- if (del_timer_sync(&dev_priv->uncore.force_wake_timer))
- gen6_force_wake_timer((unsigned long)dev_priv);
-
- /* Hold uncore.lock across reset to prevent any register access
- * with forcewake not set correctly
- */
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+ WARN_ON(active_domains);
- if (IS_VALLEYVIEW(dev))
- vlv_force_wake_reset(dev_priv);
- else if (IS_GEN6(dev) || IS_GEN7(dev))
- __gen6_gt_force_wake_reset(dev_priv);
+ for_each_fw_domain(domain, dev_priv, id)
+ if (domain->wake_count)
+ fw |= 1 << id;
- if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
- __gen7_gt_force_wake_mt_reset(dev_priv);
+ if (fw)
+ dev_priv->uncore.funcs.force_wake_put(dev_priv, fw);
- if (IS_GEN9(dev))
- __gen9_gt_force_wake_mt_reset(dev_priv);
+ fw_domains_reset(dev_priv, FORCEWAKE_ALL);
if (restore) { /* If reset with a user forcewake, try to restore */
- unsigned fw = 0;
-
- if (IS_VALLEYVIEW(dev)) {
- if (dev_priv->uncore.fw_rendercount)
- fw |= FORCEWAKE_RENDER;
-
- if (dev_priv->uncore.fw_mediacount)
- fw |= FORCEWAKE_MEDIA;
- } else if (IS_GEN9(dev)) {
- if (dev_priv->uncore.fw_rendercount)
- fw |= FORCEWAKE_RENDER;
-
- if (dev_priv->uncore.fw_mediacount)
- fw |= FORCEWAKE_MEDIA;
-
- if (dev_priv->uncore.fw_blittercount)
- fw |= FORCEWAKE_BLITTER;
- } else {
- if (dev_priv->uncore.forcewake_count)
- fw = FORCEWAKE_ALL;
- }
-
if (fw)
dev_priv->uncore.funcs.force_wake_get(dev_priv, fw);
@@ -509,17 +318,16 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
GT_FIFO_FREE_ENTRIES_MASK;
}
+ if (!restore)
+ assert_forcewakes_inactive(dev_priv);
+
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
-static void __intel_uncore_early_sanitize(struct drm_device *dev,
- bool restore_forcewake)
+static void intel_uncore_ellc_detect(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (HAS_FPGA_DBG_UNCLAIMED(dev))
- __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
-
if ((IS_HASWELL(dev) || IS_BROADWELL(dev)) &&
(__raw_i915_read32(dev_priv, HSW_EDRAM_PRESENT) == 1)) {
/* The docs do not explain exactly how the calculation can be
@@ -530,6 +338,15 @@ static void __intel_uncore_early_sanitize(struct drm_device *dev,
dev_priv->ellc_size = 128;
DRM_INFO("Found %zuMB of eLLC\n", dev_priv->ellc_size);
}
+}
+
+static void __intel_uncore_early_sanitize(struct drm_device *dev,
+ bool restore_forcewake)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (HAS_FPGA_DBG_UNCLAIMED(dev))
+ __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
/* clear out old GT FIFO errors */
if (IS_GEN6(dev) || IS_GEN7(dev))
@@ -551,81 +368,92 @@ void intel_uncore_sanitize(struct drm_device *dev)
intel_disable_gt_powersave(dev);
}
-/*
- * 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
- * be called at the beginning of the sequence followed by a call to
- * gen6_gt_force_wake_put() at the end of the sequence.
+/**
+ * intel_uncore_forcewake_get - grab forcewake domain references
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to get reference on
+ *
+ * This function can be used get GT's forcewake domain references.
+ * Normal register access will handle the forcewake domains automatically.
+ * However if some sequence requires the GT to not power down a particular
+ * forcewake domains this function should be called at the beginning of the
+ * sequence. And subsequently the reference should be dropped by symmetric
+ * call to intel_unforce_forcewake_put(). Usually caller wants all the domains
+ * to be kept awake so the @fw_domains would be then FORCEWAKE_ALL.
*/
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+ enum forcewake_domains fw_domains)
{
unsigned long irqflags;
+ struct intel_uncore_forcewake_domain *domain;
+ enum forcewake_domain_id id;
if (!dev_priv->uncore.funcs.force_wake_get)
return;
- intel_runtime_pm_get(dev_priv);
+ WARN_ON(dev_priv->pm.suspended);
- /* Redirect to Gen9 specific routine */
- if (IS_GEN9(dev_priv->dev))
- return gen9_force_wake_get(dev_priv, fw_engine);
-
- /* Redirect to VLV specific routine */
- if (IS_VALLEYVIEW(dev_priv->dev))
- return vlv_force_wake_get(dev_priv, fw_engine);
+ fw_domains &= dev_priv->uncore.fw_domains;
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- if (dev_priv->uncore.forcewake_count++ == 0)
- dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
+
+ for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
+ if (domain->wake_count++)
+ fw_domains &= ~(1 << id);
+ }
+
+ if (fw_domains)
+ dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
+
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
-/*
- * see gen6_gt_force_wake_get()
+/**
+ * intel_uncore_forcewake_put - release a forcewake domain reference
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to put references
+ *
+ * This function drops the device-level forcewakes for specified
+ * domains obtained by intel_uncore_forcewake_get().
*/
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
+void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+ enum forcewake_domains fw_domains)
{
unsigned long irqflags;
- bool delayed = false;
+ struct intel_uncore_forcewake_domain *domain;
+ enum forcewake_domain_id id;
if (!dev_priv->uncore.funcs.force_wake_put)
return;
- /* Redirect to Gen9 specific routine */
- if (IS_GEN9(dev_priv->dev)) {
- gen9_force_wake_put(dev_priv, fw_engine);
- goto out;
- }
+ fw_domains &= dev_priv->uncore.fw_domains;
- /* Redirect to VLV specific routine */
- if (IS_VALLEYVIEW(dev_priv->dev)) {
- vlv_force_wake_put(dev_priv, fw_engine);
- goto out;
- }
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+ for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
+ if (WARN_ON(domain->wake_count == 0))
+ continue;
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- WARN_ON(!dev_priv->uncore.forcewake_count);
+ if (--domain->wake_count)
+ continue;
- if (--dev_priv->uncore.forcewake_count == 0) {
- dev_priv->uncore.forcewake_count++;
- delayed = true;
- mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
- jiffies + 1);
+ domain->wake_count++;
+ fw_domain_arm_timer(domain);
}
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-out:
- if (!delayed)
- intel_runtime_pm_put(dev_priv);
+ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
-void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
+void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
{
+ struct intel_uncore_forcewake_domain *domain;
+ enum forcewake_domain_id id;
+
if (!dev_priv->uncore.funcs.force_wake_get)
return;
- WARN_ON(dev_priv->uncore.forcewake_count > 0);
+ for_each_fw_domain(domain, dev_priv, id)
+ WARN_ON(domain->wake_count);
}
/* We give fast paths for the really cool registers */
@@ -647,9 +475,9 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
#define FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg) \
(REG_RANGE((reg), 0x2000, 0x4000) || \
- REG_RANGE((reg), 0x5000, 0x8000) || \
+ REG_RANGE((reg), 0x5200, 0x8000) || \
REG_RANGE((reg), 0x8300, 0x8500) || \
- REG_RANGE((reg), 0xB000, 0xC000) || \
+ REG_RANGE((reg), 0xB000, 0xB480) || \
REG_RANGE((reg), 0xE000, 0xE800))
#define FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg) \
@@ -658,17 +486,14 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
REG_RANGE((reg), 0x12000, 0x14000) || \
REG_RANGE((reg), 0x1A000, 0x1C000) || \
REG_RANGE((reg), 0x1E800, 0x1EA00) || \
- REG_RANGE((reg), 0x30000, 0x40000))
+ REG_RANGE((reg), 0x30000, 0x38000))
#define FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg) \
(REG_RANGE((reg), 0x4000, 0x5000) || \
REG_RANGE((reg), 0x8000, 0x8300) || \
REG_RANGE((reg), 0x8500, 0x8600) || \
REG_RANGE((reg), 0x9000, 0xB000) || \
- REG_RANGE((reg), 0xC000, 0xC800) || \
- REG_RANGE((reg), 0xF000, 0x10000) || \
- REG_RANGE((reg), 0x14000, 0x14400) || \
- REG_RANGE((reg), 0x22000, 0x24000))
+ REG_RANGE((reg), 0xF000, 0x10000))
#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
REG_RANGE((reg), 0xB00, 0x2000)
@@ -740,96 +565,118 @@ hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv)
}
}
-#define REG_READ_HEADER(x) \
- unsigned long irqflags; \
+#define GEN2_READ_HEADER(x) \
u##x val = 0; \
- assert_device_not_suspended(dev_priv); \
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+ assert_device_not_suspended(dev_priv);
-#define REG_READ_FOOTER \
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
+#define GEN2_READ_FOOTER \
trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
return val
-#define __gen4_read(x) \
+#define __gen2_read(x) \
static u##x \
-gen4_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- REG_READ_HEADER(x); \
+gen2_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
+ GEN2_READ_HEADER(x); \
val = __raw_i915_read##x(dev_priv, reg); \
- REG_READ_FOOTER; \
+ GEN2_READ_FOOTER; \
}
#define __gen5_read(x) \
static u##x \
gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- REG_READ_HEADER(x); \
+ GEN2_READ_HEADER(x); \
ilk_dummy_write(dev_priv); \
val = __raw_i915_read##x(dev_priv, reg); \
- REG_READ_FOOTER; \
+ GEN2_READ_FOOTER; \
+}
+
+__gen5_read(8)
+__gen5_read(16)
+__gen5_read(32)
+__gen5_read(64)
+__gen2_read(8)
+__gen2_read(16)
+__gen2_read(32)
+__gen2_read(64)
+
+#undef __gen5_read
+#undef __gen2_read
+
+#undef GEN2_READ_FOOTER
+#undef GEN2_READ_HEADER
+
+#define GEN6_READ_HEADER(x) \
+ unsigned long irqflags; \
+ u##x val = 0; \
+ assert_device_not_suspended(dev_priv); \
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+
+#define GEN6_READ_FOOTER \
+ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
+ trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
+ return val
+
+static inline void __force_wake_get(struct drm_i915_private *dev_priv,
+ enum forcewake_domains fw_domains)
+{
+ struct intel_uncore_forcewake_domain *domain;
+ enum forcewake_domain_id id;
+
+ if (WARN_ON(!fw_domains))
+ return;
+
+ /* Ideally GCC would be constant-fold and eliminate this loop */
+ for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
+ if (domain->wake_count) {
+ fw_domains &= ~(1 << id);
+ continue;
+ }
+
+ domain->wake_count++;
+ fw_domain_arm_timer(domain);
+ }
+
+ if (fw_domains)
+ dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
}
#define __gen6_read(x) \
static u##x \
gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- REG_READ_HEADER(x); \
+ GEN6_READ_HEADER(x); \
hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
- if (dev_priv->uncore.forcewake_count == 0 && \
- NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
- dev_priv->uncore.funcs.force_wake_get(dev_priv, \
- FORCEWAKE_ALL); \
- val = __raw_i915_read##x(dev_priv, reg); \
- dev_priv->uncore.funcs.force_wake_put(dev_priv, \
- FORCEWAKE_ALL); \
- } else { \
- val = __raw_i915_read##x(dev_priv, reg); \
- } \
+ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) \
+ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+ val = __raw_i915_read##x(dev_priv, reg); \
hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
- REG_READ_FOOTER; \
+ GEN6_READ_FOOTER; \
}
#define __vlv_read(x) \
static u##x \
vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- unsigned fwengine = 0; \
- REG_READ_HEADER(x); \
- if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine = FORCEWAKE_RENDER; \
- } else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine = FORCEWAKE_MEDIA; \
- } \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+ GEN6_READ_HEADER(x); \
+ if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+ else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
val = __raw_i915_read##x(dev_priv, reg); \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
- REG_READ_FOOTER; \
+ GEN6_READ_FOOTER; \
}
#define __chv_read(x) \
static u##x \
chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- unsigned fwengine = 0; \
- REG_READ_HEADER(x); \
- if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine = FORCEWAKE_RENDER; \
- } else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine = FORCEWAKE_MEDIA; \
- } else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine |= FORCEWAKE_RENDER; \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine |= FORCEWAKE_MEDIA; \
- } \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+ GEN6_READ_HEADER(x); \
+ if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+ else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
+ else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, \
+ FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
val = __raw_i915_read##x(dev_priv, reg); \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
- REG_READ_FOOTER; \
+ GEN6_READ_FOOTER; \
}
#define SKL_NEEDS_FORCE_WAKE(dev_priv, reg) \
@@ -838,33 +685,22 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
#define __gen9_read(x) \
static u##x \
gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
- REG_READ_HEADER(x); \
- if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
- val = __raw_i915_read##x(dev_priv, reg); \
- } else { \
- unsigned fwengine = 0; \
- if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine = FORCEWAKE_RENDER; \
- } else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine = FORCEWAKE_MEDIA; \
- } else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine |= FORCEWAKE_RENDER; \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine |= FORCEWAKE_MEDIA; \
- } else { \
- if (dev_priv->uncore.fw_blittercount == 0) \
- fwengine = FORCEWAKE_BLITTER; \
- } \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
- val = __raw_i915_read##x(dev_priv, reg); \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
- } \
- REG_READ_FOOTER; \
+ enum forcewake_domains fw_engine; \
+ GEN6_READ_HEADER(x); \
+ if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) \
+ fw_engine = 0; \
+ else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \
+ fw_engine = FORCEWAKE_RENDER; \
+ else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
+ fw_engine = FORCEWAKE_MEDIA; \
+ else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
+ fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+ else \
+ fw_engine = FORCEWAKE_BLITTER; \
+ if (fw_engine) \
+ __force_wake_get(dev_priv, fw_engine); \
+ val = __raw_i915_read##x(dev_priv, reg); \
+ GEN6_READ_FOOTER; \
}
__gen9_read(8)
@@ -883,55 +719,66 @@ __gen6_read(8)
__gen6_read(16)
__gen6_read(32)
__gen6_read(64)
-__gen5_read(8)
-__gen5_read(16)
-__gen5_read(32)
-__gen5_read(64)
-__gen4_read(8)
-__gen4_read(16)
-__gen4_read(32)
-__gen4_read(64)
#undef __gen9_read
#undef __chv_read
#undef __vlv_read
#undef __gen6_read
-#undef __gen5_read
-#undef __gen4_read
-#undef REG_READ_FOOTER
-#undef REG_READ_HEADER
+#undef GEN6_READ_FOOTER
+#undef GEN6_READ_HEADER
-#define REG_WRITE_HEADER \
- unsigned long irqflags; \
+#define GEN2_WRITE_HEADER \
trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
assert_device_not_suspended(dev_priv); \
- spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
-#define REG_WRITE_FOOTER \
- spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
+#define GEN2_WRITE_FOOTER
-#define __gen4_write(x) \
+#define __gen2_write(x) \
static void \
-gen4_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- REG_WRITE_HEADER; \
+gen2_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
+ GEN2_WRITE_HEADER; \
__raw_i915_write##x(dev_priv, reg, val); \
- REG_WRITE_FOOTER; \
+ GEN2_WRITE_FOOTER; \
}
#define __gen5_write(x) \
static void \
gen5_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- REG_WRITE_HEADER; \
+ GEN2_WRITE_HEADER; \
ilk_dummy_write(dev_priv); \
__raw_i915_write##x(dev_priv, reg, val); \
- REG_WRITE_FOOTER; \
+ GEN2_WRITE_FOOTER; \
}
+__gen5_write(8)
+__gen5_write(16)
+__gen5_write(32)
+__gen5_write(64)
+__gen2_write(8)
+__gen2_write(16)
+__gen2_write(32)
+__gen2_write(64)
+
+#undef __gen5_write
+#undef __gen2_write
+
+#undef GEN2_WRITE_FOOTER
+#undef GEN2_WRITE_HEADER
+
+#define GEN6_WRITE_HEADER \
+ unsigned long irqflags; \
+ trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
+ assert_device_not_suspended(dev_priv); \
+ spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+
+#define GEN6_WRITE_FOOTER \
+ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
+
#define __gen6_write(x) \
static void \
gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
u32 __fifo_ret = 0; \
- REG_WRITE_HEADER; \
+ GEN6_WRITE_HEADER; \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
} \
@@ -939,14 +786,14 @@ gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
if (unlikely(__fifo_ret)) { \
gen6_gt_check_fifodbg(dev_priv); \
} \
- REG_WRITE_FOOTER; \
+ GEN6_WRITE_FOOTER; \
}
#define __hsw_write(x) \
static void \
hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
u32 __fifo_ret = 0; \
- REG_WRITE_HEADER; \
+ GEN6_WRITE_HEADER; \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
} \
@@ -957,7 +804,7 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
} \
hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
hsw_unclaimed_reg_detect(dev_priv); \
- REG_WRITE_FOOTER; \
+ GEN6_WRITE_FOOTER; \
}
static const u32 gen8_shadowed_regs[] = {
@@ -984,50 +831,31 @@ static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg)
#define __gen8_write(x) \
static void \
gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- REG_WRITE_HEADER; \
+ GEN6_WRITE_HEADER; \
hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
- if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \
- if (dev_priv->uncore.forcewake_count == 0) \
- dev_priv->uncore.funcs.force_wake_get(dev_priv, \
- FORCEWAKE_ALL); \
- __raw_i915_write##x(dev_priv, reg, val); \
- if (dev_priv->uncore.forcewake_count == 0) \
- dev_priv->uncore.funcs.force_wake_put(dev_priv, \
- FORCEWAKE_ALL); \
- } else { \
- __raw_i915_write##x(dev_priv, reg, val); \
- } \
+ if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+ __raw_i915_write##x(dev_priv, reg, val); \
hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
hsw_unclaimed_reg_detect(dev_priv); \
- REG_WRITE_FOOTER; \
+ GEN6_WRITE_FOOTER; \
}
#define __chv_write(x) \
static void \
chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
- unsigned fwengine = 0; \
bool shadowed = is_gen8_shadowed(dev_priv, reg); \
- REG_WRITE_HEADER; \
+ GEN6_WRITE_HEADER; \
if (!shadowed) { \
- if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine = FORCEWAKE_RENDER; \
- } else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine = FORCEWAKE_MEDIA; \
- } else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine |= FORCEWAKE_RENDER; \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine |= FORCEWAKE_MEDIA; \
- } \
+ if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+ else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
+ else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
+ __force_wake_get(dev_priv, FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
} \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
__raw_i915_write##x(dev_priv, reg, val); \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
- REG_WRITE_FOOTER; \
+ GEN6_WRITE_FOOTER; \
}
static const u32 gen9_shadowed_regs[] = {
@@ -1057,36 +885,23 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
static void \
gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
bool trace) { \
- REG_WRITE_HEADER; \
- if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
- is_gen9_shadowed(dev_priv, reg)) { \
- __raw_i915_write##x(dev_priv, reg, val); \
- } else { \
- unsigned fwengine = 0; \
- if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine = FORCEWAKE_RENDER; \
- } else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine = FORCEWAKE_MEDIA; \
- } else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
- if (dev_priv->uncore.fw_rendercount == 0) \
- fwengine |= FORCEWAKE_RENDER; \
- if (dev_priv->uncore.fw_mediacount == 0) \
- fwengine |= FORCEWAKE_MEDIA; \
- } else { \
- if (dev_priv->uncore.fw_blittercount == 0) \
- fwengine = FORCEWAKE_BLITTER; \
- } \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_get(dev_priv, \
- fwengine); \
- __raw_i915_write##x(dev_priv, reg, val); \
- if (fwengine) \
- dev_priv->uncore.funcs.force_wake_put(dev_priv, \
- fwengine); \
- } \
- REG_WRITE_FOOTER; \
+ enum forcewake_domains fw_engine; \
+ GEN6_WRITE_HEADER; \
+ if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
+ is_gen9_shadowed(dev_priv, reg)) \
+ fw_engine = 0; \
+ else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \
+ fw_engine = FORCEWAKE_RENDER; \
+ else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
+ fw_engine = FORCEWAKE_MEDIA; \
+ else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
+ fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+ else \
+ fw_engine = FORCEWAKE_BLITTER; \
+ if (fw_engine) \
+ __force_wake_get(dev_priv, fw_engine); \
+ __raw_i915_write##x(dev_priv, reg, val); \
+ GEN6_WRITE_FOOTER; \
}
__gen9_write(8)
@@ -1109,24 +924,14 @@ __gen6_write(8)
__gen6_write(16)
__gen6_write(32)
__gen6_write(64)
-__gen5_write(8)
-__gen5_write(16)
-__gen5_write(32)
-__gen5_write(64)
-__gen4_write(8)
-__gen4_write(16)
-__gen4_write(32)
-__gen4_write(64)
#undef __gen9_write
#undef __chv_write
#undef __gen8_write
#undef __hsw_write
#undef __gen6_write
-#undef __gen5_write
-#undef __gen4_write
-#undef REG_WRITE_FOOTER
-#undef REG_WRITE_HEADER
+#undef GEN6_WRITE_FOOTER
+#undef GEN6_WRITE_HEADER
#define ASSIGN_WRITE_MMIO_VFUNCS(x) \
do { \
@@ -1144,24 +949,86 @@ do { \
dev_priv->uncore.funcs.mmio_readq = x##_read64; \
} while (0)
-void intel_uncore_init(struct drm_device *dev)
+
+static void fw_domain_init(struct drm_i915_private *dev_priv,
+ enum forcewake_domain_id domain_id,
+ u32 reg_set, u32 reg_ack)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_uncore_forcewake_domain *d;
- setup_timer(&dev_priv->uncore.force_wake_timer,
- gen6_force_wake_timer, (unsigned long)dev_priv);
+ if (WARN_ON(domain_id >= FW_DOMAIN_ID_COUNT))
+ return;
- __intel_uncore_early_sanitize(dev, false);
+ d = &dev_priv->uncore.fw_domain[domain_id];
+
+ WARN_ON(d->wake_count);
+
+ d->wake_count = 0;
+ d->reg_set = reg_set;
+ d->reg_ack = reg_ack;
+
+ if (IS_GEN6(dev_priv)) {
+ d->val_reset = 0;
+ d->val_set = FORCEWAKE_KERNEL;
+ d->val_clear = 0;
+ } else {
+ d->val_reset = _MASKED_BIT_DISABLE(0xffff);
+ d->val_set = _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL);
+ d->val_clear = _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL);
+ }
+
+ if (IS_VALLEYVIEW(dev_priv))
+ d->reg_post = FORCEWAKE_ACK_VLV;
+ else if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv) || IS_GEN8(dev_priv))
+ d->reg_post = ECOBUS;
+ else
+ d->reg_post = 0;
+
+ d->i915 = dev_priv;
+ d->id = domain_id;
+
+ setup_timer(&d->timer, intel_uncore_fw_release_timer, (unsigned long)d);
+
+ dev_priv->uncore.fw_domains |= (1 << domain_id);
+
+ fw_domain_reset(d);
+}
+
+static void intel_uncore_fw_domains_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (INTEL_INFO(dev_priv->dev)->gen <= 5)
+ return;
if (IS_GEN9(dev)) {
- dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
- dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
+ dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
+ dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_RENDER_GEN9,
+ FORCEWAKE_ACK_RENDER_GEN9);
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_BLITTER,
+ FORCEWAKE_BLITTER_GEN9,
+ FORCEWAKE_ACK_BLITTER_GEN9);
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
+ FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
} else if (IS_VALLEYVIEW(dev)) {
- dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
- dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
+ dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
+ if (!IS_CHERRYVIEW(dev))
+ dev_priv->uncore.funcs.force_wake_put =
+ fw_domains_put_with_fifo;
+ else
+ dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
+ FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
- dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get;
- dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put;
+ dev_priv->uncore.funcs.force_wake_get =
+ fw_domains_get_with_thread_status;
+ dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
} else if (IS_IVYBRIDGE(dev)) {
u32 ecobus;
@@ -1174,35 +1041,54 @@ void intel_uncore_init(struct drm_device *dev)
* (correctly) interpreted by the test below as MT
* forcewake being disabled.
*/
+ dev_priv->uncore.funcs.force_wake_get =
+ fw_domains_get_with_thread_status;
+ dev_priv->uncore.funcs.force_wake_put =
+ fw_domains_put_with_fifo;
+
+ /* We need to init first for ECOBUS access and then
+ * determine later if we want to reinit, in case of MT access is
+ * not working
+ */
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_MT, FORCEWAKE_MT_ACK);
+
mutex_lock(&dev->struct_mutex);
- __gen7_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL);
+ fw_domains_get_with_thread_status(dev_priv, FORCEWAKE_ALL);
ecobus = __raw_i915_read32(dev_priv, ECOBUS);
- __gen7_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL);
+ fw_domains_put_with_fifo(dev_priv, FORCEWAKE_ALL);
mutex_unlock(&dev->struct_mutex);
- if (ecobus & FORCEWAKE_MT_ENABLE) {
- dev_priv->uncore.funcs.force_wake_get =
- __gen7_gt_force_wake_mt_get;
- dev_priv->uncore.funcs.force_wake_put =
- __gen7_gt_force_wake_mt_put;
- } else {
+ if (!(ecobus & FORCEWAKE_MT_ENABLE)) {
DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
DRM_INFO("when using vblank-synced partial screen updates.\n");
- dev_priv->uncore.funcs.force_wake_get =
- __gen6_gt_force_wake_get;
- dev_priv->uncore.funcs.force_wake_put =
- __gen6_gt_force_wake_put;
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+ FORCEWAKE, FORCEWAKE_ACK);
}
} else if (IS_GEN6(dev)) {
dev_priv->uncore.funcs.force_wake_get =
- __gen6_gt_force_wake_get;
+ fw_domains_get_with_thread_status;
dev_priv->uncore.funcs.force_wake_put =
- __gen6_gt_force_wake_put;
+ fw_domains_put_with_fifo;
+ fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+ FORCEWAKE, FORCEWAKE_ACK);
}
+ /* All future platforms are expected to require complex power gating */
+ WARN_ON(dev_priv->uncore.fw_domains == 0);
+}
+
+void intel_uncore_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ intel_uncore_ellc_detect(dev);
+ intel_uncore_fw_domains_init(dev);
+ __intel_uncore_early_sanitize(dev, false);
+
switch (INTEL_INFO(dev)->gen) {
default:
- WARN_ON(1);
+ MISSING_CASE(INTEL_INFO(dev)->gen);
return;
case 9:
ASSIGN_WRITE_MMIO_VFUNCS(gen9);
@@ -1239,8 +1125,8 @@ void intel_uncore_init(struct drm_device *dev)
case 4:
case 3:
case 2:
- ASSIGN_WRITE_MMIO_VFUNCS(gen4);
- ASSIGN_READ_MMIO_VFUNCS(gen4);
+ ASSIGN_WRITE_MMIO_VFUNCS(gen2);
+ ASSIGN_READ_MMIO_VFUNCS(gen2);
break;
}
@@ -1300,7 +1186,7 @@ int i915_reg_read_ioctl(struct drm_device *dev,
reg->val = I915_READ8(reg->offset);
break;
default:
- WARN_ON(1);
+ MISSING_CASE(entry->size);
ret = -EINVAL;
goto out;
}
diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index ab31848e92cf..33cdddf26684 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -5,7 +5,7 @@ config DRM_IMX
select VIDEOMODE_HELPERS
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
- depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM)
+ depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) && HAVE_DMA_ATTRS
depends on IMX_IPUV3_CORE
help
enable i.MX graphics support
@@ -49,6 +49,7 @@ config DRM_IMX_IPUV3
config DRM_IMX_HDMI
tristate "Freescale i.MX DRM HDMI"
+ select DRM_DW_HDMI
depends on DRM_IMX
help
Choose this if you want to use HDMI on i.MX6.
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index 582c438d8cbd..f3ecd8903d97 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o
obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o
-obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o
+obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
new file mode 100644
index 000000000000..121d30ca2d44
--- /dev/null
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -0,0 +1,258 @@
+/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ *
+ * derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <drm/bridge/dw_hdmi.h>
+#include <video/imx-ipu-v3.h>
+#include <linux/regmap.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+
+#include "imx-drm.h"
+
+struct imx_hdmi {
+ struct device *dev;
+ struct drm_encoder encoder;
+ struct regmap *regmap;
+};
+
+static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = {
+ {
+ 45250000, {
+ { 0x01e0, 0x0000 },
+ { 0x21e1, 0x0000 },
+ { 0x41e2, 0x0000 }
+ },
+ }, {
+ 92500000, {
+ { 0x0140, 0x0005 },
+ { 0x2141, 0x0005 },
+ { 0x4142, 0x0005 },
+ },
+ }, {
+ 148500000, {
+ { 0x00a0, 0x000a },
+ { 0x20a1, 0x000a },
+ { 0x40a2, 0x000a },
+ },
+ }, {
+ ~0UL, {
+ { 0x00a0, 0x000a },
+ { 0x2001, 0x000f },
+ { 0x4002, 0x000f },
+ },
+ }
+};
+
+static const struct dw_hdmi_curr_ctrl imx_cur_ctr[] = {
+ /* pixelclk bpp8 bpp10 bpp12 */
+ {
+ 54000000, { 0x091c, 0x091c, 0x06dc },
+ }, {
+ 58400000, { 0x091c, 0x06dc, 0x06dc },
+ }, {
+ 72000000, { 0x06dc, 0x06dc, 0x091c },
+ }, {
+ 74250000, { 0x06dc, 0x0b5c, 0x091c },
+ }, {
+ 118800000, { 0x091c, 0x091c, 0x06dc },
+ }, {
+ 216000000, { 0x06dc, 0x0b5c, 0x091c },
+ }
+};
+
+static const struct dw_hdmi_sym_term imx_sym_term[] = {
+ /*pixelclk symbol term*/
+ { 148500000, 0x800d, 0x0005 },
+ { ~0UL, 0x0000, 0x0000 }
+};
+
+static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi)
+{
+ struct device_node *np = hdmi->dev->of_node;
+
+ hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+ if (IS_ERR(hdmi->regmap)) {
+ dev_err(hdmi->dev, "Unable to get gpr\n");
+ return PTR_ERR(hdmi->regmap);
+ }
+
+ return 0;
+}
+
+static void dw_hdmi_imx_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static bool dw_hdmi_imx_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adj_mode)
+{
+ return true;
+}
+
+static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adj_mode)
+{
+}
+
+static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder)
+{
+ struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
+ int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
+
+ regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
+ IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
+ mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
+}
+
+static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder)
+{
+ imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
+}
+
+static struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {
+ .mode_fixup = dw_hdmi_imx_encoder_mode_fixup,
+ .mode_set = dw_hdmi_imx_encoder_mode_set,
+ .prepare = dw_hdmi_imx_encoder_prepare,
+ .commit = dw_hdmi_imx_encoder_commit,
+ .disable = dw_hdmi_imx_encoder_disable,
+};
+
+static struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+static struct dw_hdmi_plat_data imx6q_hdmi_drv_data = {
+ .mpll_cfg = imx_mpll_cfg,
+ .cur_ctr = imx_cur_ctr,
+ .sym_term = imx_sym_term,
+ .dev_type = IMX6Q_HDMI,
+};
+
+static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = {
+ .mpll_cfg = imx_mpll_cfg,
+ .cur_ctr = imx_cur_ctr,
+ .sym_term = imx_sym_term,
+ .dev_type = IMX6DL_HDMI,
+};
+
+static const struct of_device_id dw_hdmi_imx_dt_ids[] = {
+ { .compatible = "fsl,imx6q-hdmi",
+ .data = &imx6q_hdmi_drv_data
+ }, {
+ .compatible = "fsl,imx6dl-hdmi",
+ .data = &imx6dl_hdmi_drv_data
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids);
+
+static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ const struct dw_hdmi_plat_data *plat_data;
+ const struct of_device_id *match;
+ struct drm_device *drm = data;
+ struct drm_encoder *encoder;
+ struct imx_hdmi *hdmi;
+ struct resource *iores;
+ int irq;
+ int ret;
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+ if (!hdmi)
+ return -ENOMEM;
+
+ match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node);
+ plat_data = match->data;
+ hdmi->dev = &pdev->dev;
+ encoder = &hdmi->encoder;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iores)
+ return -ENXIO;
+
+ platform_set_drvdata(pdev, hdmi);
+
+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+ /*
+ * If we failed to find the CRTC(s) which this encoder is
+ * supposed to be connected to, it's because the CRTC has
+ * not been registered yet. Defer probing, and hope that
+ * the required CRTC is added later.
+ */
+ if (encoder->possible_crtcs == 0)
+ return -EPROBE_DEFER;
+
+ ret = dw_hdmi_imx_parse_dt(hdmi);
+ if (ret < 0)
+ return ret;
+
+ drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs);
+ drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+
+ return dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+}
+
+static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ return dw_hdmi_unbind(dev, master, data);
+}
+
+static const struct component_ops dw_hdmi_imx_ops = {
+ .bind = dw_hdmi_imx_bind,
+ .unbind = dw_hdmi_imx_unbind,
+};
+
+static int dw_hdmi_imx_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &dw_hdmi_imx_ops);
+}
+
+static int dw_hdmi_imx_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &dw_hdmi_imx_ops);
+
+ return 0;
+}
+
+static struct platform_driver dw_hdmi_imx_platform_driver = {
+ .probe = dw_hdmi_imx_probe,
+ .remove = dw_hdmi_imx_remove,
+ .driver = {
+ .name = "dwhdmi-imx",
+ .of_match_table = dw_hdmi_imx_dt_ids,
+ },
+};
+
+module_platform_driver(dw_hdmi_imx_platform_driver);
+
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_DESCRIPTION("IMX6 Specific DW-HDMI Driver Extension");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dwhdmi-imx");
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index b250130debc8..a002f53aab0e 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -25,6 +25,7 @@
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_plane_helper.h>
+#include <drm/drm_of.h>
#include "imx-drm.h"
@@ -46,7 +47,6 @@ struct imx_drm_crtc {
struct drm_crtc *crtc;
int pipe;
struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs;
- struct device_node *port;
};
static int legacyfb_depth = 16;
@@ -116,8 +116,7 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder,
helper = &imx_crtc->imx_drm_helper_funcs;
if (helper->set_interface_pix_fmt)
return helper->set_interface_pix_fmt(encoder->crtc,
- encoder->encoder_type, interface_pix_fmt,
- hsync_pin, vsync_pin);
+ interface_pix_fmt, hsync_pin, vsync_pin);
return 0;
}
EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins);
@@ -365,9 +364,10 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
imx_drm_crtc->pipe = imxdrm->pipes++;
- imx_drm_crtc->port = port;
imx_drm_crtc->crtc = crtc;
+ crtc->port = port;
+
imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc;
*new_crtc = imx_drm_crtc;
@@ -408,33 +408,28 @@ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
}
EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
-/*
- * Find the DRM CRTC possible mask for the connected endpoint.
- *
- * The encoder possible masks are defined by their position in the
- * mode_config crtc_list. This means that CRTCs must not be added
- * or removed once the DRM device has been fully initialised.
- */
-static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm,
- struct device_node *endpoint)
+int imx_drm_encoder_parse_of(struct drm_device *drm,
+ struct drm_encoder *encoder, struct device_node *np)
{
- struct device_node *port;
- unsigned i;
+ uint32_t crtc_mask = drm_of_find_possible_crtcs(drm, np);
- port = of_graph_get_remote_port(endpoint);
- if (!port)
- return 0;
- of_node_put(port);
+ /*
+ * If we failed to find the CRTC(s) which this encoder is
+ * supposed to be connected to, it's because the CRTC has
+ * not been registered yet. Defer probing, and hope that
+ * the required CRTC is added later.
+ */
+ if (crtc_mask == 0)
+ return -EPROBE_DEFER;
- for (i = 0; i < MAX_CRTC; i++) {
- struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i];
+ encoder->possible_crtcs = crtc_mask;
- if (imx_drm_crtc && imx_drm_crtc->port == port)
- return drm_crtc_mask(imx_drm_crtc->crtc);
- }
+ /* FIXME: this is the mask of outputs which can clone this output. */
+ encoder->possible_clones = ~0;
return 0;
}
+EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
static struct device_node *imx_drm_of_get_next_endpoint(
const struct device_node *parent, struct device_node *prev)
@@ -445,48 +440,6 @@ static struct device_node *imx_drm_of_get_next_endpoint(
return node;
}
-int imx_drm_encoder_parse_of(struct drm_device *drm,
- struct drm_encoder *encoder, struct device_node *np)
-{
- struct imx_drm_device *imxdrm = drm->dev_private;
- struct device_node *ep = NULL;
- uint32_t crtc_mask = 0;
- int i;
-
- for (i = 0; ; i++) {
- u32 mask;
-
- ep = imx_drm_of_get_next_endpoint(np, ep);
- if (!ep)
- break;
-
- mask = imx_drm_find_crtc_mask(imxdrm, ep);
-
- /*
- * If we failed to find the CRTC(s) which this encoder is
- * supposed to be connected to, it's because the CRTC has
- * not been registered yet. Defer probing, and hope that
- * the required CRTC is added later.
- */
- if (mask == 0)
- return -EPROBE_DEFER;
-
- crtc_mask |= mask;
- }
-
- of_node_put(ep);
- if (i == 0)
- return -ENOENT;
-
- encoder->possible_crtcs = crtc_mask;
-
- /* FIXME: this is the mask of outputs which can clone this output. */
- encoder->possible_clones = ~0;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
-
/*
* @node: device tree node containing encoder input ports
* @encoder: drm_encoder
@@ -510,7 +463,7 @@ int imx_drm_encoder_get_mux_id(struct device_node *node,
port = of_graph_get_remote_port(ep);
of_node_put(port);
- if (port == imx_crtc->port) {
+ if (port == imx_crtc->crtc->port) {
ret = of_graph_parse_endpoint(ep, &endpoint);
return ret ? ret : endpoint.port;
}
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
index 7453ae00c412..3c559ccd6af0 100644
--- a/drivers/gpu/drm/imx/imx-drm.h
+++ b/drivers/gpu/drm/imx/imx-drm.h
@@ -17,7 +17,7 @@ int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
struct imx_drm_crtc_helper_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
- int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type,
+ int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
u32 pix_fmt, int hsync_pin, int vsync_pin);
const struct drm_crtc_helper_funcs *crtc_helper_funcs;
const struct drm_crtc_funcs *crtc_funcs;
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index c60460043e24..1b86aac0b341 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -163,7 +163,7 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
{
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
struct imx_ldb *ldb = imx_ldb_ch->ldb;
- struct drm_display_mode *mode = &encoder->crtc->mode;
+ struct drm_display_mode *mode = &encoder->crtc->hwmode;
u32 pixel_fmt;
unsigned long serial_clk;
unsigned long di_clk = mode->clock * 1000;
@@ -241,8 +241,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
}
static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+ struct drm_display_mode *orig_mode,
+ struct drm_display_mode *mode)
{
struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
struct imx_ldb *ldb = imx_ldb_ch->ldb;
@@ -574,6 +574,8 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
channel->connector.funcs->destroy(&channel->connector);
channel->encoder.funcs->destroy(&channel->encoder);
+
+ kfree(channel->edid);
}
}
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index a729f4f7074c..4216e479a9be 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -191,10 +191,18 @@ static int tve_setup_vga(struct imx_tve *tve)
/* set gain to (1 + 10/128) to provide 0.7V peak-to-peak amplitude */
ret = regmap_update_bits(tve->regmap, TVE_TVDAC0_CONT_REG,
TVE_TVDAC_GAIN_MASK, 0x0a);
+ if (ret)
+ return ret;
+
ret = regmap_update_bits(tve->regmap, TVE_TVDAC1_CONT_REG,
TVE_TVDAC_GAIN_MASK, 0x0a);
+ if (ret)
+ return ret;
+
ret = regmap_update_bits(tve->regmap, TVE_TVDAC2_CONT_REG,
TVE_TVDAC_GAIN_MASK, 0x0a);
+ if (ret)
+ return ret;
/* set configuration register */
mask = TVE_DATA_SOURCE_MASK | TVE_INP_VIDEO_FORM;
@@ -204,16 +212,12 @@ static int tve_setup_vga(struct imx_tve *tve)
mask |= TVE_TV_OUT_MODE_MASK | TVE_SYNC_CH_0_EN;
val |= TVE_TV_OUT_RGB | TVE_SYNC_CH_0_EN;
ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, mask, val);
- if (ret < 0) {
- dev_err(tve->dev, "failed to set configuration: %d\n", ret);
+ if (ret)
return ret;
- }
/* set test mode (as documented) */
- ret = regmap_update_bits(tve->regmap, TVE_TST_MODE_REG,
+ return regmap_update_bits(tve->regmap, TVE_TST_MODE_REG,
TVE_TVDAC_TEST_MODE_MASK, 1);
-
- return 0;
}
static enum drm_connector_status imx_tve_connector_detect(
@@ -307,8 +311,8 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
}
static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+ struct drm_display_mode *orig_mode,
+ struct drm_display_mode *mode)
{
struct imx_tve *tve = enc_to_tve(encoder);
unsigned long rounded_rate;
@@ -335,9 +339,11 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
}
if (tve->mode == TVE_MODE_VGA)
- tve_setup_vga(tve);
+ ret = tve_setup_vga(tve);
else
- tve_setup_tvout(tve);
+ ret = tve_setup_tvout(tve);
+ if (ret)
+ dev_err(tve->dev, "failed to set configuration: %d\n", ret);
}
static void imx_tve_encoder_commit(struct drm_encoder *encoder)
@@ -671,6 +677,8 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data)
/* disable cable detection for VGA mode */
ret = regmap_write(tve->regmap, TVE_CD_CONT_REG, 0);
+ if (ret)
+ return ret;
ret = imx_tve_register(drm, tve);
if (ret)
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index ebee59cb96d8..98551e356e12 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -46,7 +46,6 @@ struct ipu_crtc {
struct drm_framebuffer *newfb;
int irq;
u32 interface_pix_fmt;
- unsigned long di_clkflags;
int di_hsync_pin;
int di_vsync_pin;
};
@@ -141,47 +140,51 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
int x, int y,
struct drm_framebuffer *old_fb)
{
+ struct drm_device *dev = crtc->dev;
+ struct drm_encoder *encoder;
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
- int ret;
struct ipu_di_signal_cfg sig_cfg = {};
+ unsigned long encoder_types = 0;
u32 out_pixel_fmt;
+ int ret;
dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
mode->hdisplay);
dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
mode->vdisplay);
- out_pixel_fmt = ipu_crtc->interface_pix_fmt;
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+ if (encoder->crtc == crtc)
+ encoder_types |= BIT(encoder->encoder_type);
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- sig_cfg.interlaced = 1;
- if (mode->flags & DRM_MODE_FLAG_PHSYNC)
- sig_cfg.Hsync_pol = 1;
- if (mode->flags & DRM_MODE_FLAG_PVSYNC)
- sig_cfg.Vsync_pol = 1;
+ dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n",
+ __func__, encoder_types);
+
+ /*
+ * If we have DAC, TVDAC or LDB, then we need the IPU DI clock
+ * to be the same as the LDB DI clock.
+ */
+ if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) |
+ BIT(DRM_MODE_ENCODER_TVDAC) |
+ BIT(DRM_MODE_ENCODER_LVDS)))
+ sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT;
+ else
+ sig_cfg.clkflags = 0;
+
+ out_pixel_fmt = ipu_crtc->interface_pix_fmt;
sig_cfg.enable_pol = 1;
sig_cfg.clk_pol = 0;
- sig_cfg.width = mode->hdisplay;
- sig_cfg.height = mode->vdisplay;
sig_cfg.pixel_fmt = out_pixel_fmt;
- sig_cfg.h_start_width = mode->htotal - mode->hsync_end;
- sig_cfg.h_sync_width = mode->hsync_end - mode->hsync_start;
- sig_cfg.h_end_width = mode->hsync_start - mode->hdisplay;
-
- sig_cfg.v_start_width = mode->vtotal - mode->vsync_end;
- sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start;
- sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay;
- sig_cfg.pixelclock = mode->clock * 1000;
- sig_cfg.clkflags = ipu_crtc->di_clkflags;
-
sig_cfg.v_to_h_sync = 0;
-
sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
- ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced,
- out_pixel_fmt, mode->hdisplay);
+ drm_display_mode_to_videomode(mode, &sig_cfg.mode);
+
+ ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
+ mode->flags & DRM_MODE_FLAG_INTERLACE,
+ out_pixel_fmt, mode->hdisplay);
if (ret) {
dev_err(ipu_crtc->dev,
"initializing display controller failed with %d\n",
@@ -237,6 +240,18 @@ static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+ struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+ struct videomode vm;
+ int ret;
+
+ drm_display_mode_to_videomode(adjusted_mode, &vm);
+
+ ret = ipu_di_adjust_videomode(ipu_crtc->di, &vm);
+ if (ret)
+ return false;
+
+ drm_display_mode_from_videomode(&vm, adjusted_mode);
+
return true;
}
@@ -275,7 +290,7 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
ipu_crtc->newfb = NULL;
}
-static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
+static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
u32 pixfmt, int hsync_pin, int vsync_pin)
{
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
@@ -284,19 +299,6 @@ static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
ipu_crtc->di_hsync_pin = hsync_pin;
ipu_crtc->di_vsync_pin = vsync_pin;
- switch (encoder_type) {
- case DRM_MODE_ENCODER_DAC:
- case DRM_MODE_ENCODER_TVDAC:
- case DRM_MODE_ENCODER_LVDS:
- ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC |
- IPU_DI_CLKMODE_EXT;
- break;
- case DRM_MODE_ENCODER_TMDS:
- case DRM_MODE_ENCODER_NONE:
- ipu_crtc->di_clkflags = 0;
- break;
- }
-
return 0;
}
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 796c3c1c170a..5e83e007080f 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -130,8 +130,8 @@ static void imx_pd_encoder_commit(struct drm_encoder *encoder)
}
static void imx_pd_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+ struct drm_display_mode *orig_mode,
+ struct drm_display_mode *mode)
{
}
@@ -257,6 +257,8 @@ static void imx_pd_unbind(struct device *dev, struct device *master,
imxpd->encoder.funcs->destroy(&imxpd->encoder);
imxpd->connector.funcs->destroy(&imxpd->connector);
+
+ kfree(imxpd->edid);
}
static const struct component_ops imx_pd_ops = {
@@ -272,6 +274,7 @@ static int imx_pd_probe(struct platform_device *pdev)
static int imx_pd_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &imx_pd_ops);
+
return 0;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 4415af3666ab..c36b8304042b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -303,14 +303,22 @@ int mgag200_fbdev_init(struct mga_device *mdev)
if (ret)
return ret;
- drm_fb_helper_single_add_all_connectors(&mfbdev->helper);
+ ret = drm_fb_helper_single_add_all_connectors(&mfbdev->helper);
+ if (ret)
+ goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(mdev->dev);
- drm_fb_helper_initial_config(&mfbdev->helper, bpp_sel);
+ ret = drm_fb_helper_initial_config(&mfbdev->helper, bpp_sel);
+ if (ret)
+ goto fini;
return 0;
+
+fini:
+ drm_fb_helper_fini(&mfbdev->helper);
+ return ret;
}
void mgag200_fbdev_fini(struct mga_device *mdev)
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 5b2a1ff95d3d..bacbbb70f679 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -3,6 +3,7 @@ config DRM_MSM
tristate "MSM DRM"
depends on DRM
depends on ARCH_QCOM || (ARM && COMPILE_TEST)
+ depends on OF && COMMON_CLK
select REGULATOR
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 143d988f8add..674a132fd76e 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -1,7 +1,4 @@
ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/msm
-ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
- ccflags-y += -Werror
-endif
msm-y := \
adreno/adreno_device.o \
@@ -16,6 +13,12 @@ msm-y := \
hdmi/hdmi_phy_8960.o \
hdmi/hdmi_phy_8x60.o \
hdmi/hdmi_phy_8x74.o \
+ edp/edp.o \
+ edp/edp_aux.o \
+ edp/edp_bridge.o \
+ edp/edp_connector.o \
+ edp/edp_ctrl.o \
+ edp/edp_phy.o \
mdp/mdp_format.o \
mdp/mdp_kms.o \
mdp/mdp4/mdp4_crtc.o \
diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
index 22882cc0a573..edc845fffdf4 100644
--- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
@@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54)
Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
index 109e9a263daf..e91a739452d7 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
@@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54)
Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -58,111 +58,130 @@ enum a3xx_cache_opcode {
};
enum a3xx_vtx_fmt {
- VFMT_FLOAT_32 = 0,
- VFMT_FLOAT_32_32 = 1,
- VFMT_FLOAT_32_32_32 = 2,
- VFMT_FLOAT_32_32_32_32 = 3,
- VFMT_FLOAT_16 = 4,
- VFMT_FLOAT_16_16 = 5,
- VFMT_FLOAT_16_16_16 = 6,
- VFMT_FLOAT_16_16_16_16 = 7,
- VFMT_FIXED_32 = 8,
- VFMT_FIXED_32_32 = 9,
- VFMT_FIXED_32_32_32 = 10,
- VFMT_FIXED_32_32_32_32 = 11,
- VFMT_SHORT_16 = 16,
- VFMT_SHORT_16_16 = 17,
- VFMT_SHORT_16_16_16 = 18,
- VFMT_SHORT_16_16_16_16 = 19,
- VFMT_USHORT_16 = 20,
- VFMT_USHORT_16_16 = 21,
- VFMT_USHORT_16_16_16 = 22,
- VFMT_USHORT_16_16_16_16 = 23,
- VFMT_NORM_SHORT_16 = 24,
- VFMT_NORM_SHORT_16_16 = 25,
- VFMT_NORM_SHORT_16_16_16 = 26,
- VFMT_NORM_SHORT_16_16_16_16 = 27,
- VFMT_NORM_USHORT_16 = 28,
- VFMT_NORM_USHORT_16_16 = 29,
- VFMT_NORM_USHORT_16_16_16 = 30,
- VFMT_NORM_USHORT_16_16_16_16 = 31,
- VFMT_UINT_32 = 32,
- VFMT_UINT_32_32 = 33,
- VFMT_UINT_32_32_32 = 34,
- VFMT_UINT_32_32_32_32 = 35,
- VFMT_INT_32 = 36,
- VFMT_INT_32_32 = 37,
- VFMT_INT_32_32_32 = 38,
- VFMT_INT_32_32_32_32 = 39,
- VFMT_UBYTE_8 = 40,
- VFMT_UBYTE_8_8 = 41,
- VFMT_UBYTE_8_8_8 = 42,
- VFMT_UBYTE_8_8_8_8 = 43,
- VFMT_NORM_UBYTE_8 = 44,
- VFMT_NORM_UBYTE_8_8 = 45,
- VFMT_NORM_UBYTE_8_8_8 = 46,
- VFMT_NORM_UBYTE_8_8_8_8 = 47,
- VFMT_BYTE_8 = 48,
- VFMT_BYTE_8_8 = 49,
- VFMT_BYTE_8_8_8 = 50,
- VFMT_BYTE_8_8_8_8 = 51,
- VFMT_NORM_BYTE_8 = 52,
- VFMT_NORM_BYTE_8_8 = 53,
- VFMT_NORM_BYTE_8_8_8 = 54,
- VFMT_NORM_BYTE_8_8_8_8 = 55,
- VFMT_UINT_10_10_10_2 = 60,
- VFMT_NORM_UINT_10_10_10_2 = 61,
- VFMT_INT_10_10_10_2 = 62,
- VFMT_NORM_INT_10_10_10_2 = 63,
+ VFMT_32_FLOAT = 0,
+ VFMT_32_32_FLOAT = 1,
+ VFMT_32_32_32_FLOAT = 2,
+ VFMT_32_32_32_32_FLOAT = 3,
+ VFMT_16_FLOAT = 4,
+ VFMT_16_16_FLOAT = 5,
+ VFMT_16_16_16_FLOAT = 6,
+ VFMT_16_16_16_16_FLOAT = 7,
+ VFMT_32_FIXED = 8,
+ VFMT_32_32_FIXED = 9,
+ VFMT_32_32_32_FIXED = 10,
+ VFMT_32_32_32_32_FIXED = 11,
+ VFMT_16_SINT = 16,
+ VFMT_16_16_SINT = 17,
+ VFMT_16_16_16_SINT = 18,
+ VFMT_16_16_16_16_SINT = 19,
+ VFMT_16_UINT = 20,
+ VFMT_16_16_UINT = 21,
+ VFMT_16_16_16_UINT = 22,
+ VFMT_16_16_16_16_UINT = 23,
+ VFMT_16_SNORM = 24,
+ VFMT_16_16_SNORM = 25,
+ VFMT_16_16_16_SNORM = 26,
+ VFMT_16_16_16_16_SNORM = 27,
+ VFMT_16_UNORM = 28,
+ VFMT_16_16_UNORM = 29,
+ VFMT_16_16_16_UNORM = 30,
+ VFMT_16_16_16_16_UNORM = 31,
+ VFMT_32_UINT = 32,
+ VFMT_32_32_UINT = 33,
+ VFMT_32_32_32_UINT = 34,
+ VFMT_32_32_32_32_UINT = 35,
+ VFMT_32_SINT = 36,
+ VFMT_32_32_SINT = 37,
+ VFMT_32_32_32_SINT = 38,
+ VFMT_32_32_32_32_SINT = 39,
+ VFMT_8_UINT = 40,
+ VFMT_8_8_UINT = 41,
+ VFMT_8_8_8_UINT = 42,
+ VFMT_8_8_8_8_UINT = 43,
+ VFMT_8_UNORM = 44,
+ VFMT_8_8_UNORM = 45,
+ VFMT_8_8_8_UNORM = 46,
+ VFMT_8_8_8_8_UNORM = 47,
+ VFMT_8_SINT = 48,
+ VFMT_8_8_SINT = 49,
+ VFMT_8_8_8_SINT = 50,
+ VFMT_8_8_8_8_SINT = 51,
+ VFMT_8_SNORM = 52,
+ VFMT_8_8_SNORM = 53,
+ VFMT_8_8_8_SNORM = 54,
+ VFMT_8_8_8_8_SNORM = 55,
+ VFMT_10_10_10_2_UINT = 60,
+ VFMT_10_10_10_2_UNORM = 61,
+ VFMT_10_10_10_2_SINT = 62,
+ VFMT_10_10_10_2_SNORM = 63,
};
enum a3xx_tex_fmt {
- TFMT_NORM_USHORT_565 = 4,
- TFMT_NORM_USHORT_5551 = 6,
- TFMT_NORM_USHORT_4444 = 7,
- TFMT_NORM_USHORT_Z16 = 9,
- TFMT_NORM_UINT_X8Z24 = 10,
- TFMT_FLOAT_Z32 = 11,
- TFMT_NORM_UINT_NV12_UV_TILED = 17,
- TFMT_NORM_UINT_NV12_Y_TILED = 19,
- TFMT_NORM_UINT_NV12_UV = 21,
- TFMT_NORM_UINT_NV12_Y = 23,
- TFMT_NORM_UINT_I420_Y = 24,
- TFMT_NORM_UINT_I420_U = 26,
- TFMT_NORM_UINT_I420_V = 27,
- TFMT_NORM_UINT_2_10_10_10 = 41,
- TFMT_FLOAT_9_9_9_E5 = 42,
- TFMT_FLOAT_10_11_11 = 43,
- TFMT_NORM_UINT_A8 = 44,
- TFMT_NORM_UINT_L8_A8 = 47,
- TFMT_NORM_UINT_8 = 48,
- TFMT_NORM_UINT_8_8 = 49,
- TFMT_NORM_UINT_8_8_8 = 50,
- TFMT_NORM_UINT_8_8_8_8 = 51,
- TFMT_NORM_SINT_8_8 = 53,
- TFMT_NORM_SINT_8_8_8_8 = 55,
- TFMT_UINT_8_8 = 57,
- TFMT_UINT_8_8_8_8 = 59,
- TFMT_SINT_8_8 = 61,
- TFMT_SINT_8_8_8_8 = 63,
- TFMT_FLOAT_16 = 64,
- TFMT_FLOAT_16_16 = 65,
- TFMT_FLOAT_16_16_16_16 = 67,
- TFMT_UINT_16 = 68,
- TFMT_UINT_16_16 = 69,
- TFMT_UINT_16_16_16_16 = 71,
- TFMT_SINT_16 = 72,
- TFMT_SINT_16_16 = 73,
- TFMT_SINT_16_16_16_16 = 75,
- TFMT_FLOAT_32 = 84,
- TFMT_FLOAT_32_32 = 85,
- TFMT_FLOAT_32_32_32_32 = 87,
- TFMT_UINT_32 = 88,
- TFMT_UINT_32_32 = 89,
- TFMT_UINT_32_32_32_32 = 91,
- TFMT_SINT_32 = 92,
- TFMT_SINT_32_32 = 93,
- TFMT_SINT_32_32_32_32 = 95,
+ TFMT_5_6_5_UNORM = 4,
+ TFMT_5_5_5_1_UNORM = 5,
+ TFMT_4_4_4_4_UNORM = 7,
+ TFMT_Z16_UNORM = 9,
+ TFMT_X8Z24_UNORM = 10,
+ TFMT_Z32_FLOAT = 11,
+ TFMT_NV12_UV_TILED = 17,
+ TFMT_NV12_Y_TILED = 19,
+ TFMT_NV12_UV = 21,
+ TFMT_NV12_Y = 23,
+ TFMT_I420_Y = 24,
+ TFMT_I420_U = 26,
+ TFMT_I420_V = 27,
+ TFMT_DXT1 = 36,
+ TFMT_DXT3 = 37,
+ TFMT_DXT5 = 38,
+ TFMT_10_10_10_2_UNORM = 41,
+ TFMT_9_9_9_E5_FLOAT = 42,
+ TFMT_11_11_10_FLOAT = 43,
+ TFMT_A8_UNORM = 44,
+ TFMT_L8_A8_UNORM = 47,
+ TFMT_8_UNORM = 48,
+ TFMT_8_8_UNORM = 49,
+ TFMT_8_8_8_UNORM = 50,
+ TFMT_8_8_8_8_UNORM = 51,
+ TFMT_8_SNORM = 52,
+ TFMT_8_8_SNORM = 53,
+ TFMT_8_8_8_SNORM = 54,
+ TFMT_8_8_8_8_SNORM = 55,
+ TFMT_8_UINT = 56,
+ TFMT_8_8_UINT = 57,
+ TFMT_8_8_8_UINT = 58,
+ TFMT_8_8_8_8_UINT = 59,
+ TFMT_8_SINT = 60,
+ TFMT_8_8_SINT = 61,
+ TFMT_8_8_8_SINT = 62,
+ TFMT_8_8_8_8_SINT = 63,
+ TFMT_16_FLOAT = 64,
+ TFMT_16_16_FLOAT = 65,
+ TFMT_16_16_16_16_FLOAT = 67,
+ TFMT_16_UINT = 68,
+ TFMT_16_16_UINT = 69,
+ TFMT_16_16_16_16_UINT = 71,
+ TFMT_16_SINT = 72,
+ TFMT_16_16_SINT = 73,
+ TFMT_16_16_16_16_SINT = 75,
+ TFMT_16_UNORM = 76,
+ TFMT_16_16_UNORM = 77,
+ TFMT_16_16_16_16_UNORM = 79,
+ TFMT_16_SNORM = 80,
+ TFMT_16_16_SNORM = 81,
+ TFMT_16_16_16_16_SNORM = 83,
+ TFMT_32_FLOAT = 84,
+ TFMT_32_32_FLOAT = 85,
+ TFMT_32_32_32_32_FLOAT = 87,
+ TFMT_32_UINT = 88,
+ TFMT_32_32_UINT = 89,
+ TFMT_32_32_32_32_UINT = 91,
+ TFMT_32_SINT = 92,
+ TFMT_32_32_SINT = 93,
+ TFMT_32_32_32_32_SINT = 95,
+ TFMT_RGTC2_SNORM = 112,
+ TFMT_RGTC2_UNORM = 113,
+ TFMT_RGTC1_SNORM = 114,
+ TFMT_RGTC1_UNORM = 115,
};
enum a3xx_tex_fetchsize {
@@ -180,9 +199,11 @@ enum a3xx_color_fmt {
RB_R4G4B4A4_UNORM = 3,
RB_R8G8B8_UNORM = 4,
RB_R8G8B8A8_UNORM = 8,
+ RB_R8G8B8A8_SNORM = 9,
RB_R8G8B8A8_UINT = 10,
RB_R8G8B8A8_SINT = 11,
RB_R8G8_UNORM = 12,
+ RB_R8G8_SNORM = 13,
RB_R8_UINT = 14,
RB_R8_SINT = 15,
RB_R10G10B10A2_UNORM = 16,
@@ -258,6 +279,14 @@ enum a3xx_tex_clamp {
A3XX_TEX_MIRROR_CLAMP = 4,
};
+enum a3xx_tex_aniso {
+ A3XX_TEX_ANISO_1 = 0,
+ A3XX_TEX_ANISO_2 = 1,
+ A3XX_TEX_ANISO_4 = 2,
+ A3XX_TEX_ANISO_8 = 3,
+ A3XX_TEX_ANISO_16 = 4,
+};
+
enum a3xx_tex_swiz {
A3XX_TEX_X = 0,
A3XX_TEX_Y = 1,
@@ -1563,12 +1592,13 @@ static inline uint32_t A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(uint32_t val)
{
return ((val) << A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__MASK;
}
-#define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK 0x0001ff80
+#define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK 0x0000ff80
#define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT 7
static inline uint32_t A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val)
{
return ((val) << A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK;
}
+#define A3XX_VFD_FETCH_INSTR_0_INSTANCED 0x00010000
#define A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT 0x00020000
#define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__MASK 0x00fc0000
#define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__SHIFT 18
@@ -2509,6 +2539,12 @@ static inline uint32_t A3XX_TEX_SAMP_0_WRAP_R(enum a3xx_tex_clamp val)
{
return ((val) << A3XX_TEX_SAMP_0_WRAP_R__SHIFT) & A3XX_TEX_SAMP_0_WRAP_R__MASK;
}
+#define A3XX_TEX_SAMP_0_ANISO__MASK 0x00038000
+#define A3XX_TEX_SAMP_0_ANISO__SHIFT 15
+static inline uint32_t A3XX_TEX_SAMP_0_ANISO(enum a3xx_tex_aniso val)
+{
+ return ((val) << A3XX_TEX_SAMP_0_ANISO__SHIFT) & A3XX_TEX_SAMP_0_ANISO__MASK;
+}
#define A3XX_TEX_SAMP_0_COMPARE_FUNC__MASK 0x00700000
#define A3XX_TEX_SAMP_0_COMPARE_FUNC__SHIFT 20
static inline uint32_t A3XX_TEX_SAMP_0_COMPARE_FUNC(enum adreno_compare_func val)
diff --git a/drivers/gpu/drm/msm/adreno/a4xx.xml.h b/drivers/gpu/drm/msm/adreno/a4xx.xml.h
index 5a24c416d2dd..755723fd8ba5 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a4xx.xml.h
@@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54)
Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -63,72 +63,82 @@ enum a4xx_rb_blend_opcode {
};
enum a4xx_vtx_fmt {
- VFMT4_FLOAT_32 = 1,
- VFMT4_FLOAT_32_32 = 2,
- VFMT4_FLOAT_32_32_32 = 3,
- VFMT4_FLOAT_32_32_32_32 = 4,
- VFMT4_FLOAT_16 = 5,
- VFMT4_FLOAT_16_16 = 6,
- VFMT4_FLOAT_16_16_16 = 7,
- VFMT4_FLOAT_16_16_16_16 = 8,
- VFMT4_FIXED_32 = 9,
- VFMT4_FIXED_32_32 = 10,
- VFMT4_FIXED_32_32_32 = 11,
- VFMT4_FIXED_32_32_32_32 = 12,
- VFMT4_SHORT_16 = 16,
- VFMT4_SHORT_16_16 = 17,
- VFMT4_SHORT_16_16_16 = 18,
- VFMT4_SHORT_16_16_16_16 = 19,
- VFMT4_USHORT_16 = 20,
- VFMT4_USHORT_16_16 = 21,
- VFMT4_USHORT_16_16_16 = 22,
- VFMT4_USHORT_16_16_16_16 = 23,
- VFMT4_NORM_SHORT_16 = 24,
- VFMT4_NORM_SHORT_16_16 = 25,
- VFMT4_NORM_SHORT_16_16_16 = 26,
- VFMT4_NORM_SHORT_16_16_16_16 = 27,
- VFMT4_NORM_USHORT_16 = 28,
- VFMT4_NORM_USHORT_16_16 = 29,
- VFMT4_NORM_USHORT_16_16_16 = 30,
- VFMT4_NORM_USHORT_16_16_16_16 = 31,
- VFMT4_UBYTE_8 = 40,
- VFMT4_UBYTE_8_8 = 41,
- VFMT4_UBYTE_8_8_8 = 42,
- VFMT4_UBYTE_8_8_8_8 = 43,
- VFMT4_NORM_UBYTE_8 = 44,
- VFMT4_NORM_UBYTE_8_8 = 45,
- VFMT4_NORM_UBYTE_8_8_8 = 46,
- VFMT4_NORM_UBYTE_8_8_8_8 = 47,
- VFMT4_BYTE_8 = 48,
- VFMT4_BYTE_8_8 = 49,
- VFMT4_BYTE_8_8_8 = 50,
- VFMT4_BYTE_8_8_8_8 = 51,
- VFMT4_NORM_BYTE_8 = 52,
- VFMT4_NORM_BYTE_8_8 = 53,
- VFMT4_NORM_BYTE_8_8_8 = 54,
- VFMT4_NORM_BYTE_8_8_8_8 = 55,
- VFMT4_UINT_10_10_10_2 = 60,
- VFMT4_NORM_UINT_10_10_10_2 = 61,
- VFMT4_INT_10_10_10_2 = 62,
- VFMT4_NORM_INT_10_10_10_2 = 63,
+ VFMT4_32_FLOAT = 1,
+ VFMT4_32_32_FLOAT = 2,
+ VFMT4_32_32_32_FLOAT = 3,
+ VFMT4_32_32_32_32_FLOAT = 4,
+ VFMT4_16_FLOAT = 5,
+ VFMT4_16_16_FLOAT = 6,
+ VFMT4_16_16_16_FLOAT = 7,
+ VFMT4_16_16_16_16_FLOAT = 8,
+ VFMT4_32_FIXED = 9,
+ VFMT4_32_32_FIXED = 10,
+ VFMT4_32_32_32_FIXED = 11,
+ VFMT4_32_32_32_32_FIXED = 12,
+ VFMT4_16_SINT = 16,
+ VFMT4_16_16_SINT = 17,
+ VFMT4_16_16_16_SINT = 18,
+ VFMT4_16_16_16_16_SINT = 19,
+ VFMT4_16_UINT = 20,
+ VFMT4_16_16_UINT = 21,
+ VFMT4_16_16_16_UINT = 22,
+ VFMT4_16_16_16_16_UINT = 23,
+ VFMT4_16_SNORM = 24,
+ VFMT4_16_16_SNORM = 25,
+ VFMT4_16_16_16_SNORM = 26,
+ VFMT4_16_16_16_16_SNORM = 27,
+ VFMT4_16_UNORM = 28,
+ VFMT4_16_16_UNORM = 29,
+ VFMT4_16_16_16_UNORM = 30,
+ VFMT4_16_16_16_16_UNORM = 31,
+ VFMT4_32_32_SINT = 37,
+ VFMT4_8_UINT = 40,
+ VFMT4_8_8_UINT = 41,
+ VFMT4_8_8_8_UINT = 42,
+ VFMT4_8_8_8_8_UINT = 43,
+ VFMT4_8_UNORM = 44,
+ VFMT4_8_8_UNORM = 45,
+ VFMT4_8_8_8_UNORM = 46,
+ VFMT4_8_8_8_8_UNORM = 47,
+ VFMT4_8_SINT = 48,
+ VFMT4_8_8_SINT = 49,
+ VFMT4_8_8_8_SINT = 50,
+ VFMT4_8_8_8_8_SINT = 51,
+ VFMT4_8_SNORM = 52,
+ VFMT4_8_8_SNORM = 53,
+ VFMT4_8_8_8_SNORM = 54,
+ VFMT4_8_8_8_8_SNORM = 55,
+ VFMT4_10_10_10_2_UINT = 60,
+ VFMT4_10_10_10_2_UNORM = 61,
+ VFMT4_10_10_10_2_SINT = 62,
+ VFMT4_10_10_10_2_SNORM = 63,
};
enum a4xx_tex_fmt {
- TFMT4_NORM_USHORT_565 = 11,
- TFMT4_NORM_USHORT_5551 = 10,
- TFMT4_NORM_USHORT_4444 = 8,
- TFMT4_NORM_UINT_X8Z24 = 71,
- TFMT4_NORM_UINT_2_10_10_10 = 33,
- TFMT4_NORM_UINT_A8 = 3,
- TFMT4_NORM_UINT_L8_A8 = 13,
- TFMT4_NORM_UINT_8 = 4,
- TFMT4_NORM_UINT_8_8_8_8 = 28,
- TFMT4_FLOAT_16 = 20,
- TFMT4_FLOAT_16_16 = 40,
- TFMT4_FLOAT_16_16_16_16 = 53,
- TFMT4_FLOAT_32 = 43,
- TFMT4_FLOAT_32_32 = 56,
- TFMT4_FLOAT_32_32_32_32 = 63,
+ TFMT4_5_6_5_UNORM = 11,
+ TFMT4_5_5_5_1_UNORM = 10,
+ TFMT4_4_4_4_4_UNORM = 8,
+ TFMT4_X8Z24_UNORM = 71,
+ TFMT4_10_10_10_2_UNORM = 33,
+ TFMT4_A8_UNORM = 3,
+ TFMT4_L8_A8_UNORM = 13,
+ TFMT4_8_UNORM = 4,
+ TFMT4_8_8_UNORM = 14,
+ TFMT4_8_8_8_8_UNORM = 28,
+ TFMT4_16_FLOAT = 20,
+ TFMT4_16_16_FLOAT = 40,
+ TFMT4_16_16_16_16_FLOAT = 53,
+ TFMT4_32_FLOAT = 43,
+ TFMT4_32_32_FLOAT = 56,
+ TFMT4_32_32_32_32_FLOAT = 63,
+};
+
+enum a4xx_tex_fetchsize {
+ TFETCH4_1_BYTE = 0,
+ TFETCH4_2_BYTE = 1,
+ TFETCH4_4_BYTE = 2,
+ TFETCH4_8_BYTE = 3,
+ TFETCH4_16_BYTE = 4,
};
enum a4xx_depth_format {
@@ -264,14 +274,19 @@ static inline uint32_t A4XX_RB_MSAA_CONTROL_SAMPLES(uint32_t val)
return ((val) << A4XX_RB_MSAA_CONTROL_SAMPLES__SHIFT) & A4XX_RB_MSAA_CONTROL_SAMPLES__MASK;
}
-#define REG_A4XX_RB_MSAA_CONTROL2 0x000020a3
-#define A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__MASK 0x00000380
-#define A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__SHIFT 7
-static inline uint32_t A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES(uint32_t val)
+#define REG_A4XX_RB_RENDER_CONTROL2 0x000020a3
+#define A4XX_RB_RENDER_CONTROL2_XCOORD 0x00000001
+#define A4XX_RB_RENDER_CONTROL2_YCOORD 0x00000002
+#define A4XX_RB_RENDER_CONTROL2_ZCOORD 0x00000004
+#define A4XX_RB_RENDER_CONTROL2_WCOORD 0x00000008
+#define A4XX_RB_RENDER_CONTROL2_FACENESS 0x00000020
+#define A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__MASK 0x00000380
+#define A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__SHIFT 7
+static inline uint32_t A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES(uint32_t val)
{
- return ((val) << A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__SHIFT) & A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__MASK;
+ return ((val) << A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__SHIFT) & A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__MASK;
}
-#define A4XX_RB_MSAA_CONTROL2_VARYING 0x00001000
+#define A4XX_RB_RENDER_CONTROL2_VARYING 0x00001000
static inline uint32_t REG_A4XX_RB_MRT(uint32_t i0) { return 0x000020a4 + 0x5*i0; }
@@ -362,7 +377,69 @@ static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(enum adreno_r
return ((val) << A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__MASK;
}
+#define REG_A4XX_RB_BLEND_RED 0x000020f3
+#define A4XX_RB_BLEND_RED_UINT__MASK 0x00007fff
+#define A4XX_RB_BLEND_RED_UINT__SHIFT 0
+static inline uint32_t A4XX_RB_BLEND_RED_UINT(uint32_t val)
+{
+ return ((val) << A4XX_RB_BLEND_RED_UINT__SHIFT) & A4XX_RB_BLEND_RED_UINT__MASK;
+}
+#define A4XX_RB_BLEND_RED_FLOAT__MASK 0xffff0000
+#define A4XX_RB_BLEND_RED_FLOAT__SHIFT 16
+static inline uint32_t A4XX_RB_BLEND_RED_FLOAT(float val)
+{
+ return ((util_float_to_half(val)) << A4XX_RB_BLEND_RED_FLOAT__SHIFT) & A4XX_RB_BLEND_RED_FLOAT__MASK;
+}
+
+#define REG_A4XX_RB_BLEND_GREEN 0x000020f4
+#define A4XX_RB_BLEND_GREEN_UINT__MASK 0x00007fff
+#define A4XX_RB_BLEND_GREEN_UINT__SHIFT 0
+static inline uint32_t A4XX_RB_BLEND_GREEN_UINT(uint32_t val)
+{
+ return ((val) << A4XX_RB_BLEND_GREEN_UINT__SHIFT) & A4XX_RB_BLEND_GREEN_UINT__MASK;
+}
+#define A4XX_RB_BLEND_GREEN_FLOAT__MASK 0xffff0000
+#define A4XX_RB_BLEND_GREEN_FLOAT__SHIFT 16
+static inline uint32_t A4XX_RB_BLEND_GREEN_FLOAT(float val)
+{
+ return ((util_float_to_half(val)) << A4XX_RB_BLEND_GREEN_FLOAT__SHIFT) & A4XX_RB_BLEND_GREEN_FLOAT__MASK;
+}
+
+#define REG_A4XX_RB_BLEND_BLUE 0x000020f5
+#define A4XX_RB_BLEND_BLUE_UINT__MASK 0x00007fff
+#define A4XX_RB_BLEND_BLUE_UINT__SHIFT 0
+static inline uint32_t A4XX_RB_BLEND_BLUE_UINT(uint32_t val)
+{
+ return ((val) << A4XX_RB_BLEND_BLUE_UINT__SHIFT) & A4XX_RB_BLEND_BLUE_UINT__MASK;
+}
+#define A4XX_RB_BLEND_BLUE_FLOAT__MASK 0xffff0000
+#define A4XX_RB_BLEND_BLUE_FLOAT__SHIFT 16
+static inline uint32_t A4XX_RB_BLEND_BLUE_FLOAT(float val)
+{
+ return ((util_float_to_half(val)) << A4XX_RB_BLEND_BLUE_FLOAT__SHIFT) & A4XX_RB_BLEND_BLUE_FLOAT__MASK;
+}
+
+#define REG_A4XX_RB_BLEND_ALPHA 0x000020f6
+#define A4XX_RB_BLEND_ALPHA_UINT__MASK 0x00007fff
+#define A4XX_RB_BLEND_ALPHA_UINT__SHIFT 0
+static inline uint32_t A4XX_RB_BLEND_ALPHA_UINT(uint32_t val)
+{
+ return ((val) << A4XX_RB_BLEND_ALPHA_UINT__SHIFT) & A4XX_RB_BLEND_ALPHA_UINT__MASK;
+}
+#define A4XX_RB_BLEND_ALPHA_FLOAT__MASK 0xffff0000
+#define A4XX_RB_BLEND_ALPHA_FLOAT__SHIFT 16
+static inline uint32_t A4XX_RB_BLEND_ALPHA_FLOAT(float val)
+{
+ return ((util_float_to_half(val)) << A4XX_RB_BLEND_ALPHA_FLOAT__SHIFT) & A4XX_RB_BLEND_ALPHA_FLOAT__MASK;
+}
+
#define REG_A4XX_RB_ALPHA_CONTROL 0x000020f8
+#define A4XX_RB_ALPHA_CONTROL_ALPHA_REF__MASK 0x000000ff
+#define A4XX_RB_ALPHA_CONTROL_ALPHA_REF__SHIFT 0
+static inline uint32_t A4XX_RB_ALPHA_CONTROL_ALPHA_REF(uint32_t val)
+{
+ return ((val) << A4XX_RB_ALPHA_CONTROL_ALPHA_REF__SHIFT) & A4XX_RB_ALPHA_CONTROL_ALPHA_REF__MASK;
+}
#define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST 0x00000100
#define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__MASK 0x00000e00
#define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__SHIFT 9
@@ -372,7 +449,7 @@ static inline uint32_t A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(enum adreno_compare
}
#define REG_A4XX_RB_FS_OUTPUT 0x000020f9
-#define A4XX_RB_FS_OUTPUT_ENABLE_COLOR_PIPE 0x00000001
+#define A4XX_RB_FS_OUTPUT_ENABLE_BLEND 0x00000001
#define A4XX_RB_FS_OUTPUT_FAST_CLEAR 0x00000100
#define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__MASK 0xffff0000
#define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__SHIFT 16
@@ -416,11 +493,11 @@ static inline uint32_t A4XX_RB_COPY_CONTROL_GMEM_BASE(uint32_t val)
}
#define REG_A4XX_RB_COPY_DEST_BASE 0x000020fd
-#define A4XX_RB_COPY_DEST_BASE_BASE__MASK 0xfffffff0
-#define A4XX_RB_COPY_DEST_BASE_BASE__SHIFT 4
+#define A4XX_RB_COPY_DEST_BASE_BASE__MASK 0xffffffe0
+#define A4XX_RB_COPY_DEST_BASE_BASE__SHIFT 5
static inline uint32_t A4XX_RB_COPY_DEST_BASE_BASE(uint32_t val)
{
- return ((val >> 4) << A4XX_RB_COPY_DEST_BASE_BASE__SHIFT) & A4XX_RB_COPY_DEST_BASE_BASE__MASK;
+ return ((val >> 5) << A4XX_RB_COPY_DEST_BASE_BASE__SHIFT) & A4XX_RB_COPY_DEST_BASE_BASE__MASK;
}
#define REG_A4XX_RB_COPY_DEST_PITCH 0x000020fe
@@ -508,7 +585,7 @@ static inline uint32_t A4XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val)
#define A4XX_RB_DEPTH_PITCH__SHIFT 0
static inline uint32_t A4XX_RB_DEPTH_PITCH(uint32_t val)
{
- return ((val >> 4) << A4XX_RB_DEPTH_PITCH__SHIFT) & A4XX_RB_DEPTH_PITCH__MASK;
+ return ((val >> 5) << A4XX_RB_DEPTH_PITCH__SHIFT) & A4XX_RB_DEPTH_PITCH__MASK;
}
#define REG_A4XX_RB_DEPTH_PITCH2 0x00002105
@@ -516,7 +593,7 @@ static inline uint32_t A4XX_RB_DEPTH_PITCH(uint32_t val)
#define A4XX_RB_DEPTH_PITCH2__SHIFT 0
static inline uint32_t A4XX_RB_DEPTH_PITCH2(uint32_t val)
{
- return ((val >> 4) << A4XX_RB_DEPTH_PITCH2__SHIFT) & A4XX_RB_DEPTH_PITCH2__MASK;
+ return ((val >> 5) << A4XX_RB_DEPTH_PITCH2__SHIFT) & A4XX_RB_DEPTH_PITCH2__MASK;
}
#define REG_A4XX_RB_STENCIL_CONTROL 0x00002106
@@ -630,7 +707,11 @@ static inline uint32_t A4XX_RB_BIN_OFFSET_Y(uint32_t val)
return ((val) << A4XX_RB_BIN_OFFSET_Y__SHIFT) & A4XX_RB_BIN_OFFSET_Y__MASK;
}
-#define REG_A4XX_RB_VPORT_Z_CLAMP_MAX_15 0x0000213f
+static inline uint32_t REG_A4XX_RB_VPORT_Z_CLAMP(uint32_t i0) { return 0x00002120 + 0x2*i0; }
+
+static inline uint32_t REG_A4XX_RB_VPORT_Z_CLAMP_MIN(uint32_t i0) { return 0x00002120 + 0x2*i0; }
+
+static inline uint32_t REG_A4XX_RB_VPORT_Z_CLAMP_MAX(uint32_t i0) { return 0x00002121 + 0x2*i0; }
#define REG_A4XX_RBBM_HW_VERSION 0x00000000
@@ -1121,7 +1202,9 @@ static inline uint32_t A4XX_SP_FS_CTRL_REG1_CONSTLENGTH(uint32_t val)
{
return ((val) << A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__SHIFT) & A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__MASK;
}
+#define A4XX_SP_FS_CTRL_REG1_FACENESS 0x00080000
#define A4XX_SP_FS_CTRL_REG1_VARYING 0x00100000
+#define A4XX_SP_FS_CTRL_REG1_FRAGCOORD 0x00200000
#define REG_A4XX_SP_FS_OBJ_OFFSET_REG 0x000022ea
#define A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000
@@ -1384,6 +1467,12 @@ static inline uint32_t A4XX_VFD_CONTROL_1_REGID4INST(uint32_t val)
#define REG_A4XX_VFD_CONTROL_2 0x00002202
#define REG_A4XX_VFD_CONTROL_3 0x00002203
+#define A4XX_VFD_CONTROL_3_REGID_VTXCNT__MASK 0x0000ff00
+#define A4XX_VFD_CONTROL_3_REGID_VTXCNT__SHIFT 8
+static inline uint32_t A4XX_VFD_CONTROL_3_REGID_VTXCNT(uint32_t val)
+{
+ return ((val) << A4XX_VFD_CONTROL_3_REGID_VTXCNT__SHIFT) & A4XX_VFD_CONTROL_3_REGID_VTXCNT__MASK;
+}
#define REG_A4XX_VFD_CONTROL_4 0x00002204
@@ -1405,12 +1494,7 @@ static inline uint32_t A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val)
return ((val) << A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK;
}
#define A4XX_VFD_FETCH_INSTR_0_SWITCHNEXT 0x00080000
-#define A4XX_VFD_FETCH_INSTR_0_STEPRATE__MASK 0xff000000
-#define A4XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT 24
-static inline uint32_t A4XX_VFD_FETCH_INSTR_0_STEPRATE(uint32_t val)
-{
- return ((val) << A4XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_STEPRATE__MASK;
-}
+#define A4XX_VFD_FETCH_INSTR_0_INSTANCED 0x00100000
static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_1(uint32_t i0) { return 0x0000220b + 0x4*i0; }
@@ -1423,6 +1507,12 @@ static inline uint32_t A4XX_VFD_FETCH_INSTR_2_SIZE(uint32_t val)
}
static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_3(uint32_t i0) { return 0x0000220d + 0x4*i0; }
+#define A4XX_VFD_FETCH_INSTR_3_STEPRATE__MASK 0x000001ff
+#define A4XX_VFD_FETCH_INSTR_3_STEPRATE__SHIFT 0
+static inline uint32_t A4XX_VFD_FETCH_INSTR_3_STEPRATE(uint32_t val)
+{
+ return ((val) << A4XX_VFD_FETCH_INSTR_3_STEPRATE__SHIFT) & A4XX_VFD_FETCH_INSTR_3_STEPRATE__MASK;
+}
static inline uint32_t REG_A4XX_VFD_DECODE(uint32_t i0) { return 0x0000228a + 0x1*i0; }
@@ -1446,6 +1536,7 @@ static inline uint32_t A4XX_VFD_DECODE_INSTR_REGID(uint32_t val)
{
return ((val) << A4XX_VFD_DECODE_INSTR_REGID__SHIFT) & A4XX_VFD_DECODE_INSTR_REGID__MASK;
}
+#define A4XX_VFD_DECODE_INSTR_INT 0x00100000
#define A4XX_VFD_DECODE_INSTR_SWAP__MASK 0x00c00000
#define A4XX_VFD_DECODE_INSTR_SWAP__SHIFT 22
static inline uint32_t A4XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val)
@@ -1585,7 +1676,47 @@ static inline uint32_t A4XX_GRAS_SU_POLY_OFFSET_OFFSET(float val)
return ((fui(val)) << A4XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A4XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK;
}
-#define REG_A4XX_GRAS_SC_EXTENT_WINDOW_TL 0x0000209f
+#define REG_A4XX_GRAS_DEPTH_CONTROL 0x00002077
+#define A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK 0x00000003
+#define A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT 0
+static inline uint32_t A4XX_GRAS_DEPTH_CONTROL_FORMAT(enum a4xx_depth_format val)
+{
+ return ((val) << A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT) & A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK;
+}
+
+#define REG_A4XX_GRAS_SU_MODE_CONTROL 0x00002078
+#define A4XX_GRAS_SU_MODE_CONTROL_CULL_FRONT 0x00000001
+#define A4XX_GRAS_SU_MODE_CONTROL_CULL_BACK 0x00000002
+#define A4XX_GRAS_SU_MODE_CONTROL_FRONT_CW 0x00000004
+#define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK 0x000007f8
+#define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3
+static inline uint32_t A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val)
+{
+ return ((((int32_t)(val * 4.0))) << A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK;
+}
+#define A4XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800
+#define A4XX_GRAS_SU_MODE_CONTROL_RENDERING_PASS 0x00100000
+
+#define REG_A4XX_GRAS_SC_CONTROL 0x0000207b
+#define A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK 0x0000000c
+#define A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT 2
+static inline uint32_t A4XX_GRAS_SC_CONTROL_RENDER_MODE(enum a3xx_render_mode val)
+{
+ return ((val) << A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK;
+}
+#define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK 0x00000380
+#define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT 7
+static inline uint32_t A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(uint32_t val)
+{
+ return ((val) << A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT) & A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK;
+}
+#define A4XX_GRAS_SC_CONTROL_MSAA_DISABLE 0x00000800
+#define A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK 0x0000f000
+#define A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT 12
+static inline uint32_t A4XX_GRAS_SC_CONTROL_RASTER_MODE(uint32_t val)
+{
+ return ((val) << A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK;
+}
#define REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL 0x0000207c
#define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000
@@ -1647,46 +1778,34 @@ static inline uint32_t A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(uint32_t val)
return ((val) << A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__MASK;
}
-#define REG_A4XX_GRAS_DEPTH_CONTROL 0x00002077
-#define A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK 0x00000003
-#define A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT 0
-static inline uint32_t A4XX_GRAS_DEPTH_CONTROL_FORMAT(enum a4xx_depth_format val)
+#define REG_A4XX_GRAS_SC_EXTENT_WINDOW_BR 0x0000209e
+#define A4XX_GRAS_SC_EXTENT_WINDOW_BR_WINDOW_OFFSET_DISABLE 0x80000000
+#define A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__MASK 0x00007fff
+#define A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__SHIFT 0
+static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_BR_X(uint32_t val)
{
- return ((val) << A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT) & A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK;
+ return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__MASK;
}
-
-#define REG_A4XX_GRAS_SU_MODE_CONTROL 0x00002078
-#define A4XX_GRAS_SU_MODE_CONTROL_CULL_FRONT 0x00000001
-#define A4XX_GRAS_SU_MODE_CONTROL_CULL_BACK 0x00000002
-#define A4XX_GRAS_SU_MODE_CONTROL_FRONT_CW 0x00000004
-#define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK 0x000007f8
-#define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3
-static inline uint32_t A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val)
+#define A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__MASK 0x7fff0000
+#define A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__SHIFT 16
+static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y(uint32_t val)
{
- return ((((int32_t)(val * 4.0))) << A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK;
+ return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__MASK;
}
-#define A4XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800
-#define A4XX_GRAS_SU_MODE_CONTROL_RENDERING_PASS 0x00100000
-#define REG_A4XX_GRAS_SC_CONTROL 0x0000207b
-#define A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK 0x0000000c
-#define A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT 2
-static inline uint32_t A4XX_GRAS_SC_CONTROL_RENDER_MODE(enum a3xx_render_mode val)
-{
- return ((val) << A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK;
-}
-#define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK 0x00000380
-#define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT 7
-static inline uint32_t A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(uint32_t val)
+#define REG_A4XX_GRAS_SC_EXTENT_WINDOW_TL 0x0000209f
+#define A4XX_GRAS_SC_EXTENT_WINDOW_TL_WINDOW_OFFSET_DISABLE 0x80000000
+#define A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__MASK 0x00007fff
+#define A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__SHIFT 0
+static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_TL_X(uint32_t val)
{
- return ((val) << A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT) & A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK;
+ return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__MASK;
}
-#define A4XX_GRAS_SC_CONTROL_MSAA_DISABLE 0x00000800
-#define A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK 0x0000f000
-#define A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT 12
-static inline uint32_t A4XX_GRAS_SC_CONTROL_RASTER_MODE(uint32_t val)
+#define A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__MASK 0x7fff0000
+#define A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__SHIFT 16
+static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y(uint32_t val)
{
- return ((val) << A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK;
+ return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__MASK;
}
#define REG_A4XX_UCHE_CACHE_MODE_CONTROL 0x00000e80
@@ -1742,6 +1861,12 @@ static inline uint32_t A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(enum a3xx_threadsize
}
#define A4XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE 0x00000100
#define A4XX_HLSQ_CONTROL_1_REG_RESERVED1 0x00000200
+#define A4XX_HLSQ_CONTROL_1_REG_COORDREGID__MASK 0x00ff0000
+#define A4XX_HLSQ_CONTROL_1_REG_COORDREGID__SHIFT 16
+static inline uint32_t A4XX_HLSQ_CONTROL_1_REG_COORDREGID(uint32_t val)
+{
+ return ((val) << A4XX_HLSQ_CONTROL_1_REG_COORDREGID__SHIFT) & A4XX_HLSQ_CONTROL_1_REG_COORDREGID__MASK;
+}
#define A4XX_HLSQ_CONTROL_1_REG_ZWCOORD 0x02000000
#define REG_A4XX_HLSQ_CONTROL_2_REG 0x000023c2
@@ -1751,6 +1876,12 @@ static inline uint32_t A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(uint32_t val)
{
return ((val) << A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__SHIFT) & A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK;
}
+#define A4XX_HLSQ_CONTROL_2_REG_FACEREGID__MASK 0x000003fc
+#define A4XX_HLSQ_CONTROL_2_REG_FACEREGID__SHIFT 2
+static inline uint32_t A4XX_HLSQ_CONTROL_2_REG_FACEREGID(uint32_t val)
+{
+ return ((val) << A4XX_HLSQ_CONTROL_2_REG_FACEREGID__SHIFT) & A4XX_HLSQ_CONTROL_2_REG_FACEREGID__MASK;
+}
#define REG_A4XX_HLSQ_CONTROL_3_REG 0x000023c3
#define A4XX_HLSQ_CONTROL_3_REG_REGID__MASK 0x000000ff
@@ -1965,15 +2096,13 @@ static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH(uint32_t val)
#define REG_A4XX_UNKNOWN_20F2 0x000020f2
-#define REG_A4XX_UNKNOWN_20F3 0x000020f3
-
-#define REG_A4XX_UNKNOWN_20F4 0x000020f4
-
-#define REG_A4XX_UNKNOWN_20F5 0x000020f5
-
-#define REG_A4XX_UNKNOWN_20F6 0x000020f6
-
#define REG_A4XX_UNKNOWN_20F7 0x000020f7
+#define A4XX_UNKNOWN_20F7__MASK 0xffffffff
+#define A4XX_UNKNOWN_20F7__SHIFT 0
+static inline uint32_t A4XX_UNKNOWN_20F7(float val)
+{
+ return ((fui(val)) << A4XX_UNKNOWN_20F7__SHIFT) & A4XX_UNKNOWN_20F7__MASK;
+}
#define REG_A4XX_UNKNOWN_2152 0x00002152
@@ -2000,6 +2129,7 @@ static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH(uint32_t val)
#define REG_A4XX_UNKNOWN_23A0 0x000023a0
#define REG_A4XX_TEX_SAMP_0 0x00000000
+#define A4XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR 0x00000001
#define A4XX_TEX_SAMP_0_XY_MAG__MASK 0x00000006
#define A4XX_TEX_SAMP_0_XY_MAG__SHIFT 1
static inline uint32_t A4XX_TEX_SAMP_0_XY_MAG(enum a4xx_tex_filter val)
@@ -2038,17 +2168,19 @@ static inline uint32_t A4XX_TEX_SAMP_1_COMPARE_FUNC(enum adreno_compare_func val
{
return ((val) << A4XX_TEX_SAMP_1_COMPARE_FUNC__SHIFT) & A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK;
}
+#define A4XX_TEX_SAMP_1_UNNORM_COORDS 0x00000020
+#define A4XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR 0x00000040
#define A4XX_TEX_SAMP_1_MAX_LOD__MASK 0x000fff00
#define A4XX_TEX_SAMP_1_MAX_LOD__SHIFT 8
static inline uint32_t A4XX_TEX_SAMP_1_MAX_LOD(float val)
{
- return ((((uint32_t)(val * 64.0))) << A4XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A4XX_TEX_SAMP_1_MAX_LOD__MASK;
+ return ((((uint32_t)(val * 256.0))) << A4XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A4XX_TEX_SAMP_1_MAX_LOD__MASK;
}
#define A4XX_TEX_SAMP_1_MIN_LOD__MASK 0xfff00000
#define A4XX_TEX_SAMP_1_MIN_LOD__SHIFT 20
static inline uint32_t A4XX_TEX_SAMP_1_MIN_LOD(float val)
{
- return ((((uint32_t)(val * 64.0))) << A4XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A4XX_TEX_SAMP_1_MIN_LOD__MASK;
+ return ((((uint32_t)(val * 256.0))) << A4XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A4XX_TEX_SAMP_1_MIN_LOD__MASK;
}
#define REG_A4XX_TEX_CONST_0 0x00000000
@@ -2077,6 +2209,12 @@ static inline uint32_t A4XX_TEX_CONST_0_SWIZ_W(enum a4xx_tex_swiz val)
{
return ((val) << A4XX_TEX_CONST_0_SWIZ_W__SHIFT) & A4XX_TEX_CONST_0_SWIZ_W__MASK;
}
+#define A4XX_TEX_CONST_0_MIPLVLS__MASK 0x000f0000
+#define A4XX_TEX_CONST_0_MIPLVLS__SHIFT 16
+static inline uint32_t A4XX_TEX_CONST_0_MIPLVLS(uint32_t val)
+{
+ return ((val) << A4XX_TEX_CONST_0_MIPLVLS__SHIFT) & A4XX_TEX_CONST_0_MIPLVLS__MASK;
+}
#define A4XX_TEX_CONST_0_FMT__MASK 0x1fc00000
#define A4XX_TEX_CONST_0_FMT__SHIFT 22
static inline uint32_t A4XX_TEX_CONST_0_FMT(enum a4xx_tex_fmt val)
@@ -2105,6 +2243,12 @@ static inline uint32_t A4XX_TEX_CONST_1_WIDTH(uint32_t val)
}
#define REG_A4XX_TEX_CONST_2 0x00000002
+#define A4XX_TEX_CONST_2_FETCHSIZE__MASK 0x0000000f
+#define A4XX_TEX_CONST_2_FETCHSIZE__SHIFT 0
+static inline uint32_t A4XX_TEX_CONST_2_FETCHSIZE(enum a4xx_tex_fetchsize val)
+{
+ return ((val) << A4XX_TEX_CONST_2_FETCHSIZE__SHIFT) & A4XX_TEX_CONST_2_FETCHSIZE__MASK;
+}
#define A4XX_TEX_CONST_2_PITCH__MASK 0x3ffffe00
#define A4XX_TEX_CONST_2_PITCH__SHIFT 9
static inline uint32_t A4XX_TEX_CONST_2_PITCH(uint32_t val)
@@ -2119,19 +2263,31 @@ static inline uint32_t A4XX_TEX_CONST_2_SWAP(enum a3xx_color_swap val)
}
#define REG_A4XX_TEX_CONST_3 0x00000003
-#define A4XX_TEX_CONST_3_LAYERSZ__MASK 0x0000000f
+#define A4XX_TEX_CONST_3_LAYERSZ__MASK 0x00003fff
#define A4XX_TEX_CONST_3_LAYERSZ__SHIFT 0
static inline uint32_t A4XX_TEX_CONST_3_LAYERSZ(uint32_t val)
{
return ((val >> 12) << A4XX_TEX_CONST_3_LAYERSZ__SHIFT) & A4XX_TEX_CONST_3_LAYERSZ__MASK;
}
+#define A4XX_TEX_CONST_3_DEPTH__MASK 0x7ffc0000
+#define A4XX_TEX_CONST_3_DEPTH__SHIFT 18
+static inline uint32_t A4XX_TEX_CONST_3_DEPTH(uint32_t val)
+{
+ return ((val) << A4XX_TEX_CONST_3_DEPTH__SHIFT) & A4XX_TEX_CONST_3_DEPTH__MASK;
+}
#define REG_A4XX_TEX_CONST_4 0x00000004
-#define A4XX_TEX_CONST_4_BASE__MASK 0xffffffff
-#define A4XX_TEX_CONST_4_BASE__SHIFT 0
+#define A4XX_TEX_CONST_4_LAYERSZ__MASK 0x0000000f
+#define A4XX_TEX_CONST_4_LAYERSZ__SHIFT 0
+static inline uint32_t A4XX_TEX_CONST_4_LAYERSZ(uint32_t val)
+{
+ return ((val >> 12) << A4XX_TEX_CONST_4_LAYERSZ__SHIFT) & A4XX_TEX_CONST_4_LAYERSZ__MASK;
+}
+#define A4XX_TEX_CONST_4_BASE__MASK 0xffffffe0
+#define A4XX_TEX_CONST_4_BASE__SHIFT 5
static inline uint32_t A4XX_TEX_CONST_4_BASE(uint32_t val)
{
- return ((val) << A4XX_TEX_CONST_4_BASE__SHIFT) & A4XX_TEX_CONST_4_BASE__MASK;
+ return ((val >> 5) << A4XX_TEX_CONST_4_BASE__SHIFT) & A4XX_TEX_CONST_4_BASE__MASK;
}
#define REG_A4XX_TEX_CONST_5 0x00000005
diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
index a4b33af9338d..8531beb982e7 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
@@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54)
Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
index 6a75cee94d81..6ffc4f6c8af1 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
@@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54)
Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -172,7 +172,9 @@ enum adreno_pm4_type3_packets {
CP_DRAW_INDIRECT = 40,
CP_DRAW_INDX_INDIRECT = 41,
CP_DRAW_AUTO = 36,
+ CP_UNKNOWN_19 = 25,
CP_UNKNOWN_1A = 26,
+ CP_UNKNOWN_4E = 78,
CP_WIDE_REG_WRITE = 116,
IN_IB_PREFETCH_END = 23,
IN_SUBBLK_PREFETCH = 31,
@@ -203,6 +205,12 @@ enum adreno_state_src {
SS_INDIRECT = 4,
};
+enum a4xx_index_size {
+ INDEX4_SIZE_8_BIT = 0,
+ INDEX4_SIZE_16_BIT = 1,
+ INDEX4_SIZE_32_BIT = 2,
+};
+
#define REG_CP_LOAD_STATE_0 0x00000000
#define CP_LOAD_STATE_0_DST_OFF__MASK 0x0000ffff
#define CP_LOAD_STATE_0_DST_OFF__SHIFT 0
@@ -374,29 +382,20 @@ static inline uint32_t CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT(enum pc_di_src_sel va
{
return ((val) << CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__SHIFT) & CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__MASK;
}
-#define CP_DRAW_INDX_OFFSET_0_VIS_CULL__MASK 0x00000700
-#define CP_DRAW_INDX_OFFSET_0_VIS_CULL__SHIFT 8
-static inline uint32_t CP_DRAW_INDX_OFFSET_0_VIS_CULL(enum pc_di_vis_cull_mode val)
-{
- return ((val) << CP_DRAW_INDX_OFFSET_0_VIS_CULL__SHIFT) & CP_DRAW_INDX_OFFSET_0_VIS_CULL__MASK;
-}
-#define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK 0x00000800
-#define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT 11
-static inline uint32_t CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(enum pc_di_index_size val)
+#define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK 0x00000c00
+#define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT 10
+static inline uint32_t CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(enum a4xx_index_size val)
{
return ((val) << CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT) & CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK;
}
-#define CP_DRAW_INDX_OFFSET_0_NOT_EOP 0x00001000
-#define CP_DRAW_INDX_OFFSET_0_SMALL_INDEX 0x00002000
-#define CP_DRAW_INDX_OFFSET_0_PRE_DRAW_INITIATOR_ENABLE 0x00004000
-#define CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__MASK 0xffff0000
-#define CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__SHIFT 16
-static inline uint32_t CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES(uint32_t val)
-{
- return ((val) << CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__SHIFT) & CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__MASK;
-}
#define REG_CP_DRAW_INDX_OFFSET_1 0x00000001
+#define CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__MASK 0xffffffff
+#define CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__SHIFT) & CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__MASK;
+}
#define REG_CP_DRAW_INDX_OFFSET_2 0x00000002
#define CP_DRAW_INDX_OFFSET_2_NUM_INDICES__MASK 0xffffffff
diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index 448438b759b4..abf1bba520bf 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
index c102a7f074ac..695f99d4bec2 100644
--- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
+++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
@@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h
index a900134bdf33..50ff9851d73d 100644
--- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h
+++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h
@@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c
new file mode 100644
index 000000000000..0940e84b2821
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/of_irq.h>
+#include "edp.h"
+
+static irqreturn_t edp_irq(int irq, void *dev_id)
+{
+ struct msm_edp *edp = dev_id;
+
+ /* Process eDP irq */
+ return msm_edp_ctrl_irq(edp->ctrl);
+}
+
+static void edp_destroy(struct platform_device *pdev)
+{
+ struct msm_edp *edp = platform_get_drvdata(pdev);
+
+ if (!edp)
+ return;
+
+ if (edp->ctrl) {
+ msm_edp_ctrl_destroy(edp->ctrl);
+ edp->ctrl = NULL;
+ }
+
+ platform_set_drvdata(pdev, NULL);
+}
+
+/* construct eDP at bind/probe time, grab all the resources. */
+static struct msm_edp *edp_init(struct platform_device *pdev)
+{
+ struct msm_edp *edp = NULL;
+ int ret;
+
+ if (!pdev) {
+ pr_err("no eDP device\n");
+ ret = -ENXIO;
+ goto fail;
+ }
+
+ edp = devm_kzalloc(&pdev->dev, sizeof(*edp), GFP_KERNEL);
+ if (!edp) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ DBG("eDP probed=%p", edp);
+
+ edp->pdev = pdev;
+ platform_set_drvdata(pdev, edp);
+
+ ret = msm_edp_ctrl_init(edp);
+ if (ret)
+ goto fail;
+
+ return edp;
+
+fail:
+ if (edp)
+ edp_destroy(pdev);
+
+ return ERR_PTR(ret);
+}
+
+static int edp_bind(struct device *dev, struct device *master, void *data)
+{
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct msm_drm_private *priv = drm->dev_private;
+ struct msm_edp *edp;
+
+ DBG("");
+ edp = edp_init(to_platform_device(dev));
+ if (IS_ERR(edp))
+ return PTR_ERR(edp);
+ priv->edp = edp;
+
+ return 0;
+}
+
+static void edp_unbind(struct device *dev, struct device *master, void *data)
+{
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct msm_drm_private *priv = drm->dev_private;
+
+ DBG("");
+ if (priv->edp) {
+ edp_destroy(to_platform_device(dev));
+ priv->edp = NULL;
+ }
+}
+
+static const struct component_ops edp_ops = {
+ .bind = edp_bind,
+ .unbind = edp_unbind,
+};
+
+static int edp_dev_probe(struct platform_device *pdev)
+{
+ DBG("");
+ return component_add(&pdev->dev, &edp_ops);
+}
+
+static int edp_dev_remove(struct platform_device *pdev)
+{
+ DBG("");
+ component_del(&pdev->dev, &edp_ops);
+ return 0;
+}
+
+static const struct of_device_id dt_match[] = {
+ { .compatible = "qcom,mdss-edp" },
+ {}
+};
+
+static struct platform_driver edp_driver = {
+ .probe = edp_dev_probe,
+ .remove = edp_dev_remove,
+ .driver = {
+ .name = "msm_edp",
+ .of_match_table = dt_match,
+ },
+};
+
+void __init msm_edp_register(void)
+{
+ DBG("");
+ platform_driver_register(&edp_driver);
+}
+
+void __exit msm_edp_unregister(void)
+{
+ DBG("");
+ platform_driver_unregister(&edp_driver);
+}
+
+/* Second part of initialization, the drm/kms level modeset_init */
+int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev,
+ struct drm_encoder *encoder)
+{
+ struct platform_device *pdev = edp->pdev;
+ struct msm_drm_private *priv = dev->dev_private;
+ int ret;
+
+ edp->encoder = encoder;
+ edp->dev = dev;
+
+ edp->bridge = msm_edp_bridge_init(edp);
+ if (IS_ERR(edp->bridge)) {
+ ret = PTR_ERR(edp->bridge);
+ dev_err(dev->dev, "failed to create eDP bridge: %d\n", ret);
+ edp->bridge = NULL;
+ goto fail;
+ }
+
+ edp->connector = msm_edp_connector_init(edp);
+ if (IS_ERR(edp->connector)) {
+ ret = PTR_ERR(edp->connector);
+ dev_err(dev->dev, "failed to create eDP connector: %d\n", ret);
+ edp->connector = NULL;
+ goto fail;
+ }
+
+ edp->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (edp->irq < 0) {
+ ret = edp->irq;
+ dev_err(dev->dev, "failed to get IRQ: %d\n", ret);
+ goto fail;
+ }
+
+ ret = devm_request_irq(&pdev->dev, edp->irq,
+ edp_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ "edp_isr", edp);
+ if (ret < 0) {
+ dev_err(dev->dev, "failed to request IRQ%u: %d\n",
+ edp->irq, ret);
+ goto fail;
+ }
+
+ encoder->bridge = edp->bridge;
+
+ priv->bridges[priv->num_bridges++] = edp->bridge;
+ priv->connectors[priv->num_connectors++] = edp->connector;
+
+ return 0;
+
+fail:
+ /* bridge/connector are normally destroyed by drm */
+ if (edp->bridge) {
+ edp_bridge_destroy(edp->bridge);
+ edp->bridge = NULL;
+ }
+ if (edp->connector) {
+ edp->connector->funcs->destroy(edp->connector);
+ edp->connector = NULL;
+ }
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/msm/edp/edp.h b/drivers/gpu/drm/msm/edp/edp.h
new file mode 100644
index 000000000000..ba5bedde5241
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __EDP_CONNECTOR_H__
+#define __EDP_CONNECTOR_H__
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include "drm_crtc.h"
+#include "drm_dp_helper.h"
+#include "msm_drv.h"
+
+#define edp_read(offset) msm_readl((offset))
+#define edp_write(offset, data) msm_writel((data), (offset))
+
+struct edp_ctrl;
+struct edp_aux;
+struct edp_phy;
+
+struct msm_edp {
+ struct drm_device *dev;
+ struct platform_device *pdev;
+
+ struct drm_connector *connector;
+ struct drm_bridge *bridge;
+
+ /* the encoder we are hooked to (outside of eDP block) */
+ struct drm_encoder *encoder;
+
+ struct edp_ctrl *ctrl;
+
+ int irq;
+};
+
+/* eDP bridge */
+struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp);
+void edp_bridge_destroy(struct drm_bridge *bridge);
+
+/* eDP connector */
+struct drm_connector *msm_edp_connector_init(struct msm_edp *edp);
+
+/* AUX */
+void *msm_edp_aux_init(struct device *dev, void __iomem *regbase,
+ struct drm_dp_aux **drm_aux);
+void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux);
+irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr);
+void msm_edp_aux_ctrl(struct edp_aux *aux, int enable);
+
+/* Phy */
+bool msm_edp_phy_ready(struct edp_phy *phy);
+void msm_edp_phy_ctrl(struct edp_phy *phy, int enable);
+void msm_edp_phy_vm_pe_init(struct edp_phy *phy);
+void msm_edp_phy_vm_pe_cfg(struct edp_phy *phy, u32 v0, u32 v1);
+void msm_edp_phy_lane_power_ctrl(struct edp_phy *phy, bool up, u32 max_lane);
+void *msm_edp_phy_init(struct device *dev, void __iomem *regbase);
+
+/* Ctrl */
+irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl);
+void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on);
+int msm_edp_ctrl_init(struct msm_edp *edp);
+void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl);
+bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl);
+int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl,
+ struct drm_connector *connector, struct edid **edid);
+int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl,
+ const struct drm_display_mode *mode,
+ const struct drm_display_info *info);
+/* @pixel_rate is in kHz */
+bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl,
+ u32 pixel_rate, u32 *pm, u32 *pn);
+
+#endif /* __EDP_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/msm/edp/edp.xml.h b/drivers/gpu/drm/msm/edp/edp.xml.h
new file mode 100644
index 000000000000..a29f1df15143
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp.xml.h
@@ -0,0 +1,292 @@
+#ifndef EDP_XML
+#define EDP_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
+
+Copyright (C) 2013-2014 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+enum edp_color_depth {
+ EDP_6BIT = 0,
+ EDP_8BIT = 1,
+ EDP_10BIT = 2,
+ EDP_12BIT = 3,
+ EDP_16BIT = 4,
+};
+
+enum edp_component_format {
+ EDP_RGB = 0,
+ EDP_YUV422 = 1,
+ EDP_YUV444 = 2,
+};
+
+#define REG_EDP_MAINLINK_CTRL 0x00000004
+#define EDP_MAINLINK_CTRL_ENABLE 0x00000001
+#define EDP_MAINLINK_CTRL_RESET 0x00000002
+
+#define REG_EDP_STATE_CTRL 0x00000008
+#define EDP_STATE_CTRL_TRAIN_PATTERN_1 0x00000001
+#define EDP_STATE_CTRL_TRAIN_PATTERN_2 0x00000002
+#define EDP_STATE_CTRL_TRAIN_PATTERN_3 0x00000004
+#define EDP_STATE_CTRL_SYMBOL_ERR_RATE_MEAS 0x00000008
+#define EDP_STATE_CTRL_PRBS7 0x00000010
+#define EDP_STATE_CTRL_CUSTOM_80_BIT_PATTERN 0x00000020
+#define EDP_STATE_CTRL_SEND_VIDEO 0x00000040
+#define EDP_STATE_CTRL_PUSH_IDLE 0x00000080
+
+#define REG_EDP_CONFIGURATION_CTRL 0x0000000c
+#define EDP_CONFIGURATION_CTRL_SYNC_CLK 0x00000001
+#define EDP_CONFIGURATION_CTRL_STATIC_MVID 0x00000002
+#define EDP_CONFIGURATION_CTRL_PROGRESSIVE 0x00000004
+#define EDP_CONFIGURATION_CTRL_LANES__MASK 0x00000030
+#define EDP_CONFIGURATION_CTRL_LANES__SHIFT 4
+static inline uint32_t EDP_CONFIGURATION_CTRL_LANES(uint32_t val)
+{
+ return ((val) << EDP_CONFIGURATION_CTRL_LANES__SHIFT) & EDP_CONFIGURATION_CTRL_LANES__MASK;
+}
+#define EDP_CONFIGURATION_CTRL_ENHANCED_FRAMING 0x00000040
+#define EDP_CONFIGURATION_CTRL_COLOR__MASK 0x00000100
+#define EDP_CONFIGURATION_CTRL_COLOR__SHIFT 8
+static inline uint32_t EDP_CONFIGURATION_CTRL_COLOR(enum edp_color_depth val)
+{
+ return ((val) << EDP_CONFIGURATION_CTRL_COLOR__SHIFT) & EDP_CONFIGURATION_CTRL_COLOR__MASK;
+}
+
+#define REG_EDP_SOFTWARE_MVID 0x00000014
+
+#define REG_EDP_SOFTWARE_NVID 0x00000018
+
+#define REG_EDP_TOTAL_HOR_VER 0x0000001c
+#define EDP_TOTAL_HOR_VER_HORIZ__MASK 0x0000ffff
+#define EDP_TOTAL_HOR_VER_HORIZ__SHIFT 0
+static inline uint32_t EDP_TOTAL_HOR_VER_HORIZ(uint32_t val)
+{
+ return ((val) << EDP_TOTAL_HOR_VER_HORIZ__SHIFT) & EDP_TOTAL_HOR_VER_HORIZ__MASK;
+}
+#define EDP_TOTAL_HOR_VER_VERT__MASK 0xffff0000
+#define EDP_TOTAL_HOR_VER_VERT__SHIFT 16
+static inline uint32_t EDP_TOTAL_HOR_VER_VERT(uint32_t val)
+{
+ return ((val) << EDP_TOTAL_HOR_VER_VERT__SHIFT) & EDP_TOTAL_HOR_VER_VERT__MASK;
+}
+
+#define REG_EDP_START_HOR_VER_FROM_SYNC 0x00000020
+#define EDP_START_HOR_VER_FROM_SYNC_HORIZ__MASK 0x0000ffff
+#define EDP_START_HOR_VER_FROM_SYNC_HORIZ__SHIFT 0
+static inline uint32_t EDP_START_HOR_VER_FROM_SYNC_HORIZ(uint32_t val)
+{
+ return ((val) << EDP_START_HOR_VER_FROM_SYNC_HORIZ__SHIFT) & EDP_START_HOR_VER_FROM_SYNC_HORIZ__MASK;
+}
+#define EDP_START_HOR_VER_FROM_SYNC_VERT__MASK 0xffff0000
+#define EDP_START_HOR_VER_FROM_SYNC_VERT__SHIFT 16
+static inline uint32_t EDP_START_HOR_VER_FROM_SYNC_VERT(uint32_t val)
+{
+ return ((val) << EDP_START_HOR_VER_FROM_SYNC_VERT__SHIFT) & EDP_START_HOR_VER_FROM_SYNC_VERT__MASK;
+}
+
+#define REG_EDP_HSYNC_VSYNC_WIDTH_POLARITY 0x00000024
+#define EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__MASK 0x00007fff
+#define EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__SHIFT 0
+static inline uint32_t EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ(uint32_t val)
+{
+ return ((val) << EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__SHIFT) & EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__MASK;
+}
+#define EDP_HSYNC_VSYNC_WIDTH_POLARITY_NHSYNC 0x00008000
+#define EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__MASK 0x7fff0000
+#define EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__SHIFT 16
+static inline uint32_t EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT(uint32_t val)
+{
+ return ((val) << EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__SHIFT) & EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__MASK;
+}
+#define EDP_HSYNC_VSYNC_WIDTH_POLARITY_NVSYNC 0x80000000
+
+#define REG_EDP_ACTIVE_HOR_VER 0x00000028
+#define EDP_ACTIVE_HOR_VER_HORIZ__MASK 0x0000ffff
+#define EDP_ACTIVE_HOR_VER_HORIZ__SHIFT 0
+static inline uint32_t EDP_ACTIVE_HOR_VER_HORIZ(uint32_t val)
+{
+ return ((val) << EDP_ACTIVE_HOR_VER_HORIZ__SHIFT) & EDP_ACTIVE_HOR_VER_HORIZ__MASK;
+}
+#define EDP_ACTIVE_HOR_VER_VERT__MASK 0xffff0000
+#define EDP_ACTIVE_HOR_VER_VERT__SHIFT 16
+static inline uint32_t EDP_ACTIVE_HOR_VER_VERT(uint32_t val)
+{
+ return ((val) << EDP_ACTIVE_HOR_VER_VERT__SHIFT) & EDP_ACTIVE_HOR_VER_VERT__MASK;
+}
+
+#define REG_EDP_MISC1_MISC0 0x0000002c
+#define EDP_MISC1_MISC0_MISC0__MASK 0x000000ff
+#define EDP_MISC1_MISC0_MISC0__SHIFT 0
+static inline uint32_t EDP_MISC1_MISC0_MISC0(uint32_t val)
+{
+ return ((val) << EDP_MISC1_MISC0_MISC0__SHIFT) & EDP_MISC1_MISC0_MISC0__MASK;
+}
+#define EDP_MISC1_MISC0_SYNC 0x00000001
+#define EDP_MISC1_MISC0_COMPONENT_FORMAT__MASK 0x00000006
+#define EDP_MISC1_MISC0_COMPONENT_FORMAT__SHIFT 1
+static inline uint32_t EDP_MISC1_MISC0_COMPONENT_FORMAT(enum edp_component_format val)
+{
+ return ((val) << EDP_MISC1_MISC0_COMPONENT_FORMAT__SHIFT) & EDP_MISC1_MISC0_COMPONENT_FORMAT__MASK;
+}
+#define EDP_MISC1_MISC0_CEA 0x00000008
+#define EDP_MISC1_MISC0_BT709_5 0x00000010
+#define EDP_MISC1_MISC0_COLOR__MASK 0x000000e0
+#define EDP_MISC1_MISC0_COLOR__SHIFT 5
+static inline uint32_t EDP_MISC1_MISC0_COLOR(enum edp_color_depth val)
+{
+ return ((val) << EDP_MISC1_MISC0_COLOR__SHIFT) & EDP_MISC1_MISC0_COLOR__MASK;
+}
+#define EDP_MISC1_MISC0_MISC1__MASK 0x0000ff00
+#define EDP_MISC1_MISC0_MISC1__SHIFT 8
+static inline uint32_t EDP_MISC1_MISC0_MISC1(uint32_t val)
+{
+ return ((val) << EDP_MISC1_MISC0_MISC1__SHIFT) & EDP_MISC1_MISC0_MISC1__MASK;
+}
+#define EDP_MISC1_MISC0_INTERLACED_ODD 0x00000100
+#define EDP_MISC1_MISC0_STEREO__MASK 0x00000600
+#define EDP_MISC1_MISC0_STEREO__SHIFT 9
+static inline uint32_t EDP_MISC1_MISC0_STEREO(uint32_t val)
+{
+ return ((val) << EDP_MISC1_MISC0_STEREO__SHIFT) & EDP_MISC1_MISC0_STEREO__MASK;
+}
+
+#define REG_EDP_PHY_CTRL 0x00000074
+#define EDP_PHY_CTRL_SW_RESET_PLL 0x00000001
+#define EDP_PHY_CTRL_SW_RESET 0x00000004
+
+#define REG_EDP_MAINLINK_READY 0x00000084
+#define EDP_MAINLINK_READY_TRAIN_PATTERN_1_READY 0x00000008
+#define EDP_MAINLINK_READY_TRAIN_PATTERN_2_READY 0x00000010
+#define EDP_MAINLINK_READY_TRAIN_PATTERN_3_READY 0x00000020
+
+#define REG_EDP_AUX_CTRL 0x00000300
+#define EDP_AUX_CTRL_ENABLE 0x00000001
+#define EDP_AUX_CTRL_RESET 0x00000002
+
+#define REG_EDP_INTERRUPT_REG_1 0x00000308
+#define EDP_INTERRUPT_REG_1_HPD 0x00000001
+#define EDP_INTERRUPT_REG_1_HPD_ACK 0x00000002
+#define EDP_INTERRUPT_REG_1_HPD_EN 0x00000004
+#define EDP_INTERRUPT_REG_1_AUX_I2C_DONE 0x00000008
+#define EDP_INTERRUPT_REG_1_AUX_I2C_DONE_ACK 0x00000010
+#define EDP_INTERRUPT_REG_1_AUX_I2C_DONE_EN 0x00000020
+#define EDP_INTERRUPT_REG_1_WRONG_ADDR 0x00000040
+#define EDP_INTERRUPT_REG_1_WRONG_ADDR_ACK 0x00000080
+#define EDP_INTERRUPT_REG_1_WRONG_ADDR_EN 0x00000100
+#define EDP_INTERRUPT_REG_1_TIMEOUT 0x00000200
+#define EDP_INTERRUPT_REG_1_TIMEOUT_ACK 0x00000400
+#define EDP_INTERRUPT_REG_1_TIMEOUT_EN 0x00000800
+#define EDP_INTERRUPT_REG_1_NACK_DEFER 0x00001000
+#define EDP_INTERRUPT_REG_1_NACK_DEFER_ACK 0x00002000
+#define EDP_INTERRUPT_REG_1_NACK_DEFER_EN 0x00004000
+#define EDP_INTERRUPT_REG_1_WRONG_DATA_CNT 0x00008000
+#define EDP_INTERRUPT_REG_1_WRONG_DATA_CNT_ACK 0x00010000
+#define EDP_INTERRUPT_REG_1_WRONG_DATA_CNT_EN 0x00020000
+#define EDP_INTERRUPT_REG_1_I2C_NACK 0x00040000
+#define EDP_INTERRUPT_REG_1_I2C_NACK_ACK 0x00080000
+#define EDP_INTERRUPT_REG_1_I2C_NACK_EN 0x00100000
+#define EDP_INTERRUPT_REG_1_I2C_DEFER 0x00200000
+#define EDP_INTERRUPT_REG_1_I2C_DEFER_ACK 0x00400000
+#define EDP_INTERRUPT_REG_1_I2C_DEFER_EN 0x00800000
+#define EDP_INTERRUPT_REG_1_PLL_UNLOCK 0x01000000
+#define EDP_INTERRUPT_REG_1_PLL_UNLOCK_ACK 0x02000000
+#define EDP_INTERRUPT_REG_1_PLL_UNLOCK_EN 0x04000000
+#define EDP_INTERRUPT_REG_1_AUX_ERROR 0x08000000
+#define EDP_INTERRUPT_REG_1_AUX_ERROR_ACK 0x10000000
+#define EDP_INTERRUPT_REG_1_AUX_ERROR_EN 0x20000000
+
+#define REG_EDP_INTERRUPT_REG_2 0x0000030c
+#define EDP_INTERRUPT_REG_2_READY_FOR_VIDEO 0x00000001
+#define EDP_INTERRUPT_REG_2_READY_FOR_VIDEO_ACK 0x00000002
+#define EDP_INTERRUPT_REG_2_READY_FOR_VIDEO_EN 0x00000004
+#define EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT 0x00000008
+#define EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT_ACK 0x00000010
+#define EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT_EN 0x00000020
+#define EDP_INTERRUPT_REG_2_FRAME_END 0x00000200
+#define EDP_INTERRUPT_REG_2_FRAME_END_ACK 0x00000080
+#define EDP_INTERRUPT_REG_2_FRAME_END_EN 0x00000100
+#define EDP_INTERRUPT_REG_2_CRC_UPDATED 0x00000200
+#define EDP_INTERRUPT_REG_2_CRC_UPDATED_ACK 0x00000400
+#define EDP_INTERRUPT_REG_2_CRC_UPDATED_EN 0x00000800
+
+#define REG_EDP_INTERRUPT_TRANS_NUM 0x00000310
+
+#define REG_EDP_AUX_DATA 0x00000314
+#define EDP_AUX_DATA_READ 0x00000001
+#define EDP_AUX_DATA_DATA__MASK 0x0000ff00
+#define EDP_AUX_DATA_DATA__SHIFT 8
+static inline uint32_t EDP_AUX_DATA_DATA(uint32_t val)
+{
+ return ((val) << EDP_AUX_DATA_DATA__SHIFT) & EDP_AUX_DATA_DATA__MASK;
+}
+#define EDP_AUX_DATA_INDEX__MASK 0x00ff0000
+#define EDP_AUX_DATA_INDEX__SHIFT 16
+static inline uint32_t EDP_AUX_DATA_INDEX(uint32_t val)
+{
+ return ((val) << EDP_AUX_DATA_INDEX__SHIFT) & EDP_AUX_DATA_INDEX__MASK;
+}
+#define EDP_AUX_DATA_INDEX_WRITE 0x80000000
+
+#define REG_EDP_AUX_TRANS_CTRL 0x00000318
+#define EDP_AUX_TRANS_CTRL_I2C 0x00000100
+#define EDP_AUX_TRANS_CTRL_GO 0x00000200
+
+#define REG_EDP_AUX_STATUS 0x00000324
+
+static inline uint32_t REG_EDP_PHY_LN(uint32_t i0) { return 0x00000400 + 0x40*i0; }
+
+static inline uint32_t REG_EDP_PHY_LN_PD_CTL(uint32_t i0) { return 0x00000404 + 0x40*i0; }
+
+#define REG_EDP_PHY_GLB_VM_CFG0 0x00000510
+
+#define REG_EDP_PHY_GLB_VM_CFG1 0x00000514
+
+#define REG_EDP_PHY_GLB_MISC9 0x00000518
+
+#define REG_EDP_PHY_GLB_CFG 0x00000528
+
+#define REG_EDP_PHY_GLB_PD_CTL 0x0000052c
+
+#define REG_EDP_PHY_GLB_PHY_STATUS 0x00000598
+
+
+#endif /* EDP_XML */
diff --git a/drivers/gpu/drm/msm/edp/edp_aux.c b/drivers/gpu/drm/msm/edp/edp_aux.c
new file mode 100644
index 000000000000..5f5a84f6074c
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp_aux.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "edp.h"
+#include "edp.xml.h"
+
+#define AUX_CMD_FIFO_LEN 144
+#define AUX_CMD_NATIVE_MAX 16
+#define AUX_CMD_I2C_MAX 128
+
+#define EDP_INTR_AUX_I2C_ERR \
+ (EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \
+ EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \
+ EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER)
+#define EDP_INTR_TRANS_STATUS \
+ (EDP_INTERRUPT_REG_1_AUX_I2C_DONE | EDP_INTR_AUX_I2C_ERR)
+
+struct edp_aux {
+ void __iomem *base;
+ bool msg_err;
+
+ struct completion msg_comp;
+
+ /* To prevent the message transaction routine from reentry. */
+ struct mutex msg_mutex;
+
+ struct drm_dp_aux drm_aux;
+};
+#define to_edp_aux(x) container_of(x, struct edp_aux, drm_aux)
+
+static int edp_msg_fifo_tx(struct edp_aux *aux, struct drm_dp_aux_msg *msg)
+{
+ u32 data[4];
+ u32 reg, len;
+ bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
+ bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
+ u8 *msgdata = msg->buffer;
+ int i;
+
+ if (read)
+ len = 4;
+ else
+ len = msg->size + 4;
+
+ /*
+ * cmd fifo only has depth of 144 bytes
+ */
+ if (len > AUX_CMD_FIFO_LEN)
+ return -EINVAL;
+
+ /* Pack cmd and write to HW */
+ data[0] = (msg->address >> 16) & 0xf; /* addr[19:16] */
+ if (read)
+ data[0] |= BIT(4); /* R/W */
+
+ data[1] = (msg->address >> 8) & 0xff; /* addr[15:8] */
+ data[2] = msg->address & 0xff; /* addr[7:0] */
+ data[3] = (msg->size - 1) & 0xff; /* len[7:0] */
+
+ for (i = 0; i < len; i++) {
+ reg = (i < 4) ? data[i] : msgdata[i - 4];
+ reg = EDP_AUX_DATA_DATA(reg); /* index = 0, write */
+ if (i == 0)
+ reg |= EDP_AUX_DATA_INDEX_WRITE;
+ edp_write(aux->base + REG_EDP_AUX_DATA, reg);
+ }
+
+ reg = 0; /* Transaction number is always 1 */
+ if (!native) /* i2c */
+ reg |= EDP_AUX_TRANS_CTRL_I2C;
+
+ reg |= EDP_AUX_TRANS_CTRL_GO;
+ edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, reg);
+
+ return 0;
+}
+
+static int edp_msg_fifo_rx(struct edp_aux *aux, struct drm_dp_aux_msg *msg)
+{
+ u32 data;
+ u8 *dp;
+ int i;
+ u32 len = msg->size;
+
+ edp_write(aux->base + REG_EDP_AUX_DATA,
+ EDP_AUX_DATA_INDEX_WRITE | EDP_AUX_DATA_READ); /* index = 0 */
+
+ dp = msg->buffer;
+
+ /* discard first byte */
+ data = edp_read(aux->base + REG_EDP_AUX_DATA);
+ for (i = 0; i < len; i++) {
+ data = edp_read(aux->base + REG_EDP_AUX_DATA);
+ dp[i] = (u8)((data >> 8) & 0xff);
+ }
+
+ return 0;
+}
+
+/*
+ * This function does the real job to process an AUX transaction.
+ * It will call msm_edp_aux_ctrl() function to reset the AUX channel,
+ * if the waiting is timeout.
+ * The caller who triggers the transaction should avoid the
+ * msm_edp_aux_ctrl() running concurrently in other threads, i.e.
+ * start transaction only when AUX channel is fully enabled.
+ */
+ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg)
+{
+ struct edp_aux *aux = to_edp_aux(drm_aux);
+ ssize_t ret;
+ bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
+ bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
+
+ /* Ignore address only message */
+ if ((msg->size == 0) || (msg->buffer == NULL)) {
+ msg->reply = native ?
+ DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+ return msg->size;
+ }
+
+ /* msg sanity check */
+ if ((native && (msg->size > AUX_CMD_NATIVE_MAX)) ||
+ (msg->size > AUX_CMD_I2C_MAX)) {
+ pr_err("%s: invalid msg: size(%d), request(%x)\n",
+ __func__, msg->size, msg->request);
+ return -EINVAL;
+ }
+
+ mutex_lock(&aux->msg_mutex);
+
+ aux->msg_err = false;
+ reinit_completion(&aux->msg_comp);
+
+ ret = edp_msg_fifo_tx(aux, msg);
+ if (ret < 0)
+ goto unlock_exit;
+
+ DBG("wait_for_completion");
+ ret = wait_for_completion_timeout(&aux->msg_comp, 300);
+ if (ret <= 0) {
+ /*
+ * Clear GO and reset AUX channel
+ * to cancel the current transaction.
+ */
+ edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
+ msm_edp_aux_ctrl(aux, 1);
+ pr_err("%s: aux timeout, %d\n", __func__, ret);
+ goto unlock_exit;
+ }
+ DBG("completion");
+
+ if (!aux->msg_err) {
+ if (read) {
+ ret = edp_msg_fifo_rx(aux, msg);
+ if (ret < 0)
+ goto unlock_exit;
+ }
+
+ msg->reply = native ?
+ DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+ } else {
+ /* Reply defer to retry */
+ msg->reply = native ?
+ DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
+ /*
+ * The sleep time in caller is not long enough to make sure
+ * our H/W completes transactions. Add more defer time here.
+ */
+ msleep(100);
+ }
+
+ /* Return requested size for success or retry */
+ ret = msg->size;
+
+unlock_exit:
+ mutex_unlock(&aux->msg_mutex);
+ return ret;
+}
+
+void *msm_edp_aux_init(struct device *dev, void __iomem *regbase,
+ struct drm_dp_aux **drm_aux)
+{
+ struct edp_aux *aux = NULL;
+ int ret;
+
+ DBG("");
+ aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL);
+ if (!aux)
+ return NULL;
+
+ aux->base = regbase;
+ mutex_init(&aux->msg_mutex);
+ init_completion(&aux->msg_comp);
+
+ aux->drm_aux.name = "msm_edp_aux";
+ aux->drm_aux.dev = dev;
+ aux->drm_aux.transfer = edp_aux_transfer;
+ ret = drm_dp_aux_register(&aux->drm_aux);
+ if (ret) {
+ pr_err("%s: failed to register drm aux: %d\n", __func__, ret);
+ mutex_destroy(&aux->msg_mutex);
+ }
+
+ if (drm_aux && aux)
+ *drm_aux = &aux->drm_aux;
+
+ return aux;
+}
+
+void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux)
+{
+ if (aux) {
+ drm_dp_aux_unregister(&aux->drm_aux);
+ mutex_destroy(&aux->msg_mutex);
+ }
+}
+
+irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr)
+{
+ if (isr & EDP_INTR_TRANS_STATUS) {
+ DBG("isr=%x", isr);
+ edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
+
+ if (isr & EDP_INTR_AUX_I2C_ERR)
+ aux->msg_err = true;
+ else
+ aux->msg_err = false;
+
+ complete(&aux->msg_comp);
+ }
+
+ return IRQ_HANDLED;
+}
+
+void msm_edp_aux_ctrl(struct edp_aux *aux, int enable)
+{
+ u32 data;
+
+ DBG("enable=%d", enable);
+ data = edp_read(aux->base + REG_EDP_AUX_CTRL);
+
+ if (enable) {
+ data |= EDP_AUX_CTRL_RESET;
+ edp_write(aux->base + REG_EDP_AUX_CTRL, data);
+ /* Make sure full reset */
+ wmb();
+ usleep_range(500, 1000);
+
+ data &= ~EDP_AUX_CTRL_RESET;
+ data |= EDP_AUX_CTRL_ENABLE;
+ edp_write(aux->base + REG_EDP_AUX_CTRL, data);
+ } else {
+ data &= ~EDP_AUX_CTRL_ENABLE;
+ edp_write(aux->base + REG_EDP_AUX_CTRL, data);
+ }
+}
+
diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c b/drivers/gpu/drm/msm/edp/edp_bridge.c
new file mode 100644
index 000000000000..2bc73f82f3f5
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp_bridge.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "edp.h"
+
+struct edp_bridge {
+ struct drm_bridge base;
+ struct msm_edp *edp;
+};
+#define to_edp_bridge(x) container_of(x, struct edp_bridge, base)
+
+void edp_bridge_destroy(struct drm_bridge *bridge)
+{
+}
+
+static void edp_bridge_pre_enable(struct drm_bridge *bridge)
+{
+ struct edp_bridge *edp_bridge = to_edp_bridge(bridge);
+ struct msm_edp *edp = edp_bridge->edp;
+
+ DBG("");
+ msm_edp_ctrl_power(edp->ctrl, true);
+}
+
+static void edp_bridge_enable(struct drm_bridge *bridge)
+{
+ DBG("");
+}
+
+static void edp_bridge_disable(struct drm_bridge *bridge)
+{
+ DBG("");
+}
+
+static void edp_bridge_post_disable(struct drm_bridge *bridge)
+{
+ struct edp_bridge *edp_bridge = to_edp_bridge(bridge);
+ struct msm_edp *edp = edp_bridge->edp;
+
+ DBG("");
+ msm_edp_ctrl_power(edp->ctrl, false);
+}
+
+static void edp_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = bridge->dev;
+ struct drm_connector *connector;
+ struct edp_bridge *edp_bridge = to_edp_bridge(bridge);
+ struct msm_edp *edp = edp_bridge->edp;
+
+ DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
+ mode->base.id, mode->name,
+ mode->vrefresh, mode->clock,
+ mode->hdisplay, mode->hsync_start,
+ mode->hsync_end, mode->htotal,
+ mode->vdisplay, mode->vsync_start,
+ mode->vsync_end, mode->vtotal,
+ mode->type, mode->flags);
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if ((connector->encoder != NULL) &&
+ (connector->encoder->bridge == bridge)) {
+ msm_edp_ctrl_timing_cfg(edp->ctrl,
+ adjusted_mode, &connector->display_info);
+ break;
+ }
+ }
+}
+
+static const struct drm_bridge_funcs edp_bridge_funcs = {
+ .pre_enable = edp_bridge_pre_enable,
+ .enable = edp_bridge_enable,
+ .disable = edp_bridge_disable,
+ .post_disable = edp_bridge_post_disable,
+ .mode_set = edp_bridge_mode_set,
+};
+
+/* initialize bridge */
+struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp)
+{
+ struct drm_bridge *bridge = NULL;
+ struct edp_bridge *edp_bridge;
+ int ret;
+
+ edp_bridge = devm_kzalloc(edp->dev->dev,
+ sizeof(*edp_bridge), GFP_KERNEL);
+ if (!edp_bridge) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ edp_bridge->edp = edp;
+
+ bridge = &edp_bridge->base;
+ bridge->funcs = &edp_bridge_funcs;
+
+ ret = drm_bridge_attach(edp->dev, bridge);
+ if (ret)
+ goto fail;
+
+ return bridge;
+
+fail:
+ if (bridge)
+ edp_bridge_destroy(bridge);
+
+ return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/edp/edp_connector.c b/drivers/gpu/drm/msm/edp/edp_connector.c
new file mode 100644
index 000000000000..d8812e84da54
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp_connector.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "drm/drm_edid.h"
+#include "msm_kms.h"
+#include "edp.h"
+
+struct edp_connector {
+ struct drm_connector base;
+ struct msm_edp *edp;
+};
+#define to_edp_connector(x) container_of(x, struct edp_connector, base)
+
+static enum drm_connector_status edp_connector_detect(
+ struct drm_connector *connector, bool force)
+{
+ struct edp_connector *edp_connector = to_edp_connector(connector);
+ struct msm_edp *edp = edp_connector->edp;
+
+ DBG("");
+ return msm_edp_ctrl_panel_connected(edp->ctrl) ?
+ connector_status_connected : connector_status_disconnected;
+}
+
+static void edp_connector_destroy(struct drm_connector *connector)
+{
+ struct edp_connector *edp_connector = to_edp_connector(connector);
+
+ DBG("");
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+
+ kfree(edp_connector);
+}
+
+static int edp_connector_get_modes(struct drm_connector *connector)
+{
+ struct edp_connector *edp_connector = to_edp_connector(connector);
+ struct msm_edp *edp = edp_connector->edp;
+
+ struct edid *drm_edid = NULL;
+ int ret = 0;
+
+ DBG("");
+ ret = msm_edp_ctrl_get_panel_info(edp->ctrl, connector, &drm_edid);
+ if (ret)
+ return ret;
+
+ drm_mode_connector_update_edid_property(connector, drm_edid);
+ if (drm_edid)
+ ret = drm_add_edid_modes(connector, drm_edid);
+
+ return ret;
+}
+
+static int edp_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct edp_connector *edp_connector = to_edp_connector(connector);
+ struct msm_edp *edp = edp_connector->edp;
+ struct msm_drm_private *priv = connector->dev->dev_private;
+ struct msm_kms *kms = priv->kms;
+ long actual, requested;
+
+ requested = 1000 * mode->clock;
+ actual = kms->funcs->round_pixclk(kms,
+ requested, edp_connector->edp->encoder);
+
+ DBG("requested=%ld, actual=%ld", requested, actual);
+ if (actual != requested)
+ return MODE_CLOCK_RANGE;
+
+ if (!msm_edp_ctrl_pixel_clock_valid(
+ edp->ctrl, mode->clock, NULL, NULL))
+ return MODE_CLOCK_RANGE;
+
+ /* Invalidate all modes if color format is not supported */
+ if (connector->display_info.bpc > 8)
+ return MODE_BAD;
+
+ return MODE_OK;
+}
+
+static struct drm_encoder *
+edp_connector_best_encoder(struct drm_connector *connector)
+{
+ struct edp_connector *edp_connector = to_edp_connector(connector);
+
+ DBG("");
+ return edp_connector->edp->encoder;
+}
+
+static const struct drm_connector_funcs edp_connector_funcs = {
+ .dpms = drm_atomic_helper_connector_dpms,
+ .detect = edp_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = edp_connector_destroy,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs edp_connector_helper_funcs = {
+ .get_modes = edp_connector_get_modes,
+ .mode_valid = edp_connector_mode_valid,
+ .best_encoder = edp_connector_best_encoder,
+};
+
+/* initialize connector */
+struct drm_connector *msm_edp_connector_init(struct msm_edp *edp)
+{
+ struct drm_connector *connector = NULL;
+ struct edp_connector *edp_connector;
+ int ret;
+
+ edp_connector = kzalloc(sizeof(*edp_connector), GFP_KERNEL);
+ if (!edp_connector) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ edp_connector->edp = edp;
+
+ connector = &edp_connector->base;
+
+ ret = drm_connector_init(edp->dev, connector, &edp_connector_funcs,
+ DRM_MODE_CONNECTOR_eDP);
+ if (ret)
+ goto fail;
+
+ drm_connector_helper_add(connector, &edp_connector_helper_funcs);
+
+ /* We don't support HPD, so only poll status until connected. */
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+
+ /* Display driver doesn't support interlace now. */
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
+
+ ret = drm_connector_register(connector);
+ if (ret)
+ goto fail;
+
+ return connector;
+
+fail:
+ if (connector)
+ edp_connector_destroy(connector);
+
+ return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c b/drivers/gpu/drm/msm/edp/edp_ctrl.c
new file mode 100644
index 000000000000..3e246210c46f
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c
@@ -0,0 +1,1373 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+
+#include "drm_crtc.h"
+#include "drm_dp_helper.h"
+#include "drm_edid.h"
+#include "edp.h"
+#include "edp.xml.h"
+
+#define VDDA_MIN_UV 1800000 /* uV units */
+#define VDDA_MAX_UV 1800000 /* uV units */
+#define VDDA_UA_ON_LOAD 100000 /* uA units */
+#define VDDA_UA_OFF_LOAD 100 /* uA units */
+
+#define DPCD_LINK_VOLTAGE_MAX 4
+#define DPCD_LINK_PRE_EMPHASIS_MAX 4
+
+#define EDP_LINK_BW_MAX DP_LINK_BW_2_7
+
+/* Link training return value */
+#define EDP_TRAIN_FAIL -1
+#define EDP_TRAIN_SUCCESS 0
+#define EDP_TRAIN_RECONFIG 1
+
+#define EDP_CLK_MASK_AHB BIT(0)
+#define EDP_CLK_MASK_AUX BIT(1)
+#define EDP_CLK_MASK_LINK BIT(2)
+#define EDP_CLK_MASK_PIXEL BIT(3)
+#define EDP_CLK_MASK_MDP_CORE BIT(4)
+#define EDP_CLK_MASK_LINK_CHAN (EDP_CLK_MASK_LINK | EDP_CLK_MASK_PIXEL)
+#define EDP_CLK_MASK_AUX_CHAN \
+ (EDP_CLK_MASK_AHB | EDP_CLK_MASK_AUX | EDP_CLK_MASK_MDP_CORE)
+#define EDP_CLK_MASK_ALL (EDP_CLK_MASK_AUX_CHAN | EDP_CLK_MASK_LINK_CHAN)
+
+#define EDP_BACKLIGHT_MAX 255
+
+#define EDP_INTR_STATUS1 \
+ (EDP_INTERRUPT_REG_1_HPD | EDP_INTERRUPT_REG_1_AUX_I2C_DONE | \
+ EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \
+ EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \
+ EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER | \
+ EDP_INTERRUPT_REG_1_PLL_UNLOCK | EDP_INTERRUPT_REG_1_AUX_ERROR)
+#define EDP_INTR_MASK1 (EDP_INTR_STATUS1 << 2)
+#define EDP_INTR_STATUS2 \
+ (EDP_INTERRUPT_REG_2_READY_FOR_VIDEO | \
+ EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT | \
+ EDP_INTERRUPT_REG_2_FRAME_END | EDP_INTERRUPT_REG_2_CRC_UPDATED)
+#define EDP_INTR_MASK2 (EDP_INTR_STATUS2 << 2)
+
+struct edp_ctrl {
+ struct platform_device *pdev;
+
+ void __iomem *base;
+
+ /* regulators */
+ struct regulator *vdda_vreg;
+ struct regulator *lvl_vreg;
+
+ /* clocks */
+ struct clk *aux_clk;
+ struct clk *pixel_clk;
+ struct clk *ahb_clk;
+ struct clk *link_clk;
+ struct clk *mdp_core_clk;
+
+ /* gpios */
+ struct gpio_desc *panel_en_gpio;
+ struct gpio_desc *panel_hpd_gpio;
+
+ /* completion and mutex */
+ struct completion idle_comp;
+ struct mutex dev_mutex; /* To protect device power status */
+
+ /* work queue */
+ struct work_struct on_work;
+ struct work_struct off_work;
+ struct workqueue_struct *workqueue;
+
+ /* Interrupt register lock */
+ spinlock_t irq_lock;
+
+ bool edp_connected;
+ bool power_on;
+
+ /* edid raw data */
+ struct edid *edid;
+
+ struct drm_dp_link dp_link;
+ struct drm_dp_aux *drm_aux;
+
+ /* dpcd raw data */
+ u8 dpcd[DP_RECEIVER_CAP_SIZE];
+
+ /* Link status */
+ u8 link_rate;
+ u8 lane_cnt;
+ u8 v_level;
+ u8 p_level;
+
+ /* Timing status */
+ u8 interlaced;
+ u32 pixel_rate; /* in kHz */
+ u32 color_depth;
+
+ struct edp_aux *aux;
+ struct edp_phy *phy;
+};
+
+struct edp_pixel_clk_div {
+ u32 rate; /* in kHz */
+ u32 m;
+ u32 n;
+};
+
+#define EDP_PIXEL_CLK_NUM 8
+static const struct edp_pixel_clk_div clk_divs[2][EDP_PIXEL_CLK_NUM] = {
+ { /* Link clock = 162MHz, source clock = 810MHz */
+ {119000, 31, 211}, /* WSXGA+ 1680x1050@60Hz CVT */
+ {130250, 32, 199}, /* UXGA 1600x1200@60Hz CVT */
+ {148500, 11, 60}, /* FHD 1920x1080@60Hz */
+ {154000, 50, 263}, /* WUXGA 1920x1200@60Hz CVT */
+ {209250, 31, 120}, /* QXGA 2048x1536@60Hz CVT */
+ {268500, 119, 359}, /* WQXGA 2560x1600@60Hz CVT */
+ {138530, 33, 193}, /* AUO B116HAN03.0 Panel */
+ {141400, 48, 275}, /* AUO B133HTN01.2 Panel */
+ },
+ { /* Link clock = 270MHz, source clock = 675MHz */
+ {119000, 52, 295}, /* WSXGA+ 1680x1050@60Hz CVT */
+ {130250, 11, 57}, /* UXGA 1600x1200@60Hz CVT */
+ {148500, 11, 50}, /* FHD 1920x1080@60Hz */
+ {154000, 47, 206}, /* WUXGA 1920x1200@60Hz CVT */
+ {209250, 31, 100}, /* QXGA 2048x1536@60Hz CVT */
+ {268500, 107, 269}, /* WQXGA 2560x1600@60Hz CVT */
+ {138530, 63, 307}, /* AUO B116HAN03.0 Panel */
+ {141400, 53, 253}, /* AUO B133HTN01.2 Panel */
+ },
+};
+
+static int edp_clk_init(struct edp_ctrl *ctrl)
+{
+ struct device *dev = &ctrl->pdev->dev;
+ int ret;
+
+ ctrl->aux_clk = devm_clk_get(dev, "core_clk");
+ if (IS_ERR(ctrl->aux_clk)) {
+ ret = PTR_ERR(ctrl->aux_clk);
+ pr_err("%s: Can't find aux_clk, %d\n", __func__, ret);
+ ctrl->aux_clk = NULL;
+ return ret;
+ }
+
+ ctrl->pixel_clk = devm_clk_get(dev, "pixel_clk");
+ if (IS_ERR(ctrl->pixel_clk)) {
+ ret = PTR_ERR(ctrl->pixel_clk);
+ pr_err("%s: Can't find pixel_clk, %d\n", __func__, ret);
+ ctrl->pixel_clk = NULL;
+ return ret;
+ }
+
+ ctrl->ahb_clk = devm_clk_get(dev, "iface_clk");
+ if (IS_ERR(ctrl->ahb_clk)) {
+ ret = PTR_ERR(ctrl->ahb_clk);
+ pr_err("%s: Can't find ahb_clk, %d\n", __func__, ret);
+ ctrl->ahb_clk = NULL;
+ return ret;
+ }
+
+ ctrl->link_clk = devm_clk_get(dev, "link_clk");
+ if (IS_ERR(ctrl->link_clk)) {
+ ret = PTR_ERR(ctrl->link_clk);
+ pr_err("%s: Can't find link_clk, %d\n", __func__, ret);
+ ctrl->link_clk = NULL;
+ return ret;
+ }
+
+ /* need mdp core clock to receive irq */
+ ctrl->mdp_core_clk = devm_clk_get(dev, "mdp_core_clk");
+ if (IS_ERR(ctrl->mdp_core_clk)) {
+ ret = PTR_ERR(ctrl->mdp_core_clk);
+ pr_err("%s: Can't find mdp_core_clk, %d\n", __func__, ret);
+ ctrl->mdp_core_clk = NULL;
+ return ret;
+ }
+
+ return 0;
+}
+
+static int edp_clk_enable(struct edp_ctrl *ctrl, u32 clk_mask)
+{
+ int ret;
+
+ DBG("mask=%x", clk_mask);
+ /* ahb_clk should be enabled first */
+ if (clk_mask & EDP_CLK_MASK_AHB) {
+ ret = clk_prepare_enable(ctrl->ahb_clk);
+ if (ret) {
+ pr_err("%s: Failed to enable ahb clk\n", __func__);
+ goto f0;
+ }
+ }
+ if (clk_mask & EDP_CLK_MASK_AUX) {
+ ret = clk_set_rate(ctrl->aux_clk, 19200000);
+ if (ret) {
+ pr_err("%s: Failed to set rate aux clk\n", __func__);
+ goto f1;
+ }
+ ret = clk_prepare_enable(ctrl->aux_clk);
+ if (ret) {
+ pr_err("%s: Failed to enable aux clk\n", __func__);
+ goto f1;
+ }
+ }
+ /* Need to set rate and enable link_clk prior to pixel_clk */
+ if (clk_mask & EDP_CLK_MASK_LINK) {
+ DBG("edp->link_clk, set_rate %ld",
+ (unsigned long)ctrl->link_rate * 27000000);
+ ret = clk_set_rate(ctrl->link_clk,
+ (unsigned long)ctrl->link_rate * 27000000);
+ if (ret) {
+ pr_err("%s: Failed to set rate to link clk\n",
+ __func__);
+ goto f2;
+ }
+
+ ret = clk_prepare_enable(ctrl->link_clk);
+ if (ret) {
+ pr_err("%s: Failed to enable link clk\n", __func__);
+ goto f2;
+ }
+ }
+ if (clk_mask & EDP_CLK_MASK_PIXEL) {
+ DBG("edp->pixel_clk, set_rate %ld",
+ (unsigned long)ctrl->pixel_rate * 1000);
+ ret = clk_set_rate(ctrl->pixel_clk,
+ (unsigned long)ctrl->pixel_rate * 1000);
+ if (ret) {
+ pr_err("%s: Failed to set rate to pixel clk\n",
+ __func__);
+ goto f3;
+ }
+
+ ret = clk_prepare_enable(ctrl->pixel_clk);
+ if (ret) {
+ pr_err("%s: Failed to enable pixel clk\n", __func__);
+ goto f3;
+ }
+ }
+ if (clk_mask & EDP_CLK_MASK_MDP_CORE) {
+ ret = clk_prepare_enable(ctrl->mdp_core_clk);
+ if (ret) {
+ pr_err("%s: Failed to enable mdp core clk\n", __func__);
+ goto f4;
+ }
+ }
+
+ return 0;
+
+f4:
+ if (clk_mask & EDP_CLK_MASK_PIXEL)
+ clk_disable_unprepare(ctrl->pixel_clk);
+f3:
+ if (clk_mask & EDP_CLK_MASK_LINK)
+ clk_disable_unprepare(ctrl->link_clk);
+f2:
+ if (clk_mask & EDP_CLK_MASK_AUX)
+ clk_disable_unprepare(ctrl->aux_clk);
+f1:
+ if (clk_mask & EDP_CLK_MASK_AHB)
+ clk_disable_unprepare(ctrl->ahb_clk);
+f0:
+ return ret;
+}
+
+static void edp_clk_disable(struct edp_ctrl *ctrl, u32 clk_mask)
+{
+ if (clk_mask & EDP_CLK_MASK_MDP_CORE)
+ clk_disable_unprepare(ctrl->mdp_core_clk);
+ if (clk_mask & EDP_CLK_MASK_PIXEL)
+ clk_disable_unprepare(ctrl->pixel_clk);
+ if (clk_mask & EDP_CLK_MASK_LINK)
+ clk_disable_unprepare(ctrl->link_clk);
+ if (clk_mask & EDP_CLK_MASK_AUX)
+ clk_disable_unprepare(ctrl->aux_clk);
+ if (clk_mask & EDP_CLK_MASK_AHB)
+ clk_disable_unprepare(ctrl->ahb_clk);
+}
+
+static int edp_regulator_init(struct edp_ctrl *ctrl)
+{
+ struct device *dev = &ctrl->pdev->dev;
+
+ DBG("");
+ ctrl->vdda_vreg = devm_regulator_get(dev, "vdda");
+ if (IS_ERR(ctrl->vdda_vreg)) {
+ pr_err("%s: Could not get vdda reg, ret = %ld\n", __func__,
+ PTR_ERR(ctrl->vdda_vreg));
+ ctrl->vdda_vreg = NULL;
+ return PTR_ERR(ctrl->vdda_vreg);
+ }
+ ctrl->lvl_vreg = devm_regulator_get(dev, "lvl-vdd");
+ if (IS_ERR(ctrl->lvl_vreg)) {
+ pr_err("Could not get lvl-vdd reg, %ld",
+ PTR_ERR(ctrl->lvl_vreg));
+ ctrl->lvl_vreg = NULL;
+ return PTR_ERR(ctrl->lvl_vreg);
+ }
+
+ return 0;
+}
+
+static int edp_regulator_enable(struct edp_ctrl *ctrl)
+{
+ int ret;
+
+ ret = regulator_set_voltage(ctrl->vdda_vreg, VDDA_MIN_UV, VDDA_MAX_UV);
+ if (ret) {
+ pr_err("%s:vdda_vreg set_voltage failed, %d\n", __func__, ret);
+ goto vdda_set_fail;
+ }
+
+ ret = regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_ON_LOAD);
+ if (ret < 0) {
+ pr_err("%s: vdda_vreg set regulator mode failed.\n", __func__);
+ goto vdda_set_fail;
+ }
+
+ ret = regulator_enable(ctrl->vdda_vreg);
+ if (ret) {
+ pr_err("%s: Failed to enable vdda_vreg regulator.\n", __func__);
+ goto vdda_enable_fail;
+ }
+
+ ret = regulator_enable(ctrl->lvl_vreg);
+ if (ret) {
+ pr_err("Failed to enable lvl-vdd reg regulator, %d", ret);
+ goto lvl_enable_fail;
+ }
+
+ DBG("exit");
+ return 0;
+
+lvl_enable_fail:
+ regulator_disable(ctrl->vdda_vreg);
+vdda_enable_fail:
+ regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
+vdda_set_fail:
+ return ret;
+}
+
+static void edp_regulator_disable(struct edp_ctrl *ctrl)
+{
+ regulator_disable(ctrl->lvl_vreg);
+ regulator_disable(ctrl->vdda_vreg);
+ regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
+}
+
+static int edp_gpio_config(struct edp_ctrl *ctrl)
+{
+ struct device *dev = &ctrl->pdev->dev;
+ int ret;
+
+ ctrl->panel_hpd_gpio = devm_gpiod_get(dev, "panel-hpd");
+ if (IS_ERR(ctrl->panel_hpd_gpio)) {
+ ret = PTR_ERR(ctrl->panel_hpd_gpio);
+ ctrl->panel_hpd_gpio = NULL;
+ pr_err("%s: cannot get panel-hpd-gpios, %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = gpiod_direction_input(ctrl->panel_hpd_gpio);
+ if (ret) {
+ pr_err("%s: Set direction for hpd failed, %d\n", __func__, ret);
+ return ret;
+ }
+
+ ctrl->panel_en_gpio = devm_gpiod_get(dev, "panel-en");
+ if (IS_ERR(ctrl->panel_en_gpio)) {
+ ret = PTR_ERR(ctrl->panel_en_gpio);
+ ctrl->panel_en_gpio = NULL;
+ pr_err("%s: cannot get panel-en-gpios, %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = gpiod_direction_output(ctrl->panel_en_gpio, 0);
+ if (ret) {
+ pr_err("%s: Set direction for panel_en failed, %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ DBG("gpio on");
+
+ return 0;
+}
+
+static void edp_ctrl_irq_enable(struct edp_ctrl *ctrl, int enable)
+{
+ unsigned long flags;
+
+ DBG("%d", enable);
+ spin_lock_irqsave(&ctrl->irq_lock, flags);
+ if (enable) {
+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, EDP_INTR_MASK1);
+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, EDP_INTR_MASK2);
+ } else {
+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, 0x0);
+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, 0x0);
+ }
+ spin_unlock_irqrestore(&ctrl->irq_lock, flags);
+ DBG("exit");
+}
+
+static void edp_fill_link_cfg(struct edp_ctrl *ctrl)
+{
+ u32 prate;
+ u32 lrate;
+ u32 bpp;
+ u8 max_lane = ctrl->dp_link.num_lanes;
+ u8 lane;
+
+ prate = ctrl->pixel_rate;
+ bpp = ctrl->color_depth * 3;
+
+ /*
+ * By default, use the maximum link rate and minimum lane count,
+ * so that we can do rate down shift during link training.
+ */
+ ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate);
+
+ prate *= bpp;
+ prate /= 8; /* in kByte */
+
+ lrate = 270000; /* in kHz */
+ lrate *= ctrl->link_rate;
+ lrate /= 10; /* in kByte, 10 bits --> 8 bits */
+
+ for (lane = 1; lane <= max_lane; lane <<= 1) {
+ if (lrate >= prate)
+ break;
+ lrate <<= 1;
+ }
+
+ ctrl->lane_cnt = lane;
+ DBG("rate=%d lane=%d", ctrl->link_rate, ctrl->lane_cnt);
+}
+
+static void edp_config_ctrl(struct edp_ctrl *ctrl)
+{
+ u32 data;
+ enum edp_color_depth depth;
+
+ data = EDP_CONFIGURATION_CTRL_LANES(ctrl->lane_cnt - 1);
+
+ if (ctrl->dp_link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
+ data |= EDP_CONFIGURATION_CTRL_ENHANCED_FRAMING;
+
+ depth = EDP_6BIT;
+ if (ctrl->color_depth == 8)
+ depth = EDP_8BIT;
+
+ data |= EDP_CONFIGURATION_CTRL_COLOR(depth);
+
+ if (!ctrl->interlaced) /* progressive */
+ data |= EDP_CONFIGURATION_CTRL_PROGRESSIVE;
+
+ data |= (EDP_CONFIGURATION_CTRL_SYNC_CLK |
+ EDP_CONFIGURATION_CTRL_STATIC_MVID);
+
+ edp_write(ctrl->base + REG_EDP_CONFIGURATION_CTRL, data);
+}
+
+static void edp_state_ctrl(struct edp_ctrl *ctrl, u32 state)
+{
+ edp_write(ctrl->base + REG_EDP_STATE_CTRL, state);
+ /* Make sure H/W status is set */
+ wmb();
+}
+
+static int edp_lane_set_write(struct edp_ctrl *ctrl,
+ u8 voltage_level, u8 pre_emphasis_level)
+{
+ int i;
+ u8 buf[4];
+
+ if (voltage_level >= DPCD_LINK_VOLTAGE_MAX)
+ voltage_level |= 0x04;
+
+ if (pre_emphasis_level >= DPCD_LINK_PRE_EMPHASIS_MAX)
+ pre_emphasis_level |= 0x04;
+
+ pre_emphasis_level <<= 3;
+
+ for (i = 0; i < 4; i++)
+ buf[i] = voltage_level | pre_emphasis_level;
+
+ DBG("%s: p|v=0x%x", __func__, voltage_level | pre_emphasis_level);
+ if (drm_dp_dpcd_write(ctrl->drm_aux, 0x103, buf, 4) < 4) {
+ pr_err("%s: Set sw/pe to panel failed\n", __func__);
+ return -ENOLINK;
+ }
+
+ return 0;
+}
+
+static int edp_train_pattern_set_write(struct edp_ctrl *ctrl, u8 pattern)
+{
+ u8 p = pattern;
+
+ DBG("pattern=%x", p);
+ if (drm_dp_dpcd_write(ctrl->drm_aux,
+ DP_TRAINING_PATTERN_SET, &p, 1) < 1) {
+ pr_err("%s: Set training pattern to panel failed\n", __func__);
+ return -ENOLINK;
+ }
+
+ return 0;
+}
+
+static void edp_sink_train_set_adjust(struct edp_ctrl *ctrl,
+ const u8 *link_status)
+{
+ int i;
+ u8 max = 0;
+ u8 data;
+
+ /* use the max level across lanes */
+ for (i = 0; i < ctrl->lane_cnt; i++) {
+ data = drm_dp_get_adjust_request_voltage(link_status, i);
+ DBG("lane=%d req_voltage_swing=0x%x", i, data);
+ if (max < data)
+ max = data;
+ }
+
+ ctrl->v_level = max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
+
+ /* use the max level across lanes */
+ max = 0;
+ for (i = 0; i < ctrl->lane_cnt; i++) {
+ data = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
+ DBG("lane=%d req_pre_emphasis=0x%x", i, data);
+ if (max < data)
+ max = data;
+ }
+
+ ctrl->p_level = max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
+ DBG("v_level=%d, p_level=%d", ctrl->v_level, ctrl->p_level);
+}
+
+static void edp_host_train_set(struct edp_ctrl *ctrl, u32 train)
+{
+ int cnt = 10;
+ u32 data;
+ u32 shift = train - 1;
+
+ DBG("train=%d", train);
+
+ edp_state_ctrl(ctrl, EDP_STATE_CTRL_TRAIN_PATTERN_1 << shift);
+ while (--cnt) {
+ data = edp_read(ctrl->base + REG_EDP_MAINLINK_READY);
+ if (data & (EDP_MAINLINK_READY_TRAIN_PATTERN_1_READY << shift))
+ break;
+ }
+
+ if (cnt == 0)
+ pr_err("%s: set link_train=%d failed\n", __func__, train);
+}
+
+static const u8 vm_pre_emphasis[4][4] = {
+ {0x03, 0x06, 0x09, 0x0C}, /* pe0, 0 db */
+ {0x03, 0x06, 0x09, 0xFF}, /* pe1, 3.5 db */
+ {0x03, 0x06, 0xFF, 0xFF}, /* pe2, 6.0 db */
+ {0x03, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */
+};
+
+/* voltage swing, 0.2v and 1.0v are not support */
+static const u8 vm_voltage_swing[4][4] = {
+ {0x14, 0x18, 0x1A, 0x1E}, /* sw0, 0.4v */
+ {0x18, 0x1A, 0x1E, 0xFF}, /* sw1, 0.6 v */
+ {0x1A, 0x1E, 0xFF, 0xFF}, /* sw1, 0.8 v */
+ {0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */
+};
+
+static int edp_voltage_pre_emphasise_set(struct edp_ctrl *ctrl)
+{
+ u32 value0;
+ u32 value1;
+
+ DBG("v=%d p=%d", ctrl->v_level, ctrl->p_level);
+
+ value0 = vm_pre_emphasis[(int)(ctrl->v_level)][(int)(ctrl->p_level)];
+ value1 = vm_voltage_swing[(int)(ctrl->v_level)][(int)(ctrl->p_level)];
+
+ /* Configure host and panel only if both values are allowed */
+ if (value0 != 0xFF && value1 != 0xFF) {
+ msm_edp_phy_vm_pe_cfg(ctrl->phy, value0, value1);
+ return edp_lane_set_write(ctrl, ctrl->v_level, ctrl->p_level);
+ }
+
+ return -EINVAL;
+}
+
+static int edp_start_link_train_1(struct edp_ctrl *ctrl)
+{
+ u8 link_status[DP_LINK_STATUS_SIZE];
+ u8 old_v_level;
+ int tries;
+ int ret;
+ int rlen;
+
+ DBG("");
+
+ edp_host_train_set(ctrl, DP_TRAINING_PATTERN_1);
+ ret = edp_voltage_pre_emphasise_set(ctrl);
+ if (ret)
+ return ret;
+ ret = edp_train_pattern_set_write(ctrl,
+ DP_TRAINING_PATTERN_1 | DP_RECOVERED_CLOCK_OUT_EN);
+ if (ret)
+ return ret;
+
+ tries = 0;
+ old_v_level = ctrl->v_level;
+ while (1) {
+ drm_dp_link_train_clock_recovery_delay(ctrl->dpcd);
+
+ rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status);
+ if (rlen < DP_LINK_STATUS_SIZE) {
+ pr_err("%s: read link status failed\n", __func__);
+ return -ENOLINK;
+ }
+ if (drm_dp_clock_recovery_ok(link_status, ctrl->lane_cnt)) {
+ ret = 0;
+ break;
+ }
+
+ if (ctrl->v_level == DPCD_LINK_VOLTAGE_MAX) {
+ ret = -1;
+ break;
+ }
+
+ if (old_v_level == ctrl->v_level) {
+ tries++;
+ if (tries >= 5) {
+ ret = -1;
+ break;
+ }
+ } else {
+ tries = 0;
+ old_v_level = ctrl->v_level;
+ }
+
+ edp_sink_train_set_adjust(ctrl, link_status);
+ ret = edp_voltage_pre_emphasise_set(ctrl);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+static int edp_start_link_train_2(struct edp_ctrl *ctrl)
+{
+ u8 link_status[DP_LINK_STATUS_SIZE];
+ int tries = 0;
+ int ret;
+ int rlen;
+
+ DBG("");
+
+ edp_host_train_set(ctrl, DP_TRAINING_PATTERN_2);
+ ret = edp_voltage_pre_emphasise_set(ctrl);
+ if (ret)
+ return ret;
+
+ ret = edp_train_pattern_set_write(ctrl,
+ DP_TRAINING_PATTERN_2 | DP_RECOVERED_CLOCK_OUT_EN);
+ if (ret)
+ return ret;
+
+ while (1) {
+ drm_dp_link_train_channel_eq_delay(ctrl->dpcd);
+
+ rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status);
+ if (rlen < DP_LINK_STATUS_SIZE) {
+ pr_err("%s: read link status failed\n", __func__);
+ return -ENOLINK;
+ }
+ if (drm_dp_channel_eq_ok(link_status, ctrl->lane_cnt)) {
+ ret = 0;
+ break;
+ }
+
+ tries++;
+ if (tries > 10) {
+ ret = -1;
+ break;
+ }
+
+ edp_sink_train_set_adjust(ctrl, link_status);
+ ret = edp_voltage_pre_emphasise_set(ctrl);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+static int edp_link_rate_down_shift(struct edp_ctrl *ctrl)
+{
+ u32 prate, lrate, bpp;
+ u8 rate, lane, max_lane;
+ int changed = 0;
+
+ rate = ctrl->link_rate;
+ lane = ctrl->lane_cnt;
+ max_lane = ctrl->dp_link.num_lanes;
+
+ bpp = ctrl->color_depth * 3;
+ prate = ctrl->pixel_rate;
+ prate *= bpp;
+ prate /= 8; /* in kByte */
+
+ if (rate > DP_LINK_BW_1_62 && rate <= EDP_LINK_BW_MAX) {
+ rate -= 4; /* reduce rate */
+ changed++;
+ }
+
+ if (changed) {
+ if (lane >= 1 && lane < max_lane)
+ lane <<= 1; /* increase lane */
+
+ lrate = 270000; /* in kHz */
+ lrate *= rate;
+ lrate /= 10; /* kByte, 10 bits --> 8 bits */
+ lrate *= lane;
+
+ DBG("new lrate=%u prate=%u(kHz) rate=%d lane=%d p=%u b=%d",
+ lrate, prate, rate, lane,
+ ctrl->pixel_rate,
+ bpp);
+
+ if (lrate > prate) {
+ ctrl->link_rate = rate;
+ ctrl->lane_cnt = lane;
+ DBG("new rate=%d %d", rate, lane);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int edp_clear_training_pattern(struct edp_ctrl *ctrl)
+{
+ int ret;
+
+ ret = edp_train_pattern_set_write(ctrl, 0);
+
+ drm_dp_link_train_channel_eq_delay(ctrl->dpcd);
+
+ return ret;
+}
+
+static int edp_do_link_train(struct edp_ctrl *ctrl)
+{
+ int ret;
+ struct drm_dp_link dp_link;
+
+ DBG("");
+ /*
+ * Set the current link rate and lane cnt to panel. They may have been
+ * adjusted and the values are different from them in DPCD CAP
+ */
+ dp_link.num_lanes = ctrl->lane_cnt;
+ dp_link.rate = drm_dp_bw_code_to_link_rate(ctrl->link_rate);
+ dp_link.capabilities = ctrl->dp_link.capabilities;
+ if (drm_dp_link_configure(ctrl->drm_aux, &dp_link) < 0)
+ return EDP_TRAIN_FAIL;
+
+ ctrl->v_level = 0; /* start from default level */
+ ctrl->p_level = 0;
+
+ edp_state_ctrl(ctrl, 0);
+ if (edp_clear_training_pattern(ctrl))
+ return EDP_TRAIN_FAIL;
+
+ ret = edp_start_link_train_1(ctrl);
+ if (ret < 0) {
+ if (edp_link_rate_down_shift(ctrl) == 0) {
+ DBG("link reconfig");
+ ret = EDP_TRAIN_RECONFIG;
+ goto clear;
+ } else {
+ pr_err("%s: Training 1 failed", __func__);
+ ret = EDP_TRAIN_FAIL;
+ goto clear;
+ }
+ }
+ DBG("Training 1 completed successfully");
+
+ edp_state_ctrl(ctrl, 0);
+ if (edp_clear_training_pattern(ctrl))
+ return EDP_TRAIN_FAIL;
+
+ ret = edp_start_link_train_2(ctrl);
+ if (ret < 0) {
+ if (edp_link_rate_down_shift(ctrl) == 0) {
+ DBG("link reconfig");
+ ret = EDP_TRAIN_RECONFIG;
+ goto clear;
+ } else {
+ pr_err("%s: Training 2 failed", __func__);
+ ret = EDP_TRAIN_FAIL;
+ goto clear;
+ }
+ }
+ DBG("Training 2 completed successfully");
+
+ edp_state_ctrl(ctrl, EDP_STATE_CTRL_SEND_VIDEO);
+clear:
+ edp_clear_training_pattern(ctrl);
+
+ return ret;
+}
+
+static void edp_clock_synchrous(struct edp_ctrl *ctrl, int sync)
+{
+ u32 data;
+ enum edp_color_depth depth;
+
+ data = edp_read(ctrl->base + REG_EDP_MISC1_MISC0);
+
+ if (sync)
+ data |= EDP_MISC1_MISC0_SYNC;
+ else
+ data &= ~EDP_MISC1_MISC0_SYNC;
+
+ /* only legacy rgb mode supported */
+ depth = EDP_6BIT; /* Default */
+ if (ctrl->color_depth == 8)
+ depth = EDP_8BIT;
+ else if (ctrl->color_depth == 10)
+ depth = EDP_10BIT;
+ else if (ctrl->color_depth == 12)
+ depth = EDP_12BIT;
+ else if (ctrl->color_depth == 16)
+ depth = EDP_16BIT;
+
+ data |= EDP_MISC1_MISC0_COLOR(depth);
+
+ edp_write(ctrl->base + REG_EDP_MISC1_MISC0, data);
+}
+
+static int edp_sw_mvid_nvid(struct edp_ctrl *ctrl, u32 m, u32 n)
+{
+ u32 n_multi, m_multi = 5;
+
+ if (ctrl->link_rate == DP_LINK_BW_1_62) {
+ n_multi = 1;
+ } else if (ctrl->link_rate == DP_LINK_BW_2_7) {
+ n_multi = 2;
+ } else {
+ pr_err("%s: Invalid link rate, %d\n", __func__,
+ ctrl->link_rate);
+ return -EINVAL;
+ }
+
+ edp_write(ctrl->base + REG_EDP_SOFTWARE_MVID, m * m_multi);
+ edp_write(ctrl->base + REG_EDP_SOFTWARE_NVID, n * n_multi);
+
+ return 0;
+}
+
+static void edp_mainlink_ctrl(struct edp_ctrl *ctrl, int enable)
+{
+ u32 data = 0;
+
+ edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, EDP_MAINLINK_CTRL_RESET);
+ /* Make sure fully reset */
+ wmb();
+ usleep_range(500, 1000);
+
+ if (enable)
+ data |= EDP_MAINLINK_CTRL_ENABLE;
+
+ edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, data);
+}
+
+static void edp_ctrl_phy_aux_enable(struct edp_ctrl *ctrl, int enable)
+{
+ if (enable) {
+ edp_regulator_enable(ctrl);
+ edp_clk_enable(ctrl, EDP_CLK_MASK_AUX_CHAN);
+ msm_edp_phy_ctrl(ctrl->phy, 1);
+ msm_edp_aux_ctrl(ctrl->aux, 1);
+ gpiod_set_value(ctrl->panel_en_gpio, 1);
+ } else {
+ gpiod_set_value(ctrl->panel_en_gpio, 0);
+ msm_edp_aux_ctrl(ctrl->aux, 0);
+ msm_edp_phy_ctrl(ctrl->phy, 0);
+ edp_clk_disable(ctrl, EDP_CLK_MASK_AUX_CHAN);
+ edp_regulator_disable(ctrl);
+ }
+}
+
+static void edp_ctrl_link_enable(struct edp_ctrl *ctrl, int enable)
+{
+ u32 m, n;
+
+ if (enable) {
+ /* Enable link channel clocks */
+ edp_clk_enable(ctrl, EDP_CLK_MASK_LINK_CHAN);
+
+ msm_edp_phy_lane_power_ctrl(ctrl->phy, true, ctrl->lane_cnt);
+
+ msm_edp_phy_vm_pe_init(ctrl->phy);
+
+ /* Make sure phy is programed */
+ wmb();
+ msm_edp_phy_ready(ctrl->phy);
+
+ edp_config_ctrl(ctrl);
+ msm_edp_ctrl_pixel_clock_valid(ctrl, ctrl->pixel_rate, &m, &n);
+ edp_sw_mvid_nvid(ctrl, m, n);
+ edp_mainlink_ctrl(ctrl, 1);
+ } else {
+ edp_mainlink_ctrl(ctrl, 0);
+
+ msm_edp_phy_lane_power_ctrl(ctrl->phy, false, 0);
+ edp_clk_disable(ctrl, EDP_CLK_MASK_LINK_CHAN);
+ }
+}
+
+static int edp_ctrl_training(struct edp_ctrl *ctrl)
+{
+ int ret;
+
+ /* Do link training only when power is on */
+ if (!ctrl->power_on)
+ return -EINVAL;
+
+train_start:
+ ret = edp_do_link_train(ctrl);
+ if (ret == EDP_TRAIN_RECONFIG) {
+ /* Re-configure main link */
+ edp_ctrl_irq_enable(ctrl, 0);
+ edp_ctrl_link_enable(ctrl, 0);
+ msm_edp_phy_ctrl(ctrl->phy, 0);
+
+ /* Make sure link is fully disabled */
+ wmb();
+ usleep_range(500, 1000);
+
+ msm_edp_phy_ctrl(ctrl->phy, 1);
+ edp_ctrl_link_enable(ctrl, 1);
+ edp_ctrl_irq_enable(ctrl, 1);
+ goto train_start;
+ }
+
+ return ret;
+}
+
+static void edp_ctrl_on_worker(struct work_struct *work)
+{
+ struct edp_ctrl *ctrl = container_of(
+ work, struct edp_ctrl, on_work);
+ int ret;
+
+ mutex_lock(&ctrl->dev_mutex);
+
+ if (ctrl->power_on) {
+ DBG("already on");
+ goto unlock_ret;
+ }
+
+ edp_ctrl_phy_aux_enable(ctrl, 1);
+ edp_ctrl_link_enable(ctrl, 1);
+
+ edp_ctrl_irq_enable(ctrl, 1);
+ ret = drm_dp_link_power_up(ctrl->drm_aux, &ctrl->dp_link);
+ if (ret)
+ goto fail;
+
+ ctrl->power_on = true;
+
+ /* Start link training */
+ ret = edp_ctrl_training(ctrl);
+ if (ret != EDP_TRAIN_SUCCESS)
+ goto fail;
+
+ DBG("DONE");
+ goto unlock_ret;
+
+fail:
+ edp_ctrl_irq_enable(ctrl, 0);
+ edp_ctrl_link_enable(ctrl, 0);
+ edp_ctrl_phy_aux_enable(ctrl, 0);
+ ctrl->power_on = false;
+unlock_ret:
+ mutex_unlock(&ctrl->dev_mutex);
+}
+
+static void edp_ctrl_off_worker(struct work_struct *work)
+{
+ struct edp_ctrl *ctrl = container_of(
+ work, struct edp_ctrl, off_work);
+ int ret;
+
+ mutex_lock(&ctrl->dev_mutex);
+
+ if (!ctrl->power_on) {
+ DBG("already off");
+ goto unlock_ret;
+ }
+
+ reinit_completion(&ctrl->idle_comp);
+ edp_state_ctrl(ctrl, EDP_STATE_CTRL_PUSH_IDLE);
+
+ ret = wait_for_completion_timeout(&ctrl->idle_comp,
+ msecs_to_jiffies(500));
+ if (ret <= 0)
+ DBG("%s: idle pattern timedout, %d\n",
+ __func__, ret);
+
+ edp_state_ctrl(ctrl, 0);
+
+ drm_dp_link_power_down(ctrl->drm_aux, &ctrl->dp_link);
+
+ edp_ctrl_irq_enable(ctrl, 0);
+
+ edp_ctrl_link_enable(ctrl, 0);
+
+ edp_ctrl_phy_aux_enable(ctrl, 0);
+
+ ctrl->power_on = false;
+
+unlock_ret:
+ mutex_unlock(&ctrl->dev_mutex);
+}
+
+irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl)
+{
+ u32 isr1, isr2, mask1, mask2;
+ u32 ack;
+
+ DBG("");
+ spin_lock(&ctrl->irq_lock);
+ isr1 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_1);
+ isr2 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_2);
+
+ mask1 = isr1 & EDP_INTR_MASK1;
+ mask2 = isr2 & EDP_INTR_MASK2;
+
+ isr1 &= ~mask1; /* remove masks bit */
+ isr2 &= ~mask2;
+
+ DBG("isr=%x mask=%x isr2=%x mask2=%x",
+ isr1, mask1, isr2, mask2);
+
+ ack = isr1 & EDP_INTR_STATUS1;
+ ack <<= 1; /* ack bits */
+ ack |= mask1;
+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, ack);
+
+ ack = isr2 & EDP_INTR_STATUS2;
+ ack <<= 1; /* ack bits */
+ ack |= mask2;
+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, ack);
+ spin_unlock(&ctrl->irq_lock);
+
+ if (isr1 & EDP_INTERRUPT_REG_1_HPD)
+ DBG("edp_hpd");
+
+ if (isr2 & EDP_INTERRUPT_REG_2_READY_FOR_VIDEO)
+ DBG("edp_video_ready");
+
+ if (isr2 & EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT) {
+ DBG("idle_patterns_sent");
+ complete(&ctrl->idle_comp);
+ }
+
+ msm_edp_aux_irq(ctrl->aux, isr1);
+
+ return IRQ_HANDLED;
+}
+
+void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on)
+{
+ if (on)
+ queue_work(ctrl->workqueue, &ctrl->on_work);
+ else
+ queue_work(ctrl->workqueue, &ctrl->off_work);
+}
+
+int msm_edp_ctrl_init(struct msm_edp *edp)
+{
+ struct edp_ctrl *ctrl = NULL;
+ struct device *dev = &edp->pdev->dev;
+ int ret;
+
+ if (!edp) {
+ pr_err("%s: edp is NULL!\n", __func__);
+ return -EINVAL;
+ }
+
+ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
+ if (!ctrl)
+ return -ENOMEM;
+
+ edp->ctrl = ctrl;
+ ctrl->pdev = edp->pdev;
+
+ ctrl->base = msm_ioremap(ctrl->pdev, "edp", "eDP");
+ if (IS_ERR(ctrl->base))
+ return PTR_ERR(ctrl->base);
+
+ /* Get regulator, clock, gpio, pwm */
+ ret = edp_regulator_init(ctrl);
+ if (ret) {
+ pr_err("%s:regulator init fail\n", __func__);
+ return ret;
+ }
+ ret = edp_clk_init(ctrl);
+ if (ret) {
+ pr_err("%s:clk init fail\n", __func__);
+ return ret;
+ }
+ ret = edp_gpio_config(ctrl);
+ if (ret) {
+ pr_err("%s:failed to configure GPIOs: %d", __func__, ret);
+ return ret;
+ }
+
+ /* Init aux and phy */
+ ctrl->aux = msm_edp_aux_init(dev, ctrl->base, &ctrl->drm_aux);
+ if (!ctrl->aux || !ctrl->drm_aux) {
+ pr_err("%s:failed to init aux\n", __func__);
+ return ret;
+ }
+
+ ctrl->phy = msm_edp_phy_init(dev, ctrl->base);
+ if (!ctrl->phy) {
+ pr_err("%s:failed to init phy\n", __func__);
+ goto err_destory_aux;
+ }
+
+ spin_lock_init(&ctrl->irq_lock);
+ mutex_init(&ctrl->dev_mutex);
+ init_completion(&ctrl->idle_comp);
+
+ /* setup workqueue */
+ ctrl->workqueue = alloc_ordered_workqueue("edp_drm_work", 0);
+ INIT_WORK(&ctrl->on_work, edp_ctrl_on_worker);
+ INIT_WORK(&ctrl->off_work, edp_ctrl_off_worker);
+
+ return 0;
+
+err_destory_aux:
+ msm_edp_aux_destroy(dev, ctrl->aux);
+ ctrl->aux = NULL;
+ return ret;
+}
+
+void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl)
+{
+ if (!ctrl)
+ return;
+
+ if (ctrl->workqueue) {
+ flush_workqueue(ctrl->workqueue);
+ destroy_workqueue(ctrl->workqueue);
+ ctrl->workqueue = NULL;
+ }
+
+ if (ctrl->aux) {
+ msm_edp_aux_destroy(&ctrl->pdev->dev, ctrl->aux);
+ ctrl->aux = NULL;
+ }
+
+ kfree(ctrl->edid);
+ ctrl->edid = NULL;
+
+ mutex_destroy(&ctrl->dev_mutex);
+}
+
+bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl)
+{
+ mutex_lock(&ctrl->dev_mutex);
+ DBG("connect status = %d", ctrl->edp_connected);
+ if (ctrl->edp_connected) {
+ mutex_unlock(&ctrl->dev_mutex);
+ return true;
+ }
+
+ if (!ctrl->power_on) {
+ edp_ctrl_phy_aux_enable(ctrl, 1);
+ edp_ctrl_irq_enable(ctrl, 1);
+ }
+
+ if (drm_dp_dpcd_read(ctrl->drm_aux, DP_DPCD_REV, ctrl->dpcd,
+ DP_RECEIVER_CAP_SIZE) < DP_RECEIVER_CAP_SIZE) {
+ pr_err("%s: AUX channel is NOT ready\n", __func__);
+ memset(ctrl->dpcd, 0, DP_RECEIVER_CAP_SIZE);
+ } else {
+ ctrl->edp_connected = true;
+ }
+
+ if (!ctrl->power_on) {
+ edp_ctrl_irq_enable(ctrl, 0);
+ edp_ctrl_phy_aux_enable(ctrl, 0);
+ }
+
+ DBG("exit: connect status=%d", ctrl->edp_connected);
+
+ mutex_unlock(&ctrl->dev_mutex);
+
+ return ctrl->edp_connected;
+}
+
+int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl,
+ struct drm_connector *connector, struct edid **edid)
+{
+ int ret = 0;
+
+ mutex_lock(&ctrl->dev_mutex);
+
+ if (ctrl->edid) {
+ if (edid) {
+ DBG("Just return edid buffer");
+ *edid = ctrl->edid;
+ }
+ goto unlock_ret;
+ }
+
+ if (!ctrl->power_on) {
+ edp_ctrl_phy_aux_enable(ctrl, 1);
+ edp_ctrl_irq_enable(ctrl, 1);
+ }
+
+ ret = drm_dp_link_probe(ctrl->drm_aux, &ctrl->dp_link);
+ if (ret) {
+ pr_err("%s: read dpcd cap failed, %d\n", __func__, ret);
+ goto disable_ret;
+ }
+
+ /* Initialize link rate as panel max link rate */
+ ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate);
+
+ ctrl->edid = drm_get_edid(connector, &ctrl->drm_aux->ddc);
+ if (!ctrl->edid) {
+ pr_err("%s: edid read fail\n", __func__);
+ goto disable_ret;
+ }
+
+ if (edid)
+ *edid = ctrl->edid;
+
+disable_ret:
+ if (!ctrl->power_on) {
+ edp_ctrl_irq_enable(ctrl, 0);
+ edp_ctrl_phy_aux_enable(ctrl, 0);
+ }
+unlock_ret:
+ mutex_unlock(&ctrl->dev_mutex);
+ return ret;
+}
+
+int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl,
+ const struct drm_display_mode *mode,
+ const struct drm_display_info *info)
+{
+ u32 hstart_from_sync, vstart_from_sync;
+ u32 data;
+ int ret = 0;
+
+ mutex_lock(&ctrl->dev_mutex);
+ /*
+ * Need to keep color depth, pixel rate and
+ * interlaced information in ctrl context
+ */
+ ctrl->color_depth = info->bpc;
+ ctrl->pixel_rate = mode->clock;
+ ctrl->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+
+ /* Fill initial link config based on passed in timing */
+ edp_fill_link_cfg(ctrl);
+
+ if (edp_clk_enable(ctrl, EDP_CLK_MASK_AHB)) {
+ pr_err("%s, fail to prepare enable ahb clk\n", __func__);
+ ret = -EINVAL;
+ goto unlock_ret;
+ }
+ edp_clock_synchrous(ctrl, 1);
+
+ /* Configure eDP timing to HW */
+ edp_write(ctrl->base + REG_EDP_TOTAL_HOR_VER,
+ EDP_TOTAL_HOR_VER_HORIZ(mode->htotal) |
+ EDP_TOTAL_HOR_VER_VERT(mode->vtotal));
+
+ vstart_from_sync = mode->vtotal - mode->vsync_start;
+ hstart_from_sync = mode->htotal - mode->hsync_start;
+ edp_write(ctrl->base + REG_EDP_START_HOR_VER_FROM_SYNC,
+ EDP_START_HOR_VER_FROM_SYNC_HORIZ(hstart_from_sync) |
+ EDP_START_HOR_VER_FROM_SYNC_VERT(vstart_from_sync));
+
+ data = EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT(
+ mode->vsync_end - mode->vsync_start);
+ data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ(
+ mode->hsync_end - mode->hsync_start);
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_NVSYNC;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_NHSYNC;
+ edp_write(ctrl->base + REG_EDP_HSYNC_VSYNC_WIDTH_POLARITY, data);
+
+ edp_write(ctrl->base + REG_EDP_ACTIVE_HOR_VER,
+ EDP_ACTIVE_HOR_VER_HORIZ(mode->hdisplay) |
+ EDP_ACTIVE_HOR_VER_VERT(mode->vdisplay));
+
+ edp_clk_disable(ctrl, EDP_CLK_MASK_AHB);
+
+unlock_ret:
+ mutex_unlock(&ctrl->dev_mutex);
+ return ret;
+}
+
+bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl,
+ u32 pixel_rate, u32 *pm, u32 *pn)
+{
+ const struct edp_pixel_clk_div *divs;
+ u32 err = 1; /* 1% error tolerance */
+ u32 clk_err;
+ int i;
+
+ if (ctrl->link_rate == DP_LINK_BW_1_62) {
+ divs = clk_divs[0];
+ } else if (ctrl->link_rate == DP_LINK_BW_2_7) {
+ divs = clk_divs[1];
+ } else {
+ pr_err("%s: Invalid link rate,%d\n", __func__, ctrl->link_rate);
+ return false;
+ }
+
+ for (i = 0; i < EDP_PIXEL_CLK_NUM; i++) {
+ clk_err = abs(divs[i].rate - pixel_rate);
+ if ((divs[i].rate * err / 100) >= clk_err) {
+ if (pm)
+ *pm = divs[i].m;
+ if (pn)
+ *pn = divs[i].n;
+ return true;
+ }
+ }
+
+ DBG("pixel clock %d(kHz) not supported", pixel_rate);
+
+ return false;
+}
+
diff --git a/drivers/gpu/drm/msm/edp/edp_phy.c b/drivers/gpu/drm/msm/edp/edp_phy.c
new file mode 100644
index 000000000000..36bb8933e9ee
--- /dev/null
+++ b/drivers/gpu/drm/msm/edp/edp_phy.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "edp.h"
+#include "edp.xml.h"
+
+#define EDP_MAX_LANE 4
+
+struct edp_phy {
+ void __iomem *base;
+};
+
+bool msm_edp_phy_ready(struct edp_phy *phy)
+{
+ u32 status;
+ int cnt = 100;
+
+ while (--cnt) {
+ status = edp_read(phy->base +
+ REG_EDP_PHY_GLB_PHY_STATUS);
+ if (status & 0x01)
+ break;
+ usleep_range(500, 1000);
+ }
+
+ if (cnt == 0) {
+ pr_err("%s: PHY NOT ready\n", __func__);
+ return false;
+ } else {
+ return true;
+ }
+}
+
+void msm_edp_phy_ctrl(struct edp_phy *phy, int enable)
+{
+ DBG("enable=%d", enable);
+ if (enable) {
+ /* Reset */
+ edp_write(phy->base + REG_EDP_PHY_CTRL,
+ EDP_PHY_CTRL_SW_RESET | EDP_PHY_CTRL_SW_RESET_PLL);
+ /* Make sure fully reset */
+ wmb();
+ usleep_range(500, 1000);
+ edp_write(phy->base + REG_EDP_PHY_CTRL, 0x000);
+ edp_write(phy->base + REG_EDP_PHY_GLB_PD_CTL, 0x3f);
+ edp_write(phy->base + REG_EDP_PHY_GLB_CFG, 0x1);
+ } else {
+ edp_write(phy->base + REG_EDP_PHY_GLB_PD_CTL, 0xc0);
+ }
+}
+
+/* voltage mode and pre emphasis cfg */
+void msm_edp_phy_vm_pe_init(struct edp_phy *phy)
+{
+ edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG0, 0x3);
+ edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG1, 0x64);
+ edp_write(phy->base + REG_EDP_PHY_GLB_MISC9, 0x6c);
+}
+
+void msm_edp_phy_vm_pe_cfg(struct edp_phy *phy, u32 v0, u32 v1)
+{
+ edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG0, v0);
+ edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG1, v1);
+}
+
+void msm_edp_phy_lane_power_ctrl(struct edp_phy *phy, bool up, u32 max_lane)
+{
+ u32 i;
+ u32 data;
+
+ if (up)
+ data = 0; /* power up */
+ else
+ data = 0x7; /* power down */
+
+ for (i = 0; i < max_lane; i++)
+ edp_write(phy->base + REG_EDP_PHY_LN_PD_CTL(i) , data);
+
+ /* power down unused lane */
+ data = 0x7; /* power down */
+ for (i = max_lane; i < EDP_MAX_LANE; i++)
+ edp_write(phy->base + REG_EDP_PHY_LN_PD_CTL(i) , data);
+}
+
+void *msm_edp_phy_init(struct device *dev, void __iomem *regbase)
+{
+ struct edp_phy *phy = NULL;
+
+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return NULL;
+
+ phy->base = regbase;
+ return phy;
+}
+
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 062c68725376..814536202efe 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -106,7 +107,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev)
goto fail;
}
- BUG_ON(config->hpd_reg_cnt > ARRAY_SIZE(hdmi->hpd_regs));
+ hdmi->hpd_regs = devm_kzalloc(&pdev->dev, sizeof(hdmi->hpd_regs[0]) *
+ config->hpd_reg_cnt, GFP_KERNEL);
+ if (!hdmi->hpd_regs) {
+ ret = -ENOMEM;
+ goto fail;
+ }
for (i = 0; i < config->hpd_reg_cnt; i++) {
struct regulator *reg;
@@ -122,7 +128,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev)
hdmi->hpd_regs[i] = reg;
}
- BUG_ON(config->pwr_reg_cnt > ARRAY_SIZE(hdmi->pwr_regs));
+ hdmi->pwr_regs = devm_kzalloc(&pdev->dev, sizeof(hdmi->pwr_regs[0]) *
+ config->pwr_reg_cnt, GFP_KERNEL);
+ if (!hdmi->pwr_regs) {
+ ret = -ENOMEM;
+ goto fail;
+ }
for (i = 0; i < config->pwr_reg_cnt; i++) {
struct regulator *reg;
@@ -138,7 +149,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev)
hdmi->pwr_regs[i] = reg;
}
- BUG_ON(config->hpd_clk_cnt > ARRAY_SIZE(hdmi->hpd_clks));
+ hdmi->hpd_clks = devm_kzalloc(&pdev->dev, sizeof(hdmi->hpd_clks[0]) *
+ config->hpd_clk_cnt, GFP_KERNEL);
+ if (!hdmi->hpd_clks) {
+ ret = -ENOMEM;
+ goto fail;
+ }
for (i = 0; i < config->hpd_clk_cnt; i++) {
struct clk *clk;
@@ -153,7 +169,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev)
hdmi->hpd_clks[i] = clk;
}
- BUG_ON(config->pwr_clk_cnt > ARRAY_SIZE(hdmi->pwr_clks));
+ hdmi->pwr_clks = devm_kzalloc(&pdev->dev, sizeof(hdmi->pwr_clks[0]) *
+ config->pwr_clk_cnt, GFP_KERNEL);
+ if (!hdmi->pwr_clks) {
+ ret = -ENOMEM;
+ goto fail;
+ }
for (i = 0; i < config->pwr_clk_cnt; i++) {
struct clk *clk;
@@ -247,9 +268,9 @@ int hdmi_modeset_init(struct hdmi *hdmi,
return 0;
fail:
- /* bridge/connector are normally destroyed by drm: */
+ /* bridge is normally destroyed by drm: */
if (hdmi->bridge) {
- hdmi->bridge->funcs->destroy(hdmi->bridge);
+ hdmi_bridge_destroy(hdmi->bridge);
hdmi->bridge = NULL;
}
if (hdmi->connector) {
@@ -266,6 +287,57 @@ fail:
#include <linux/of_gpio.h>
+#define HDMI_CFG(item, entry) \
+ .item ## _names = item ##_names_ ## entry, \
+ .item ## _cnt = ARRAY_SIZE(item ## _names_ ## entry)
+
+static struct hdmi_platform_config hdmi_tx_8660_config = {
+ .phy_init = hdmi_phy_8x60_init,
+};
+
+static const char *hpd_reg_names_8960[] = {"core-vdda", "hdmi-mux"};
+static const char *hpd_clk_names_8960[] = {"core_clk", "master_iface_clk", "slave_iface_clk"};
+
+static struct hdmi_platform_config hdmi_tx_8960_config = {
+ .phy_init = hdmi_phy_8960_init,
+ HDMI_CFG(hpd_reg, 8960),
+ HDMI_CFG(hpd_clk, 8960),
+};
+
+static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
+static const char *hpd_reg_names_8x74[] = {"hpd-gdsc", "hpd-5v"};
+static const char *pwr_clk_names_8x74[] = {"extp_clk", "alt_iface_clk"};
+static const char *hpd_clk_names_8x74[] = {"iface_clk", "core_clk", "mdp_core_clk"};
+static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0};
+
+static struct hdmi_platform_config hdmi_tx_8074_config = {
+ .phy_init = hdmi_phy_8x74_init,
+ HDMI_CFG(pwr_reg, 8x74),
+ HDMI_CFG(hpd_reg, 8x74),
+ HDMI_CFG(pwr_clk, 8x74),
+ HDMI_CFG(hpd_clk, 8x74),
+ .hpd_freq = hpd_clk_freq_8x74,
+};
+
+static const char *hpd_reg_names_8084[] = {"hpd-gdsc", "hpd-5v", "hpd-5v-en"};
+
+static struct hdmi_platform_config hdmi_tx_8084_config = {
+ .phy_init = hdmi_phy_8x74_init,
+ HDMI_CFG(pwr_reg, 8x74),
+ HDMI_CFG(hpd_reg, 8084),
+ HDMI_CFG(pwr_clk, 8x74),
+ HDMI_CFG(hpd_clk, 8x74),
+ .hpd_freq = hpd_clk_freq_8x74,
+};
+
+static const struct of_device_id dt_match[] = {
+ { .compatible = "qcom,hdmi-tx-8084", .data = &hdmi_tx_8084_config },
+ { .compatible = "qcom,hdmi-tx-8074", .data = &hdmi_tx_8074_config },
+ { .compatible = "qcom,hdmi-tx-8960", .data = &hdmi_tx_8960_config },
+ { .compatible = "qcom,hdmi-tx-8660", .data = &hdmi_tx_8660_config },
+ {}
+};
+
#ifdef CONFIG_OF
static int get_gpio(struct device *dev, struct device_node *of_node, const char *name)
{
@@ -288,50 +360,31 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
{
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;
- static struct hdmi_platform_config config = {};
+ static struct hdmi_platform_config *hdmi_cfg;
struct hdmi *hdmi;
#ifdef CONFIG_OF
struct device_node *of_node = dev->of_node;
+ const struct of_device_id *match;
- if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8074")) {
- static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"};
- static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"};
- static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"};
- static unsigned long hpd_clk_freq[] = {0, 19200000, 0};
- static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"};
- config.phy_init = hdmi_phy_8x74_init;
- config.hpd_reg_names = hpd_reg_names;
- config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names);
- config.pwr_reg_names = pwr_reg_names;
- config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names);
- config.hpd_clk_names = hpd_clk_names;
- config.hpd_freq = hpd_clk_freq;
- config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names);
- config.pwr_clk_names = pwr_clk_names;
- config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names);
- } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8960")) {
- static const char *hpd_clk_names[] = {"core_clk", "master_iface_clk", "slave_iface_clk"};
- static const char *hpd_reg_names[] = {"core-vdda", "hdmi-mux"};
- config.phy_init = hdmi_phy_8960_init;
- config.hpd_reg_names = hpd_reg_names;
- config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names);
- config.hpd_clk_names = hpd_clk_names;
- config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names);
- } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8660")) {
- config.phy_init = hdmi_phy_8x60_init;
+ match = of_match_node(dt_match, of_node);
+ if (match && match->data) {
+ hdmi_cfg = (struct hdmi_platform_config *)match->data;
+ DBG("hdmi phy: %s", match->compatible);
} else {
dev_err(dev, "unknown phy: %s\n", of_node->name);
+ return -ENXIO;
}
- config.mmio_name = "core_physical";
- config.ddc_clk_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-clk");
- config.ddc_data_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-data");
- config.hpd_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-hpd");
- config.mux_en_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-en");
- config.mux_sel_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-sel");
- config.mux_lpm_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-lpm");
+ hdmi_cfg->mmio_name = "core_physical";
+ hdmi_cfg->ddc_clk_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-clk");
+ hdmi_cfg->ddc_data_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-data");
+ hdmi_cfg->hpd_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-hpd");
+ hdmi_cfg->mux_en_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-en");
+ hdmi_cfg->mux_sel_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-sel");
+ hdmi_cfg->mux_lpm_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-lpm");
#else
+ static struct hdmi_platform_config config = {};
static const char *hpd_clk_names[] = {
"core_clk", "master_iface_clk", "slave_iface_clk",
};
@@ -377,12 +430,15 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
config.mux_en_gpio = -1;
config.mux_sel_gpio = -1;
}
+ hdmi_cfg = &config;
#endif
- dev->platform_data = &config;
+ dev->platform_data = hdmi_cfg;
+
hdmi = hdmi_init(to_platform_device(dev));
if (IS_ERR(hdmi))
return PTR_ERR(hdmi);
priv->hdmi = hdmi;
+
return 0;
}
@@ -413,13 +469,6 @@ static int hdmi_dev_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id dt_match[] = {
- { .compatible = "qcom,hdmi-tx-8074" },
- { .compatible = "qcom,hdmi-tx-8960" },
- { .compatible = "qcom,hdmi-tx-8660" },
- {}
-};
-
static struct platform_driver hdmi_driver = {
.probe = hdmi_dev_probe,
.remove = hdmi_dev_remove,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 43e654f751b7..68fdfb3622a5 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -52,10 +52,10 @@ struct hdmi {
void __iomem *mmio;
- struct regulator *hpd_regs[2];
- struct regulator *pwr_regs[2];
- struct clk *hpd_clks[3];
- struct clk *pwr_clks[2];
+ struct regulator **hpd_regs;
+ struct regulator **pwr_regs;
+ struct clk **hpd_clks;
+ struct clk **pwr_clks;
struct hdmi_phy *phy;
struct i2c_adapter *i2c;
@@ -146,6 +146,7 @@ void hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
*/
struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi);
+void hdmi_bridge_destroy(struct drm_bridge *bridge);
/*
* hdmi connector:
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
index 5b0844befbab..350988740e9f 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
@@ -8,18 +8,19 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
-Copyright (C) 2013-2014 by the following authors:
+Copyright (C) 2013-2015 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -45,12 +46,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
enum hdmi_hdcp_key_state {
- NO_KEYS = 0,
- NOT_CHECKED = 1,
- CHECKING = 2,
- KEYS_VALID = 3,
- AKSV_INVALID = 4,
- CHECKSUM_MISMATCH = 5,
+ HDCP_KEYS_STATE_NO_KEYS = 0,
+ HDCP_KEYS_STATE_NOT_CHECKED = 1,
+ HDCP_KEYS_STATE_CHECKING = 2,
+ HDCP_KEYS_STATE_VALID = 3,
+ HDCP_KEYS_STATE_AKSV_NOT_VALID = 4,
+ HDCP_KEYS_STATE_CHKSUM_MISMATCH = 5,
+ HDCP_KEYS_STATE_PROD_AKSV = 6,
+ HDCP_KEYS_STATE_RESERVED = 7,
};
enum hdmi_ddc_read_write {
@@ -199,11 +202,29 @@ static inline uint32_t HDMI_AUDIO_INFO1_LSV(uint32_t val)
#define HDMI_HDCP_CTRL_ENABLE 0x00000001
#define HDMI_HDCP_CTRL_ENCRYPTION_ENABLE 0x00000100
+#define REG_HDMI_HDCP_DEBUG_CTRL 0x00000114
+#define HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER 0x00000004
+
#define REG_HDMI_HDCP_INT_CTRL 0x00000118
+#define HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_INT 0x00000001
+#define HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_ACK 0x00000002
+#define HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_MASK 0x00000004
+#define HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT 0x00000010
+#define HDMI_HDCP_INT_CTRL_AUTH_FAIL_ACK 0x00000020
+#define HDMI_HDCP_INT_CTRL_AUTH_FAIL_MASK 0x00000040
+#define HDMI_HDCP_INT_CTRL_AUTH_FAIL_INFO_ACK 0x00000080
+#define HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_INT 0x00000100
+#define HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_ACK 0x00000200
+#define HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_MASK 0x00000400
+#define HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_INT 0x00001000
+#define HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_ACK 0x00002000
+#define HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_MASK 0x00004000
#define REG_HDMI_HDCP_LINK0_STATUS 0x0000011c
#define HDMI_HDCP_LINK0_STATUS_AN_0_READY 0x00000100
#define HDMI_HDCP_LINK0_STATUS_AN_1_READY 0x00000200
+#define HDMI_HDCP_LINK0_STATUS_RI_MATCHES 0x00001000
+#define HDMI_HDCP_LINK0_STATUS_V_MATCHES 0x00100000
#define HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK 0x70000000
#define HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT 28
static inline uint32_t HDMI_HDCP_LINK0_STATUS_KEY_STATE(enum hdmi_hdcp_key_state val)
@@ -211,9 +232,56 @@ static inline uint32_t HDMI_HDCP_LINK0_STATUS_KEY_STATE(enum hdmi_hdcp_key_state
return ((val) << HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT) & HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK;
}
+#define REG_HDMI_HDCP_DDC_CTRL_0 0x00000120
+#define HDMI_HDCP_DDC_CTRL_0_DISABLE 0x00000001
+
+#define REG_HDMI_HDCP_DDC_CTRL_1 0x00000124
+#define HDMI_HDCP_DDC_CTRL_1_FAILED_ACK 0x00000001
+
+#define REG_HDMI_HDCP_DDC_STATUS 0x00000128
+#define HDMI_HDCP_DDC_STATUS_XFER_REQ 0x00000010
+#define HDMI_HDCP_DDC_STATUS_XFER_DONE 0x00000400
+#define HDMI_HDCP_DDC_STATUS_ABORTED 0x00001000
+#define HDMI_HDCP_DDC_STATUS_TIMEOUT 0x00002000
+#define HDMI_HDCP_DDC_STATUS_NACK0 0x00004000
+#define HDMI_HDCP_DDC_STATUS_NACK1 0x00008000
+#define HDMI_HDCP_DDC_STATUS_FAILED 0x00010000
+
+#define REG_HDMI_HDCP_ENTROPY_CTRL0 0x0000012c
+
+#define REG_HDMI_HDCP_ENTROPY_CTRL1 0x0000025c
+
#define REG_HDMI_HDCP_RESET 0x00000130
#define HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE 0x00000001
+#define REG_HDMI_HDCP_RCVPORT_DATA0 0x00000134
+
+#define REG_HDMI_HDCP_RCVPORT_DATA1 0x00000138
+
+#define REG_HDMI_HDCP_RCVPORT_DATA2_0 0x0000013c
+
+#define REG_HDMI_HDCP_RCVPORT_DATA2_1 0x00000140
+
+#define REG_HDMI_HDCP_RCVPORT_DATA3 0x00000144
+
+#define REG_HDMI_HDCP_RCVPORT_DATA4 0x00000148
+
+#define REG_HDMI_HDCP_RCVPORT_DATA5 0x0000014c
+
+#define REG_HDMI_HDCP_RCVPORT_DATA6 0x00000150
+
+#define REG_HDMI_HDCP_RCVPORT_DATA7 0x00000154
+
+#define REG_HDMI_HDCP_RCVPORT_DATA8 0x00000158
+
+#define REG_HDMI_HDCP_RCVPORT_DATA9 0x0000015c
+
+#define REG_HDMI_HDCP_RCVPORT_DATA10 0x00000160
+
+#define REG_HDMI_HDCP_RCVPORT_DATA11 0x00000164
+
+#define REG_HDMI_HDCP_RCVPORT_DATA12 0x00000168
+
#define REG_HDMI_VENSPEC_INFO0 0x0000016c
#define REG_HDMI_VENSPEC_INFO1 0x00000170
@@ -266,6 +334,7 @@ static inline uint32_t HDMI_DDC_CTRL_TRANSACTION_CNT(uint32_t val)
#define HDMI_DDC_SW_STATUS_NACK3 0x00008000
#define REG_HDMI_DDC_HW_STATUS 0x0000021c
+#define HDMI_DDC_HW_STATUS_DONE 0x00000008
#define REG_HDMI_DDC_SPEED 0x00000220
#define HDMI_DDC_SPEED_THRESHOLD__MASK 0x00000003
@@ -329,6 +398,15 @@ static inline uint32_t HDMI_DDC_DATA_INDEX(uint32_t val)
}
#define HDMI_DDC_DATA_INDEX_WRITE 0x80000000
+#define REG_HDMI_HDCP_SHA_CTRL 0x0000023c
+
+#define REG_HDMI_HDCP_SHA_STATUS 0x00000240
+#define HDMI_HDCP_SHA_STATUS_BLOCK_DONE 0x00000001
+#define HDMI_HDCP_SHA_STATUS_COMP_DONE 0x00000010
+
+#define REG_HDMI_HDCP_SHA_DATA 0x00000244
+#define HDMI_HDCP_SHA_DATA_DONE 0x00000001
+
#define REG_HDMI_HPD_INT_STATUS 0x00000250
#define HDMI_HPD_INT_STATUS_INT 0x00000001
#define HDMI_HPD_INT_STATUS_CABLE_DETECTED 0x00000002
@@ -359,6 +437,10 @@ static inline uint32_t HDMI_DDC_REF_REFTIMER(uint32_t val)
return ((val) << HDMI_DDC_REF_REFTIMER__SHIFT) & HDMI_DDC_REF_REFTIMER__MASK;
}
+#define REG_HDMI_HDCP_SW_UPPER_AKSV 0x00000284
+
+#define REG_HDMI_HDCP_SW_LOWER_AKSV 0x00000288
+
#define REG_HDMI_CEC_STATUS 0x00000298
#define REG_HDMI_CEC_INT 0x0000029c
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 6902ad6da710..a7a1d8267cf0 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -23,11 +23,8 @@ struct hdmi_bridge {
};
#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
-static void hdmi_bridge_destroy(struct drm_bridge *bridge)
+void hdmi_bridge_destroy(struct drm_bridge *bridge)
{
- struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
- drm_bridge_cleanup(bridge);
- kfree(hdmi_bridge);
}
static void power_on(struct drm_bridge *bridge)
@@ -200,7 +197,6 @@ static const struct drm_bridge_funcs hdmi_bridge_funcs = {
.disable = hdmi_bridge_disable,
.post_disable = hdmi_bridge_post_disable,
.mode_set = hdmi_bridge_mode_set,
- .destroy = hdmi_bridge_destroy,
};
@@ -211,7 +207,8 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi)
struct hdmi_bridge *hdmi_bridge;
int ret;
- hdmi_bridge = kzalloc(sizeof(*hdmi_bridge), GFP_KERNEL);
+ hdmi_bridge = devm_kzalloc(hdmi->dev->dev,
+ sizeof(*hdmi_bridge), GFP_KERNEL);
if (!hdmi_bridge) {
ret = -ENOMEM;
goto fail;
@@ -220,8 +217,11 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi)
hdmi_bridge->hdmi = hdmi;
bridge = &hdmi_bridge->base;
+ bridge->funcs = &hdmi_bridge_funcs;
- drm_bridge_init(hdmi->dev, bridge, &hdmi_bridge_funcs);
+ ret = drm_bridge_attach(hdmi->dev, bridge);
+ if (ret)
+ goto fail;
return bridge;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
index b4e70e0e3cfa..b62cdb968614 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
@@ -386,7 +386,7 @@ hdmi_connector_best_encoder(struct drm_connector *connector)
}
static const struct drm_connector_funcs hdmi_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = drm_atomic_helper_connector_dpms,
.detect = hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = hdmi_connector_destroy,
@@ -426,7 +426,7 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi)
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
- connector->interlace_allowed = 1;
+ connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
drm_connector_register(connector);
diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
index 29bd796797de..43bb54a9afbf 100644
--- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
+++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
@@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h
index a4a7f8c7122a..1d39174d91fb 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h
@@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -72,6 +73,18 @@ enum mdp4_cursor_format {
CURSOR_XRGB = 2,
};
+enum mdp4_frame_format {
+ FRAME_LINEAR = 0,
+ FRAME_TILE_ARGB_4X4 = 1,
+ FRAME_TILE_YCBCR_420 = 2,
+};
+
+enum mdp4_scale_unit {
+ SCALE_FIR = 0,
+ SCALE_MN_PHASE = 1,
+ SCALE_PIXEL_RPT = 2,
+};
+
enum mdp4_dma {
DMA_P = 0,
DMA_S = 1,
@@ -637,6 +650,8 @@ static inline uint32_t REG_MDP4_PIPE_SRCP1_BASE(enum mdp4_pipe i0) { return 0x00
static inline uint32_t REG_MDP4_PIPE_SRCP2_BASE(enum mdp4_pipe i0) { return 0x00020018 + 0x10000*i0; }
+static inline uint32_t REG_MDP4_PIPE_SRCP3_BASE(enum mdp4_pipe i0) { return 0x0002001c + 0x10000*i0; }
+
static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_A(enum mdp4_pipe i0) { return 0x00020040 + 0x10000*i0; }
#define MDP4_PIPE_SRC_STRIDE_A_P0__MASK 0x0000ffff
#define MDP4_PIPE_SRC_STRIDE_A_P0__SHIFT 0
@@ -720,7 +735,25 @@ static inline uint32_t MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(uint32_t val)
}
#define MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT 0x00020000
#define MDP4_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000
+#define MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__MASK 0x00180000
+#define MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__SHIFT 19
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(uint32_t val)
+{
+ return ((val) << MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__SHIFT) & MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__MASK;
+}
#define MDP4_PIPE_SRC_FORMAT_SOLID_FILL 0x00400000
+#define MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK 0x0c000000
+#define MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT 26
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(enum mdp_chroma_samp_type val)
+{
+ return ((val) << MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT) & MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK;
+}
+#define MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__MASK 0x60000000
+#define MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__SHIFT 29
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT(enum mdp4_frame_format val)
+{
+ return ((val) << MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__SHIFT) & MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__MASK;
+}
static inline uint32_t REG_MDP4_PIPE_SRC_UNPACK(enum mdp4_pipe i0) { return 0x00020054 + 0x10000*i0; }
#define MDP4_PIPE_SRC_UNPACK_ELEM0__MASK 0x000000ff
@@ -751,6 +784,18 @@ static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM3(uint32_t val)
static inline uint32_t REG_MDP4_PIPE_OP_MODE(enum mdp4_pipe i0) { return 0x00020058 + 0x10000*i0; }
#define MDP4_PIPE_OP_MODE_SCALEX_EN 0x00000001
#define MDP4_PIPE_OP_MODE_SCALEY_EN 0x00000002
+#define MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__MASK 0x0000000c
+#define MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__SHIFT 2
+static inline uint32_t MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL(enum mdp4_scale_unit val)
+{
+ return ((val) << MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__SHIFT) & MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__MASK;
+}
+#define MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__MASK 0x00000030
+#define MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__SHIFT 4
+static inline uint32_t MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL(enum mdp4_scale_unit val)
+{
+ return ((val) << MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__SHIFT) & MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__MASK;
+}
#define MDP4_PIPE_OP_MODE_SRC_YCBCR 0x00000200
#define MDP4_PIPE_OP_MODE_DST_YCBCR 0x00000400
#define MDP4_PIPE_OP_MODE_CSC_EN 0x00000800
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
index 3449213f1e76..73afa21822b4 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
@@ -140,26 +140,6 @@ static void mdp4_crtc_destroy(struct drm_crtc *crtc)
kfree(mdp4_crtc);
}
-static void mdp4_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
- struct mdp4_kms *mdp4_kms = get_kms(crtc);
- bool enabled = (mode == DRM_MODE_DPMS_ON);
-
- DBG("%s: mode=%d", mdp4_crtc->name, mode);
-
- if (enabled != mdp4_crtc->enabled) {
- if (enabled) {
- mdp4_enable(mdp4_kms);
- mdp_irq_register(&mdp4_kms->base, &mdp4_crtc->err);
- } else {
- mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err);
- mdp4_disable(mdp4_kms);
- }
- mdp4_crtc->enabled = enabled;
- }
-}
-
static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -304,27 +284,38 @@ static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc)
}
}
-static void mdp4_crtc_prepare(struct drm_crtc *crtc)
+static void mdp4_crtc_disable(struct drm_crtc *crtc)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+ struct mdp4_kms *mdp4_kms = get_kms(crtc);
+
DBG("%s", mdp4_crtc->name);
- /* make sure we hold a ref to mdp clks while setting up mode: */
- drm_crtc_vblank_get(crtc);
- mdp4_enable(get_kms(crtc));
- mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+
+ if (WARN_ON(!mdp4_crtc->enabled))
+ return;
+
+ mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err);
+ mdp4_disable(mdp4_kms);
+
+ mdp4_crtc->enabled = false;
}
-static void mdp4_crtc_commit(struct drm_crtc *crtc)
+static void mdp4_crtc_enable(struct drm_crtc *crtc)
{
- mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+ struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+ struct mdp4_kms *mdp4_kms = get_kms(crtc);
+
+ DBG("%s", mdp4_crtc->name);
+
+ if (WARN_ON(mdp4_crtc->enabled))
+ return;
+
+ mdp4_enable(mdp4_kms);
+ mdp_irq_register(&mdp4_kms->base, &mdp4_crtc->err);
+
crtc_flush(crtc);
- /* drop the ref to mdp clk's that we got in prepare: */
- mdp4_disable(get_kms(crtc));
- drm_crtc_vblank_put(crtc);
-}
-static void mdp4_crtc_load_lut(struct drm_crtc *crtc)
-{
+ mdp4_crtc->enabled = true;
}
static int mdp4_crtc_atomic_check(struct drm_crtc *crtc,
@@ -508,14 +499,10 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = {
};
static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = {
- .dpms = mdp4_crtc_dpms,
.mode_fixup = mdp4_crtc_mode_fixup,
.mode_set_nofb = mdp4_crtc_mode_set_nofb,
- .mode_set = drm_helper_crtc_mode_set,
- .mode_set_base = drm_helper_crtc_mode_set_base,
- .prepare = mdp4_crtc_prepare,
- .commit = mdp4_crtc_commit,
- .load_lut = mdp4_crtc_load_lut,
+ .disable = mdp4_crtc_disable,
+ .enable = mdp4_crtc_enable,
.atomic_check = mdp4_crtc_atomic_check,
.atomic_begin = mdp4_crtc_atomic_begin,
.atomic_flush = mdp4_crtc_atomic_flush,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c
index c3878420180b..7896323b2631 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c
@@ -94,61 +94,6 @@ static const struct drm_encoder_funcs mdp4_dtv_encoder_funcs = {
.destroy = mdp4_dtv_encoder_destroy,
};
-static void mdp4_dtv_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct drm_device *dev = encoder->dev;
- struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
- struct mdp4_kms *mdp4_kms = get_kms(encoder);
- bool enabled = (mode == DRM_MODE_DPMS_ON);
-
- DBG("mode=%d", mode);
-
- if (enabled == mdp4_dtv_encoder->enabled)
- return;
-
- if (enabled) {
- unsigned long pc = mdp4_dtv_encoder->pixclock;
- int ret;
-
- bs_set(mdp4_dtv_encoder, 1);
-
- DBG("setting src_clk=%lu", pc);
-
- ret = clk_set_rate(mdp4_dtv_encoder->src_clk, pc);
- if (ret)
- dev_err(dev->dev, "failed to set src_clk to %lu: %d\n", pc, ret);
- clk_prepare_enable(mdp4_dtv_encoder->src_clk);
- ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk);
- if (ret)
- dev_err(dev->dev, "failed to enable hdmi_clk: %d\n", ret);
- ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk);
- if (ret)
- dev_err(dev->dev, "failed to enabled mdp_clk: %d\n", ret);
-
- mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1);
- } else {
- mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
-
- /*
- * Wait for a vsync so we know the ENABLE=0 latched before
- * the (connector) source of the vsync's gets disabled,
- * otherwise we end up in a funny state if we re-enable
- * before the disable latches, which results that some of
- * the settings changes for the new modeset (like new
- * scanout buffer) don't latch properly..
- */
- mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_EXTERNAL_VSYNC);
-
- clk_disable_unprepare(mdp4_dtv_encoder->src_clk);
- clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk);
- clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk);
-
- bs_set(mdp4_dtv_encoder, 0);
- }
-
- mdp4_dtv_encoder->enabled = enabled;
-}
-
static bool mdp4_dtv_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -221,28 +166,78 @@ static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder,
mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VEND, 0);
}
-static void mdp4_dtv_encoder_prepare(struct drm_encoder *encoder)
+static void mdp4_dtv_encoder_disable(struct drm_encoder *encoder)
{
- mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+ struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+ struct mdp4_kms *mdp4_kms = get_kms(encoder);
+
+ if (WARN_ON(!mdp4_dtv_encoder->enabled))
+ return;
+
+ mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
+
+ /*
+ * Wait for a vsync so we know the ENABLE=0 latched before
+ * the (connector) source of the vsync's gets disabled,
+ * otherwise we end up in a funny state if we re-enable
+ * before the disable latches, which results that some of
+ * the settings changes for the new modeset (like new
+ * scanout buffer) don't latch properly..
+ */
+ mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_EXTERNAL_VSYNC);
+
+ clk_disable_unprepare(mdp4_dtv_encoder->src_clk);
+ clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk);
+ clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk);
+
+ bs_set(mdp4_dtv_encoder, 0);
+
+ mdp4_dtv_encoder->enabled = false;
}
-static void mdp4_dtv_encoder_commit(struct drm_encoder *encoder)
+static void mdp4_dtv_encoder_enable(struct drm_encoder *encoder)
{
+ struct drm_device *dev = encoder->dev;
+ struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+ struct mdp4_kms *mdp4_kms = get_kms(encoder);
+ unsigned long pc = mdp4_dtv_encoder->pixclock;
+ int ret;
+
+ if (WARN_ON(mdp4_dtv_encoder->enabled))
+ return;
+
mdp4_crtc_set_config(encoder->crtc,
MDP4_DMA_CONFIG_R_BPC(BPC8) |
MDP4_DMA_CONFIG_G_BPC(BPC8) |
MDP4_DMA_CONFIG_B_BPC(BPC8) |
MDP4_DMA_CONFIG_PACK(0x21));
mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 1);
- mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
+
+ bs_set(mdp4_dtv_encoder, 1);
+
+ DBG("setting src_clk=%lu", pc);
+
+ ret = clk_set_rate(mdp4_dtv_encoder->src_clk, pc);
+ if (ret)
+ dev_err(dev->dev, "failed to set src_clk to %lu: %d\n", pc, ret);
+ clk_prepare_enable(mdp4_dtv_encoder->src_clk);
+ ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk);
+ if (ret)
+ dev_err(dev->dev, "failed to enable hdmi_clk: %d\n", ret);
+ ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk);
+ if (ret)
+ dev_err(dev->dev, "failed to enabled mdp_clk: %d\n", ret);
+
+ mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1);
+
+ mdp4_dtv_encoder->enabled = true;
}
static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = {
- .dpms = mdp4_dtv_encoder_dpms,
.mode_fixup = mdp4_dtv_encoder_mode_fixup,
.mode_set = mdp4_dtv_encoder_mode_set,
- .prepare = mdp4_dtv_encoder_prepare,
- .commit = mdp4_dtv_encoder_commit,
+ .enable = mdp4_dtv_encoder_enable,
+ .disable = mdp4_dtv_encoder_disable,
};
long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index a62109e4ae0d..d847b9436194 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -125,6 +125,38 @@ out:
return ret;
}
+static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
+{
+ struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+ int i, ncrtcs = state->dev->mode_config.num_crtc;
+
+ mdp4_enable(mdp4_kms);
+
+ /* see 119ecb7fd */
+ for (i = 0; i < ncrtcs; i++) {
+ struct drm_crtc *crtc = state->crtcs[i];
+ if (!crtc)
+ continue;
+ drm_crtc_vblank_get(crtc);
+ }
+}
+
+static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
+{
+ struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+ int i, ncrtcs = state->dev->mode_config.num_crtc;
+
+ /* see 119ecb7fd */
+ for (i = 0; i < ncrtcs; i++) {
+ struct drm_crtc *crtc = state->crtcs[i];
+ if (!crtc)
+ continue;
+ drm_crtc_vblank_put(crtc);
+ }
+
+ mdp4_disable(mdp4_kms);
+}
+
static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
struct drm_encoder *encoder)
{
@@ -161,6 +193,8 @@ static const struct mdp_kms_funcs kms_funcs = {
.irq = mdp4_irq,
.enable_vblank = mdp4_enable_vblank,
.disable_vblank = mdp4_disable_vblank,
+ .prepare_commit = mdp4_prepare_commit,
+ .complete_commit = mdp4_complete_commit,
.get_format = mdp_get_format,
.round_pixclk = mdp4_round_pixclk,
.preclose = mdp4_preclose,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
index cbd77bc626d5..0a5c58bde7a9 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
@@ -175,14 +175,25 @@ irqreturn_t mdp4_irq(struct msm_kms *kms);
int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+static inline bool pipe_supports_yuv(enum mdp4_pipe pipe)
+{
+ switch (pipe) {
+ case VG1:
+ case VG2:
+ case VG3:
+ case VG4:
+ return true;
+ default:
+ return false;
+ }
+}
+
static inline
uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats,
uint32_t max_formats)
{
- /* TODO when we have YUV, we need to filter supported formats
- * based on pipe_id..
- */
- return mdp_get_formats(pixel_formats, max_formats);
+ return mdp_get_formats(pixel_formats, max_formats,
+ !pipe_supports_yuv(pipe_id));
}
void mdp4_plane_install_properties(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c
index 41f6436754fc..60ec8222c9f6 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c
@@ -259,77 +259,6 @@ static void setup_phy(struct drm_encoder *encoder)
mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0);
}
-static void mdp4_lcdc_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct drm_device *dev = encoder->dev;
- struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
- to_mdp4_lcdc_encoder(encoder);
- struct mdp4_kms *mdp4_kms = get_kms(encoder);
- struct drm_panel *panel = mdp4_lcdc_encoder->panel;
- bool enabled = (mode == DRM_MODE_DPMS_ON);
- int i, ret;
-
- DBG("mode=%d", mode);
-
- if (enabled == mdp4_lcdc_encoder->enabled)
- return;
-
- if (enabled) {
- unsigned long pc = mdp4_lcdc_encoder->pixclock;
- int ret;
-
- bs_set(mdp4_lcdc_encoder, 1);
-
- for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
- ret = regulator_enable(mdp4_lcdc_encoder->regs[i]);
- if (ret)
- dev_err(dev->dev, "failed to enable regulator: %d\n", ret);
- }
-
- DBG("setting lcdc_clk=%lu", pc);
- ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc);
- if (ret)
- dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
- ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk);
- if (ret)
- dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
-
- if (panel)
- drm_panel_enable(panel);
-
- setup_phy(encoder);
-
- mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1);
- } else {
- mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
-
- if (panel)
- drm_panel_disable(panel);
-
- /*
- * Wait for a vsync so we know the ENABLE=0 latched before
- * the (connector) source of the vsync's gets disabled,
- * otherwise we end up in a funny state if we re-enable
- * before the disable latches, which results that some of
- * the settings changes for the new modeset (like new
- * scanout buffer) don't latch properly..
- */
- mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC);
-
- clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk);
-
- for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
- ret = regulator_disable(mdp4_lcdc_encoder->regs[i]);
- if (ret)
- dev_err(dev->dev, "failed to disable regulator: %d\n", ret);
- }
-
- bs_set(mdp4_lcdc_encoder, 0);
- }
-
- mdp4_lcdc_encoder->enabled = enabled;
-}
-
static bool mdp4_lcdc_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -403,13 +332,59 @@ static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder,
mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VEND, 0);
}
-static void mdp4_lcdc_encoder_prepare(struct drm_encoder *encoder)
+static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)
{
- mdp4_lcdc_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+ struct drm_device *dev = encoder->dev;
+ struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
+ to_mdp4_lcdc_encoder(encoder);
+ struct mdp4_kms *mdp4_kms = get_kms(encoder);
+ struct drm_panel *panel = mdp4_lcdc_encoder->panel;
+ int i, ret;
+
+ if (WARN_ON(!mdp4_lcdc_encoder->enabled))
+ return;
+
+ mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
+
+ if (panel)
+ drm_panel_disable(panel);
+
+ /*
+ * Wait for a vsync so we know the ENABLE=0 latched before
+ * the (connector) source of the vsync's gets disabled,
+ * otherwise we end up in a funny state if we re-enable
+ * before the disable latches, which results that some of
+ * the settings changes for the new modeset (like new
+ * scanout buffer) don't latch properly..
+ */
+ mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC);
+
+ clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk);
+
+ for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
+ ret = regulator_disable(mdp4_lcdc_encoder->regs[i]);
+ if (ret)
+ dev_err(dev->dev, "failed to disable regulator: %d\n", ret);
+ }
+
+ bs_set(mdp4_lcdc_encoder, 0);
+
+ mdp4_lcdc_encoder->enabled = false;
}
-static void mdp4_lcdc_encoder_commit(struct drm_encoder *encoder)
+static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
{
+ struct drm_device *dev = encoder->dev;
+ struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
+ to_mdp4_lcdc_encoder(encoder);
+ unsigned long pc = mdp4_lcdc_encoder->pixclock;
+ struct mdp4_kms *mdp4_kms = get_kms(encoder);
+ struct drm_panel *panel = mdp4_lcdc_encoder->panel;
+ int i, ret;
+
+ if (WARN_ON(mdp4_lcdc_encoder->enabled))
+ return;
+
/* TODO: hard-coded for 18bpp: */
mdp4_crtc_set_config(encoder->crtc,
MDP4_DMA_CONFIG_R_BPC(BPC6) |
@@ -420,15 +395,38 @@ static void mdp4_lcdc_encoder_commit(struct drm_encoder *encoder)
MDP4_DMA_CONFIG_DEFLKR_EN |
MDP4_DMA_CONFIG_DITHER_EN);
mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);
- mdp4_lcdc_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
+
+ bs_set(mdp4_lcdc_encoder, 1);
+
+ for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
+ ret = regulator_enable(mdp4_lcdc_encoder->regs[i]);
+ if (ret)
+ dev_err(dev->dev, "failed to enable regulator: %d\n", ret);
+ }
+
+ DBG("setting lcdc_clk=%lu", pc);
+ ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc);
+ if (ret)
+ dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
+ ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk);
+ if (ret)
+ dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
+
+ if (panel)
+ drm_panel_enable(panel);
+
+ setup_phy(encoder);
+
+ mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1);
+
+ mdp4_lcdc_encoder->enabled = true;
}
static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = {
- .dpms = mdp4_lcdc_encoder_dpms,
.mode_fixup = mdp4_lcdc_encoder_mode_fixup,
.mode_set = mdp4_lcdc_encoder_mode_set,
- .prepare = mdp4_lcdc_encoder_prepare,
- .commit = mdp4_lcdc_encoder_commit,
+ .disable = mdp4_lcdc_encoder_disable,
+ .enable = mdp4_lcdc_encoder_enable,
};
long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
index 4ddc28e1275b..921185133d38 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
@@ -94,7 +94,7 @@ mdp4_lvds_connector_best_encoder(struct drm_connector *connector)
}
static const struct drm_connector_funcs mdp4_lvds_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = drm_atomic_helper_connector_dpms,
.detect = mdp4_lvds_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = mdp4_lvds_connector_destroy,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index 1e5ebe83647d..cde25009203a 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -17,6 +17,8 @@
#include "mdp4_kms.h"
+#define DOWN_SCALE_MAX 8
+#define UP_SCALE_MAX 8
struct mdp4_plane {
struct drm_plane base;
@@ -136,10 +138,6 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane,
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
struct mdp4_kms *mdp4_kms = get_kms(plane);
enum mdp4_pipe pipe = mdp4_plane->pipe;
- uint32_t iova = msm_framebuffer_iova(fb, mdp4_kms->id, 0);
-
- DBG("%s: set_scanout: %08x (%u)", mdp4_plane->name,
- iova, fb->pitches[0]);
mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe),
MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) |
@@ -149,11 +147,45 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane,
MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) |
MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3]));
- mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), iova);
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe),
+ msm_framebuffer_iova(fb, mdp4_kms->id, 0));
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP1_BASE(pipe),
+ msm_framebuffer_iova(fb, mdp4_kms->id, 1));
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP2_BASE(pipe),
+ msm_framebuffer_iova(fb, mdp4_kms->id, 2));
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe),
+ msm_framebuffer_iova(fb, mdp4_kms->id, 3));
plane->fb = fb;
}
+static void mdp4_write_csc_config(struct mdp4_kms *mdp4_kms,
+ enum mdp4_pipe pipe, struct csc_cfg *csc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(csc->matrix); i++) {
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_MV(pipe, i),
+ csc->matrix[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(csc->post_bias) ; i++) {
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_BV(pipe, i),
+ csc->pre_bias[i]);
+
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_BV(pipe, i),
+ csc->post_bias[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(csc->post_clamp) ; i++) {
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_LV(pipe, i),
+ csc->pre_clamp[i]);
+
+ mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_LV(pipe, i),
+ csc->post_clamp[i]);
+ }
+}
+
#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000
static int mdp4_plane_mode_set(struct drm_plane *plane,
@@ -163,6 +195,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
{
+ struct drm_device *dev = plane->dev;
struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
struct mdp4_kms *mdp4_kms = get_kms(plane);
enum mdp4_pipe pipe = mdp4_plane->pipe;
@@ -186,14 +219,59 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
fb->base.id, src_x, src_y, src_w, src_h,
crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
+ format = to_mdp_format(msm_framebuffer_format(fb));
+
+ if (src_w > (crtc_w * DOWN_SCALE_MAX)) {
+ dev_err(dev->dev, "Width down scaling exceeds limits!\n");
+ return -ERANGE;
+ }
+
+ if (src_h > (crtc_h * DOWN_SCALE_MAX)) {
+ dev_err(dev->dev, "Height down scaling exceeds limits!\n");
+ return -ERANGE;
+ }
+
+ if (crtc_w > (src_w * UP_SCALE_MAX)) {
+ dev_err(dev->dev, "Width up scaling exceeds limits!\n");
+ return -ERANGE;
+ }
+
+ if (crtc_h > (src_h * UP_SCALE_MAX)) {
+ dev_err(dev->dev, "Height up scaling exceeds limits!\n");
+ return -ERANGE;
+ }
+
if (src_w != crtc_w) {
+ uint32_t sel_unit = SCALE_FIR;
op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
- /* TODO calc phasex_step */
+
+ if (MDP_FORMAT_IS_YUV(format)) {
+ if (crtc_w > src_w)
+ sel_unit = SCALE_PIXEL_RPT;
+ else if (crtc_w <= (src_w / 4))
+ sel_unit = SCALE_MN_PHASE;
+
+ op_mode |= MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL(sel_unit);
+ phasex_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT,
+ src_w, crtc_w);
+ }
}
if (src_h != crtc_h) {
+ uint32_t sel_unit = SCALE_FIR;
op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN;
- /* TODO calc phasey_step */
+
+ if (MDP_FORMAT_IS_YUV(format)) {
+
+ if (crtc_h > src_h)
+ sel_unit = SCALE_PIXEL_RPT;
+ else if (crtc_h <= (src_h / 4))
+ sel_unit = SCALE_MN_PHASE;
+
+ op_mode |= MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL(sel_unit);
+ phasey_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT,
+ src_h, crtc_h);
+ }
}
mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe),
@@ -214,8 +292,6 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
mdp4_plane_set_scanout(plane, fb);
- format = to_mdp_format(msm_framebuffer_format(fb));
-
mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe),
MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) |
MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
@@ -224,6 +300,8 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) |
MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) |
MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) |
+ MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(format->fetch_type) |
+ MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample) |
COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT));
mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe),
@@ -232,6 +310,14 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) |
MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3]));
+ if (MDP_FORMAT_IS_YUV(format)) {
+ struct csc_cfg *csc = mdp_get_default_csc_cfg(CSC_YUV2RGB);
+
+ op_mode |= MDP4_PIPE_OP_MODE_SRC_YCBCR;
+ op_mode |= MDP4_PIPE_OP_MODE_CSC_EN;
+ mdp4_write_csc_config(mdp4_kms, pipe, csc);
+ }
+
mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(pipe), op_mode);
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
index e87ef5512cb0..09b4a25eb553 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
@@ -8,18 +8,19 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
-Copyright (C) 2013-2014 by the following authors:
+Copyright (C) 2013-2015 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -88,13 +89,6 @@ enum mdp5_pack_3d {
PACK_3D_COL_INT = 3,
};
-enum mdp5_chroma_samp_type {
- CHROMA_RGB = 0,
- CHROMA_H2V1 = 1,
- CHROMA_H1V2 = 2,
- CHROMA_420 = 3,
-};
-
enum mdp5_scale_filter {
SCALE_FILTER_NEAREST = 0,
SCALE_FILTER_BIL = 1,
@@ -135,6 +129,17 @@ enum mdp5_client_id {
CID_MAX = 23,
};
+enum mdp5_cursor_format {
+ CURSOR_FMT_ARGB8888 = 0,
+ CURSOR_FMT_ARGB1555 = 2,
+ CURSOR_FMT_ARGB4444 = 4,
+};
+
+enum mdp5_cursor_alpha {
+ CURSOR_ALPHA_CONST = 0,
+ CURSOR_ALPHA_PER_PIXEL = 2,
+};
+
enum mdp5_igc_type {
IGC_VIG = 0,
IGC_RGB = 1,
@@ -142,6 +147,11 @@ enum mdp5_igc_type {
IGC_DSPP = 3,
};
+enum mdp5_data_format {
+ DATA_FORMAT_RGB = 0,
+ DATA_FORMAT_YUV = 1,
+};
+
#define MDP5_IRQ_INTF0_WB_ROT_COMP 0x00000001
#define MDP5_IRQ_INTF1_WB_ROT_COMP 0x00000002
#define MDP5_IRQ_INTF2_WB_ROT_COMP 0x00000004
@@ -463,12 +473,143 @@ static inline uint32_t __offset_PIPE(enum mdp5_pipe idx)
}
static inline uint32_t REG_MDP5_PIPE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); }
+static inline uint32_t REG_MDP5_PIPE_OP_MODE(enum mdp5_pipe i0) { return 0x00000200 + __offset_PIPE(i0); }
+#define MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__MASK 0x00080000
+#define MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__SHIFT 19
+static inline uint32_t MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT(enum mdp5_data_format val)
+{
+ return ((val) << MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__SHIFT) & MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__MASK;
+}
+#define MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__MASK 0x00040000
+#define MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__SHIFT 18
+static inline uint32_t MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT(enum mdp5_data_format val)
+{
+ return ((val) << MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__SHIFT) & MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__MASK;
+}
+#define MDP5_PIPE_OP_MODE_CSC_1_EN 0x00020000
+
static inline uint32_t REG_MDP5_PIPE_HIST_CTL_BASE(enum mdp5_pipe i0) { return 0x000002c4 + __offset_PIPE(i0); }
static inline uint32_t REG_MDP5_PIPE_HIST_LUT_BASE(enum mdp5_pipe i0) { return 0x000002f0 + __offset_PIPE(i0); }
static inline uint32_t REG_MDP5_PIPE_HIST_LUT_SWAP(enum mdp5_pipe i0) { return 0x00000300 + __offset_PIPE(i0); }
+static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_0(enum mdp5_pipe i0) { return 0x00000320 + __offset_PIPE(i0); }
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__MASK 0x00001fff
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__MASK;
+}
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__MASK 0x1fff0000
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__SHIFT 16
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_1(enum mdp5_pipe i0) { return 0x00000324 + __offset_PIPE(i0); }
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__MASK 0x00001fff
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__MASK;
+}
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__MASK 0x1fff0000
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__SHIFT 16
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_2(enum mdp5_pipe i0) { return 0x00000328 + __offset_PIPE(i0); }
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__MASK 0x00001fff
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__MASK;
+}
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__MASK 0x1fff0000
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__SHIFT 16
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_3(enum mdp5_pipe i0) { return 0x0000032c + __offset_PIPE(i0); }
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__MASK 0x00001fff
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__MASK;
+}
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__MASK 0x1fff0000
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__SHIFT 16
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_4(enum mdp5_pipe i0) { return 0x00000330 + __offset_PIPE(i0); }
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__MASK 0x00001fff
+#define MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_CLAMP(enum mdp5_pipe i0, uint32_t i1) { return 0x00000334 + __offset_PIPE(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_CLAMP_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x00000334 + __offset_PIPE(i0) + 0x4*i1; }
+#define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__MASK 0x000000ff
+#define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__SHIFT) & MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__MASK;
+}
+#define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__MASK 0x0000ff00
+#define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__SHIFT 8
+static inline uint32_t MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__SHIFT) & MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_CLAMP(enum mdp5_pipe i0, uint32_t i1) { return 0x00000340 + __offset_PIPE(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_CLAMP_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x00000340 + __offset_PIPE(i0) + 0x4*i1; }
+#define MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__MASK 0x000000ff
+#define MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__SHIFT) & MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__MASK;
+}
+#define MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__MASK 0x0000ff00
+#define MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__SHIFT 8
+static inline uint32_t MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__SHIFT) & MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_BIAS(enum mdp5_pipe i0, uint32_t i1) { return 0x0000034c + __offset_PIPE(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_BIAS_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x0000034c + __offset_PIPE(i0) + 0x4*i1; }
+#define MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__MASK 0x000001ff
+#define MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__SHIFT) & MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__MASK;
+}
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_BIAS(enum mdp5_pipe i0, uint32_t i1) { return 0x00000358 + __offset_PIPE(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_BIAS_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x00000358 + __offset_PIPE(i0) + 0x4*i1; }
+#define MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__MASK 0x000001ff
+#define MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__SHIFT 0
+static inline uint32_t MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE(uint32_t val)
+{
+ return ((val) << MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__SHIFT) & MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__MASK;
+}
+
static inline uint32_t REG_MDP5_PIPE_SRC_SIZE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_SIZE_HEIGHT__MASK 0xffff0000
#define MDP5_PIPE_SRC_SIZE_HEIGHT__SHIFT 16
@@ -618,15 +759,15 @@ static inline uint32_t MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT(uint32_t val)
}
#define MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT 0x00020000
#define MDP5_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000
-#define MDP5_PIPE_SRC_FORMAT_NUM_PLANES__MASK 0x00780000
+#define MDP5_PIPE_SRC_FORMAT_NUM_PLANES__MASK 0x00180000
#define MDP5_PIPE_SRC_FORMAT_NUM_PLANES__SHIFT 19
-static inline uint32_t MDP5_PIPE_SRC_FORMAT_NUM_PLANES(uint32_t val)
+static inline uint32_t MDP5_PIPE_SRC_FORMAT_NUM_PLANES(enum mdp_sspp_fetch_type val)
{
return ((val) << MDP5_PIPE_SRC_FORMAT_NUM_PLANES__SHIFT) & MDP5_PIPE_SRC_FORMAT_NUM_PLANES__MASK;
}
#define MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK 0x01800000
#define MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT 23
-static inline uint32_t MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(enum mdp5_chroma_samp_type val)
+static inline uint32_t MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(enum mdp_chroma_samp_type val)
{
return ((val) << MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT) & MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK;
}
@@ -753,6 +894,10 @@ static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_X(enum mdp5_pipe i0) { ret
static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(enum mdp5_pipe i0) { return 0x00000214 + __offset_PIPE(i0); }
+static inline uint32_t REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_X(enum mdp5_pipe i0) { return 0x00000218 + __offset_PIPE(i0); }
+
+static inline uint32_t REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_Y(enum mdp5_pipe i0) { return 0x0000021c + __offset_PIPE(i0); }
+
static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_X(enum mdp5_pipe i0) { return 0x00000220 + __offset_PIPE(i0); }
static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_Y(enum mdp5_pipe i0) { return 0x00000224 + __offset_PIPE(i0); }
@@ -839,20 +984,88 @@ static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH0(uint32_t i0, uint32_t i
static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00000048 + __offset_LM(i0) + 0x30*i1; }
static inline uint32_t REG_MDP5_LM_CURSOR_IMG_SIZE(uint32_t i0) { return 0x000000e0 + __offset_LM(i0); }
+#define MDP5_LM_CURSOR_IMG_SIZE_SRC_W__MASK 0x0000ffff
+#define MDP5_LM_CURSOR_IMG_SIZE_SRC_W__SHIFT 0
+static inline uint32_t MDP5_LM_CURSOR_IMG_SIZE_SRC_W(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_IMG_SIZE_SRC_W__SHIFT) & MDP5_LM_CURSOR_IMG_SIZE_SRC_W__MASK;
+}
+#define MDP5_LM_CURSOR_IMG_SIZE_SRC_H__MASK 0xffff0000
+#define MDP5_LM_CURSOR_IMG_SIZE_SRC_H__SHIFT 16
+static inline uint32_t MDP5_LM_CURSOR_IMG_SIZE_SRC_H(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_IMG_SIZE_SRC_H__SHIFT) & MDP5_LM_CURSOR_IMG_SIZE_SRC_H__MASK;
+}
static inline uint32_t REG_MDP5_LM_CURSOR_SIZE(uint32_t i0) { return 0x000000e4 + __offset_LM(i0); }
+#define MDP5_LM_CURSOR_SIZE_ROI_W__MASK 0x0000ffff
+#define MDP5_LM_CURSOR_SIZE_ROI_W__SHIFT 0
+static inline uint32_t MDP5_LM_CURSOR_SIZE_ROI_W(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_SIZE_ROI_W__SHIFT) & MDP5_LM_CURSOR_SIZE_ROI_W__MASK;
+}
+#define MDP5_LM_CURSOR_SIZE_ROI_H__MASK 0xffff0000
+#define MDP5_LM_CURSOR_SIZE_ROI_H__SHIFT 16
+static inline uint32_t MDP5_LM_CURSOR_SIZE_ROI_H(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_SIZE_ROI_H__SHIFT) & MDP5_LM_CURSOR_SIZE_ROI_H__MASK;
+}
static inline uint32_t REG_MDP5_LM_CURSOR_XY(uint32_t i0) { return 0x000000e8 + __offset_LM(i0); }
+#define MDP5_LM_CURSOR_XY_SRC_X__MASK 0x0000ffff
+#define MDP5_LM_CURSOR_XY_SRC_X__SHIFT 0
+static inline uint32_t MDP5_LM_CURSOR_XY_SRC_X(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_XY_SRC_X__SHIFT) & MDP5_LM_CURSOR_XY_SRC_X__MASK;
+}
+#define MDP5_LM_CURSOR_XY_SRC_Y__MASK 0xffff0000
+#define MDP5_LM_CURSOR_XY_SRC_Y__SHIFT 16
+static inline uint32_t MDP5_LM_CURSOR_XY_SRC_Y(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_XY_SRC_Y__SHIFT) & MDP5_LM_CURSOR_XY_SRC_Y__MASK;
+}
static inline uint32_t REG_MDP5_LM_CURSOR_STRIDE(uint32_t i0) { return 0x000000dc + __offset_LM(i0); }
+#define MDP5_LM_CURSOR_STRIDE_STRIDE__MASK 0x0000ffff
+#define MDP5_LM_CURSOR_STRIDE_STRIDE__SHIFT 0
+static inline uint32_t MDP5_LM_CURSOR_STRIDE_STRIDE(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_STRIDE_STRIDE__SHIFT) & MDP5_LM_CURSOR_STRIDE_STRIDE__MASK;
+}
static inline uint32_t REG_MDP5_LM_CURSOR_FORMAT(uint32_t i0) { return 0x000000ec + __offset_LM(i0); }
+#define MDP5_LM_CURSOR_FORMAT_FORMAT__MASK 0x00000007
+#define MDP5_LM_CURSOR_FORMAT_FORMAT__SHIFT 0
+static inline uint32_t MDP5_LM_CURSOR_FORMAT_FORMAT(enum mdp5_cursor_format val)
+{
+ return ((val) << MDP5_LM_CURSOR_FORMAT_FORMAT__SHIFT) & MDP5_LM_CURSOR_FORMAT_FORMAT__MASK;
+}
static inline uint32_t REG_MDP5_LM_CURSOR_BASE_ADDR(uint32_t i0) { return 0x000000f0 + __offset_LM(i0); }
static inline uint32_t REG_MDP5_LM_CURSOR_START_XY(uint32_t i0) { return 0x000000f4 + __offset_LM(i0); }
+#define MDP5_LM_CURSOR_START_XY_X_START__MASK 0x0000ffff
+#define MDP5_LM_CURSOR_START_XY_X_START__SHIFT 0
+static inline uint32_t MDP5_LM_CURSOR_START_XY_X_START(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_START_XY_X_START__SHIFT) & MDP5_LM_CURSOR_START_XY_X_START__MASK;
+}
+#define MDP5_LM_CURSOR_START_XY_Y_START__MASK 0xffff0000
+#define MDP5_LM_CURSOR_START_XY_Y_START__SHIFT 16
+static inline uint32_t MDP5_LM_CURSOR_START_XY_Y_START(uint32_t val)
+{
+ return ((val) << MDP5_LM_CURSOR_START_XY_Y_START__SHIFT) & MDP5_LM_CURSOR_START_XY_Y_START__MASK;
+}
static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_CONFIG(uint32_t i0) { return 0x000000f8 + __offset_LM(i0); }
+#define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN 0x00000001
+#define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__MASK 0x00000006
+#define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__SHIFT 1
+static inline uint32_t MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(enum mdp5_cursor_alpha val)
+{
+ return ((val) << MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__SHIFT) & MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__MASK;
+}
+#define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN 0x00000008
static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_PARAM(uint32_t i0) { return 0x000000fc + __offset_LM(i0); }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index f021f960a8a2..46fac545dc2b 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -24,6 +24,9 @@
#include "drm_crtc_helper.h"
#include "drm_flip_work.h"
+#define CURSOR_WIDTH 64
+#define CURSOR_HEIGHT 64
+
#define SSPP_MAX (SSPP_RGB3 + 1) /* TODO: Add SSPP_MAX in mdp5.xml.h */
struct mdp5_crtc {
@@ -47,8 +50,21 @@ struct mdp5_crtc {
#define PENDING_FLIP 0x2
atomic_t pending;
+ /* for unref'ing cursor bo's after scanout completes: */
+ struct drm_flip_work unref_cursor_work;
+
struct mdp_irq vblank;
struct mdp_irq err;
+
+ struct {
+ /* protect REG_MDP5_LM_CURSOR* registers and cursor scanout_bo*/
+ spinlock_t lock;
+
+ /* current cursor being scanned out: */
+ struct drm_gem_object *scanout_bo;
+ uint32_t width;
+ uint32_t height;
+ } cursor;
};
#define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base)
@@ -129,37 +145,26 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
}
}
+static void unref_cursor_worker(struct drm_flip_work *work, void *val)
+{
+ struct mdp5_crtc *mdp5_crtc =
+ container_of(work, struct mdp5_crtc, unref_cursor_work);
+ struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base);
+
+ msm_gem_put_iova(val, mdp5_kms->id);
+ drm_gem_object_unreference_unlocked(val);
+}
+
static void mdp5_crtc_destroy(struct drm_crtc *crtc)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
drm_crtc_cleanup(crtc);
+ drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work);
kfree(mdp5_crtc);
}
-static void mdp5_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
- struct mdp5_kms *mdp5_kms = get_kms(crtc);
- bool enabled = (mode == DRM_MODE_DPMS_ON);
-
- DBG("%s: mode=%d", mdp5_crtc->name, mode);
-
- if (enabled != mdp5_crtc->enabled) {
- if (enabled) {
- mdp5_enable(mdp5_kms);
- mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err);
- } else {
- /* set STAGE_UNUSED for all layers */
- mdp5_ctl_blend(mdp5_crtc->ctl, mdp5_crtc->lm, 0x00000000);
- mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err);
- mdp5_disable(mdp5_kms);
- }
- mdp5_crtc->enabled = enabled;
- }
-}
-
static bool mdp5_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -256,27 +261,41 @@ static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc)
spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
}
-static void mdp5_crtc_prepare(struct drm_crtc *crtc)
+static void mdp5_crtc_disable(struct drm_crtc *crtc)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+ struct mdp5_kms *mdp5_kms = get_kms(crtc);
+
DBG("%s", mdp5_crtc->name);
- /* make sure we hold a ref to mdp clks while setting up mode: */
- mdp5_enable(get_kms(crtc));
- mdp5_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+
+ if (WARN_ON(!mdp5_crtc->enabled))
+ return;
+
+ /* set STAGE_UNUSED for all layers */
+ mdp5_ctl_blend(mdp5_crtc->ctl, mdp5_crtc->lm, 0x00000000);
+
+ mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err);
+ mdp5_disable(mdp5_kms);
+
+ mdp5_crtc->enabled = false;
}
-static void mdp5_crtc_commit(struct drm_crtc *crtc)
+static void mdp5_crtc_enable(struct drm_crtc *crtc)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+ struct mdp5_kms *mdp5_kms = get_kms(crtc);
+
DBG("%s", mdp5_crtc->name);
- mdp5_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+
+ if (WARN_ON(mdp5_crtc->enabled))
+ return;
+
+ mdp5_enable(mdp5_kms);
+ mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err);
+
crtc_flush_all(crtc);
- /* drop the ref to mdp clk's that we got in prepare: */
- mdp5_disable(get_kms(crtc));
-}
-static void mdp5_crtc_load_lut(struct drm_crtc *crtc)
-{
+ mdp5_crtc->enabled = true;
}
struct plane_state {
@@ -384,6 +403,132 @@ static int mdp5_crtc_set_property(struct drm_crtc *crtc,
return -EINVAL;
}
+static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
+ struct drm_file *file, uint32_t handle,
+ uint32_t width, uint32_t height)
+{
+ struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct drm_gem_object *cursor_bo, *old_bo;
+ uint32_t blendcfg, cursor_addr, stride;
+ int ret, bpp, lm;
+ unsigned int depth;
+ enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;
+ uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
+ unsigned long flags;
+
+ if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
+ dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
+ return -EINVAL;
+ }
+
+ if (NULL == mdp5_crtc->ctl)
+ return -EINVAL;
+
+ if (!handle) {
+ DBG("Cursor off");
+ return mdp5_ctl_set_cursor(mdp5_crtc->ctl, false);
+ }
+
+ cursor_bo = drm_gem_object_lookup(dev, file, handle);
+ if (!cursor_bo)
+ return -ENOENT;
+
+ ret = msm_gem_get_iova(cursor_bo, mdp5_kms->id, &cursor_addr);
+ if (ret)
+ return -EINVAL;
+
+ lm = mdp5_crtc->lm;
+ drm_fb_get_bpp_depth(DRM_FORMAT_ARGB8888, &depth, &bpp);
+ stride = width * (bpp >> 3);
+
+ spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
+ old_bo = mdp5_crtc->cursor.scanout_bo;
+
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),
+ MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_IMG_SIZE(lm),
+ MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) |
+ MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width));
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm),
+ MDP5_LM_CURSOR_SIZE_ROI_H(height) |
+ MDP5_LM_CURSOR_SIZE_ROI_W(width));
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr);
+
+
+ blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN;
+ blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN;
+ blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha);
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg);
+
+ mdp5_crtc->cursor.scanout_bo = cursor_bo;
+ mdp5_crtc->cursor.width = width;
+ mdp5_crtc->cursor.height = height;
+ spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
+
+ ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true);
+ if (ret)
+ goto end;
+
+ flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl);
+ crtc_flush(crtc, flush_mask);
+
+end:
+ if (old_bo) {
+ drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo);
+ /* enable vblank to complete cursor work: */
+ request_pending(crtc, PENDING_CURSOR);
+ }
+ return ret;
+}
+
+static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+ struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+ uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
+ uint32_t xres = crtc->mode.hdisplay;
+ uint32_t yres = crtc->mode.vdisplay;
+ uint32_t roi_w;
+ uint32_t roi_h;
+ unsigned long flags;
+
+ x = (x > 0) ? x : 0;
+ y = (y > 0) ? y : 0;
+
+ /*
+ * Cursor Region Of Interest (ROI) is a plane read from cursor
+ * buffer to render. The ROI region is determined by the visiblity of
+ * the cursor point. In the default Cursor image the cursor point will
+ * be at the top left of the cursor image, unless it is specified
+ * otherwise using hotspot feature.
+ *
+ * If the cursor point reaches the right (xres - x < cursor.width) or
+ * bottom (yres - y < cursor.height) boundary of the screen, then ROI
+ * width and ROI height need to be evaluated to crop the cursor image
+ * accordingly.
+ * (xres-x) will be new cursor width when x > (xres - cursor.width)
+ * (yres-y) will be new cursor height when y > (yres - cursor.height)
+ */
+ roi_w = min(mdp5_crtc->cursor.width, xres - x);
+ roi_h = min(mdp5_crtc->cursor.height, yres - y);
+
+ spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(mdp5_crtc->lm),
+ MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) |
+ MDP5_LM_CURSOR_SIZE_ROI_W(roi_w));
+ mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(mdp5_crtc->lm),
+ MDP5_LM_CURSOR_START_XY_Y_START(y) |
+ MDP5_LM_CURSOR_START_XY_X_START(x));
+ spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
+
+ crtc_flush(crtc, flush_mask);
+
+ return 0;
+}
+
static const struct drm_crtc_funcs mdp5_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp5_crtc_destroy,
@@ -392,17 +537,15 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = {
.reset = drm_atomic_helper_crtc_reset,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+ .cursor_set = mdp5_crtc_cursor_set,
+ .cursor_move = mdp5_crtc_cursor_move,
};
static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
- .dpms = mdp5_crtc_dpms,
.mode_fixup = mdp5_crtc_mode_fixup,
.mode_set_nofb = mdp5_crtc_mode_set_nofb,
- .mode_set = drm_helper_crtc_mode_set,
- .mode_set_base = drm_helper_crtc_mode_set_base,
- .prepare = mdp5_crtc_prepare,
- .commit = mdp5_crtc_commit,
- .load_lut = mdp5_crtc_load_lut,
+ .prepare = mdp5_crtc_disable,
+ .commit = mdp5_crtc_enable,
.atomic_check = mdp5_crtc_atomic_check,
.atomic_begin = mdp5_crtc_atomic_begin,
.atomic_flush = mdp5_crtc_atomic_flush,
@@ -412,6 +555,7 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
{
struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, vblank);
struct drm_crtc *crtc = &mdp5_crtc->base;
+ struct msm_drm_private *priv = crtc->dev->dev_private;
unsigned pending;
mdp_irq_unregister(&get_kms(crtc)->base, &mdp5_crtc->vblank);
@@ -421,6 +565,9 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
if (pending & PENDING_FLIP) {
complete_flip(crtc, NULL);
}
+
+ if (pending & PENDING_CURSOR)
+ drm_flip_work_commit(&mdp5_crtc->unref_cursor_work, priv->wq);
}
static void mdp5_crtc_err_irq(struct mdp_irq *irq, uint32_t irqstatus)
@@ -520,6 +667,7 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
mdp5_crtc->lm = GET_LM_ID(id);
spin_lock_init(&mdp5_crtc->lm_lock);
+ spin_lock_init(&mdp5_crtc->cursor.lock);
mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq;
mdp5_crtc->err.irq = mdp5_crtc_err_irq;
@@ -528,6 +676,10 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
pipe2name(mdp5_plane_pipe(plane)), id);
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs);
+
+ drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
+ "unref cursor", unref_cursor_worker);
+
drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs);
plane->crtc = crtc;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c
index dea4505ac963..151129032d16 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c
@@ -95,7 +95,7 @@ u32 ctl_read(struct mdp5_ctl *ctl, u32 reg)
}
-int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, enum mdp5_intf intf)
+int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, int intf)
{
unsigned long flags;
static const enum mdp5_intfnum intfnum[] = {
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h
index 1018519b6af2..ad48788efeea 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h
@@ -34,7 +34,7 @@ void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm);
*/
struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc);
-int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, enum mdp5_intf intf);
+int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, int intf);
int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
index 0254bfdeb92f..d6a14bb99988 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -110,45 +111,6 @@ static const struct drm_encoder_funcs mdp5_encoder_funcs = {
.destroy = mdp5_encoder_destroy,
};
-static void mdp5_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
- struct mdp5_kms *mdp5_kms = get_kms(encoder);
- int intf = mdp5_encoder->intf;
- bool enabled = (mode == DRM_MODE_DPMS_ON);
- unsigned long flags;
-
- DBG("mode=%d", mode);
-
- if (enabled == mdp5_encoder->enabled)
- return;
-
- if (enabled) {
- bs_set(mdp5_encoder, 1);
- spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
- mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1);
- spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
- } else {
- spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
- mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0);
- spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
-
- /*
- * Wait for a vsync so we know the ENABLE=0 latched before
- * the (connector) source of the vsync's gets disabled,
- * otherwise we end up in a funny state if we re-enable
- * before the disable latches, which results that some of
- * the settings changes for the new modeset (like new
- * scanout buffer) don't latch properly..
- */
- mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf));
-
- bs_set(mdp5_encoder, 0);
- }
-
- mdp5_encoder->enabled = enabled;
-}
-
static bool mdp5_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -162,11 +124,13 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
{
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_kms *mdp5_kms = get_kms(encoder);
+ struct drm_device *dev = encoder->dev;
+ struct drm_connector *connector;
int intf = mdp5_encoder->intf;
uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
uint32_t display_v_start, display_v_end;
uint32_t hsync_start_x, hsync_end_x;
- uint32_t format;
+ uint32_t format = 0x2100;
unsigned long flags;
mode = adjusted_mode;
@@ -188,7 +152,28 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
/* probably need to get DATA_EN polarity from panel.. */
dtv_hsync_skew = 0; /* get this from panel? */
- format = 0x213f; /* get this from panel? */
+
+ /* Get color format from panel, default is 8bpc */
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (connector->encoder == encoder) {
+ switch (connector->display_info.bpc) {
+ case 4:
+ format |= 0;
+ break;
+ case 5:
+ format |= 0x15;
+ break;
+ case 6:
+ format |= 0x2A;
+ break;
+ case 8:
+ default:
+ format |= 0x3F;
+ break;
+ }
+ break;
+ }
+ }
hsync_start_x = (mode->htotal - mode->hsync_start);
hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
@@ -198,6 +183,16 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew;
display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1;
+ /*
+ * For edp only:
+ * DISPLAY_V_START = (VBP * HCYCLE) + HBP
+ * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
+ */
+ if (mdp5_encoder->intf_id == INTF_eDP) {
+ display_v_start += mode->htotal - mode->hsync_start;
+ display_v_end -= mode->hsync_start - mode->hdisplay;
+ }
+
spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_CTL(intf),
@@ -225,25 +220,61 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
}
-static void mdp5_encoder_prepare(struct drm_encoder *encoder)
+static void mdp5_encoder_disable(struct drm_encoder *encoder)
{
- mdp5_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+ struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+ struct mdp5_kms *mdp5_kms = get_kms(encoder);
+ int intf = mdp5_encoder->intf;
+ unsigned long flags;
+
+ if (WARN_ON(!mdp5_encoder->enabled))
+ return;
+
+ spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
+ mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0);
+ spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+
+ /*
+ * Wait for a vsync so we know the ENABLE=0 latched before
+ * the (connector) source of the vsync's gets disabled,
+ * otherwise we end up in a funny state if we re-enable
+ * before the disable latches, which results that some of
+ * the settings changes for the new modeset (like new
+ * scanout buffer) don't latch properly..
+ */
+ mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf));
+
+ bs_set(mdp5_encoder, 0);
+
+ mdp5_encoder->enabled = false;
}
-static void mdp5_encoder_commit(struct drm_encoder *encoder)
+static void mdp5_encoder_enable(struct drm_encoder *encoder)
{
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+ struct mdp5_kms *mdp5_kms = get_kms(encoder);
+ int intf = mdp5_encoder->intf;
+ unsigned long flags;
+
+ if (WARN_ON(mdp5_encoder->enabled))
+ return;
+
mdp5_crtc_set_intf(encoder->crtc, mdp5_encoder->intf,
mdp5_encoder->intf_id);
- mdp5_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
+
+ bs_set(mdp5_encoder, 1);
+ spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
+ mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1);
+ spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+
+ mdp5_encoder->enabled = false;
}
static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
- .dpms = mdp5_encoder_dpms,
.mode_fixup = mdp5_encoder_mode_fixup,
.mode_set = mdp5_encoder_mode_set,
- .prepare = mdp5_encoder_prepare,
- .commit = mdp5_encoder_commit,
+ .prepare = mdp5_encoder_disable,
+ .commit = mdp5_encoder_enable,
};
/* initialize encoder */
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 9f01a4f21af2..92b61db5754c 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -68,6 +68,18 @@ static int mdp5_hw_init(struct msm_kms *kms)
return 0;
}
+static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
+{
+ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ mdp5_enable(mdp5_kms);
+}
+
+static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
+{
+ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ mdp5_disable(mdp5_kms);
+}
+
static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
struct drm_encoder *encoder)
{
@@ -115,6 +127,8 @@ static const struct mdp_kms_funcs kms_funcs = {
.irq = mdp5_irq,
.enable_vblank = mdp5_enable_vblank,
.disable_vblank = mdp5_disable_vblank,
+ .prepare_commit = mdp5_prepare_commit,
+ .complete_commit = mdp5_complete_commit,
.get_format = mdp_get_format,
.round_pixclk = mdp5_round_pixclk,
.preclose = mdp5_preclose,
@@ -208,19 +222,18 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
}
}
- /* Construct encoder for HDMI: */
- encoder = mdp5_encoder_init(dev, 3, INTF_HDMI);
- if (IS_ERR(encoder)) {
- dev_err(dev->dev, "failed to construct encoder\n");
- ret = PTR_ERR(encoder);
- goto fail;
- }
+ if (priv->hdmi) {
+ /* Construct encoder for HDMI: */
+ encoder = mdp5_encoder_init(dev, 3, INTF_HDMI);
+ if (IS_ERR(encoder)) {
+ dev_err(dev->dev, "failed to construct encoder\n");
+ ret = PTR_ERR(encoder);
+ goto fail;
+ }
- encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;;
- priv->encoders[priv->num_encoders++] = encoder;
+ encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;;
+ priv->encoders[priv->num_encoders++] = encoder;
- /* Construct bridge/connector for HDMI: */
- if (priv->hdmi) {
ret = hdmi_modeset_init(priv->hdmi, dev, encoder);
if (ret) {
dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret);
@@ -228,6 +241,27 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
}
}
+ if (priv->edp) {
+ /* Construct encoder for eDP: */
+ encoder = mdp5_encoder_init(dev, 0, INTF_eDP);
+ if (IS_ERR(encoder)) {
+ dev_err(dev->dev, "failed to construct eDP encoder\n");
+ ret = PTR_ERR(encoder);
+ goto fail;
+ }
+
+ encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
+ priv->encoders[priv->num_encoders++] = encoder;
+
+ /* Construct bridge/connector for eDP: */
+ ret = msm_edp_modeset_init(priv->edp, dev, encoder);
+ if (ret) {
+ dev_err(dev->dev, "failed to initialize eDP: %d\n",
+ ret);
+ goto fail;
+ }
+ }
+
return 0;
fail:
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index dd69c77c0d64..49d011e8835b 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -165,14 +165,25 @@ void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms);
void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms);
+static inline bool pipe_supports_yuv(enum mdp5_pipe pipe)
+{
+ switch (pipe) {
+ case SSPP_VIG0:
+ case SSPP_VIG1:
+ case SSPP_VIG2:
+ case SSPP_VIG3:
+ return true;
+ default:
+ return false;
+ }
+}
+
static inline
uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats,
uint32_t max_formats)
{
- /* TODO when we have YUV, we need to filter supported formats
- * based on pipe id..
- */
- return mdp_get_formats(pixel_formats, max_formats);
+ return mdp_get_formats(pixel_formats, max_formats,
+ !pipe_supports_yuv(pipe));
}
void mdp5_plane_install_properties(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 26e5fdea6594..05cf9ab2a876 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -18,8 +18,6 @@
#include "mdp5_kms.h"
-#define MAX_PLANE 4
-
struct mdp5_plane {
struct drm_plane base;
const char *name;
@@ -113,6 +111,7 @@ static void mdp5_plane_reset(struct drm_plane *plane)
} else {
mdp5_state->zpos = 1 + drm_plane_index(plane);
}
+ mdp5_state->base.plane = plane;
plane->state = &mdp5_state->base;
}
@@ -277,6 +276,155 @@ static void set_scanout_locked(struct drm_plane *plane,
plane->fb = fb;
}
+/* Note: mdp5_plane->pipe_lock must be locked */
+static void csc_disable(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe)
+{
+ uint32_t value = mdp5_read(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe)) &
+ ~MDP5_PIPE_OP_MODE_CSC_1_EN;
+
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe), value);
+}
+
+/* Note: mdp5_plane->pipe_lock must be locked */
+static void csc_enable(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
+ struct csc_cfg *csc)
+{
+ uint32_t i, mode = 0; /* RGB, no CSC */
+ uint32_t *matrix;
+
+ if (unlikely(!csc))
+ return;
+
+ if ((csc->type == CSC_YUV2RGB) || (CSC_YUV2YUV == csc->type))
+ mode |= MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT(DATA_FORMAT_YUV);
+ if ((csc->type == CSC_RGB2YUV) || (CSC_YUV2YUV == csc->type))
+ mode |= MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT(DATA_FORMAT_YUV);
+ mode |= MDP5_PIPE_OP_MODE_CSC_1_EN;
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe), mode);
+
+ matrix = csc->matrix;
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_0(pipe),
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11(matrix[0]) |
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12(matrix[1]));
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_1(pipe),
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13(matrix[2]) |
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21(matrix[3]));
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_2(pipe),
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22(matrix[4]) |
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23(matrix[5]));
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_3(pipe),
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31(matrix[6]) |
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32(matrix[7]));
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_4(pipe),
+ MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33(matrix[8]));
+
+ for (i = 0; i < ARRAY_SIZE(csc->pre_bias); i++) {
+ uint32_t *pre_clamp = csc->pre_clamp;
+ uint32_t *post_clamp = csc->post_clamp;
+
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_PRE_CLAMP(pipe, i),
+ MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH(pre_clamp[2*i+1]) |
+ MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW(pre_clamp[2*i]));
+
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_POST_CLAMP(pipe, i),
+ MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH(post_clamp[2*i+1]) |
+ MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW(post_clamp[2*i]));
+
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_PRE_BIAS(pipe, i),
+ MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE(csc->pre_bias[i]));
+
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_POST_BIAS(pipe, i),
+ MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE(csc->post_bias[i]));
+ }
+}
+
+#define PHASE_STEP_SHIFT 21
+#define DOWN_SCALE_RATIO_MAX 32 /* 2^(26-21) */
+
+static int calc_phase_step(uint32_t src, uint32_t dst, uint32_t *out_phase)
+{
+ uint32_t unit;
+
+ if (src == 0 || dst == 0)
+ return -EINVAL;
+
+ /*
+ * PHASE_STEP_X/Y is coded on 26 bits (25:0),
+ * where 2^21 represents the unity "1" in fixed-point hardware design.
+ * This leaves 5 bits for the integer part (downscale case):
+ * -> maximum downscale ratio = 0b1_1111 = 31
+ */
+ if (src > (dst * DOWN_SCALE_RATIO_MAX))
+ return -EOVERFLOW;
+
+ unit = 1 << PHASE_STEP_SHIFT;
+ *out_phase = mult_frac(unit, src, dst);
+
+ return 0;
+}
+
+static int calc_scalex_steps(uint32_t pixel_format, uint32_t src, uint32_t dest,
+ uint32_t phasex_steps[2])
+{
+ uint32_t phasex_step;
+ unsigned int hsub;
+ int ret;
+
+ ret = calc_phase_step(src, dest, &phasex_step);
+ if (ret)
+ return ret;
+
+ hsub = drm_format_horz_chroma_subsampling(pixel_format);
+
+ phasex_steps[0] = phasex_step;
+ phasex_steps[1] = phasex_step / hsub;
+
+ return 0;
+}
+
+static int calc_scaley_steps(uint32_t pixel_format, uint32_t src, uint32_t dest,
+ uint32_t phasey_steps[2])
+{
+ uint32_t phasey_step;
+ unsigned int vsub;
+ int ret;
+
+ ret = calc_phase_step(src, dest, &phasey_step);
+ if (ret)
+ return ret;
+
+ vsub = drm_format_vert_chroma_subsampling(pixel_format);
+
+ phasey_steps[0] = phasey_step;
+ phasey_steps[1] = phasey_step / vsub;
+
+ return 0;
+}
+
+static uint32_t get_scalex_config(uint32_t src, uint32_t dest)
+{
+ uint32_t filter;
+
+ filter = (src <= dest) ? SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
+
+ return MDP5_PIPE_SCALE_CONFIG_SCALEX_EN |
+ MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER(filter) |
+ MDP5_PIPE_SCALE_CONFIG_SCALEX_CR_FILTER(filter) |
+ MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(filter);
+}
+
+static uint32_t get_scaley_config(uint32_t src, uint32_t dest)
+{
+ uint32_t filter;
+
+ filter = (src <= dest) ? SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
+
+ return MDP5_PIPE_SCALE_CONFIG_SCALEY_EN |
+ MDP5_PIPE_SCALE_CONFIG_SCALEY_MIN_FILTER(filter) |
+ MDP5_PIPE_SCALE_CONFIG_SCALEY_CR_FILTER(filter) |
+ MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(filter);
+}
+
static int mdp5_plane_mode_set(struct drm_plane *plane,
struct drm_crtc *crtc, struct drm_framebuffer *fb,
int crtc_x, int crtc_y,
@@ -286,11 +434,14 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
{
struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
struct mdp5_kms *mdp5_kms = get_kms(plane);
+ struct device *dev = mdp5_kms->dev->dev;
enum mdp5_pipe pipe = mdp5_plane->pipe;
const struct mdp_format *format;
uint32_t nplanes, config = 0;
- uint32_t phasex_step = 0, phasey_step = 0;
+ /* below array -> index 0: comp 0/3 ; index 1: comp 1/2 */
+ uint32_t phasex_step[2] = {0,}, phasey_step[2] = {0,};
uint32_t hdecm = 0, vdecm = 0;
+ uint32_t pix_format;
unsigned long flags;
int ret;
@@ -300,6 +451,9 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
if (WARN_ON(nplanes > pipe2nclients(pipe)))
return -EINVAL;
+ format = to_mdp_format(msm_framebuffer_format(fb));
+ pix_format = format->base.pixel_format;
+
/* src values are in Q16 fixed point, convert to integer: */
src_x = src_x >> 16;
src_y = src_y >> 16;
@@ -324,14 +478,28 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
*/
mdp5_smp_configure(mdp5_kms->smp, pipe);
- if (src_w != crtc_w) {
- config |= MDP5_PIPE_SCALE_CONFIG_SCALEX_EN;
- /* TODO calc phasex_step, hdecm */
+ /* SCALE is used to both scale and up-sample chroma components */
+
+ if ((src_w != crtc_w) || MDP_FORMAT_IS_YUV(format)) {
+ /* TODO calc hdecm */
+ ret = calc_scalex_steps(pix_format, src_w, crtc_w, phasex_step);
+ if (ret) {
+ dev_err(dev, "X scaling (%d -> %d) failed: %d\n",
+ src_w, crtc_w, ret);
+ return ret;
+ }
+ config |= get_scalex_config(src_w, crtc_w);
}
- if (src_h != crtc_h) {
- config |= MDP5_PIPE_SCALE_CONFIG_SCALEY_EN;
- /* TODO calc phasey_step, vdecm */
+ if ((src_h != crtc_h) || MDP_FORMAT_IS_YUV(format)) {
+ /* TODO calc vdecm */
+ ret = calc_scaley_steps(pix_format, src_h, crtc_h, phasey_step);
+ if (ret) {
+ dev_err(dev, "Y scaling (%d -> %d) failed: %d\n",
+ src_h, crtc_h, ret);
+ return ret;
+ }
+ config |= get_scaley_config(src_h, crtc_h);
}
spin_lock_irqsave(&mdp5_plane->pipe_lock, flags);
@@ -356,8 +524,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
MDP5_PIPE_OUT_XY_X(crtc_x) |
MDP5_PIPE_OUT_XY_Y(crtc_y));
- format = to_mdp_format(msm_framebuffer_format(fb));
-
mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_FORMAT(pipe),
MDP5_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) |
MDP5_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
@@ -367,8 +533,8 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
MDP5_PIPE_SRC_FORMAT_CPP(format->cpp - 1) |
MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) |
COND(format->unpack_tight, MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT) |
- MDP5_PIPE_SRC_FORMAT_NUM_PLANES(nplanes - 1) |
- MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(CHROMA_RGB));
+ MDP5_PIPE_SRC_FORMAT_NUM_PLANES(format->fetch_type) |
+ MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample));
mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_UNPACK(pipe),
MDP5_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) |
@@ -382,18 +548,24 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
/* not using secure mode: */
mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_ADDR_SW_STATUS(pipe), 0);
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_X(pipe), phasex_step);
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(pipe), phasey_step);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_X(pipe),
+ phasex_step[0]);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(pipe),
+ phasey_step[0]);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_X(pipe),
+ phasex_step[1]);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_Y(pipe),
+ phasey_step[1]);
mdp5_write(mdp5_kms, REG_MDP5_PIPE_DECIMATION(pipe),
MDP5_PIPE_DECIMATION_VERT(vdecm) |
MDP5_PIPE_DECIMATION_HORZ(hdecm));
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CONFIG(pipe),
- MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER(SCALE_FILTER_NEAREST) |
- MDP5_PIPE_SCALE_CONFIG_SCALEY_MIN_FILTER(SCALE_FILTER_NEAREST) |
- MDP5_PIPE_SCALE_CONFIG_SCALEX_CR_FILTER(SCALE_FILTER_NEAREST) |
- MDP5_PIPE_SCALE_CONFIG_SCALEY_CR_FILTER(SCALE_FILTER_NEAREST) |
- MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(SCALE_FILTER_NEAREST) |
- MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(SCALE_FILTER_NEAREST));
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CONFIG(pipe), config);
+
+ if (MDP_FORMAT_IS_YUV(format))
+ csc_enable(mdp5_kms, pipe,
+ mdp_get_default_csc_cfg(CSC_YUV2RGB));
+ else
+ csc_disable(mdp5_kms, pipe);
set_scanout_locked(plane, fb);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
index bf551885e019..1f795af89680 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
@@ -119,9 +119,10 @@ static int smp_request_block(struct mdp5_smp *smp,
spin_lock_irqsave(&smp->state_lock, flags);
- nblks -= reserved;
- if (reserved)
+ if (reserved) {
+ nblks = max(0, nblks - reserved);
DBG("%d MMBs allocated (%d reserved)", nblks, reserved);
+ }
avail = cnt - bitmap_weight(smp->state, cnt);
if (nblks > avail) {
diff --git a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h
index 64c1afd6030a..a1d35f162c7f 100644
--- a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h
+++ b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h
@@ -8,18 +8,19 @@ http://github.com/freedreno/envytools/
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
-- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35)
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
-- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57)
+- /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00)
-Copyright (C) 2013 by the following authors:
+Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -44,6 +45,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+enum mdp_chroma_samp_type {
+ CHROMA_RGB = 0,
+ CHROMA_H2V1 = 1,
+ CHROMA_H1V2 = 2,
+ CHROMA_420 = 3,
+};
+
+enum mdp_sspp_fetch_type {
+ MDP_PLANE_INTERLEAVED = 0,
+ MDP_PLANE_PLANAR = 1,
+ MDP_PLANE_PSEUDO_PLANAR = 2,
+};
+
enum mdp_mixer_stage_id {
STAGE_UNUSED = 0,
STAGE_BASE = 1,
diff --git a/drivers/gpu/drm/msm/mdp/mdp_format.c b/drivers/gpu/drm/msm/mdp/mdp_format.c
index e0a6ffbe6ab4..f683433b6727 100644
--- a/drivers/gpu/drm/msm/mdp/mdp_format.c
+++ b/drivers/gpu/drm/msm/mdp/mdp_format.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -19,7 +20,58 @@
#include "msm_drv.h"
#include "mdp_kms.h"
-#define FMT(name, a, r, g, b, e0, e1, e2, e3, alpha, tight, c, cnt) { \
+static struct csc_cfg csc_convert[CSC_MAX] = {
+ [CSC_RGB2RGB] = {
+ .type = CSC_RGB2RGB,
+ .matrix = {
+ 0x0200, 0x0000, 0x0000,
+ 0x0000, 0x0200, 0x0000,
+ 0x0000, 0x0000, 0x0200
+ },
+ .pre_bias = { 0x0, 0x0, 0x0 },
+ .post_bias = { 0x0, 0x0, 0x0 },
+ .pre_clamp = { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff },
+ .post_clamp = { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff },
+ },
+ [CSC_YUV2RGB] = {
+ .type = CSC_YUV2RGB,
+ .matrix = {
+ 0x0254, 0x0000, 0x0331,
+ 0x0254, 0xff37, 0xfe60,
+ 0x0254, 0x0409, 0x0000
+ },
+ .pre_bias = { 0xfff0, 0xff80, 0xff80 },
+ .post_bias = { 0x00, 0x00, 0x00 },
+ .pre_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+ .post_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+ },
+ [CSC_RGB2YUV] = {
+ .type = CSC_RGB2YUV,
+ .matrix = {
+ 0x0083, 0x0102, 0x0032,
+ 0x1fb5, 0x1f6c, 0x00e1,
+ 0x00e1, 0x1f45, 0x1fdc
+ },
+ .pre_bias = { 0x00, 0x00, 0x00 },
+ .post_bias = { 0x10, 0x80, 0x80 },
+ .pre_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+ .post_clamp = { 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0 },
+ },
+ [CSC_YUV2YUV] = {
+ .type = CSC_YUV2YUV,
+ .matrix = {
+ 0x0200, 0x0000, 0x0000,
+ 0x0000, 0x0200, 0x0000,
+ 0x0000, 0x0000, 0x0200
+ },
+ .pre_bias = { 0x00, 0x00, 0x00 },
+ .post_bias = { 0x00, 0x00, 0x00 },
+ .pre_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+ .post_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+ },
+};
+
+#define FMT(name, a, r, g, b, e0, e1, e2, e3, alpha, tight, c, cnt, fp, cs) { \
.base = { .pixel_format = DRM_FORMAT_ ## name }, \
.bpc_a = BPC ## a ## A, \
.bpc_r = BPC ## r, \
@@ -30,21 +82,46 @@
.unpack_tight = tight, \
.cpp = c, \
.unpack_count = cnt, \
- }
+ .fetch_type = fp, \
+ .chroma_sample = cs \
+}
#define BPC0A 0
+/*
+ * Note: Keep RGB formats 1st, followed by YUV formats to avoid breaking
+ * mdp_get_rgb_formats()'s implementation.
+ */
static const struct mdp_format formats[] = {
- /* name a r g b e0 e1 e2 e3 alpha tight cpp cnt */
- FMT(ARGB8888, 8, 8, 8, 8, 1, 0, 2, 3, true, true, 4, 4),
- FMT(XRGB8888, 8, 8, 8, 8, 1, 0, 2, 3, false, true, 4, 4),
- FMT(RGB888, 0, 8, 8, 8, 1, 0, 2, 0, false, true, 3, 3),
- FMT(BGR888, 0, 8, 8, 8, 2, 0, 1, 0, false, true, 3, 3),
- FMT(RGB565, 0, 5, 6, 5, 1, 0, 2, 0, false, true, 2, 3),
- FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3),
+ /* name a r g b e0 e1 e2 e3 alpha tight cpp cnt ... */
+ FMT(ARGB8888, 8, 8, 8, 8, 1, 0, 2, 3, true, true, 4, 4,
+ MDP_PLANE_INTERLEAVED, CHROMA_RGB),
+ FMT(XRGB8888, 8, 8, 8, 8, 1, 0, 2, 3, false, true, 4, 4,
+ MDP_PLANE_INTERLEAVED, CHROMA_RGB),
+ FMT(RGB888, 0, 8, 8, 8, 1, 0, 2, 0, false, true, 3, 3,
+ MDP_PLANE_INTERLEAVED, CHROMA_RGB),
+ FMT(BGR888, 0, 8, 8, 8, 2, 0, 1, 0, false, true, 3, 3,
+ MDP_PLANE_INTERLEAVED, CHROMA_RGB),
+ FMT(RGB565, 0, 5, 6, 5, 1, 0, 2, 0, false, true, 2, 3,
+ MDP_PLANE_INTERLEAVED, CHROMA_RGB),
+ FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3,
+ MDP_PLANE_INTERLEAVED, CHROMA_RGB),
+
+ /* --- RGB formats above / YUV formats below this line --- */
+
+ FMT(NV12, 0, 8, 8, 8, 1, 2, 0, 0, false, true, 2, 2,
+ MDP_PLANE_PSEUDO_PLANAR, CHROMA_420),
+ FMT(NV21, 0, 8, 8, 8, 2, 1, 0, 0, false, true, 2, 2,
+ MDP_PLANE_PSEUDO_PLANAR, CHROMA_420),
};
-uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats)
+/*
+ * Note:
+ * @rgb_only must be set to true, when requesting
+ * supported formats for RGB pipes.
+ */
+uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats,
+ bool rgb_only)
{
uint32_t i;
for (i = 0; i < ARRAY_SIZE(formats); i++) {
@@ -53,6 +130,9 @@ uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats)
if (i == max_formats)
break;
+ if (rgb_only && MDP_FORMAT_IS_YUV(f))
+ break;
+
pixel_formats[i] = f->base.pixel_format;
}
@@ -69,3 +149,11 @@ const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format)
}
return NULL;
}
+
+struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type type)
+{
+ if (unlikely(WARN_ON(type >= CSC_MAX)))
+ return NULL;
+
+ return &csc_convert[type];
+}
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.c b/drivers/gpu/drm/msm/mdp/mdp_kms.c
index 2a731722d840..1988c243f437 100644
--- a/drivers/gpu/drm/msm/mdp/mdp_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp_kms.c
@@ -34,7 +34,7 @@ static void update_irq(struct mdp_kms *mdp_kms)
struct mdp_irq *irq;
uint32_t irqmask = mdp_kms->vblank_mask;
- BUG_ON(!spin_is_locked(&list_lock));
+ assert_spin_locked(&list_lock);
list_for_each_entry(irq, &mdp_kms->irq_list, node)
irqmask |= irq->irqmask;
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.h b/drivers/gpu/drm/msm/mdp/mdp_kms.h
index b268ce95d394..5ae4039d68e4 100644
--- a/drivers/gpu/drm/msm/mdp/mdp_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp_kms.h
@@ -88,10 +88,32 @@ struct mdp_format {
uint8_t unpack[4];
bool alpha_enable, unpack_tight;
uint8_t cpp, unpack_count;
+ enum mdp_sspp_fetch_type fetch_type;
+ enum mdp_chroma_samp_type chroma_sample;
};
#define to_mdp_format(x) container_of(x, struct mdp_format, base)
+#define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->chroma_sample > CHROMA_RGB)
-uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats);
+uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format);
+enum csc_type {
+ CSC_RGB2RGB = 0,
+ CSC_YUV2RGB,
+ CSC_RGB2YUV,
+ CSC_YUV2YUV,
+ CSC_MAX
+};
+
+struct csc_cfg {
+ enum csc_type type;
+ uint32_t matrix[9];
+ uint32_t pre_bias[3];
+ uint32_t post_bias[3];
+ uint32_t pre_clamp[6];
+ uint32_t post_clamp[6];
+};
+
+struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type);
+
#endif /* __MDP_KMS_H__ */
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 191968256c58..871aa2108dc6 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -20,6 +20,7 @@
#include "msm_gem.h"
struct msm_commit {
+ struct drm_device *dev;
struct drm_atomic_state *state;
uint32_t fence;
struct msm_fence_cb fence_cb;
@@ -58,14 +59,16 @@ static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask)
spin_unlock(&priv->pending_crtcs_event.lock);
}
-static struct msm_commit *new_commit(struct drm_atomic_state *state)
+static struct msm_commit *commit_init(struct drm_atomic_state *state)
{
struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
return NULL;
+ c->dev = state->dev;
c->state = state;
+
/* TODO we might need a way to indicate to run the cb on a
* different wq so wait_for_vblanks() doesn't block retiring
* bo's..
@@ -75,6 +78,12 @@ static struct msm_commit *new_commit(struct drm_atomic_state *state)
return c;
}
+static void commit_destroy(struct msm_commit *c)
+{
+ end_atomic(c->dev->dev_private, c->crtc_mask);
+ kfree(c);
+}
+
/* The (potentially) asynchronous part of the commit. At this point
* nothing can fail short of armageddon.
*/
@@ -82,6 +91,10 @@ static void complete_commit(struct msm_commit *c)
{
struct drm_atomic_state *state = c->state;
struct drm_device *dev = state->dev;
+ struct msm_drm_private *priv = dev->dev_private;
+ struct msm_kms *kms = priv->kms;
+
+ kms->funcs->prepare_commit(kms, state);
drm_atomic_helper_commit_pre_planes(dev, state);
@@ -106,11 +119,11 @@ static void complete_commit(struct msm_commit *c)
drm_atomic_helper_cleanup_planes(dev, state);
- drm_atomic_state_free(state);
+ kms->funcs->complete_commit(kms, state);
- end_atomic(dev->dev_private, c->crtc_mask);
+ drm_atomic_state_free(state);
- kfree(c);
+ commit_destroy(c);
}
static void fence_cb(struct msm_fence_cb *cb)
@@ -127,6 +140,26 @@ static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb)
}
+int msm_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ int ret;
+
+ /*
+ * msm ->atomic_check can update ->mode_changed for pixel format
+ * changes, hence must be run before we check the modeset changes.
+ */
+ ret = drm_atomic_helper_check_planes(dev, state);
+ if (ret)
+ return ret;
+
+ ret = drm_atomic_helper_check_modeset(dev, state);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
/**
* drm_atomic_helper_commit - commit validated state object
* @dev: DRM device
@@ -145,6 +178,7 @@ int msm_atomic_commit(struct drm_device *dev,
{
int nplanes = dev->mode_config.num_total_plane;
int ncrtcs = dev->mode_config.num_crtc;
+ struct timespec timeout;
struct msm_commit *c;
int i, ret;
@@ -152,7 +186,7 @@ int msm_atomic_commit(struct drm_device *dev,
if (ret)
return ret;
- c = new_commit(state);
+ c = commit_init(state);
if (!c)
return -ENOMEM;
@@ -217,10 +251,12 @@ int msm_atomic_commit(struct drm_device *dev,
return 0;
}
- ret = msm_wait_fence_interruptable(dev, c->fence, NULL);
+ jiffies_to_timespec(jiffies + msecs_to_jiffies(1000), &timeout);
+
+ ret = msm_wait_fence_interruptable(dev, c->fence, &timeout);
if (ret) {
WARN_ON(ret); // TODO unswap state back? or??
- kfree(c);
+ commit_destroy(c);
return ret;
}
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9a61546a0b05..a4269119f9ea 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -29,7 +29,7 @@ static void msm_fb_output_poll_changed(struct drm_device *dev)
static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = msm_framebuffer_create,
.output_poll_changed = msm_fb_output_poll_changed,
- .atomic_check = drm_atomic_helper_check,
+ .atomic_check = msm_atomic_check,
.atomic_commit = msm_atomic_commit,
};
@@ -54,6 +54,12 @@ module_param(reglog, bool, 0600);
#define reglog 0
#endif
+#ifdef CONFIG_DRM_MSM_FBDEV
+static bool fbdev = true;
+MODULE_PARM_DESC(fbdev, "Enable fbdev compat layer");
+module_param(fbdev, bool, 0600);
+#endif
+
static char *vram = "16m";
MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU");
module_param(vram, charp, 0);
@@ -300,7 +306,8 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
drm_mode_config_reset(dev);
#ifdef CONFIG_DRM_MSM_FBDEV
- priv->fbdev = msm_fbdev_init(dev);
+ if (fbdev)
+ priv->fbdev = msm_fbdev_init(dev);
#endif
ret = msm_debugfs_late_init(dev);
@@ -1023,6 +1030,7 @@ static struct platform_driver msm_platform_driver = {
static int __init msm_drm_register(void)
{
DBG("init");
+ msm_edp_register();
hdmi_register();
adreno_register();
return platform_driver_register(&msm_platform_driver);
@@ -1034,6 +1042,7 @@ static void __exit msm_drm_unregister(void)
platform_driver_unregister(&msm_platform_driver);
hdmi_unregister();
adreno_unregister();
+ msm_edp_unregister();
}
module_init(msm_drm_register);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index b69ef2d5a26c..9e8d441b61c3 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -76,6 +76,12 @@ struct msm_drm_private {
*/
struct hdmi *hdmi;
+ /* eDP is for mdp5 only, but kms has not been created
+ * when edp_bind() and edp_init() are called. Here is the only
+ * place to keep the edp instance.
+ */
+ struct msm_edp *edp;
+
/* when we have more than one 'msm_gpu' these need to be an array: */
struct msm_gpu *gpu;
struct msm_file_private *lastctx;
@@ -148,6 +154,8 @@ void __msm_fence_worker(struct work_struct *work);
(_cb)->func = _func; \
} while (0)
+int msm_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state);
int msm_atomic_commit(struct drm_device *dev,
struct drm_atomic_state *state, bool async);
@@ -222,6 +230,12 @@ int hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
void __init hdmi_register(void);
void __exit hdmi_unregister(void);
+struct msm_edp;
+void __init msm_edp_register(void);
+void __exit msm_edp_unregister(void);
+int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev,
+ struct drm_encoder *encoder);
+
#ifdef CONFIG_DEBUG_FS
void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 84dec161d836..6b573e612f27 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -24,7 +24,7 @@
struct msm_framebuffer {
struct drm_framebuffer base;
const struct msm_format *format;
- struct drm_gem_object *planes[3];
+ struct drm_gem_object *planes[MAX_PLANE];
};
#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
@@ -122,7 +122,7 @@ uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane)
struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
if (!msm_fb->planes[plane])
return 0;
- return msm_gem_iova(msm_fb->planes[plane], id);
+ return msm_gem_iova(msm_fb->planes[plane], id) + fb->offsets[plane];
}
struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane)
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 1f3af13ccede..df60f65728ff 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -241,17 +241,20 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
goto fail;
}
- drm_fb_helper_single_add_all_connectors(helper);
+ ret = drm_fb_helper_single_add_all_connectors(helper);
+ if (ret)
+ goto fini;
- /* disable all the possible outputs/crtcs before entering KMS mode */
- drm_helper_disable_unused_functions(dev);
-
- drm_fb_helper_initial_config(helper, 32);
+ ret = drm_fb_helper_initial_config(helper, 32);
+ if (ret)
+ goto fini;
priv->fbdev = helper;
return helper;
+fini:
+ drm_fb_helper_fini(helper);
fail:
kfree(fbdev);
return NULL;
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 06437745bc2c..3a78cb48662b 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -23,6 +23,8 @@
#include "msm_drv.h"
+#define MAX_PLANE 4
+
/* As there are different display controller blocks depending on the
* snapdragon version, the kms support is split out and the appropriate
* implementation is loaded at runtime. The kms module is responsible
@@ -38,6 +40,9 @@ struct msm_kms_funcs {
irqreturn_t (*irq)(struct msm_kms *kms);
int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
+ /* modeset, bracketing atomic_commit(): */
+ void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state);
+ void (*complete_commit)(struct msm_kms *kms, struct drm_atomic_state *state);
/* misc: */
const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format);
long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild
new file mode 100644
index 000000000000..2b765663c1a3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/Kbuild
@@ -0,0 +1,66 @@
+ccflags-y := -Iinclude/drm
+ccflags-y += -I$(src)/include
+ccflags-y += -I$(src)/include/nvkm
+ccflags-y += -I$(src)/nvkm
+ccflags-y += -I$(src)
+
+# NVKM - HW resource manager
+#- code also used by various userspace tools/tests
+include $(src)/nvif/Kbuild
+nouveau-y := $(nvif-y)
+
+# NVIF - NVKM interface library (NVKM user interface also defined here)
+#- code also used by various userspace tools/tests
+include $(src)/nvkm/Kbuild
+nouveau-y += $(nvkm-y)
+
+# DRM - general
+ifdef CONFIG_X86
+nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
+endif
+nouveau-y += nouveau_agp.o
+nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
+nouveau-y += nouveau_drm.o
+nouveau-y += nouveau_hwmon.o
+nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
+nouveau-y += nouveau_nvif.o
+nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
+nouveau-y += nouveau_sysfs.o
+nouveau-y += nouveau_usif.o # userspace <-> nvif
+nouveau-y += nouveau_vga.o
+
+# DRM - memory management
+nouveau-y += nouveau_bo.o
+nouveau-y += nouveau_gem.o
+nouveau-y += nouveau_prime.o
+nouveau-y += nouveau_sgdma.o
+nouveau-y += nouveau_ttm.o
+
+# DRM - modesetting
+nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
+nouveau-y += nouveau_connector.o
+nouveau-y += nouveau_display.o
+nouveau-y += nv50_display.o
+nouveau-y += nouveau_dp.o
+nouveau-y += nouveau_fbcon.o
+nouveau-y += nv04_fbcon.o
+nouveau-y += nv50_fbcon.o
+nouveau-y += nvc0_fbcon.o
+
+# DRM - command submission
+nouveau-y += nouveau_abi16.o
+nouveau-y += nouveau_chan.o
+nouveau-y += nouveau_dma.o
+nouveau-y += nouveau_fence.o
+nouveau-y += nv04_fence.o
+nouveau-y += nv10_fence.o
+nouveau-y += nv17_fence.o
+nouveau-y += nv50_fence.o
+nouveau-y += nv84_fence.o
+nouveau-y += nvc0_fence.o
+
+# DRM - prehistoric modesetting (NV04-G7x)
+nouveau-y += nouveau_bios.o
+include $(src)/dispnv04/Kbuild
+
+obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 40afc69a3778..5ab13e7939db 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -26,7 +26,7 @@ config DRM_NOUVEAU
Choose this option for open-source NVIDIA support.
config NOUVEAU_PLATFORM_DRIVER
- tristate "Nouveau (NVIDIA) SoC GPUs"
+ bool "Nouveau (NVIDIA) SoC GPUs"
depends on DRM_NOUVEAU && ARCH_TEGRA
default y
help
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
deleted file mode 100644
index 6461e3565afe..000000000000
--- a/drivers/gpu/drm/nouveau/Makefile
+++ /dev/null
@@ -1,400 +0,0 @@
-#
-# Makefile for the drm device driver. This driver provides support for the
-# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
-
-ccflags-y := -Iinclude/drm
-ccflags-y += -I$(src)/core/include
-ccflags-y += -I$(src)/core
-ccflags-y += -I$(src)
-
-nouveau-y := core/core/client.o
-nouveau-y += core/core/engctx.o
-nouveau-y += core/core/engine.o
-nouveau-y += core/core/enum.o
-nouveau-y += core/core/event.o
-nouveau-y += core/core/gpuobj.o
-nouveau-y += core/core/handle.o
-nouveau-y += core/core/ioctl.o
-nouveau-y += core/core/mm.o
-nouveau-y += core/core/namedb.o
-nouveau-y += core/core/notify.o
-nouveau-y += core/core/object.o
-nouveau-y += core/core/option.o
-nouveau-y += core/core/parent.o
-nouveau-y += core/core/printk.o
-nouveau-y += core/core/ramht.o
-nouveau-y += core/core/subdev.o
-
-nouveau-y += core/subdev/bar/base.o
-nouveau-y += core/subdev/bar/nv50.o
-nouveau-y += core/subdev/bar/nvc0.o
-nouveau-y += core/subdev/bar/gk20a.o
-nouveau-y += core/subdev/bios/base.o
-nouveau-y += core/subdev/bios/bit.o
-nouveau-y += core/subdev/bios/boost.o
-nouveau-y += core/subdev/bios/conn.o
-nouveau-y += core/subdev/bios/cstep.o
-nouveau-y += core/subdev/bios/dcb.o
-nouveau-y += core/subdev/bios/disp.o
-nouveau-y += core/subdev/bios/dp.o
-nouveau-y += core/subdev/bios/extdev.o
-nouveau-y += core/subdev/bios/fan.o
-nouveau-y += core/subdev/bios/gpio.o
-nouveau-y += core/subdev/bios/i2c.o
-nouveau-y += core/subdev/bios/image.o
-nouveau-y += core/subdev/bios/init.o
-nouveau-y += core/subdev/bios/mxm.o
-nouveau-y += core/subdev/bios/npde.o
-nouveau-y += core/subdev/bios/pcir.o
-nouveau-y += core/subdev/bios/perf.o
-nouveau-y += core/subdev/bios/pll.o
-nouveau-y += core/subdev/bios/pmu.o
-nouveau-y += core/subdev/bios/ramcfg.o
-nouveau-y += core/subdev/bios/rammap.o
-nouveau-y += core/subdev/bios/shadow.o
-nouveau-y += core/subdev/bios/shadowacpi.o
-nouveau-y += core/subdev/bios/shadowof.o
-nouveau-y += core/subdev/bios/shadowpci.o
-nouveau-y += core/subdev/bios/shadowramin.o
-nouveau-y += core/subdev/bios/shadowrom.o
-nouveau-y += core/subdev/bios/timing.o
-nouveau-y += core/subdev/bios/therm.o
-nouveau-y += core/subdev/bios/vmap.o
-nouveau-y += core/subdev/bios/volt.o
-nouveau-y += core/subdev/bios/xpio.o
-nouveau-y += core/subdev/bios/M0203.o
-nouveau-y += core/subdev/bios/M0205.o
-nouveau-y += core/subdev/bios/M0209.o
-nouveau-y += core/subdev/bios/P0260.o
-nouveau-y += core/subdev/bus/hwsq.o
-nouveau-y += core/subdev/bus/nv04.o
-nouveau-y += core/subdev/bus/nv31.o
-nouveau-y += core/subdev/bus/nv50.o
-nouveau-y += core/subdev/bus/nv94.o
-nouveau-y += core/subdev/bus/nvc0.o
-nouveau-y += core/subdev/clock/base.o
-nouveau-y += core/subdev/clock/nv04.o
-nouveau-y += core/subdev/clock/nv40.o
-nouveau-y += core/subdev/clock/nv50.o
-nouveau-y += core/subdev/clock/nv84.o
-nouveau-y += core/subdev/clock/nva3.o
-nouveau-y += core/subdev/clock/nvaa.o
-nouveau-y += core/subdev/clock/nvc0.o
-nouveau-y += core/subdev/clock/nve0.o
-nouveau-y += core/subdev/clock/gk20a.o
-nouveau-y += core/subdev/clock/pllnv04.o
-nouveau-y += core/subdev/clock/pllnva3.o
-nouveau-y += core/subdev/devinit/base.o
-nouveau-y += core/subdev/devinit/nv04.o
-nouveau-y += core/subdev/devinit/nv05.o
-nouveau-y += core/subdev/devinit/nv10.o
-nouveau-y += core/subdev/devinit/nv1a.o
-nouveau-y += core/subdev/devinit/nv20.o
-nouveau-y += core/subdev/devinit/nv50.o
-nouveau-y += core/subdev/devinit/nv84.o
-nouveau-y += core/subdev/devinit/nv98.o
-nouveau-y += core/subdev/devinit/nva3.o
-nouveau-y += core/subdev/devinit/nvaf.o
-nouveau-y += core/subdev/devinit/nvc0.o
-nouveau-y += core/subdev/devinit/gm107.o
-nouveau-y += core/subdev/devinit/gm204.o
-nouveau-y += core/subdev/fb/base.o
-nouveau-y += core/subdev/fb/nv04.o
-nouveau-y += core/subdev/fb/nv10.o
-nouveau-y += core/subdev/fb/nv1a.o
-nouveau-y += core/subdev/fb/nv20.o
-nouveau-y += core/subdev/fb/nv25.o
-nouveau-y += core/subdev/fb/nv30.o
-nouveau-y += core/subdev/fb/nv35.o
-nouveau-y += core/subdev/fb/nv36.o
-nouveau-y += core/subdev/fb/nv40.o
-nouveau-y += core/subdev/fb/nv41.o
-nouveau-y += core/subdev/fb/nv44.o
-nouveau-y += core/subdev/fb/nv46.o
-nouveau-y += core/subdev/fb/nv47.o
-nouveau-y += core/subdev/fb/nv49.o
-nouveau-y += core/subdev/fb/nv4e.o
-nouveau-y += core/subdev/fb/nv50.o
-nouveau-y += core/subdev/fb/nv84.o
-nouveau-y += core/subdev/fb/nva3.o
-nouveau-y += core/subdev/fb/nvaa.o
-nouveau-y += core/subdev/fb/nvaf.o
-nouveau-y += core/subdev/fb/nvc0.o
-nouveau-y += core/subdev/fb/nve0.o
-nouveau-y += core/subdev/fb/gk20a.o
-nouveau-y += core/subdev/fb/gm107.o
-nouveau-y += core/subdev/fb/ramnv04.o
-nouveau-y += core/subdev/fb/ramnv10.o
-nouveau-y += core/subdev/fb/ramnv1a.o
-nouveau-y += core/subdev/fb/ramnv20.o
-nouveau-y += core/subdev/fb/ramnv40.o
-nouveau-y += core/subdev/fb/ramnv41.o
-nouveau-y += core/subdev/fb/ramnv44.o
-nouveau-y += core/subdev/fb/ramnv49.o
-nouveau-y += core/subdev/fb/ramnv4e.o
-nouveau-y += core/subdev/fb/ramnv50.o
-nouveau-y += core/subdev/fb/ramnva3.o
-nouveau-y += core/subdev/fb/ramnvaa.o
-nouveau-y += core/subdev/fb/ramnvc0.o
-nouveau-y += core/subdev/fb/ramnve0.o
-nouveau-y += core/subdev/fb/ramgk20a.o
-nouveau-y += core/subdev/fb/ramgm107.o
-nouveau-y += core/subdev/fb/sddr2.o
-nouveau-y += core/subdev/fb/sddr3.o
-nouveau-y += core/subdev/fb/gddr3.o
-nouveau-y += core/subdev/fb/gddr5.o
-nouveau-y += core/subdev/fuse/base.o
-nouveau-y += core/subdev/fuse/g80.o
-nouveau-y += core/subdev/fuse/gf100.o
-nouveau-y += core/subdev/fuse/gm107.o
-nouveau-y += core/subdev/gpio/base.o
-nouveau-y += core/subdev/gpio/nv10.o
-nouveau-y += core/subdev/gpio/nv50.o
-nouveau-y += core/subdev/gpio/nv94.o
-nouveau-y += core/subdev/gpio/nvd0.o
-nouveau-y += core/subdev/gpio/nve0.o
-nouveau-y += core/subdev/i2c/base.o
-nouveau-y += core/subdev/i2c/anx9805.o
-nouveau-y += core/subdev/i2c/aux.o
-nouveau-y += core/subdev/i2c/bit.o
-nouveau-y += core/subdev/i2c/pad.o
-nouveau-y += core/subdev/i2c/padnv04.o
-nouveau-y += core/subdev/i2c/padnv94.o
-nouveau-y += core/subdev/i2c/padgm204.o
-nouveau-y += core/subdev/i2c/nv04.o
-nouveau-y += core/subdev/i2c/nv4e.o
-nouveau-y += core/subdev/i2c/nv50.o
-nouveau-y += core/subdev/i2c/nv94.o
-nouveau-y += core/subdev/i2c/nvd0.o
-nouveau-y += core/subdev/i2c/gf117.o
-nouveau-y += core/subdev/i2c/nve0.o
-nouveau-y += core/subdev/i2c/gm204.o
-nouveau-y += core/subdev/ibus/nvc0.o
-nouveau-y += core/subdev/ibus/nve0.o
-nouveau-y += core/subdev/ibus/gk20a.o
-nouveau-y += core/subdev/instmem/base.o
-nouveau-y += core/subdev/instmem/nv04.o
-nouveau-y += core/subdev/instmem/nv40.o
-nouveau-y += core/subdev/instmem/nv50.o
-nouveau-y += core/subdev/ltc/base.o
-nouveau-y += core/subdev/ltc/gf100.o
-nouveau-y += core/subdev/ltc/gk104.o
-nouveau-y += core/subdev/ltc/gm107.o
-nouveau-y += core/subdev/mc/base.o
-nouveau-y += core/subdev/mc/nv04.o
-nouveau-y += core/subdev/mc/nv40.o
-nouveau-y += core/subdev/mc/nv44.o
-nouveau-y += core/subdev/mc/nv4c.o
-nouveau-y += core/subdev/mc/nv50.o
-nouveau-y += core/subdev/mc/nv94.o
-nouveau-y += core/subdev/mc/nv98.o
-nouveau-y += core/subdev/mc/nvc0.o
-nouveau-y += core/subdev/mc/nvc3.o
-nouveau-y += core/subdev/mc/gk20a.o
-nouveau-y += core/subdev/mxm/base.o
-nouveau-y += core/subdev/mxm/mxms.o
-nouveau-y += core/subdev/mxm/nv50.o
-nouveau-y += core/subdev/pwr/base.o
-nouveau-y += core/subdev/pwr/memx.o
-nouveau-y += core/subdev/pwr/nva3.o
-nouveau-y += core/subdev/pwr/nvc0.o
-nouveau-y += core/subdev/pwr/nvd0.o
-nouveau-y += core/subdev/pwr/gk104.o
-nouveau-y += core/subdev/pwr/nv108.o
-nouveau-y += core/subdev/therm/base.o
-nouveau-y += core/subdev/therm/fan.o
-nouveau-y += core/subdev/therm/fannil.o
-nouveau-y += core/subdev/therm/fanpwm.o
-nouveau-y += core/subdev/therm/fantog.o
-nouveau-y += core/subdev/therm/ic.o
-nouveau-y += core/subdev/therm/temp.o
-nouveau-y += core/subdev/therm/nv40.o
-nouveau-y += core/subdev/therm/nv50.o
-nouveau-y += core/subdev/therm/nv84.o
-nouveau-y += core/subdev/therm/nva3.o
-nouveau-y += core/subdev/therm/nvd0.o
-nouveau-y += core/subdev/therm/gm107.o
-nouveau-y += core/subdev/timer/base.o
-nouveau-y += core/subdev/timer/nv04.o
-nouveau-y += core/subdev/timer/gk20a.o
-nouveau-y += core/subdev/vm/base.o
-nouveau-y += core/subdev/vm/nv04.o
-nouveau-y += core/subdev/vm/nv41.o
-nouveau-y += core/subdev/vm/nv44.o
-nouveau-y += core/subdev/vm/nv50.o
-nouveau-y += core/subdev/vm/nvc0.o
-nouveau-y += core/subdev/volt/base.o
-nouveau-y += core/subdev/volt/gpio.o
-nouveau-y += core/subdev/volt/nv40.o
-nouveau-y += core/subdev/volt/gk20a.o
-
-nouveau-y += core/engine/falcon.o
-nouveau-y += core/engine/xtensa.o
-nouveau-y += core/engine/dmaobj/base.o
-nouveau-y += core/engine/dmaobj/nv04.o
-nouveau-y += core/engine/dmaobj/nv50.o
-nouveau-y += core/engine/dmaobj/nvc0.o
-nouveau-y += core/engine/dmaobj/nvd0.o
-nouveau-y += core/engine/bsp/nv84.o
-nouveau-y += core/engine/bsp/nv98.o
-nouveau-y += core/engine/bsp/nvc0.o
-nouveau-y += core/engine/bsp/nve0.o
-nouveau-y += core/engine/copy/nva3.o
-nouveau-y += core/engine/copy/nvc0.o
-nouveau-y += core/engine/copy/nve0.o
-nouveau-y += core/engine/crypt/nv84.o
-nouveau-y += core/engine/crypt/nv98.o
-nouveau-y += core/engine/device/acpi.o
-nouveau-y += core/engine/device/base.o
-nouveau-y += core/engine/device/ctrl.o
-nouveau-y += core/engine/device/nv04.o
-nouveau-y += core/engine/device/nv10.o
-nouveau-y += core/engine/device/nv20.o
-nouveau-y += core/engine/device/nv30.o
-nouveau-y += core/engine/device/nv40.o
-nouveau-y += core/engine/device/nv50.o
-nouveau-y += core/engine/device/nvc0.o
-nouveau-y += core/engine/device/nve0.o
-nouveau-y += core/engine/device/gm100.o
-nouveau-y += core/engine/disp/base.o
-nouveau-y += core/engine/disp/conn.o
-nouveau-y += core/engine/disp/outp.o
-nouveau-y += core/engine/disp/outpdp.o
-nouveau-y += core/engine/disp/nv04.o
-nouveau-y += core/engine/disp/nv50.o
-nouveau-y += core/engine/disp/nv84.o
-nouveau-y += core/engine/disp/nv94.o
-nouveau-y += core/engine/disp/nva0.o
-nouveau-y += core/engine/disp/nva3.o
-nouveau-y += core/engine/disp/nvd0.o
-nouveau-y += core/engine/disp/nve0.o
-nouveau-y += core/engine/disp/nvf0.o
-nouveau-y += core/engine/disp/gm107.o
-nouveau-y += core/engine/disp/gm204.o
-nouveau-y += core/engine/disp/dacnv50.o
-nouveau-y += core/engine/disp/dport.o
-nouveau-y += core/engine/disp/hdanva3.o
-nouveau-y += core/engine/disp/hdanvd0.o
-nouveau-y += core/engine/disp/hdminv84.o
-nouveau-y += core/engine/disp/hdminva3.o
-nouveau-y += core/engine/disp/hdminvd0.o
-nouveau-y += core/engine/disp/hdminve0.o
-nouveau-y += core/engine/disp/piornv50.o
-nouveau-y += core/engine/disp/sornv50.o
-nouveau-y += core/engine/disp/sornv94.o
-nouveau-y += core/engine/disp/sornvd0.o
-nouveau-y += core/engine/disp/sorgm204.o
-nouveau-y += core/engine/disp/vga.o
-nouveau-y += core/engine/fifo/base.o
-nouveau-y += core/engine/fifo/nv04.o
-nouveau-y += core/engine/fifo/nv10.o
-nouveau-y += core/engine/fifo/nv17.o
-nouveau-y += core/engine/fifo/nv40.o
-nouveau-y += core/engine/fifo/nv50.o
-nouveau-y += core/engine/fifo/nv84.o
-nouveau-y += core/engine/fifo/nvc0.o
-nouveau-y += core/engine/fifo/nve0.o
-nouveau-y += core/engine/fifo/gk20a.o
-nouveau-y += core/engine/fifo/nv108.o
-nouveau-y += core/engine/graph/ctxnv40.o
-nouveau-y += core/engine/graph/ctxnv50.o
-nouveau-y += core/engine/graph/ctxnvc0.o
-nouveau-y += core/engine/graph/ctxnvc1.o
-nouveau-y += core/engine/graph/ctxnvc4.o
-nouveau-y += core/engine/graph/ctxnvc8.o
-nouveau-y += core/engine/graph/ctxnvd7.o
-nouveau-y += core/engine/graph/ctxnvd9.o
-nouveau-y += core/engine/graph/ctxnve4.o
-nouveau-y += core/engine/graph/ctxgk20a.o
-nouveau-y += core/engine/graph/ctxnvf0.o
-nouveau-y += core/engine/graph/ctxgk110b.o
-nouveau-y += core/engine/graph/ctxnv108.o
-nouveau-y += core/engine/graph/ctxgm107.o
-nouveau-y += core/engine/graph/nv04.o
-nouveau-y += core/engine/graph/nv10.o
-nouveau-y += core/engine/graph/nv20.o
-nouveau-y += core/engine/graph/nv25.o
-nouveau-y += core/engine/graph/nv2a.o
-nouveau-y += core/engine/graph/nv30.o
-nouveau-y += core/engine/graph/nv34.o
-nouveau-y += core/engine/graph/nv35.o
-nouveau-y += core/engine/graph/nv40.o
-nouveau-y += core/engine/graph/nv50.o
-nouveau-y += core/engine/graph/nvc0.o
-nouveau-y += core/engine/graph/nvc1.o
-nouveau-y += core/engine/graph/nvc4.o
-nouveau-y += core/engine/graph/nvc8.o
-nouveau-y += core/engine/graph/nvd7.o
-nouveau-y += core/engine/graph/nvd9.o
-nouveau-y += core/engine/graph/nve4.o
-nouveau-y += core/engine/graph/gk20a.o
-nouveau-y += core/engine/graph/nvf0.o
-nouveau-y += core/engine/graph/gk110b.o
-nouveau-y += core/engine/graph/nv108.o
-nouveau-y += core/engine/graph/gm107.o
-nouveau-y += core/engine/mpeg/nv31.o
-nouveau-y += core/engine/mpeg/nv40.o
-nouveau-y += core/engine/mpeg/nv44.o
-nouveau-y += core/engine/mpeg/nv50.o
-nouveau-y += core/engine/mpeg/nv84.o
-nouveau-y += core/engine/perfmon/base.o
-nouveau-y += core/engine/perfmon/daemon.o
-nouveau-y += core/engine/perfmon/nv40.o
-nouveau-y += core/engine/perfmon/nv50.o
-nouveau-y += core/engine/perfmon/nv84.o
-nouveau-y += core/engine/perfmon/nva3.o
-nouveau-y += core/engine/perfmon/nvc0.o
-nouveau-y += core/engine/perfmon/nve0.o
-nouveau-y += core/engine/perfmon/nvf0.o
-nouveau-y += core/engine/ppp/nv98.o
-nouveau-y += core/engine/ppp/nvc0.o
-nouveau-y += core/engine/software/nv04.o
-nouveau-y += core/engine/software/nv10.o
-nouveau-y += core/engine/software/nv50.o
-nouveau-y += core/engine/software/nvc0.o
-nouveau-y += core/engine/vp/nv84.o
-nouveau-y += core/engine/vp/nv98.o
-nouveau-y += core/engine/vp/nvc0.o
-nouveau-y += core/engine/vp/nve0.o
-
-# nvif
-nouveau-y += nvif/object.o
-nouveau-y += nvif/client.o
-nouveau-y += nvif/device.o
-nouveau-y += nvif/notify.o
-
-# drm/core
-nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
-nouveau-y += nouveau_vga.o nouveau_agp.o
-nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o
-nouveau-y += nouveau_prime.o nouveau_abi16.o
-nouveau-y += nouveau_nvif.o nouveau_usif.o
-nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o
-nouveau-y += nv50_fence.o nv84_fence.o nvc0_fence.o
-
-# drm/kms
-nouveau-y += nouveau_bios.o nouveau_fbcon.o nouveau_display.o
-nouveau-y += nouveau_connector.o nouveau_dp.o
-nouveau-y += nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o
-
-# drm/kms/nv04:nv50
-include $(src)/dispnv04/Makefile
-
-# drm/kms/nv50-
-nouveau-y += nv50_display.o
-
-# drm/pm
-nouveau-y += nouveau_hwmon.o nouveau_sysfs.o
-
-# other random bits
-nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
-ifdef CONFIG_X86
-nouveau-$(CONFIG_ACPI) += nouveau_acpi.o
-endif
-nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
-nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
-
-obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
-
-# platform driver
-obj-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
diff --git a/drivers/gpu/drm/nouveau/core/core/gpuobj.c b/drivers/gpu/drm/nouveau/core/core/gpuobj.c
deleted file mode 100644
index daee87702502..000000000000
--- a/drivers/gpu/drm/nouveau/core/core/gpuobj.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <core/object.h>
-#include <core/gpuobj.h>
-
-#include <subdev/instmem.h>
-#include <subdev/bar.h>
-#include <subdev/vm.h>
-
-void
-nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
-{
- int i;
-
- if (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE) {
- for (i = 0; i < gpuobj->size; i += 4)
- nv_wo32(gpuobj, i, 0x00000000);
- }
-
- if (gpuobj->node) {
- nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
- &gpuobj->node);
- }
-
- if (gpuobj->heap.block_size)
- nouveau_mm_fini(&gpuobj->heap);
-
- nouveau_object_destroy(&gpuobj->base);
-}
-
-int
-nouveau_gpuobj_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 pclass,
- struct nouveau_object *pargpu,
- u32 size, u32 align, u32 flags,
- int length, void **pobject)
-{
- struct nouveau_instmem *imem = nouveau_instmem(parent);
- struct nouveau_bar *bar = nouveau_bar(parent);
- struct nouveau_gpuobj *gpuobj;
- struct nouveau_mm *heap = NULL;
- int ret, i;
- u64 addr;
-
- *pobject = NULL;
-
- if (pargpu) {
- while ((pargpu = nv_pclass(pargpu, NV_GPUOBJ_CLASS))) {
- if (nv_gpuobj(pargpu)->heap.block_size)
- break;
- pargpu = pargpu->parent;
- }
-
- if (unlikely(pargpu == NULL)) {
- nv_error(parent, "no gpuobj heap\n");
- return -EINVAL;
- }
-
- addr = nv_gpuobj(pargpu)->addr;
- heap = &nv_gpuobj(pargpu)->heap;
- atomic_inc(&parent->refcount);
- } else {
- ret = imem->alloc(imem, parent, size, align, &parent);
- pargpu = parent;
- if (ret)
- return ret;
-
- addr = nv_memobj(pargpu)->addr;
- size = nv_memobj(pargpu)->size;
-
- if (bar && bar->alloc) {
- struct nouveau_instobj *iobj = (void *)parent;
- struct nouveau_mem **mem = (void *)(iobj + 1);
- struct nouveau_mem *node = *mem;
- if (!bar->alloc(bar, parent, node, &pargpu)) {
- nouveau_object_ref(NULL, &parent);
- parent = pargpu;
- }
- }
- }
-
- ret = nouveau_object_create_(parent, engine, oclass, pclass |
- NV_GPUOBJ_CLASS, length, pobject);
- nouveau_object_ref(NULL, &parent);
- gpuobj = *pobject;
- if (ret)
- return ret;
-
- gpuobj->parent = pargpu;
- gpuobj->flags = flags;
- gpuobj->addr = addr;
- gpuobj->size = size;
-
- if (heap) {
- ret = nouveau_mm_head(heap, 0, 1, size, size,
- max(align, (u32)1), &gpuobj->node);
- if (ret)
- return ret;
-
- gpuobj->addr += gpuobj->node->offset;
- }
-
- if (gpuobj->flags & NVOBJ_FLAG_HEAP) {
- ret = nouveau_mm_init(&gpuobj->heap, 0, gpuobj->size, 1);
- if (ret)
- return ret;
- }
-
- if (flags & NVOBJ_FLAG_ZERO_ALLOC) {
- for (i = 0; i < gpuobj->size; i += 4)
- nv_wo32(gpuobj, i, 0x00000000);
- }
-
- return ret;
-}
-
-struct nouveau_gpuobj_class {
- struct nouveau_object *pargpu;
- u64 size;
- u32 align;
- u32 flags;
-};
-
-static int
-_nouveau_gpuobj_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nouveau_gpuobj_class *args = data;
- struct nouveau_gpuobj *object;
- int ret;
-
- ret = nouveau_gpuobj_create(parent, engine, oclass, 0, args->pargpu,
- args->size, args->align, args->flags,
- &object);
- *pobject = nv_object(object);
- if (ret)
- return ret;
-
- return 0;
-}
-
-void
-_nouveau_gpuobj_dtor(struct nouveau_object *object)
-{
- nouveau_gpuobj_destroy(nv_gpuobj(object));
-}
-
-int
-_nouveau_gpuobj_init(struct nouveau_object *object)
-{
- return nouveau_gpuobj_init(nv_gpuobj(object));
-}
-
-int
-_nouveau_gpuobj_fini(struct nouveau_object *object, bool suspend)
-{
- return nouveau_gpuobj_fini(nv_gpuobj(object), suspend);
-}
-
-u32
-_nouveau_gpuobj_rd32(struct nouveau_object *object, u64 addr)
-{
- struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
- struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
- if (gpuobj->node)
- addr += gpuobj->node->offset;
- return pfuncs->rd32(gpuobj->parent, addr);
-}
-
-void
-_nouveau_gpuobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
-{
- struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
- struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
- if (gpuobj->node)
- addr += gpuobj->node->offset;
- pfuncs->wr32(gpuobj->parent, addr, data);
-}
-
-static struct nouveau_oclass
-_nouveau_gpuobj_oclass = {
- .handle = 0x00000000,
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_gpuobj_ctor,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
- },
-};
-
-int
-nouveau_gpuobj_new(struct nouveau_object *parent, struct nouveau_object *pargpu,
- u32 size, u32 align, u32 flags,
- struct nouveau_gpuobj **pgpuobj)
-{
- struct nouveau_object *engine = parent;
- struct nouveau_gpuobj_class args = {
- .pargpu = pargpu,
- .size = size,
- .align = align,
- .flags = flags,
- };
-
- if (!nv_iclass(engine, NV_SUBDEV_CLASS))
- engine = engine->engine;
- BUG_ON(engine == NULL);
-
- return nouveau_object_ctor(parent, engine, &_nouveau_gpuobj_oclass,
- &args, sizeof(args),
- (struct nouveau_object **)pgpuobj);
-}
-
-int
-nouveau_gpuobj_map(struct nouveau_gpuobj *gpuobj, u32 access,
- struct nouveau_vma *vma)
-{
- struct nouveau_bar *bar = nouveau_bar(gpuobj);
- int ret = -EINVAL;
-
- if (bar && bar->umap) {
- struct nouveau_instobj *iobj = (void *)
- nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
- struct nouveau_mem **mem = (void *)(iobj + 1);
- ret = bar->umap(bar, *mem, access, vma);
- }
-
- return ret;
-}
-
-int
-nouveau_gpuobj_map_vm(struct nouveau_gpuobj *gpuobj, struct nouveau_vm *vm,
- u32 access, struct nouveau_vma *vma)
-{
- struct nouveau_instobj *iobj = (void *)
- nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
- struct nouveau_mem **mem = (void *)(iobj + 1);
- int ret;
-
- ret = nouveau_vm_get(vm, gpuobj->size, 12, access, vma);
- if (ret)
- return ret;
-
- nouveau_vm_map(vma, *mem);
- return 0;
-}
-
-void
-nouveau_gpuobj_unmap(struct nouveau_vma *vma)
-{
- if (vma->node) {
- nouveau_vm_unmap(vma);
- nouveau_vm_put(vma);
- }
-}
-
-/* the below is basically only here to support sharing the paged dma object
- * for PCI(E)GART on <=nv4x chipsets, and should *not* be expected to work
- * anywhere else.
- */
-
-static void
-nouveau_gpudup_dtor(struct nouveau_object *object)
-{
- struct nouveau_gpuobj *gpuobj = (void *)object;
- nouveau_object_ref(NULL, &gpuobj->parent);
- nouveau_object_destroy(&gpuobj->base);
-}
-
-static struct nouveau_oclass
-nouveau_gpudup_oclass = {
- .handle = NV_GPUOBJ_CLASS,
- .ofuncs = &(struct nouveau_ofuncs) {
- .dtor = nouveau_gpudup_dtor,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
- },
-};
-
-int
-nouveau_gpuobj_dup(struct nouveau_object *parent, struct nouveau_gpuobj *base,
- struct nouveau_gpuobj **pgpuobj)
-{
- struct nouveau_gpuobj *gpuobj;
- int ret;
-
- ret = nouveau_object_create(parent, parent->engine,
- &nouveau_gpudup_oclass, 0, &gpuobj);
- *pgpuobj = gpuobj;
- if (ret)
- return ret;
-
- nouveau_object_ref(nv_object(base), &gpuobj->parent);
- gpuobj->addr = base->addr;
- gpuobj->size = base->size;
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
deleted file mode 100644
index 9261694d0d35..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <engine/falcon.h>
-#include <engine/fifo.h>
-#include <engine/copy.h>
-
-#include <core/enum.h>
-#include <core/enum.h>
-
-#include "fuc/nvc0.fuc.h"
-
-struct nvc0_copy_priv {
- struct nouveau_falcon base;
-};
-
-/*******************************************************************************
- * Copy object classes
- ******************************************************************************/
-
-static struct nouveau_oclass
-nvc0_copy0_sclass[] = {
- { 0x90b5, &nouveau_object_ofuncs },
- {},
-};
-
-static struct nouveau_oclass
-nvc0_copy1_sclass[] = {
- { 0x90b8, &nouveau_object_ofuncs },
- {},
-};
-
-/*******************************************************************************
- * PCOPY context
- ******************************************************************************/
-
-static struct nouveau_ofuncs
-nvc0_copy_context_ofuncs = {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
-};
-
-static struct nouveau_oclass
-nvc0_copy0_cclass = {
- .handle = NV_ENGCTX(COPY0, 0xc0),
- .ofuncs = &nvc0_copy_context_ofuncs,
-};
-
-static struct nouveau_oclass
-nvc0_copy1_cclass = {
- .handle = NV_ENGCTX(COPY1, 0xc0),
- .ofuncs = &nvc0_copy_context_ofuncs,
-};
-
-/*******************************************************************************
- * PCOPY engine/subdev functions
- ******************************************************************************/
-
-static int
-nvc0_copy_init(struct nouveau_object *object)
-{
- struct nvc0_copy_priv *priv = (void *)object;
- int ret;
-
- ret = nouveau_falcon_init(&priv->base);
- if (ret)
- return ret;
-
- nv_wo32(priv, 0x084, nv_engidx(object) - NVDEV_ENGINE_COPY0);
- return 0;
-}
-
-static int
-nvc0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_copy_priv *priv;
- int ret;
-
- ret = nouveau_falcon_create(parent, engine, oclass, 0x104000, true,
- "PCE0", "copy0", &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- nv_subdev(priv)->unit = 0x00000040;
- nv_subdev(priv)->intr = nva3_copy_intr;
- nv_engine(priv)->cclass = &nvc0_copy0_cclass;
- nv_engine(priv)->sclass = nvc0_copy0_sclass;
- nv_falcon(priv)->code.data = nvc0_pcopy_code;
- nv_falcon(priv)->code.size = sizeof(nvc0_pcopy_code);
- nv_falcon(priv)->data.data = nvc0_pcopy_data;
- nv_falcon(priv)->data.size = sizeof(nvc0_pcopy_data);
- return 0;
-}
-
-static int
-nvc0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_copy_priv *priv;
- int ret;
-
- ret = nouveau_falcon_create(parent, engine, oclass, 0x105000, true,
- "PCE1", "copy1", &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- nv_subdev(priv)->unit = 0x00000080;
- nv_subdev(priv)->intr = nva3_copy_intr;
- nv_engine(priv)->cclass = &nvc0_copy1_cclass;
- nv_engine(priv)->sclass = nvc0_copy1_sclass;
- nv_falcon(priv)->code.data = nvc0_pcopy_code;
- nv_falcon(priv)->code.size = sizeof(nvc0_pcopy_code);
- nv_falcon(priv)->data.data = nvc0_pcopy_data;
- nv_falcon(priv)->data.size = sizeof(nvc0_pcopy_data);
- return 0;
-}
-
-struct nouveau_oclass
-nvc0_copy0_oclass = {
- .handle = NV_ENGINE(COPY0, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_copy0_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nvc0_copy_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
- },
-};
-
-struct nouveau_oclass
-nvc0_copy1_oclass = {
- .handle = NV_ENGINE(COPY1, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_copy1_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nvc0_copy_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
deleted file mode 100644
index c7194b354605..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <core/os.h>
-#include <core/enum.h>
-#include <core/engctx.h>
-
-#include <engine/copy.h>
-
-struct nve0_copy_priv {
- struct nouveau_engine base;
-};
-
-/*******************************************************************************
- * Copy object classes
- ******************************************************************************/
-
-static struct nouveau_oclass
-nve0_copy_sclass[] = {
- { 0xa0b5, &nouveau_object_ofuncs },
- {},
-};
-
-/*******************************************************************************
- * PCOPY context
- ******************************************************************************/
-
-static struct nouveau_ofuncs
-nve0_copy_context_ofuncs = {
- .ctor = _nouveau_engctx_ctor,
- .dtor = _nouveau_engctx_dtor,
- .init = _nouveau_engctx_init,
- .fini = _nouveau_engctx_fini,
- .rd32 = _nouveau_engctx_rd32,
- .wr32 = _nouveau_engctx_wr32,
-};
-
-static struct nouveau_oclass
-nve0_copy_cclass = {
- .handle = NV_ENGCTX(COPY0, 0xc0),
- .ofuncs = &nve0_copy_context_ofuncs,
-};
-
-/*******************************************************************************
- * PCOPY engine/subdev functions
- ******************************************************************************/
-
-static void
-nve0_copy_intr(struct nouveau_subdev *subdev)
-{
- const int ce = nv_subidx(nv_object(subdev)) - NVDEV_ENGINE_COPY0;
- struct nve0_copy_priv *priv = (void *)subdev;
- u32 stat = nv_rd32(priv, 0x104908 + (ce * 0x1000));
-
- if (stat) {
- nv_warn(priv, "unhandled intr 0x%08x\n", stat);
- nv_wr32(priv, 0x104908 + (ce * 0x1000), stat);
- }
-}
-
-static int
-nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nve0_copy_priv *priv;
- int ret;
-
- ret = nouveau_engine_create(parent, engine, oclass, true,
- "PCE0", "copy0", &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- nv_subdev(priv)->unit = 0x00000040;
- nv_subdev(priv)->intr = nve0_copy_intr;
- nv_engine(priv)->cclass = &nve0_copy_cclass;
- nv_engine(priv)->sclass = nve0_copy_sclass;
- return 0;
-}
-
-static int
-nve0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nve0_copy_priv *priv;
- int ret;
-
- ret = nouveau_engine_create(parent, engine, oclass, true,
- "PCE1", "copy1", &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- nv_subdev(priv)->unit = 0x00000080;
- nv_subdev(priv)->intr = nve0_copy_intr;
- nv_engine(priv)->cclass = &nve0_copy_cclass;
- nv_engine(priv)->sclass = nve0_copy_sclass;
- return 0;
-}
-
-static int
-nve0_copy2_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nve0_copy_priv *priv;
- int ret;
-
- ret = nouveau_engine_create(parent, engine, oclass, true,
- "PCE2", "copy2", &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- nv_subdev(priv)->unit = 0x00200000;
- nv_subdev(priv)->intr = nve0_copy_intr;
- nv_engine(priv)->cclass = &nve0_copy_cclass;
- nv_engine(priv)->sclass = nve0_copy_sclass;
- return 0;
-}
-
-struct nouveau_oclass
-nve0_copy0_oclass = {
- .handle = NV_ENGINE(COPY0, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_copy0_ctor,
- .dtor = _nouveau_engine_dtor,
- .init = _nouveau_engine_init,
- .fini = _nouveau_engine_fini,
- },
-};
-
-struct nouveau_oclass
-nve0_copy1_oclass = {
- .handle = NV_ENGINE(COPY1, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_copy1_ctor,
- .dtor = _nouveau_engine_dtor,
- .init = _nouveau_engine_init,
- .fini = _nouveau_engine_fini,
- },
-};
-
-struct nouveau_oclass
-nve0_copy2_oclass = {
- .handle = NV_ENGINE(COPY2, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_copy2_ctor,
- .dtor = _nouveau_engine_dtor,
- .init = _nouveau_engine_init,
- .fini = _nouveau_engine_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/acpi.h b/drivers/gpu/drm/nouveau/core/engine/device/acpi.h
deleted file mode 100644
index cc49f4f568cd..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/device/acpi.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __NVKM_DEVICE_ACPI_H__
-#define __NVKM_DEVICE_ACPI_H__
-
-#include <engine/device.h>
-
-int nvkm_acpi_init(struct nouveau_device *);
-int nvkm_acpi_fini(struct nouveau_device *, bool);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
deleted file mode 100644
index 96f568d1321b..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <subdev/bios.h>
-#include <subdev/bus.h>
-#include <subdev/gpio.h>
-#include <subdev/i2c.h>
-#include <subdev/fuse.h>
-#include <subdev/clock.h>
-#include <subdev/therm.h>
-#include <subdev/mxm.h>
-#include <subdev/devinit.h>
-#include <subdev/mc.h>
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <subdev/instmem.h>
-#include <subdev/vm.h>
-#include <subdev/bar.h>
-#include <subdev/pwr.h>
-#include <subdev/volt.h>
-
-#include <engine/device.h>
-#include <engine/dmaobj.h>
-#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
-#include <engine/mpeg.h>
-#include <engine/vp.h>
-#include <engine/crypt.h>
-#include <engine/bsp.h>
-#include <engine/ppp.h>
-#include <engine/copy.h>
-#include <engine/disp.h>
-#include <engine/perfmon.h>
-
-int
-nv50_identify(struct nouveau_device *device)
-{
- switch (device->chipset) {
- case 0x50:
- device->cname = "G80";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv50_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv50_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv50_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv50_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv50_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv50_perfmon_oclass;
- break;
- case 0x84:
- device->cname = "G84";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0x86:
- device->cname = "G86";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0x92:
- device->cname = "G92";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0x94:
- device->cname = "G94";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0x96:
- device->cname = "G96";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0x98:
- device->cname = "G98";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv98_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0xa0:
- device->cname = "G200";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva0_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0xaa:
- device->cname = "MCP77/MCP78";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv98_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0xac:
- device->cname = "MCP79/MCP7A";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nv98_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
- device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
- break;
- case 0xa3:
- device->cname = "GT215";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nva3_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
- break;
- case 0xa5:
- device->cname = "GT216";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nva3_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
- break;
- case 0xa8:
- device->cname = "GT218";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nva3_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
- break;
- case 0xaf:
- device->cname = "MCP89";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &g80_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvaf_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvaf_fb_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
- break;
- default:
- nv_fatal(device, "unknown Tesla chipset\n");
- return -EINVAL;
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
deleted file mode 100644
index 72a40f95d048..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <subdev/bios.h>
-#include <subdev/bus.h>
-#include <subdev/gpio.h>
-#include <subdev/i2c.h>
-#include <subdev/fuse.h>
-#include <subdev/clock.h>
-#include <subdev/therm.h>
-#include <subdev/mxm.h>
-#include <subdev/devinit.h>
-#include <subdev/mc.h>
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <subdev/ltc.h>
-#include <subdev/ibus.h>
-#include <subdev/instmem.h>
-#include <subdev/vm.h>
-#include <subdev/bar.h>
-#include <subdev/pwr.h>
-#include <subdev/volt.h>
-
-#include <engine/device.h>
-#include <engine/dmaobj.h>
-#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
-#include <engine/vp.h>
-#include <engine/bsp.h>
-#include <engine/ppp.h>
-#include <engine/copy.h>
-#include <engine/disp.h>
-#include <engine/perfmon.h>
-
-int
-nvc0_identify(struct nouveau_device *device)
-{
- switch (device->chipset) {
- case 0xc0:
- device->cname = "GF100";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvc0_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xc4:
- device->cname = "GF104";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xc3:
- device->cname = "GF106";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xce:
- device->cname = "GF114";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xcf:
- device->cname = "GF116";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xc1:
- device->cname = "GF108";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvc1_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xc8:
- device->cname = "GF110";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nv94_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvc8_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xd9:
- device->cname = "GF119";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nvd0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nvd0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvd9_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nvd0_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- case 0xd7:
- device->cname = "GF117";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nvd0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = gf117_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvd7_graph_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nvd0_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
- break;
- default:
- nv_fatal(device, "unknown Fermi chipset\n");
- return -EINVAL;
- }
-
- return 0;
- }
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
deleted file mode 100644
index 732922690653..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <subdev/bios.h>
-#include <subdev/bus.h>
-#include <subdev/gpio.h>
-#include <subdev/i2c.h>
-#include <subdev/fuse.h>
-#include <subdev/clock.h>
-#include <subdev/therm.h>
-#include <subdev/mxm.h>
-#include <subdev/devinit.h>
-#include <subdev/mc.h>
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <subdev/ltc.h>
-#include <subdev/ibus.h>
-#include <subdev/instmem.h>
-#include <subdev/vm.h>
-#include <subdev/bar.h>
-#include <subdev/pwr.h>
-#include <subdev/volt.h>
-
-#include <engine/device.h>
-#include <engine/dmaobj.h>
-#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
-#include <engine/disp.h>
-#include <engine/copy.h>
-#include <engine/bsp.h>
-#include <engine/vp.h>
-#include <engine/ppp.h>
-#include <engine/perfmon.h>
-
-int
-nve0_identify(struct nouveau_device *device)
-{
- switch (device->chipset) {
- case 0xe4:
- device->cname = "GK104";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = gk104_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
- break;
- case 0xe7:
- device->cname = "GK107";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
- break;
- case 0xe6:
- device->cname = "GK106";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = gk104_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
- break;
- case 0xea:
- device->cname = "GK20A";
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &gk20a_clock_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &gk20a_bar_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = gk20a_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &gk20a_volt_oclass;
- break;
- case 0xf0:
- device->cname = "GK110";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
- break;
- case 0xf1:
- device->cname = "GK110B";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nvd0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = gk110b_graph_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
- break;
- case 0x106:
- device->cname = "GK208B";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- break;
- case 0x108:
- device->cname = "GK208";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
- device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
- device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
- device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
- device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
- device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
- device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
- device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
- device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass;
- device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass;
- device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
- break;
- default:
- nv_fatal(device, "unknown Kepler chipset\n");
- return -EINVAL;
- }
-
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/priv.h b/drivers/gpu/drm/nouveau/core/engine/device/priv.h
deleted file mode 100644
index 035fd5b9cfc3..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/device/priv.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __NVKM_DEVICE_PRIV_H__
-#define __NVKM_DEVICE_PRIV_H__
-
-#include <engine/device.h>
-
-extern struct nouveau_oclass nouveau_control_oclass[];
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
deleted file mode 100644
index 7f08078ee925..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
+++ /dev/null
@@ -1,252 +0,0 @@
-#ifndef __NV50_DISP_H__
-#define __NV50_DISP_H__
-
-#include <core/parent.h>
-#include <core/namedb.h>
-#include <core/engctx.h>
-#include <core/ramht.h>
-#include <core/event.h>
-
-#include <engine/dmaobj.h>
-
-#include "dport.h"
-#include "priv.h"
-#include "outp.h"
-#include "outpdp.h"
-
-#define NV50_DISP_MTHD_ struct nouveau_object *object, \
- struct nv50_disp_priv *priv, void *data, u32 size
-#define NV50_DISP_MTHD_V0 NV50_DISP_MTHD_, int head
-#define NV50_DISP_MTHD_V1 NV50_DISP_MTHD_, int head, struct nvkm_output *outp
-
-struct nv50_disp_priv {
- struct nouveau_disp base;
- struct nouveau_oclass *sclass;
-
- struct work_struct supervisor;
- u32 super;
-
- struct nvkm_event uevent;
-
- struct {
- int nr;
- } head;
- struct {
- int nr;
- int (*power)(NV50_DISP_MTHD_V1);
- int (*sense)(NV50_DISP_MTHD_V1);
- } dac;
- struct {
- int nr;
- int (*power)(NV50_DISP_MTHD_V1);
- int (*hda_eld)(NV50_DISP_MTHD_V1);
- int (*hdmi)(NV50_DISP_MTHD_V1);
- u32 lvdsconf;
- void (*magic)(struct nvkm_output *);
- } sor;
- struct {
- int nr;
- int (*power)(NV50_DISP_MTHD_V1);
- u8 type[3];
- } pior;
-};
-
-struct nv50_disp_impl {
- struct nouveau_disp_impl base;
- struct {
- const struct nv50_disp_mthd_chan *core;
- const struct nv50_disp_mthd_chan *base;
- const struct nv50_disp_mthd_chan *ovly;
- int prev;
- } mthd;
- struct {
- int (*scanoutpos)(NV50_DISP_MTHD_V0);
- } head;
-};
-
-int nv50_disp_main_scanoutpos(NV50_DISP_MTHD_V0);
-int nv50_disp_main_mthd(struct nouveau_object *, u32, void *, u32);
-
-int nvd0_disp_main_scanoutpos(NV50_DISP_MTHD_V0);
-
-int nv50_dac_power(NV50_DISP_MTHD_V1);
-int nv50_dac_sense(NV50_DISP_MTHD_V1);
-
-int nva3_hda_eld(NV50_DISP_MTHD_V1);
-int nvd0_hda_eld(NV50_DISP_MTHD_V1);
-
-int nv84_hdmi_ctrl(NV50_DISP_MTHD_V1);
-int nva3_hdmi_ctrl(NV50_DISP_MTHD_V1);
-int nvd0_hdmi_ctrl(NV50_DISP_MTHD_V1);
-int nve0_hdmi_ctrl(NV50_DISP_MTHD_V1);
-
-int nv50_sor_power(NV50_DISP_MTHD_V1);
-
-int nv94_sor_dp_train_init(struct nv50_disp_priv *, int, int, int, u16, u16,
- u32, struct dcb_output *);
-int nv94_sor_dp_train_fini(struct nv50_disp_priv *, int, int, int, u16, u16,
- u32, struct dcb_output *);
-int nv94_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32,
- struct dcb_output *);
-int nv94_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
- struct dcb_output *);
-int nv94_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
- struct dcb_output *);
-
-int nvd0_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32,
- struct dcb_output *);
-int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
- struct dcb_output *);
-int nvd0_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
- struct dcb_output *);
-
-int nv50_pior_power(NV50_DISP_MTHD_V1);
-
-struct nv50_disp_base {
- struct nouveau_parent base;
- struct nouveau_ramht *ramht;
- u32 chan;
-};
-
-struct nv50_disp_chan_impl {
- struct nouveau_ofuncs base;
- int chid;
- int (*attach)(struct nouveau_object *, struct nouveau_object *, u32);
- void (*detach)(struct nouveau_object *, int);
-};
-
-struct nv50_disp_chan {
- struct nouveau_namedb base;
- int chid;
-};
-
-int nv50_disp_chan_ntfy(struct nouveau_object *, u32, struct nvkm_event **);
-int nv50_disp_chan_map(struct nouveau_object *, u64 *, u32 *);
-u32 nv50_disp_chan_rd32(struct nouveau_object *, u64);
-void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32);
-extern const struct nvkm_event_func nv50_disp_chan_uevent;
-int nv50_disp_chan_uevent_ctor(struct nouveau_object *, void *, u32,
- struct nvkm_notify *);
-void nv50_disp_chan_uevent_send(struct nv50_disp_priv *, int);
-
-extern const struct nvkm_event_func nvd0_disp_chan_uevent;
-
-#define nv50_disp_chan_init(a) \
- nouveau_namedb_init(&(a)->base)
-#define nv50_disp_chan_fini(a,b) \
- nouveau_namedb_fini(&(a)->base, (b))
-
-struct nv50_disp_dmac {
- struct nv50_disp_chan base;
- struct nouveau_dmaobj *pushdma;
- u32 push;
-};
-
-void nv50_disp_dmac_dtor(struct nouveau_object *);
-
-struct nv50_disp_pioc {
- struct nv50_disp_chan base;
-};
-
-void nv50_disp_pioc_dtor(struct nouveau_object *);
-
-struct nv50_disp_mthd_list {
- u32 mthd;
- u32 addr;
- struct {
- u32 mthd;
- u32 addr;
- const char *name;
- } data[];
-};
-
-struct nv50_disp_mthd_chan {
- const char *name;
- u32 addr;
- struct {
- const char *name;
- int nr;
- const struct nv50_disp_mthd_list *mthd;
- } data[];
-};
-
-extern struct nv50_disp_chan_impl nv50_disp_core_ofuncs;
-int nv50_disp_core_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_base;
-extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_sor;
-extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_pior;
-extern struct nv50_disp_chan_impl nv50_disp_base_ofuncs;
-int nv50_disp_base_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-extern const struct nv50_disp_mthd_list nv50_disp_base_mthd_image;
-extern struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs;
-int nv50_disp_ovly_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-extern const struct nv50_disp_mthd_list nv50_disp_ovly_mthd_base;
-extern struct nv50_disp_chan_impl nv50_disp_oimm_ofuncs;
-int nv50_disp_oimm_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-extern struct nv50_disp_chan_impl nv50_disp_curs_ofuncs;
-int nv50_disp_curs_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-extern struct nouveau_ofuncs nv50_disp_main_ofuncs;
-int nv50_disp_main_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv50_disp_main_dtor(struct nouveau_object *);
-extern struct nouveau_omthds nv50_disp_main_omthds[];
-extern struct nouveau_oclass nv50_disp_cclass;
-void nv50_disp_mthd_chan(struct nv50_disp_priv *, int debug, int head,
- const struct nv50_disp_mthd_chan *);
-void nv50_disp_intr_supervisor(struct work_struct *);
-void nv50_disp_intr(struct nouveau_subdev *);
-extern const struct nvkm_event_func nv50_disp_vblank_func;
-
-extern const struct nv50_disp_mthd_chan nv84_disp_core_mthd_chan;
-extern const struct nv50_disp_mthd_list nv84_disp_core_mthd_dac;
-extern const struct nv50_disp_mthd_list nv84_disp_core_mthd_head;
-extern const struct nv50_disp_mthd_chan nv84_disp_base_mthd_chan;
-extern const struct nv50_disp_mthd_chan nv84_disp_ovly_mthd_chan;
-
-extern const struct nv50_disp_mthd_chan nv94_disp_core_mthd_chan;
-
-extern struct nv50_disp_chan_impl nvd0_disp_core_ofuncs;
-extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_base;
-extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_dac;
-extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_sor;
-extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_pior;
-extern struct nv50_disp_chan_impl nvd0_disp_base_ofuncs;
-extern struct nv50_disp_chan_impl nvd0_disp_ovly_ofuncs;
-extern const struct nv50_disp_mthd_chan nvd0_disp_base_mthd_chan;
-extern struct nv50_disp_chan_impl nvd0_disp_oimm_ofuncs;
-extern struct nv50_disp_chan_impl nvd0_disp_curs_ofuncs;
-extern struct nouveau_ofuncs nvd0_disp_main_ofuncs;
-extern struct nouveau_oclass nvd0_disp_cclass;
-void nvd0_disp_intr_supervisor(struct work_struct *);
-void nvd0_disp_intr(struct nouveau_subdev *);
-extern const struct nvkm_event_func nvd0_disp_vblank_func;
-
-extern const struct nv50_disp_mthd_chan nve0_disp_core_mthd_chan;
-extern const struct nv50_disp_mthd_chan nve0_disp_ovly_mthd_chan;
-
-extern struct nvkm_output_dp_impl nv50_pior_dp_impl;
-extern struct nouveau_oclass *nv50_disp_outp_sclass[];
-
-extern struct nvkm_output_dp_impl nv94_sor_dp_impl;
-int nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int);
-extern struct nouveau_oclass *nv94_disp_outp_sclass[];
-
-extern struct nvkm_output_dp_impl nvd0_sor_dp_impl;
-int nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
-extern struct nouveau_oclass *nvd0_disp_outp_sclass[];
-
-void gm204_sor_magic(struct nvkm_output *outp);
-extern struct nvkm_output_dp_impl gm204_sor_dp_impl;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/priv.h b/drivers/gpu/drm/nouveau/core/engine/disp/priv.h
deleted file mode 100644
index 6a0511d54ce6..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/disp/priv.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __NVKM_DISP_PRIV_H__
-#define __NVKM_DISP_PRIV_H__
-
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
-#include <subdev/bios/conn.h>
-
-#include <engine/disp.h>
-
-struct nouveau_disp_impl {
- struct nouveau_oclass base;
- struct nouveau_oclass **outp;
- struct nouveau_oclass **conn;
- const struct nvkm_event_func *vblank;
-};
-
-#define nouveau_disp_create(p,e,c,h,i,x,d) \
- nouveau_disp_create_((p), (e), (c), (h), (i), (x), \
- sizeof(**d), (void **)d)
-#define nouveau_disp_destroy(d) ({ \
- struct nouveau_disp *disp = (d); \
- _nouveau_disp_dtor(nv_object(disp)); \
-})
-#define nouveau_disp_init(d) ({ \
- struct nouveau_disp *disp = (d); \
- _nouveau_disp_init(nv_object(disp)); \
-})
-#define nouveau_disp_fini(d,s) ({ \
- struct nouveau_disp *disp = (d); \
- _nouveau_disp_fini(nv_object(disp), (s)); \
-})
-
-int nouveau_disp_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int heads,
- const char *, const char *, int, void **);
-void _nouveau_disp_dtor(struct nouveau_object *);
-int _nouveau_disp_init(struct nouveau_object *);
-int _nouveau_disp_fini(struct nouveau_object *, bool);
-
-extern struct nouveau_oclass *nvkm_output_oclass;
-extern struct nouveau_oclass *nvkm_connector_oclass;
-
-int nouveau_disp_vblank_ctor(struct nouveau_object *, void *data, u32 size,
- struct nvkm_notify *);
-void nouveau_disp_vblank(struct nouveau_disp *, int head);
-int nouveau_disp_ntfy(struct nouveau_object *, u32, struct nvkm_event **);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h b/drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h
deleted file mode 100644
index 36f743866937..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __NVKM_DMAOBJ_PRIV_H__
-#define __NVKM_DMAOBJ_PRIV_H__
-
-#include <engine/dmaobj.h>
-
-#define nvkm_dmaobj_create(p,e,c,pa,sa,d) \
- nvkm_dmaobj_create_((p), (e), (c), (pa), (sa), sizeof(**d), (void **)d)
-
-int nvkm_dmaobj_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void **, u32 *,
- int, void **);
-#define _nvkm_dmaobj_dtor nouveau_object_destroy
-#define _nvkm_dmaobj_init nouveau_object_init
-#define _nvkm_dmaobj_fini nouveau_object_fini
-
-int _nvkm_dmaeng_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-#define _nvkm_dmaeng_dtor _nouveau_engine_dtor
-#define _nvkm_dmaeng_init _nouveau_engine_init
-#define _nvkm_dmaeng_fini _nouveau_engine_fini
-
-struct nvkm_dmaeng_impl {
- struct nouveau_oclass base;
- struct nouveau_oclass *sclass;
- int (*bind)(struct nouveau_dmaobj *, struct nouveau_object *,
- struct nouveau_gpuobj **);
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h
deleted file mode 100644
index 3a9ceb315c20..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __NV50_FIFO_H__
-#define __NV50_FIFO_H__
-
-struct nv50_fifo_priv {
- struct nouveau_fifo base;
- struct nouveau_gpuobj *playlist[2];
- int cur_playlist;
-};
-
-struct nv50_fifo_base {
- struct nouveau_fifo_base base;
- struct nouveau_gpuobj *ramfc;
- struct nouveau_gpuobj *cache;
- struct nouveau_gpuobj *eng;
- struct nouveau_gpuobj *pgd;
- struct nouveau_vm *vm;
-};
-
-struct nv50_fifo_chan {
- struct nouveau_fifo_chan base;
- u32 subc[8];
- struct nouveau_ramht *ramht;
-};
-
-void nv50_fifo_playlist_update(struct nv50_fifo_priv *);
-
-void nv50_fifo_object_detach(struct nouveau_object *, int);
-void nv50_fifo_chan_dtor(struct nouveau_object *);
-int nv50_fifo_chan_fini(struct nouveau_object *, bool);
-
-void nv50_fifo_context_dtor(struct nouveau_object *);
-
-void nv50_fifo_dtor(struct nouveau_object *);
-int nv50_fifo_init(struct nouveau_object *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
deleted file mode 100644
index e96b32bb1bbc..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __NVKM_FIFO_NVE0_H__
-#define __NVKM_FIFO_NVE0_H__
-
-#include <engine/fifo.h>
-
-int nve0_fifo_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nve0_fifo_dtor(struct nouveau_object *);
-int nve0_fifo_init(struct nouveau_object *);
-int nve0_fifo_fini(struct nouveau_object *, bool);
-
-struct nve0_fifo_impl {
- struct nouveau_oclass base;
- u32 channels;
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h
deleted file mode 100644
index c776cd715e33..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h
+++ /dev/null
@@ -1,202 +0,0 @@
-#ifndef __NVKM_GRCTX_NVC0_H__
-#define __NVKM_GRCTX_NVC0_H__
-
-#include "nvc0.h"
-
-struct nvc0_grctx {
- struct nvc0_graph_priv *priv;
- struct nvc0_graph_data *data;
- struct nvc0_graph_mmio *mmio;
- int buffer_nr;
- u64 buffer[4];
- u64 addr;
-};
-
-int nvc0_grctx_mmio_data(struct nvc0_grctx *, u32 size, u32 align, u32 access);
-void nvc0_grctx_mmio_item(struct nvc0_grctx *, u32 addr, u32 data, int s, int);
-
-#define mmio_vram(a,b,c,d) nvc0_grctx_mmio_data((a), (b), (c), (d))
-#define mmio_refn(a,b,c,d,e) nvc0_grctx_mmio_item((a), (b), (c), (d), (e))
-#define mmio_skip(a,b,c) mmio_refn((a), (b), (c), -1, -1)
-#define mmio_wr32(a,b,c) mmio_refn((a), (b), (c), 0, -1)
-
-struct nvc0_grctx_oclass {
- struct nouveau_oclass base;
- /* main context generation function */
- void (*main)(struct nvc0_graph_priv *, struct nvc0_grctx *);
- /* context-specific modify-on-first-load list generation function */
- void (*unkn)(struct nvc0_graph_priv *);
- /* mmio context data */
- const struct nvc0_graph_pack *hub;
- const struct nvc0_graph_pack *gpc;
- const struct nvc0_graph_pack *zcull;
- const struct nvc0_graph_pack *tpc;
- const struct nvc0_graph_pack *ppc;
- /* indirect context data, generated with icmds/mthds */
- const struct nvc0_graph_pack *icmd;
- const struct nvc0_graph_pack *mthd;
- /* bundle circular buffer */
- void (*bundle)(struct nvc0_grctx *);
- u32 bundle_size;
- u32 bundle_min_gpm_fifo_depth;
- u32 bundle_token_limit;
- /* pagepool */
- void (*pagepool)(struct nvc0_grctx *);
- u32 pagepool_size;
- /* attribute(/alpha) circular buffer */
- void (*attrib)(struct nvc0_grctx *);
- u32 attrib_nr_max;
- u32 attrib_nr;
- u32 alpha_nr_max;
- u32 alpha_nr;
-};
-
-static inline const struct nvc0_grctx_oclass *
-nvc0_grctx_impl(struct nvc0_graph_priv *priv)
-{
- return (void *)nv_engine(priv)->cclass;
-}
-
-extern struct nouveau_oclass *nvc0_grctx_oclass;
-int nvc0_grctx_generate(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
-void nvc0_grctx_generate_bundle(struct nvc0_grctx *);
-void nvc0_grctx_generate_pagepool(struct nvc0_grctx *);
-void nvc0_grctx_generate_attrib(struct nvc0_grctx *);
-void nvc0_grctx_generate_unkn(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r406800(struct nvc0_graph_priv *);
-
-extern struct nouveau_oclass *nvc1_grctx_oclass;
-void nvc1_grctx_generate_attrib(struct nvc0_grctx *);
-void nvc1_grctx_generate_unkn(struct nvc0_graph_priv *);
-
-extern struct nouveau_oclass *nvc4_grctx_oclass;
-extern struct nouveau_oclass *nvc8_grctx_oclass;
-
-extern struct nouveau_oclass *nvd7_grctx_oclass;
-void nvd7_grctx_generate_attrib(struct nvc0_grctx *);
-
-extern struct nouveau_oclass *nvd9_grctx_oclass;
-
-extern struct nouveau_oclass *nve4_grctx_oclass;
-extern struct nouveau_oclass *gk20a_grctx_oclass;
-void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
-void nve4_grctx_generate_bundle(struct nvc0_grctx *);
-void nve4_grctx_generate_pagepool(struct nvc0_grctx *);
-void nve4_grctx_generate_unkn(struct nvc0_graph_priv *);
-void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *);
-
-extern struct nouveau_oclass *nvf0_grctx_oclass;
-extern struct nouveau_oclass *gk110b_grctx_oclass;
-extern struct nouveau_oclass *nv108_grctx_oclass;
-extern struct nouveau_oclass *gm107_grctx_oclass;
-
-/* context init value lists */
-
-extern const struct nvc0_graph_pack nvc0_grctx_pack_icmd[];
-
-extern const struct nvc0_graph_pack nvc0_grctx_pack_mthd[];
-extern const struct nvc0_graph_init nvc0_grctx_init_902d_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_9039_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_90c0_0[];
-
-extern const struct nvc0_graph_pack nvc0_grctx_pack_hub[];
-extern const struct nvc0_graph_init nvc0_grctx_init_main_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_fe_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_pri_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_memfmt_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_rstr2d_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_scc_0[];
-
-extern const struct nvc0_graph_pack nvc0_grctx_pack_gpc[];
-extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_prop_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_1[];
-extern const struct nvc0_graph_init nvc0_grctx_init_zcull_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_crstr_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_gpm_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_gcc_0[];
-
-extern const struct nvc0_graph_pack nvc0_grctx_pack_zcull[];
-
-extern const struct nvc0_graph_pack nvc0_grctx_pack_tpc[];
-extern const struct nvc0_graph_init nvc0_grctx_init_pe_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_wwdx_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_mpc_0[];
-extern const struct nvc0_graph_init nvc0_grctx_init_tpccs_0[];
-
-extern const struct nvc0_graph_init nvc4_grctx_init_tex_0[];
-extern const struct nvc0_graph_init nvc4_grctx_init_l1c_0[];
-extern const struct nvc0_graph_init nvc4_grctx_init_sm_0[];
-
-extern const struct nvc0_graph_init nvc1_grctx_init_9097_0[];
-
-extern const struct nvc0_graph_init nvc1_grctx_init_gpm_0[];
-
-extern const struct nvc0_graph_init nvc1_grctx_init_pe_0[];
-extern const struct nvc0_graph_init nvc1_grctx_init_wwdx_0[];
-extern const struct nvc0_graph_init nvc1_grctx_init_tpccs_0[];
-
-extern const struct nvc0_graph_init nvc8_grctx_init_9197_0[];
-extern const struct nvc0_graph_init nvc8_grctx_init_9297_0[];
-
-extern const struct nvc0_graph_pack nvd9_grctx_pack_icmd[];
-
-extern const struct nvc0_graph_pack nvd9_grctx_pack_mthd[];
-
-extern const struct nvc0_graph_init nvd9_grctx_init_fe_0[];
-extern const struct nvc0_graph_init nvd9_grctx_init_be_0[];
-
-extern const struct nvc0_graph_init nvd9_grctx_init_prop_0[];
-extern const struct nvc0_graph_init nvd9_grctx_init_gpc_unk_1[];
-extern const struct nvc0_graph_init nvd9_grctx_init_crstr_0[];
-
-extern const struct nvc0_graph_init nvd9_grctx_init_sm_0[];
-
-extern const struct nvc0_graph_init nvd7_grctx_init_pe_0[];
-
-extern const struct nvc0_graph_init nvd7_grctx_init_wwdx_0[];
-
-extern const struct nvc0_graph_init nve4_grctx_init_memfmt_0[];
-extern const struct nvc0_graph_init nve4_grctx_init_ds_0[];
-extern const struct nvc0_graph_init nve4_grctx_init_scc_0[];
-
-extern const struct nvc0_graph_init nve4_grctx_init_gpm_0[];
-
-extern const struct nvc0_graph_init nve4_grctx_init_pes_0[];
-
-extern const struct nvc0_graph_pack nve4_grctx_pack_hub[];
-extern const struct nvc0_graph_pack nve4_grctx_pack_gpc[];
-extern const struct nvc0_graph_pack nve4_grctx_pack_tpc[];
-extern const struct nvc0_graph_pack nve4_grctx_pack_ppc[];
-extern const struct nvc0_graph_pack nve4_grctx_pack_icmd[];
-extern const struct nvc0_graph_init nve4_grctx_init_a097_0[];
-
-extern const struct nvc0_graph_pack nvf0_grctx_pack_icmd[];
-
-extern const struct nvc0_graph_pack nvf0_grctx_pack_mthd[];
-
-extern const struct nvc0_graph_pack nvf0_grctx_pack_hub[];
-extern const struct nvc0_graph_init nvf0_grctx_init_pri_0[];
-extern const struct nvc0_graph_init nvf0_grctx_init_cwd_0[];
-
-extern const struct nvc0_graph_pack nvf0_grctx_pack_gpc[];
-extern const struct nvc0_graph_init nvf0_grctx_init_gpc_unk_2[];
-
-extern const struct nvc0_graph_init nvf0_grctx_init_tex_0[];
-extern const struct nvc0_graph_init nvf0_grctx_init_mpc_0[];
-extern const struct nvc0_graph_init nvf0_grctx_init_l1c_0[];
-
-extern const struct nvc0_graph_pack nvf0_grctx_pack_ppc[];
-
-extern const struct nvc0_graph_init nv108_grctx_init_rstr2d_0[];
-
-extern const struct nvc0_graph_init nv108_grctx_init_prop_0[];
-extern const struct nvc0_graph_init nv108_grctx_init_crstr_0[];
-
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h
deleted file mode 100644
index 2bea7313e03f..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __NV20_GRAPH_H__
-#define __NV20_GRAPH_H__
-
-#include <core/enum.h>
-
-#include <engine/graph.h>
-#include <engine/fifo.h>
-
-struct nv20_graph_priv {
- struct nouveau_graph base;
- struct nouveau_gpuobj *ctxtab;
-};
-
-struct nv20_graph_chan {
- struct nouveau_graph_chan base;
- int chid;
-};
-
-extern struct nouveau_oclass nv25_graph_sclass[];
-int nv20_graph_context_init(struct nouveau_object *);
-int nv20_graph_context_fini(struct nouveau_object *, bool);
-
-void nv20_graph_tile_prog(struct nouveau_engine *, int);
-void nv20_graph_intr(struct nouveau_subdev *);
-
-void nv20_graph_dtor(struct nouveau_object *);
-int nv20_graph_init(struct nouveau_object *);
-
-int nv30_graph_init(struct nouveau_object *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h
deleted file mode 100644
index 0505fb419bde..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __NV50_GRAPH_H__
-#define __NV50_GRAPH_H__
-
-int nv50_grctx_init(struct nouveau_device *, u32 *size);
-void nv50_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
deleted file mode 100644
index 7ed9e89c3435..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright 2010 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#ifndef __NVC0_GRAPH_H__
-#define __NVC0_GRAPH_H__
-
-#include <core/client.h>
-#include <core/handle.h>
-#include <core/gpuobj.h>
-#include <core/option.h>
-
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
-#include <subdev/fb.h>
-#include <subdev/vm.h>
-#include <subdev/bar.h>
-#include <subdev/timer.h>
-#include <subdev/mc.h>
-#include <subdev/ltc.h>
-
-#include <engine/fifo.h>
-#include <engine/graph.h>
-
-#include "fuc/os.h"
-
-#define GPC_MAX 32
-#define TPC_MAX (GPC_MAX * 8)
-
-#define ROP_BCAST(r) (0x408800 + (r))
-#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
-#define GPC_BCAST(r) (0x418000 + (r))
-#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r))
-#define PPC_UNIT(t, m, r) (0x503000 + (t) * 0x8000 + (m) * 0x200 + (r))
-#define TPC_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
-
-struct nvc0_graph_data {
- u32 size;
- u32 align;
- u32 access;
-};
-
-struct nvc0_graph_mmio {
- u32 addr;
- u32 data;
- u32 shift;
- int buffer;
-};
-
-struct nvc0_graph_fuc {
- u32 *data;
- u32 size;
-};
-
-struct nvc0_graph_zbc_color {
- u32 format;
- u32 ds[4];
- u32 l2[4];
-};
-
-struct nvc0_graph_zbc_depth {
- u32 format;
- u32 ds;
- u32 l2;
-};
-
-struct nvc0_graph_priv {
- struct nouveau_graph base;
-
- struct nvc0_graph_fuc fuc409c;
- struct nvc0_graph_fuc fuc409d;
- struct nvc0_graph_fuc fuc41ac;
- struct nvc0_graph_fuc fuc41ad;
- bool firmware;
-
- struct nvc0_graph_zbc_color zbc_color[NOUVEAU_LTC_MAX_ZBC_CNT];
- struct nvc0_graph_zbc_depth zbc_depth[NOUVEAU_LTC_MAX_ZBC_CNT];
-
- u8 rop_nr;
- u8 gpc_nr;
- u8 tpc_nr[GPC_MAX];
- u8 tpc_total;
- u8 ppc_nr[GPC_MAX];
- u8 ppc_tpc_nr[GPC_MAX][4];
-
- struct nouveau_gpuobj *unk4188b4;
- struct nouveau_gpuobj *unk4188b8;
-
- struct nvc0_graph_data mmio_data[4];
- struct nvc0_graph_mmio mmio_list[4096/8];
- u32 size;
- u32 *data;
-
- u8 magic_not_rop_nr;
-};
-
-struct nvc0_graph_chan {
- struct nouveau_graph_chan base;
-
- struct nouveau_gpuobj *mmio;
- struct nouveau_vma mmio_vma;
- int mmio_nr;
- struct {
- struct nouveau_gpuobj *mem;
- struct nouveau_vma vma;
- } data[4];
-};
-
-int nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nvc0_graph_context_dtor(struct nouveau_object *);
-
-void nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *);
-
-u64 nvc0_graph_units(struct nouveau_graph *);
-int nvc0_graph_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *data, u32 size,
- struct nouveau_object **);
-void nvc0_graph_dtor(struct nouveau_object *);
-int nvc0_graph_init(struct nouveau_object *);
-void nvc0_graph_zbc_init(struct nvc0_graph_priv *);
-
-int nve4_graph_fini(struct nouveau_object *, bool);
-int nve4_graph_init(struct nouveau_object *);
-
-int nvf0_graph_fini(struct nouveau_object *, bool);
-
-extern struct nouveau_ofuncs nvc0_fermi_ofuncs;
-
-extern struct nouveau_oclass nvc0_graph_sclass[];
-extern struct nouveau_omthds nvc0_graph_9097_omthds[];
-extern struct nouveau_omthds nvc0_graph_90c0_omthds[];
-extern struct nouveau_oclass nvc8_graph_sclass[];
-extern struct nouveau_oclass nvf0_graph_sclass[];
-
-struct nvc0_graph_init {
- u32 addr;
- u8 count;
- u8 pitch;
- u32 data;
-};
-
-struct nvc0_graph_pack {
- const struct nvc0_graph_init *init;
- u32 type;
-};
-
-#define pack_for_each_init(init, pack, head) \
- for (pack = head; pack && pack->init; pack++) \
- for (init = pack->init; init && init->count; init++)
-
-struct nvc0_graph_ucode {
- struct nvc0_graph_fuc code;
- struct nvc0_graph_fuc data;
-};
-
-extern struct nvc0_graph_ucode nvc0_graph_fecs_ucode;
-extern struct nvc0_graph_ucode nvc0_graph_gpccs_ucode;
-
-extern struct nvc0_graph_ucode nvf0_graph_fecs_ucode;
-extern struct nvc0_graph_ucode nvf0_graph_gpccs_ucode;
-
-struct nvc0_graph_oclass {
- struct nouveau_oclass base;
- struct nouveau_oclass **cclass;
- struct nouveau_oclass *sclass;
- const struct nvc0_graph_pack *mmio;
- struct {
- struct nvc0_graph_ucode *ucode;
- } fecs;
- struct {
- struct nvc0_graph_ucode *ucode;
- } gpccs;
- int ppc_nr;
-};
-
-void nvc0_graph_mmio(struct nvc0_graph_priv *, const struct nvc0_graph_pack *);
-void nvc0_graph_icmd(struct nvc0_graph_priv *, const struct nvc0_graph_pack *);
-void nvc0_graph_mthd(struct nvc0_graph_priv *, const struct nvc0_graph_pack *);
-int nvc0_graph_init_ctxctl(struct nvc0_graph_priv *);
-
-/* register init value lists */
-
-extern const struct nvc0_graph_init nvc0_graph_init_main_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_fe_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_pri_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_rstr2d_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_pd_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_ds_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_scc_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_prop_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_gpc_unk_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_setup_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_crstr_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_setup_1[];
-extern const struct nvc0_graph_init nvc0_graph_init_zcull_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_gpm_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_gpc_unk_1[];
-extern const struct nvc0_graph_init nvc0_graph_init_gcc_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_tpccs_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_tex_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_pe_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_l1c_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_wwdx_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_tpccs_1[];
-extern const struct nvc0_graph_init nvc0_graph_init_mpc_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_be_0[];
-extern const struct nvc0_graph_init nvc0_graph_init_fe_1[];
-extern const struct nvc0_graph_init nvc0_graph_init_pe_1[];
-
-extern const struct nvc0_graph_init nvc4_graph_init_ds_0[];
-extern const struct nvc0_graph_init nvc4_graph_init_tex_0[];
-extern const struct nvc0_graph_init nvc4_graph_init_sm_0[];
-
-extern const struct nvc0_graph_init nvc1_graph_init_gpc_unk_0[];
-extern const struct nvc0_graph_init nvc1_graph_init_setup_1[];
-
-extern const struct nvc0_graph_init nvd9_graph_init_pd_0[];
-extern const struct nvc0_graph_init nvd9_graph_init_ds_0[];
-extern const struct nvc0_graph_init nvd9_graph_init_prop_0[];
-extern const struct nvc0_graph_init nvd9_graph_init_gpm_0[];
-extern const struct nvc0_graph_init nvd9_graph_init_gpc_unk_1[];
-extern const struct nvc0_graph_init nvd9_graph_init_tex_0[];
-extern const struct nvc0_graph_init nvd9_graph_init_sm_0[];
-extern const struct nvc0_graph_init nvd9_graph_init_fe_1[];
-
-extern const struct nvc0_graph_init nvd7_graph_init_pes_0[];
-extern const struct nvc0_graph_init nvd7_graph_init_wwdx_0[];
-extern const struct nvc0_graph_init nvd7_graph_init_cbm_0[];
-
-extern const struct nvc0_graph_init nve4_graph_init_main_0[];
-extern const struct nvc0_graph_init nve4_graph_init_tpccs_0[];
-extern const struct nvc0_graph_init nve4_graph_init_pe_0[];
-extern const struct nvc0_graph_init nve4_graph_init_be_0[];
-extern const struct nvc0_graph_pack nve4_graph_pack_mmio[];
-
-extern const struct nvc0_graph_init nvf0_graph_init_fe_0[];
-extern const struct nvc0_graph_init nvf0_graph_init_ds_0[];
-extern const struct nvc0_graph_init nvf0_graph_init_sked_0[];
-extern const struct nvc0_graph_init nvf0_graph_init_cwd_0[];
-extern const struct nvc0_graph_init nvf0_graph_init_gpc_unk_1[];
-extern const struct nvc0_graph_init nvf0_graph_init_tex_0[];
-extern const struct nvc0_graph_init nvf0_graph_init_sm_0[];
-
-extern const struct nvc0_graph_init nv108_graph_init_gpc_unk_0[];
-
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h
deleted file mode 100644
index 1b5792d1df14..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __NVKM_PM_NV40_H__
-#define __NVKM_PM_NV40_H__
-
-#include "priv.h"
-
-struct nv40_perfmon_oclass {
- struct nouveau_oclass base;
- const struct nouveau_specdom *doms;
-};
-
-struct nv40_perfmon_priv {
- struct nouveau_perfmon base;
- u32 sequence;
-};
-
-int nv40_perfmon_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *data, u32 size,
- struct nouveau_object **pobject);
-
-struct nv40_perfmon_cntr {
- struct nouveau_perfctr base;
-};
-
-extern const struct nouveau_funcdom nv40_perfctr_func;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c
deleted file mode 100644
index 94217691fe67..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include "nv40.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nv50_perfmon[] = {
- { 0x040, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x100, (const struct nouveau_specsig[]) {
- { 0xc8, "gr_idle" },
- {}
- }, &nv40_perfctr_func },
- { 0x100, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x020, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x040, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- {}
-};
-
-struct nouveau_oclass *
-nv50_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
- },
- .doms = nv50_perfmon,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c
deleted file mode 100644
index 6197ebdeb648..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include "nv40.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nva3_perfmon[] = {
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
- {}
- }, &nv40_perfctr_func },
- {}
-};
-
-static int
-nva3_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **object)
-{
- int ret = nv40_perfmon_ctor(parent, engine, oclass, data, size, object);
- if (ret == 0) {
- struct nv40_perfmon_priv *priv = (void *)*object;
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nva3_perfmon_pwr);
- if (ret)
- return ret;
-
- priv->base.last = 3;
- }
- return ret;
-}
-
-struct nouveau_oclass *
-nva3_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0xa3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
- },
- .doms = nva3_perfmon,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h
deleted file mode 100644
index f66bca484263..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __NVKM_PM_NVC0_H__
-#define __NVKM_PM_NVC0_H__
-
-#include "priv.h"
-
-struct nvc0_perfmon_priv {
- struct nouveau_perfmon base;
-};
-
-struct nvc0_perfmon_cntr {
- struct nouveau_perfctr base;
-};
-
-extern const struct nouveau_funcdom nvc0_perfctr_func;
-int nvc0_perfmon_fini(struct nouveau_object *, bool);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c
deleted file mode 100644
index 71d718c12075..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include "nvc0.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nve0_perfmon_hub[] = {
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub00_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x40, (const struct nouveau_specsig[]) {
- { 0x27, "hub01_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub02_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub03_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x40, (const struct nouveau_specsig[]) {
- { 0x03, "host_mmio_rd" },
- { 0x27, "hub04_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub05_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0xc0, (const struct nouveau_specsig[]) {
- { 0x74, "host_fb_rd3x" },
- { 0x75, "host_fb_rd3x_2" },
- { 0xa7, "hub06_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "hub07_user_0" },
- {}
- }, &nvc0_perfctr_func },
- {}
-};
-
-static const struct nouveau_specdom
-nve0_perfmon_gpc[] = {
- { 0xe0, (const struct nouveau_specsig[]) {
- { 0xc7, "gpc00_user_0" },
- {}
- }, &nvc0_perfctr_func },
- {}
-};
-
-static const struct nouveau_specdom
-nve0_perfmon_part[] = {
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "part00_user_0" },
- {}
- }, &nvc0_perfctr_func },
- { 0x60, (const struct nouveau_specsig[]) {
- { 0x47, "part01_user_0" },
- {}
- }, &nvc0_perfctr_func },
- {}
-};
-
-static int
-nve0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_perfmon_priv *priv;
- u32 mask;
- int ret;
-
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- /* PDAEMON */
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nve0_perfmon_pwr);
- if (ret)
- return ret;
-
- /* HUB */
- ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
- nve0_perfmon_hub);
- if (ret)
- return ret;
-
- /* GPC */
- mask = (1 << nv_rd32(priv, 0x022430)) - 1;
- mask &= ~nv_rd32(priv, 0x022504);
- mask &= ~nv_rd32(priv, 0x022584);
-
- ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000,
- 0x1000, 0x200, nve0_perfmon_gpc);
- if (ret)
- return ret;
-
- /* PART */
- mask = (1 << nv_rd32(priv, 0x022438)) - 1;
- mask &= ~nv_rd32(priv, 0x022548);
- mask &= ~nv_rd32(priv, 0x0225c8);
-
- ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000,
- 0x1000, 0x200, nve0_perfmon_part);
- if (ret)
- return ret;
-
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
- priv->base.last = 7;
- return 0;
-}
-
-struct nouveau_oclass
-nve0_perfmon_oclass = {
- .handle = NV_ENGINE(PERFMON, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = nvc0_perfmon_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c
deleted file mode 100644
index 47256f78a895..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include "nvc0.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static int
-nvf0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nvc0_perfmon_priv *priv;
- int ret;
-
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nve0_perfmon_pwr);
- if (ret)
- return ret;
-
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
- return 0;
-}
-
-struct nouveau_oclass
-nvf0_perfmon_oclass = {
- .handle = NV_ENGINE(PERFMON, 0xf0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvf0_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = nvc0_perfmon_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h
deleted file mode 100644
index 0ac8714fe0ba..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef __NVKM_PERFMON_PRIV_H__
-#define __NVKM_PERFMON_PRIV_H__
-
-#include <engine/perfmon.h>
-
-struct nouveau_perfctr {
- struct nouveau_object base;
- struct list_head head;
- struct nouveau_perfsig *signal[4];
- int slot;
- u32 logic_op;
- u32 clk;
- u32 ctr;
-};
-
-extern struct nouveau_oclass nouveau_perfmon_sclass[];
-
-struct nouveau_perfctx {
- struct nouveau_engctx base;
-};
-
-extern struct nouveau_oclass nouveau_perfmon_cclass;
-
-struct nouveau_specsig {
- u8 signal;
- const char *name;
-};
-
-struct nouveau_perfsig {
- const char *name;
-};
-
-struct nouveau_perfdom;
-struct nouveau_perfctr *
-nouveau_perfsig_wrap(struct nouveau_perfmon *, const char *,
- struct nouveau_perfdom **);
-
-struct nouveau_specdom {
- u16 signal_nr;
- const struct nouveau_specsig *signal;
- const struct nouveau_funcdom *func;
-};
-
-extern const struct nouveau_specdom nva3_perfmon_pwr[];
-extern const struct nouveau_specdom nvc0_perfmon_pwr[];
-extern const struct nouveau_specdom nve0_perfmon_pwr[];
-
-struct nouveau_perfdom {
- struct list_head head;
- struct list_head list;
- const struct nouveau_funcdom *func;
- char name[32];
- u32 addr;
- u8 quad;
- u32 signal_nr;
- struct nouveau_perfsig signal[];
-};
-
-struct nouveau_funcdom {
- void (*init)(struct nouveau_perfmon *, struct nouveau_perfdom *,
- struct nouveau_perfctr *);
- void (*read)(struct nouveau_perfmon *, struct nouveau_perfdom *,
- struct nouveau_perfctr *);
- void (*next)(struct nouveau_perfmon *, struct nouveau_perfdom *);
-};
-
-int nouveau_perfdom_new(struct nouveau_perfmon *, const char *, u32,
- u32, u32, u32, const struct nouveau_specdom *);
-
-#define nouveau_perfmon_create(p,e,o,d) \
- nouveau_perfmon_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_perfmon_dtor(p) ({ \
- struct nouveau_perfmon *c = (p); \
- _nouveau_perfmon_dtor(nv_object(c)); \
-})
-#define nouveau_perfmon_init(p) ({ \
- struct nouveau_perfmon *c = (p); \
- _nouveau_perfmon_init(nv_object(c)); \
-})
-#define nouveau_perfmon_fini(p,s) ({ \
- struct nouveau_perfmon *c = (p); \
- _nouveau_perfmon_fini(nv_object(c), (s)); \
-})
-
-int nouveau_perfmon_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_perfmon_dtor(struct nouveau_object *);
-int _nouveau_perfmon_init(struct nouveau_object *);
-int _nouveau_perfmon_fini(struct nouveau_object *, bool);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h
deleted file mode 100644
index 41542e725b4b..000000000000
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __NVKM_SW_NV50_H__
-#define __NVKM_SW_NV50_H__
-
-#include <engine/software.h>
-
-struct nv50_software_oclass {
- struct nouveau_oclass base;
- struct nouveau_oclass *cclass;
- struct nouveau_oclass *sclass;
-};
-
-struct nv50_software_priv {
- struct nouveau_software base;
-};
-
-int nv50_software_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-struct nv50_software_cclass {
- struct nouveau_oclass base;
- int (*vblank)(struct nvkm_notify *);
-};
-
-struct nv50_software_chan {
- struct nouveau_software_chan base;
- struct {
- struct nvkm_notify notify[4];
- u32 channel;
- u32 ctxdma;
- u64 offset;
- u32 value;
- } vblank;
-};
-
-int nv50_software_context_ctor(struct nouveau_object *,
- struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv50_software_context_dtor(struct nouveau_object *);
-
-int nv50_software_mthd_vblsem_value(struct nouveau_object *, u32, void *, u32);
-int nv50_software_mthd_vblsem_release(struct nouveau_object *, u32, void *, u32);
-int nv50_software_mthd_flip(struct nouveau_object *, u32, void *, u32);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h
deleted file mode 100644
index b0ce9f6680b5..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/client.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef __NOUVEAU_CLIENT_H__
-#define __NOUVEAU_CLIENT_H__
-
-#include <core/namedb.h>
-
-struct nouveau_client {
- struct nouveau_namedb base;
- struct nouveau_handle *root;
- struct nouveau_object *device;
- char name[32];
- u32 debug;
- struct nouveau_vm *vm;
- bool super;
- void *data;
-
- int (*ntfy)(const void *, u32, const void *, u32);
- struct nvkm_client_notify *notify[16];
-};
-
-static inline struct nouveau_client *
-nv_client(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(obj, NV_CLIENT_CLASS)))
- nv_assert("BAD CAST -> NvClient, %08x", nv_hclass(obj));
-#endif
- return obj;
-}
-
-static inline struct nouveau_client *
-nouveau_client(void *obj)
-{
- struct nouveau_object *client = nv_object(obj);
- while (client && !(nv_iclass(client, NV_CLIENT_CLASS)))
- client = client->parent;
- return (void *)client;
-}
-
-#define nouveau_client_create(n,c,oc,od,d) \
- nouveau_client_create_((n), (c), (oc), (od), sizeof(**d), (void **)d)
-
-int nouveau_client_create_(const char *name, u64 device, const char *cfg,
- const char *dbg, int, void **);
-#define nouveau_client_destroy(p) \
- nouveau_namedb_destroy(&(p)->base)
-
-int nouveau_client_init(struct nouveau_client *);
-int nouveau_client_fini(struct nouveau_client *, bool suspend);
-const char *nouveau_client_name(void *obj);
-
-int nvkm_client_notify_new(struct nouveau_object *, struct nvkm_event *,
- void *data, u32 size);
-int nvkm_client_notify_del(struct nouveau_client *, int index);
-int nvkm_client_notify_get(struct nouveau_client *, int index);
-int nvkm_client_notify_put(struct nouveau_client *, int index);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
deleted file mode 100644
index 2ec2e50d3676..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef __NOUVEAU_DEVICE_H__
-#define __NOUVEAU_DEVICE_H__
-
-#include <core/object.h>
-#include <core/subdev.h>
-#include <core/engine.h>
-#include <core/event.h>
-
-enum nv_subdev_type {
- NVDEV_ENGINE_DEVICE,
- NVDEV_SUBDEV_VBIOS,
-
- /* All subdevs from DEVINIT to DEVINIT_LAST will be created before
- * *any* of them are initialised. This subdev category is used
- * for any subdevs that the VBIOS init table parsing may call out
- * to during POST.
- */
- NVDEV_SUBDEV_DEVINIT,
- NVDEV_SUBDEV_IBUS,
- NVDEV_SUBDEV_GPIO,
- NVDEV_SUBDEV_I2C,
- NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_I2C,
-
- /* This grouping of subdevs are initialised right after they've
- * been created, and are allowed to assume any subdevs in the
- * list above them exist and have been initialised.
- */
- NVDEV_SUBDEV_FUSE,
- NVDEV_SUBDEV_MXM,
- NVDEV_SUBDEV_MC,
- NVDEV_SUBDEV_BUS,
- NVDEV_SUBDEV_TIMER,
- NVDEV_SUBDEV_FB,
- NVDEV_SUBDEV_LTC,
- NVDEV_SUBDEV_INSTMEM,
- NVDEV_SUBDEV_VM,
- NVDEV_SUBDEV_BAR,
- NVDEV_SUBDEV_PWR,
- NVDEV_SUBDEV_VOLT,
- NVDEV_SUBDEV_THERM,
- NVDEV_SUBDEV_CLOCK,
-
- NVDEV_ENGINE_FIRST,
- NVDEV_ENGINE_DMAOBJ = NVDEV_ENGINE_FIRST,
- NVDEV_ENGINE_IFB,
- NVDEV_ENGINE_FIFO,
- NVDEV_ENGINE_SW,
- NVDEV_ENGINE_GR,
- NVDEV_ENGINE_MPEG,
- NVDEV_ENGINE_ME,
- NVDEV_ENGINE_VP,
- NVDEV_ENGINE_CRYPT,
- NVDEV_ENGINE_BSP,
- NVDEV_ENGINE_PPP,
- NVDEV_ENGINE_COPY0,
- NVDEV_ENGINE_COPY1,
- NVDEV_ENGINE_COPY2,
- NVDEV_ENGINE_VIC,
- NVDEV_ENGINE_VENC,
- NVDEV_ENGINE_DISP,
- NVDEV_ENGINE_PERFMON,
-
- NVDEV_SUBDEV_NR,
-};
-
-struct nouveau_device {
- struct nouveau_engine base;
- struct list_head head;
-
- struct pci_dev *pdev;
- struct platform_device *platformdev;
- u64 handle;
-
- struct nvkm_event event;
-
- const char *cfgopt;
- const char *dbgopt;
- const char *name;
- const char *cname;
- u64 disable_mask;
-
- enum {
- NV_04 = 0x04,
- NV_10 = 0x10,
- NV_11 = 0x11,
- NV_20 = 0x20,
- NV_30 = 0x30,
- NV_40 = 0x40,
- NV_50 = 0x50,
- NV_C0 = 0xc0,
- NV_E0 = 0xe0,
- GM100 = 0x110,
- } card_type;
- u32 chipset;
- u8 chiprev;
- u32 crystal;
-
- struct nouveau_oclass *oclass[NVDEV_SUBDEV_NR];
- struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
-
- struct {
- struct notifier_block nb;
- } acpi;
-};
-
-int nouveau_device_list(u64 *name, int size);
-
-static inline struct nouveau_device *
-nv_device(void *obj)
-{
- struct nouveau_object *object = nv_object(obj);
- struct nouveau_object *device = object;
-
- if (device->engine)
- device = device->engine;
- if (device->parent)
- device = device->parent;
-
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) ||
- (nv_hclass(device) & 0xff) != NVDEV_ENGINE_DEVICE)) {
- nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x",
- nv_hclass(object), nv_hclass(device));
- }
-#endif
-
- return (void *)device;
-}
-
-static inline struct nouveau_subdev *
-nouveau_subdev(void *obj, int sub)
-{
- if (nv_device(obj)->subdev[sub])
- return nv_subdev(nv_device(obj)->subdev[sub]);
- return NULL;
-}
-
-static inline struct nouveau_engine *
-nouveau_engine(void *obj, int sub)
-{
- struct nouveau_subdev *subdev = nouveau_subdev(obj, sub);
- if (subdev && nv_iclass(subdev, NV_ENGINE_CLASS))
- return nv_engine(subdev);
- return NULL;
-}
-
-static inline bool
-nv_device_match(struct nouveau_object *object, u16 dev, u16 ven, u16 sub)
-{
- struct nouveau_device *device = nv_device(object);
- return device->pdev->device == dev &&
- device->pdev->subsystem_vendor == ven &&
- device->pdev->subsystem_device == sub;
-}
-
-static inline bool
-nv_device_is_pci(struct nouveau_device *device)
-{
- return device->pdev != NULL;
-}
-
-static inline bool
-nv_device_is_cpu_coherent(struct nouveau_device *device)
-{
- return (!IS_ENABLED(CONFIG_ARM) && nv_device_is_pci(device));
-}
-
-static inline struct device *
-nv_device_base(struct nouveau_device *device)
-{
- return nv_device_is_pci(device) ? &device->pdev->dev :
- &device->platformdev->dev;
-}
-
-resource_size_t
-nv_device_resource_start(struct nouveau_device *device, unsigned int bar);
-
-resource_size_t
-nv_device_resource_len(struct nouveau_device *device, unsigned int bar);
-
-int
-nv_device_get_irq(struct nouveau_device *device, bool stall);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/engctx.h b/drivers/gpu/drm/nouveau/core/include/core/engctx.h
deleted file mode 100644
index 2fd48b564c7d..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/engctx.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef __NOUVEAU_ENGCTX_H__
-#define __NOUVEAU_ENGCTX_H__
-
-#include <core/object.h>
-#include <core/gpuobj.h>
-
-#include <subdev/vm.h>
-
-#define NV_ENGCTX_(eng,var) (NV_ENGCTX_CLASS | ((var) << 8) | (eng))
-#define NV_ENGCTX(name,var) NV_ENGCTX_(NVDEV_ENGINE_##name, (var))
-
-struct nouveau_engctx {
- struct nouveau_gpuobj base;
- struct nouveau_vma vma;
- struct list_head head;
- unsigned long save;
- u64 addr;
-};
-
-static inline struct nouveau_engctx *
-nv_engctx(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(obj, NV_ENGCTX_CLASS)))
- nv_assert("BAD CAST -> NvEngCtx, %08x", nv_hclass(obj));
-#endif
- return obj;
-}
-
-#define nouveau_engctx_create(p,e,c,g,s,a,f,d) \
- nouveau_engctx_create_((p), (e), (c), (g), (s), (a), (f), \
- sizeof(**d), (void **)d)
-
-int nouveau_engctx_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, struct nouveau_object *,
- u32 size, u32 align, u32 flags,
- int length, void **data);
-void nouveau_engctx_destroy(struct nouveau_engctx *);
-int nouveau_engctx_init(struct nouveau_engctx *);
-int nouveau_engctx_fini(struct nouveau_engctx *, bool suspend);
-
-int _nouveau_engctx_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void _nouveau_engctx_dtor(struct nouveau_object *);
-int _nouveau_engctx_init(struct nouveau_object *);
-int _nouveau_engctx_fini(struct nouveau_object *, bool suspend);
-#define _nouveau_engctx_rd32 _nouveau_gpuobj_rd32
-#define _nouveau_engctx_wr32 _nouveau_gpuobj_wr32
-
-struct nouveau_object *nouveau_engctx_get(struct nouveau_engine *, u64 addr);
-void nouveau_engctx_put(struct nouveau_object *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/engine.h b/drivers/gpu/drm/nouveau/core/include/core/engine.h
deleted file mode 100644
index 666d06de77ec..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/engine.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef __NOUVEAU_ENGINE_H__
-#define __NOUVEAU_ENGINE_H__
-
-#include <core/object.h>
-#include <core/subdev.h>
-
-#define NV_ENGINE_(eng,var) (NV_ENGINE_CLASS | ((var) << 8) | (eng))
-#define NV_ENGINE(name,var) NV_ENGINE_(NVDEV_ENGINE_##name, (var))
-
-struct nouveau_engine {
- struct nouveau_subdev base;
- struct nouveau_oclass *cclass;
- struct nouveau_oclass *sclass;
-
- struct list_head contexts;
- spinlock_t lock;
-
- void (*tile_prog)(struct nouveau_engine *, int region);
- int (*tlb_flush)(struct nouveau_engine *);
-};
-
-static inline struct nouveau_engine *
-nv_engine(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(obj, NV_ENGINE_CLASS)))
- nv_assert("BAD CAST -> NvEngine, %08x", nv_hclass(obj));
-#endif
- return obj;
-}
-
-static inline int
-nv_engidx(struct nouveau_object *object)
-{
- return nv_subidx(object);
-}
-
-#define nouveau_engine_create(p,e,c,d,i,f,r) \
- nouveau_engine_create_((p), (e), (c), (d), (i), (f), \
- sizeof(**r),(void **)r)
-
-#define nouveau_engine_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_engine_init(p) \
- nouveau_subdev_init(&(p)->base)
-#define nouveau_engine_fini(p,s) \
- nouveau_subdev_fini(&(p)->base, (s))
-
-int nouveau_engine_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, bool, const char *,
- const char *, int, void **);
-
-#define _nouveau_engine_dtor _nouveau_subdev_dtor
-#define _nouveau_engine_init _nouveau_subdev_init
-#define _nouveau_engine_fini _nouveau_subdev_fini
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/enum.h b/drivers/gpu/drm/nouveau/core/include/core/enum.h
deleted file mode 100644
index 4fc62bb8c1f0..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/enum.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef __NOUVEAU_ENUM_H__
-#define __NOUVEAU_ENUM_H__
-
-struct nouveau_enum {
- u32 value;
- const char *name;
- const void *data;
- u32 data2;
-};
-
-const struct nouveau_enum *
-nouveau_enum_find(const struct nouveau_enum *, u32 value);
-
-const struct nouveau_enum *
-nouveau_enum_print(const struct nouveau_enum *en, u32 value);
-
-struct nouveau_bitfield {
- u32 mask;
- const char *name;
-};
-
-void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h b/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h
deleted file mode 100644
index b3b9ce4e9d38..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __NOUVEAU_GPUOBJ_H__
-#define __NOUVEAU_GPUOBJ_H__
-
-#include <core/object.h>
-#include <core/device.h>
-#include <core/parent.h>
-#include <core/mm.h>
-
-struct nouveau_vma;
-struct nouveau_vm;
-
-#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001
-#define NVOBJ_FLAG_ZERO_FREE 0x00000002
-#define NVOBJ_FLAG_HEAP 0x00000004
-
-struct nouveau_gpuobj {
- struct nouveau_object base;
- struct nouveau_object *parent;
- struct nouveau_mm_node *node;
- struct nouveau_mm heap;
-
- u32 flags;
- u64 addr;
- u32 size;
-};
-
-static inline struct nouveau_gpuobj *
-nv_gpuobj(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(obj, NV_GPUOBJ_CLASS)))
- nv_assert("BAD CAST -> NvGpuObj, %08x", nv_hclass(obj));
-#endif
- return obj;
-}
-
-#define nouveau_gpuobj_create(p,e,c,v,g,s,a,f,d) \
- nouveau_gpuobj_create_((p), (e), (c), (v), (g), (s), (a), (f), \
- sizeof(**d), (void **)d)
-#define nouveau_gpuobj_init(p) nouveau_object_init(&(p)->base)
-#define nouveau_gpuobj_fini(p,s) nouveau_object_fini(&(p)->base, (s))
-int nouveau_gpuobj_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u32 pclass,
- struct nouveau_object *, u32 size, u32 align,
- u32 flags, int length, void **);
-void nouveau_gpuobj_destroy(struct nouveau_gpuobj *);
-
-int nouveau_gpuobj_new(struct nouveau_object *, struct nouveau_object *,
- u32 size, u32 align, u32 flags,
- struct nouveau_gpuobj **);
-int nouveau_gpuobj_dup(struct nouveau_object *, struct nouveau_gpuobj *,
- struct nouveau_gpuobj **);
-
-int nouveau_gpuobj_map(struct nouveau_gpuobj *, u32 acc, struct nouveau_vma *);
-int nouveau_gpuobj_map_vm(struct nouveau_gpuobj *, struct nouveau_vm *,
- u32 access, struct nouveau_vma *);
-void nouveau_gpuobj_unmap(struct nouveau_vma *);
-
-static inline void
-nouveau_gpuobj_ref(struct nouveau_gpuobj *obj, struct nouveau_gpuobj **ref)
-{
- nouveau_object_ref(&obj->base, (struct nouveau_object **)ref);
-}
-
-void _nouveau_gpuobj_dtor(struct nouveau_object *);
-int _nouveau_gpuobj_init(struct nouveau_object *);
-int _nouveau_gpuobj_fini(struct nouveau_object *, bool);
-u32 _nouveau_gpuobj_rd32(struct nouveau_object *, u64);
-void _nouveau_gpuobj_wr32(struct nouveau_object *, u64, u32);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/handle.h b/drivers/gpu/drm/nouveau/core/include/core/handle.h
deleted file mode 100644
index d22a59138a9b..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/handle.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __NOUVEAU_HANDLE_H__
-#define __NOUVEAU_HANDLE_H__
-
-struct nouveau_handle {
- struct nouveau_namedb *namedb;
- struct list_head node;
-
- struct list_head head;
- struct list_head tree;
- u32 name;
- u32 priv;
-
- u8 route;
- u64 token;
-
- struct nouveau_handle *parent;
- struct nouveau_object *object;
-};
-
-int nouveau_handle_create(struct nouveau_object *, u32 parent, u32 handle,
- struct nouveau_object *, struct nouveau_handle **);
-void nouveau_handle_destroy(struct nouveau_handle *);
-int nouveau_handle_init(struct nouveau_handle *);
-int nouveau_handle_fini(struct nouveau_handle *, bool suspend);
-
-struct nouveau_object *
-nouveau_handle_ref(struct nouveau_object *, u32 name);
-
-struct nouveau_handle *nouveau_handle_get_class(struct nouveau_object *, u16);
-struct nouveau_handle *nouveau_handle_get_vinst(struct nouveau_object *, u64);
-struct nouveau_handle *nouveau_handle_get_cinst(struct nouveau_object *, u32);
-void nouveau_handle_put(struct nouveau_handle *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/ioctl.h b/drivers/gpu/drm/nouveau/core/include/core/ioctl.h
deleted file mode 100644
index ac7935c2474e..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/ioctl.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __NVKM_IOCTL_H__
-#define __NVKM_IOCTL_H__
-
-int nvkm_ioctl(struct nouveau_client *, bool, void *, u32, void **);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/mm.h b/drivers/gpu/drm/nouveau/core/include/core/mm.h
deleted file mode 100644
index bfe6931544fe..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/mm.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __NOUVEAU_MM_H__
-#define __NOUVEAU_MM_H__
-
-struct nouveau_mm_node {
- struct list_head nl_entry;
- struct list_head fl_entry;
- struct list_head rl_entry;
-
-#define NVKM_MM_HEAP_ANY 0x00
- u8 heap;
-#define NVKM_MM_TYPE_NONE 0x00
-#define NVKM_MM_TYPE_HOLE 0xff
- u8 type;
- u32 offset;
- u32 length;
-};
-
-struct nouveau_mm {
- struct list_head nodes;
- struct list_head free;
-
- u32 block_size;
- int heap_nodes;
-};
-
-static inline bool
-nouveau_mm_initialised(struct nouveau_mm *mm)
-{
- return mm->block_size != 0;
-}
-
-int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);
-int nouveau_mm_fini(struct nouveau_mm *);
-int nouveau_mm_head(struct nouveau_mm *, u8 heap, u8 type, u32 size_max,
- u32 size_min, u32 align, struct nouveau_mm_node **);
-int nouveau_mm_tail(struct nouveau_mm *, u8 heap, u8 type, u32 size_max,
- u32 size_min, u32 align, struct nouveau_mm_node **);
-void nouveau_mm_free(struct nouveau_mm *, struct nouveau_mm_node **);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/namedb.h b/drivers/gpu/drm/nouveau/core/include/core/namedb.h
deleted file mode 100644
index f5b5fd8e1fc9..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/namedb.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __NOUVEAU_NAMEDB_H__
-#define __NOUVEAU_NAMEDB_H__
-
-#include <core/parent.h>
-
-struct nouveau_handle;
-
-struct nouveau_namedb {
- struct nouveau_parent base;
- rwlock_t lock;
- struct list_head list;
-};
-
-static inline struct nouveau_namedb *
-nv_namedb(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(obj, NV_NAMEDB_CLASS)))
- nv_assert("BAD CAST -> NvNameDB, %08x", nv_hclass(obj));
-#endif
- return obj;
-}
-
-#define nouveau_namedb_create(p,e,c,v,s,m,d) \
- nouveau_namedb_create_((p), (e), (c), (v), (s), (m), \
- sizeof(**d), (void **)d)
-#define nouveau_namedb_init(p) \
- nouveau_parent_init(&(p)->base)
-#define nouveau_namedb_fini(p,s) \
- nouveau_parent_fini(&(p)->base, (s))
-#define nouveau_namedb_destroy(p) \
- nouveau_parent_destroy(&(p)->base)
-
-int nouveau_namedb_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u32 pclass,
- struct nouveau_oclass *, u64 engcls,
- int size, void **);
-
-int _nouveau_namedb_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-#define _nouveau_namedb_dtor _nouveau_parent_dtor
-#define _nouveau_namedb_init _nouveau_parent_init
-#define _nouveau_namedb_fini _nouveau_parent_fini
-
-int nouveau_namedb_insert(struct nouveau_namedb *, u32 name,
- struct nouveau_object *, struct nouveau_handle *);
-void nouveau_namedb_remove(struct nouveau_handle *);
-
-struct nouveau_handle *nouveau_namedb_get(struct nouveau_namedb *, u32);
-struct nouveau_handle *nouveau_namedb_get_class(struct nouveau_namedb *, u16);
-struct nouveau_handle *nouveau_namedb_get_vinst(struct nouveau_namedb *, u64);
-struct nouveau_handle *nouveau_namedb_get_cinst(struct nouveau_namedb *, u32);
-void nouveau_namedb_put(struct nouveau_handle *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/option.h b/drivers/gpu/drm/nouveau/core/include/core/option.h
deleted file mode 100644
index ed055847887e..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/option.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __NOUVEAU_OPTION_H__
-#define __NOUVEAU_OPTION_H__
-
-#include <core/os.h>
-
-const char *nouveau_stropt(const char *optstr, const char *opt, int *len);
-bool nouveau_boolopt(const char *optstr, const char *opt, bool value);
-
-int nouveau_dbgopt(const char *optstr, const char *sub);
-
-/* compares unterminated string 'str' with zero-terminated string 'cmp' */
-static inline int
-strncasecmpz(const char *str, const char *cmp, size_t len)
-{
- if (strlen(cmp) != len)
- return len;
- return strncasecmp(str, cmp, len);
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/parent.h b/drivers/gpu/drm/nouveau/core/include/core/parent.h
deleted file mode 100644
index 12da418ec70a..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/parent.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __NOUVEAU_PARENT_H__
-#define __NOUVEAU_PARENT_H__
-
-#include <core/device.h>
-#include <core/object.h>
-
-struct nouveau_sclass {
- struct nouveau_sclass *sclass;
- struct nouveau_engine *engine;
- struct nouveau_oclass *oclass;
-};
-
-struct nouveau_parent {
- struct nouveau_object base;
-
- struct nouveau_sclass *sclass;
- u64 engine;
-
- int (*context_attach)(struct nouveau_object *,
- struct nouveau_object *);
- int (*context_detach)(struct nouveau_object *, bool suspend,
- struct nouveau_object *);
-
- int (*object_attach)(struct nouveau_object *parent,
- struct nouveau_object *object, u32 name);
- void (*object_detach)(struct nouveau_object *parent, int cookie);
-};
-
-static inline struct nouveau_parent *
-nv_parent(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!(nv_iclass(obj, NV_PARENT_CLASS))))
- nv_assert("BAD CAST -> NvParent, %08x", nv_hclass(obj));
-#endif
- return obj;
-}
-
-#define nouveau_parent_create(p,e,c,v,s,m,d) \
- nouveau_parent_create_((p), (e), (c), (v), (s), (m), \
- sizeof(**d), (void **)d)
-#define nouveau_parent_init(p) \
- nouveau_object_init(&(p)->base)
-#define nouveau_parent_fini(p,s) \
- nouveau_object_fini(&(p)->base, (s))
-
-int nouveau_parent_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u32 pclass,
- struct nouveau_oclass *, u64 engcls,
- int size, void **);
-void nouveau_parent_destroy(struct nouveau_parent *);
-
-void _nouveau_parent_dtor(struct nouveau_object *);
-#define _nouveau_parent_init nouveau_object_init
-#define _nouveau_parent_fini nouveau_object_fini
-
-int nouveau_parent_sclass(struct nouveau_object *, u16 handle,
- struct nouveau_object **pengine,
- struct nouveau_oclass **poclass);
-int nouveau_parent_lclass(struct nouveau_object *, u32 *, int);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/ramht.h b/drivers/gpu/drm/nouveau/core/include/core/ramht.h
deleted file mode 100644
index 47e4cacbca37..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/core/ramht.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __NOUVEAU_RAMHT_H__
-#define __NOUVEAU_RAMHT_H__
-
-#include <core/gpuobj.h>
-
-struct nouveau_ramht {
- struct nouveau_gpuobj base;
- int bits;
-};
-
-int nouveau_ramht_insert(struct nouveau_ramht *, int chid,
- u32 handle, u32 context);
-void nouveau_ramht_remove(struct nouveau_ramht *, int cookie);
-int nouveau_ramht_new(struct nouveau_object *, struct nouveau_object *,
- u32 size, u32 align, struct nouveau_ramht **);
-
-static inline void
-nouveau_ramht_ref(struct nouveau_ramht *obj, struct nouveau_ramht **ref)
-{
- nouveau_gpuobj_ref(&obj->base, (struct nouveau_gpuobj **)ref);
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/bsp.h b/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
deleted file mode 100644
index 67662e2c4547..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __NOUVEAU_BSP_H__
-#define __NOUVEAU_BSP_H__
-
-extern struct nouveau_oclass nv84_bsp_oclass;
-extern struct nouveau_oclass nv98_bsp_oclass;
-extern struct nouveau_oclass nvc0_bsp_oclass;
-extern struct nouveau_oclass nve0_bsp_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/copy.h b/drivers/gpu/drm/nouveau/core/include/engine/copy.h
deleted file mode 100644
index 316a28ae5f5c..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/copy.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __NOUVEAU_COPY_H__
-#define __NOUVEAU_COPY_H__
-
-void nva3_copy_intr(struct nouveau_subdev *);
-
-extern struct nouveau_oclass nva3_copy_oclass;
-extern struct nouveau_oclass nvc0_copy0_oclass;
-extern struct nouveau_oclass nvc0_copy1_oclass;
-extern struct nouveau_oclass nve0_copy0_oclass;
-extern struct nouveau_oclass nve0_copy1_oclass;
-extern struct nouveau_oclass nve0_copy2_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/crypt.h b/drivers/gpu/drm/nouveau/core/include/engine/crypt.h
deleted file mode 100644
index db975618e937..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/crypt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __NOUVEAU_CRYPT_H__
-#define __NOUVEAU_CRYPT_H__
-
-extern struct nouveau_oclass nv84_crypt_oclass;
-extern struct nouveau_oclass nv98_crypt_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/disp.h b/drivers/gpu/drm/nouveau/core/include/engine/disp.h
deleted file mode 100644
index fc307f1317ff..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/disp.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __NOUVEAU_DISP_H__
-#define __NOUVEAU_DISP_H__
-
-#include <core/object.h>
-#include <core/engine.h>
-#include <core/device.h>
-#include <core/event.h>
-
-struct nouveau_disp {
- struct nouveau_engine base;
-
- struct list_head outp;
-
- struct nvkm_event hpd;
- struct nvkm_event vblank;
-};
-
-static inline struct nouveau_disp *
-nouveau_disp(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_DISP];
-}
-
-extern struct nouveau_oclass *nv04_disp_oclass;
-extern struct nouveau_oclass *nv50_disp_oclass;
-extern struct nouveau_oclass *nv84_disp_oclass;
-extern struct nouveau_oclass *nva0_disp_oclass;
-extern struct nouveau_oclass *nv94_disp_oclass;
-extern struct nouveau_oclass *nva3_disp_oclass;
-extern struct nouveau_oclass *nvd0_disp_oclass;
-extern struct nouveau_oclass *nve0_disp_oclass;
-extern struct nouveau_oclass *nvf0_disp_oclass;
-extern struct nouveau_oclass *gm107_disp_oclass;
-extern struct nouveau_oclass *gm204_disp_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h b/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h
deleted file mode 100644
index 1b283a7b78e6..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __NOUVEAU_DMAOBJ_H__
-#define __NOUVEAU_DMAOBJ_H__
-
-#include <core/object.h>
-#include <core/engine.h>
-
-struct nouveau_gpuobj;
-
-struct nouveau_dmaobj {
- struct nouveau_object base;
- u32 target;
- u32 access;
- u64 start;
- u64 limit;
-};
-
-struct nouveau_dmaeng {
- struct nouveau_engine base;
-
- /* creates a "physical" dma object from a struct nouveau_dmaobj */
- int (*bind)(struct nouveau_dmaobj *dmaobj,
- struct nouveau_object *parent,
- struct nouveau_gpuobj **);
-};
-
-extern struct nouveau_oclass *nv04_dmaeng_oclass;
-extern struct nouveau_oclass *nv50_dmaeng_oclass;
-extern struct nouveau_oclass *nvc0_dmaeng_oclass;
-extern struct nouveau_oclass *nvd0_dmaeng_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/falcon.h b/drivers/gpu/drm/nouveau/core/include/engine/falcon.h
deleted file mode 100644
index 181aa7da524d..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/falcon.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef __NOUVEAU_FALCON_H__
-#define __NOUVEAU_FALCON_H__
-
-#include <core/engine.h>
-#include <core/engctx.h>
-#include <core/gpuobj.h>
-
-struct nouveau_falcon_chan {
- struct nouveau_engctx base;
-};
-
-#define nouveau_falcon_context_create(p,e,c,g,s,a,f,d) \
- nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
-#define nouveau_falcon_context_destroy(d) \
- nouveau_engctx_destroy(&(d)->base)
-#define nouveau_falcon_context_init(d) \
- nouveau_engctx_init(&(d)->base)
-#define nouveau_falcon_context_fini(d,s) \
- nouveau_engctx_fini(&(d)->base, (s))
-
-#define _nouveau_falcon_context_ctor _nouveau_engctx_ctor
-#define _nouveau_falcon_context_dtor _nouveau_engctx_dtor
-#define _nouveau_falcon_context_init _nouveau_engctx_init
-#define _nouveau_falcon_context_fini _nouveau_engctx_fini
-#define _nouveau_falcon_context_rd32 _nouveau_engctx_rd32
-#define _nouveau_falcon_context_wr32 _nouveau_engctx_wr32
-
-struct nouveau_falcon_data {
- bool external;
-};
-
-struct nouveau_falcon {
- struct nouveau_engine base;
-
- u32 addr;
- u8 version;
- u8 secret;
-
- struct nouveau_gpuobj *core;
- bool external;
-
- struct {
- u32 limit;
- u32 *data;
- u32 size;
- } code;
-
- struct {
- u32 limit;
- u32 *data;
- u32 size;
- } data;
-};
-
-#define nv_falcon(priv) (&(priv)->base)
-
-#define nouveau_falcon_create(p,e,c,b,d,i,f,r) \
- nouveau_falcon_create_((p), (e), (c), (b), (d), (i), (f), \
- sizeof(**r),(void **)r)
-#define nouveau_falcon_destroy(p) \
- nouveau_engine_destroy(&(p)->base)
-#define nouveau_falcon_init(p) ({ \
- struct nouveau_falcon *falcon = (p); \
- _nouveau_falcon_init(nv_object(falcon)); \
-})
-#define nouveau_falcon_fini(p,s) ({ \
- struct nouveau_falcon *falcon = (p); \
- _nouveau_falcon_fini(nv_object(falcon), (s)); \
-})
-
-int nouveau_falcon_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u32, bool, const char *,
- const char *, int, void **);
-
-void nouveau_falcon_intr(struct nouveau_subdev *subdev);
-
-#define _nouveau_falcon_dtor _nouveau_engine_dtor
-int _nouveau_falcon_init(struct nouveau_object *);
-int _nouveau_falcon_fini(struct nouveau_object *, bool);
-u32 _nouveau_falcon_rd32(struct nouveau_object *, u64);
-void _nouveau_falcon_wr32(struct nouveau_object *, u64, u32);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
deleted file mode 100644
index 2007453f6fce..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef __NOUVEAU_FIFO_H__
-#define __NOUVEAU_FIFO_H__
-
-#include <core/namedb.h>
-#include <core/gpuobj.h>
-#include <core/engine.h>
-#include <core/event.h>
-
-struct nouveau_fifo_chan {
- struct nouveau_namedb base;
- struct nouveau_dmaobj *pushdma;
- struct nouveau_gpuobj *pushgpu;
- void __iomem *user;
- u64 addr;
- u32 size;
- u16 chid;
- atomic_t refcnt; /* NV04_NVSW_SET_REF */
-};
-
-static inline struct nouveau_fifo_chan *
-nouveau_fifo_chan(void *obj)
-{
- return (void *)nv_namedb(obj);
-}
-
-#define nouveau_fifo_channel_create(p,e,c,b,a,s,n,m,d) \
- nouveau_fifo_channel_create_((p), (e), (c), (b), (a), (s), (n), \
- (m), sizeof(**d), (void **)d)
-#define nouveau_fifo_channel_init(p) \
- nouveau_namedb_init(&(p)->base)
-#define nouveau_fifo_channel_fini(p,s) \
- nouveau_namedb_fini(&(p)->base, (s))
-
-int nouveau_fifo_channel_create_(struct nouveau_object *,
- struct nouveau_object *,
- struct nouveau_oclass *,
- int bar, u32 addr, u32 size, u32 push,
- u64 engmask, int len, void **);
-void nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *);
-
-#define _nouveau_fifo_channel_init _nouveau_namedb_init
-#define _nouveau_fifo_channel_fini _nouveau_namedb_fini
-
-void _nouveau_fifo_channel_dtor(struct nouveau_object *);
-int _nouveau_fifo_channel_map(struct nouveau_object *, u64 *, u32 *);
-u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u64);
-void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32);
-int _nouveau_fifo_channel_ntfy(struct nouveau_object *, u32, struct nvkm_event **);
-
-struct nouveau_fifo_base {
- struct nouveau_gpuobj base;
-};
-
-#define nouveau_fifo_context_create(p,e,c,g,s,a,f,d) \
- nouveau_gpuobj_create((p), (e), (c), 0, (g), (s), (a), (f), (d))
-#define nouveau_fifo_context_destroy(p) \
- nouveau_gpuobj_destroy(&(p)->base)
-#define nouveau_fifo_context_init(p) \
- nouveau_gpuobj_init(&(p)->base)
-#define nouveau_fifo_context_fini(p,s) \
- nouveau_gpuobj_fini(&(p)->base, (s))
-
-#define _nouveau_fifo_context_dtor _nouveau_gpuobj_dtor
-#define _nouveau_fifo_context_init _nouveau_gpuobj_init
-#define _nouveau_fifo_context_fini _nouveau_gpuobj_fini
-#define _nouveau_fifo_context_rd32 _nouveau_gpuobj_rd32
-#define _nouveau_fifo_context_wr32 _nouveau_gpuobj_wr32
-
-struct nouveau_fifo {
- struct nouveau_engine base;
-
- struct nvkm_event cevent; /* channel creation event */
- struct nvkm_event uevent; /* async user trigger */
-
- struct nouveau_object **channel;
- spinlock_t lock;
- u16 min;
- u16 max;
-
- int (*chid)(struct nouveau_fifo *, struct nouveau_object *);
- void (*pause)(struct nouveau_fifo *, unsigned long *);
- void (*start)(struct nouveau_fifo *, unsigned long *);
-};
-
-static inline struct nouveau_fifo *
-nouveau_fifo(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_FIFO];
-}
-
-#define nouveau_fifo_create(o,e,c,fc,lc,d) \
- nouveau_fifo_create_((o), (e), (c), (fc), (lc), sizeof(**d), (void **)d)
-#define nouveau_fifo_init(p) \
- nouveau_engine_init(&(p)->base)
-#define nouveau_fifo_fini(p,s) \
- nouveau_engine_fini(&(p)->base, (s))
-
-int nouveau_fifo_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int min, int max,
- int size, void **);
-void nouveau_fifo_destroy(struct nouveau_fifo *);
-const char *
-nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid);
-
-#define _nouveau_fifo_init _nouveau_engine_init
-#define _nouveau_fifo_fini _nouveau_engine_fini
-
-extern struct nouveau_oclass *nv04_fifo_oclass;
-extern struct nouveau_oclass *nv10_fifo_oclass;
-extern struct nouveau_oclass *nv17_fifo_oclass;
-extern struct nouveau_oclass *nv40_fifo_oclass;
-extern struct nouveau_oclass *nv50_fifo_oclass;
-extern struct nouveau_oclass *nv84_fifo_oclass;
-extern struct nouveau_oclass *nvc0_fifo_oclass;
-extern struct nouveau_oclass *nve0_fifo_oclass;
-extern struct nouveau_oclass *gk20a_fifo_oclass;
-extern struct nouveau_oclass *nv108_fifo_oclass;
-
-int nouveau_fifo_uevent_ctor(struct nouveau_object *, void *, u32,
- struct nvkm_notify *);
-void nouveau_fifo_uevent(struct nouveau_fifo *);
-
-void nv04_fifo_intr(struct nouveau_subdev *);
-int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/graph.h b/drivers/gpu/drm/nouveau/core/include/engine/graph.h
deleted file mode 100644
index d5055570d01b..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/graph.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __NOUVEAU_GRAPH_H__
-#define __NOUVEAU_GRAPH_H__
-
-#include <core/engine.h>
-#include <core/engctx.h>
-#include <core/enum.h>
-
-struct nouveau_graph_chan {
- struct nouveau_engctx base;
-};
-
-#define nouveau_graph_context_create(p,e,c,g,s,a,f,d) \
- nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
-#define nouveau_graph_context_destroy(d) \
- nouveau_engctx_destroy(&(d)->base)
-#define nouveau_graph_context_init(d) \
- nouveau_engctx_init(&(d)->base)
-#define nouveau_graph_context_fini(d,s) \
- nouveau_engctx_fini(&(d)->base, (s))
-
-#define _nouveau_graph_context_dtor _nouveau_engctx_dtor
-#define _nouveau_graph_context_init _nouveau_engctx_init
-#define _nouveau_graph_context_fini _nouveau_engctx_fini
-#define _nouveau_graph_context_rd32 _nouveau_engctx_rd32
-#define _nouveau_graph_context_wr32 _nouveau_engctx_wr32
-
-struct nouveau_graph {
- struct nouveau_engine base;
-
- /* Returns chipset-specific counts of units packed into an u64.
- */
- u64 (*units)(struct nouveau_graph *);
-};
-
-static inline struct nouveau_graph *
-nouveau_graph(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_GR];
-}
-
-#define nouveau_graph_create(p,e,c,y,d) \
- nouveau_engine_create((p), (e), (c), (y), "PGRAPH", "graphics", (d))
-#define nouveau_graph_destroy(d) \
- nouveau_engine_destroy(&(d)->base)
-#define nouveau_graph_init(d) \
- nouveau_engine_init(&(d)->base)
-#define nouveau_graph_fini(d,s) \
- nouveau_engine_fini(&(d)->base, (s))
-
-#define _nouveau_graph_dtor _nouveau_engine_dtor
-#define _nouveau_graph_init _nouveau_engine_init
-#define _nouveau_graph_fini _nouveau_engine_fini
-
-extern struct nouveau_oclass nv04_graph_oclass;
-extern struct nouveau_oclass nv10_graph_oclass;
-extern struct nouveau_oclass nv20_graph_oclass;
-extern struct nouveau_oclass nv25_graph_oclass;
-extern struct nouveau_oclass nv2a_graph_oclass;
-extern struct nouveau_oclass nv30_graph_oclass;
-extern struct nouveau_oclass nv34_graph_oclass;
-extern struct nouveau_oclass nv35_graph_oclass;
-extern struct nouveau_oclass nv40_graph_oclass;
-extern struct nouveau_oclass nv50_graph_oclass;
-extern struct nouveau_oclass *nvc0_graph_oclass;
-extern struct nouveau_oclass *nvc1_graph_oclass;
-extern struct nouveau_oclass *nvc4_graph_oclass;
-extern struct nouveau_oclass *nvc8_graph_oclass;
-extern struct nouveau_oclass *nvd7_graph_oclass;
-extern struct nouveau_oclass *nvd9_graph_oclass;
-extern struct nouveau_oclass *nve4_graph_oclass;
-extern struct nouveau_oclass *gk20a_graph_oclass;
-extern struct nouveau_oclass *nvf0_graph_oclass;
-extern struct nouveau_oclass *gk110b_graph_oclass;
-extern struct nouveau_oclass *nv108_graph_oclass;
-extern struct nouveau_oclass *gm107_graph_oclass;
-
-extern const struct nouveau_bitfield nv04_graph_nsource[];
-extern struct nouveau_ofuncs nv04_graph_ofuncs;
-bool nv04_graph_idle(void *obj);
-
-extern const struct nouveau_bitfield nv10_graph_intr_name[];
-extern const struct nouveau_bitfield nv10_graph_nstatus[];
-
-extern const struct nouveau_enum nv50_data_error_names[];
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
deleted file mode 100644
index 9b0d938199f6..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef __NOUVEAU_MPEG_H__
-#define __NOUVEAU_MPEG_H__
-
-#include <core/engine.h>
-#include <core/engctx.h>
-
-struct nouveau_mpeg_chan {
- struct nouveau_engctx base;
-};
-
-#define nouveau_mpeg_context_create(p,e,c,g,s,a,f,d) \
- nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
-#define nouveau_mpeg_context_destroy(d) \
- nouveau_engctx_destroy(&(d)->base)
-#define nouveau_mpeg_context_init(d) \
- nouveau_engctx_init(&(d)->base)
-#define nouveau_mpeg_context_fini(d,s) \
- nouveau_engctx_fini(&(d)->base, (s))
-
-#define _nouveau_mpeg_context_dtor _nouveau_engctx_dtor
-#define _nouveau_mpeg_context_init _nouveau_engctx_init
-#define _nouveau_mpeg_context_fini _nouveau_engctx_fini
-#define _nouveau_mpeg_context_rd32 _nouveau_engctx_rd32
-#define _nouveau_mpeg_context_wr32 _nouveau_engctx_wr32
-
-struct nouveau_mpeg {
- struct nouveau_engine base;
-};
-
-#define nouveau_mpeg_create(p,e,c,d) \
- nouveau_engine_create((p), (e), (c), true, "PMPEG", "mpeg", (d))
-#define nouveau_mpeg_destroy(d) \
- nouveau_engine_destroy(&(d)->base)
-#define nouveau_mpeg_init(d) \
- nouveau_engine_init(&(d)->base)
-#define nouveau_mpeg_fini(d,s) \
- nouveau_engine_fini(&(d)->base, (s))
-
-#define _nouveau_mpeg_dtor _nouveau_engine_dtor
-#define _nouveau_mpeg_init _nouveau_engine_init
-#define _nouveau_mpeg_fini _nouveau_engine_fini
-
-extern struct nouveau_oclass nv31_mpeg_oclass;
-extern struct nouveau_oclass nv40_mpeg_oclass;
-extern struct nouveau_oclass nv44_mpeg_oclass;
-extern struct nouveau_oclass nv50_mpeg_oclass;
-extern struct nouveau_oclass nv84_mpeg_oclass;
-extern struct nouveau_ofuncs nv31_mpeg_ofuncs;
-extern struct nouveau_oclass nv31_mpeg_cclass;
-extern struct nouveau_oclass nv31_mpeg_sclass[];
-extern struct nouveau_oclass nv40_mpeg_sclass[];
-void nv31_mpeg_intr(struct nouveau_subdev *);
-void nv31_mpeg_tile_prog(struct nouveau_engine *, int);
-int nv31_mpeg_init(struct nouveau_object *);
-
-extern struct nouveau_ofuncs nv50_mpeg_ofuncs;
-int nv50_mpeg_context_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv50_mpeg_intr(struct nouveau_subdev *);
-int nv50_mpeg_init(struct nouveau_object *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h b/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h
deleted file mode 100644
index 88cc812baaa3..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __NVKM_PERFMON_H__
-#define __NVKM_PERFMON_H__
-
-#include <core/device.h>
-#include <core/engine.h>
-#include <core/engctx.h>
-
-struct nouveau_perfdom;
-struct nouveau_perfctr;
-struct nouveau_perfmon {
- struct nouveau_engine base;
-
- struct nouveau_perfctx *context;
- void *profile_data;
-
- struct list_head domains;
- u32 sequence;
-
- /*XXX: temp for daemon backend */
- u32 pwr[8];
- u32 last;
-};
-
-static inline struct nouveau_perfmon *
-nouveau_perfmon(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_PERFMON];
-}
-
-extern struct nouveau_oclass *nv40_perfmon_oclass;
-extern struct nouveau_oclass *nv50_perfmon_oclass;
-extern struct nouveau_oclass *nv84_perfmon_oclass;
-extern struct nouveau_oclass *nva3_perfmon_oclass;
-extern struct nouveau_oclass nvc0_perfmon_oclass;
-extern struct nouveau_oclass nve0_perfmon_oclass;
-extern struct nouveau_oclass nvf0_perfmon_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/ppp.h b/drivers/gpu/drm/nouveau/core/include/engine/ppp.h
deleted file mode 100644
index 0a66781e8cf1..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/ppp.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __NOUVEAU_PPP_H__
-#define __NOUVEAU_PPP_H__
-
-extern struct nouveau_oclass nv98_ppp_oclass;
-extern struct nouveau_oclass nvc0_ppp_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/software.h b/drivers/gpu/drm/nouveau/core/include/engine/software.h
deleted file mode 100644
index 23a462b50d03..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/software.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef __NOUVEAU_SOFTWARE_H__
-#define __NOUVEAU_SOFTWARE_H__
-
-#include <core/engine.h>
-#include <core/engctx.h>
-
-struct nouveau_software_chan {
- struct nouveau_engctx base;
-
- int (*flip)(void *);
- void *flip_data;
-};
-
-#define nouveau_software_context_create(p,e,c,d) \
- nouveau_engctx_create((p), (e), (c), (p), 0, 0, 0, (d))
-#define nouveau_software_context_destroy(d) \
- nouveau_engctx_destroy(&(d)->base)
-#define nouveau_software_context_init(d) \
- nouveau_engctx_init(&(d)->base)
-#define nouveau_software_context_fini(d,s) \
- nouveau_engctx_fini(&(d)->base, (s))
-
-#define _nouveau_software_context_dtor _nouveau_engctx_dtor
-#define _nouveau_software_context_init _nouveau_engctx_init
-#define _nouveau_software_context_fini _nouveau_engctx_fini
-
-struct nouveau_software {
- struct nouveau_engine base;
-};
-
-#define nouveau_software_create(p,e,c,d) \
- nouveau_engine_create((p), (e), (c), true, "SW", "software", (d))
-#define nouveau_software_destroy(d) \
- nouveau_engine_destroy(&(d)->base)
-#define nouveau_software_init(d) \
- nouveau_engine_init(&(d)->base)
-#define nouveau_software_fini(d,s) \
- nouveau_engine_fini(&(d)->base, (s))
-
-#define _nouveau_software_dtor _nouveau_engine_dtor
-#define _nouveau_software_init _nouveau_engine_init
-#define _nouveau_software_fini _nouveau_engine_fini
-
-extern struct nouveau_oclass *nv04_software_oclass;
-extern struct nouveau_oclass *nv10_software_oclass;
-extern struct nouveau_oclass *nv50_software_oclass;
-extern struct nouveau_oclass *nvc0_software_oclass;
-
-void nv04_software_intr(struct nouveau_subdev *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/vp.h b/drivers/gpu/drm/nouveau/core/include/engine/vp.h
deleted file mode 100644
index 39baebec7fbb..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/vp.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __NOUVEAU_VP_H__
-#define __NOUVEAU_VP_H__
-
-extern struct nouveau_oclass nv84_vp_oclass;
-extern struct nouveau_oclass nv98_vp_oclass;
-extern struct nouveau_oclass nvc0_vp_oclass;
-extern struct nouveau_oclass nve0_vp_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h b/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h
deleted file mode 100644
index 306100f31f02..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __NOUVEAU_XTENSA_H__
-#define __NOUVEAU_XTENSA_H__
-
-#include <core/engine.h>
-#include <core/engctx.h>
-#include <core/gpuobj.h>
-
-struct nouveau_xtensa {
- struct nouveau_engine base;
-
- u32 addr;
- struct nouveau_gpuobj *gpu_fw;
- u32 fifo_val;
- u32 unkd28;
-};
-
-#define nouveau_xtensa_create(p,e,c,b,d,i,f,r) \
- nouveau_xtensa_create_((p), (e), (c), (b), (d), (i), (f), \
- sizeof(**r),(void **)r)
-
-int _nouveau_xtensa_engctx_ctor(struct nouveau_object *,
- struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-void _nouveau_xtensa_intr(struct nouveau_subdev *);
-int nouveau_xtensa_create_(struct nouveau_object *,
- struct nouveau_object *,
- struct nouveau_oclass *, u32, bool,
- const char *, const char *,
- int, void **);
-#define _nouveau_xtensa_dtor _nouveau_engine_dtor
-int _nouveau_xtensa_init(struct nouveau_object *);
-int _nouveau_xtensa_fini(struct nouveau_object *, bool);
-u32 _nouveau_xtensa_rd32(struct nouveau_object *, u64);
-void _nouveau_xtensa_wr32(struct nouveau_object *, u64, u32);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/nvif/class.h b/drivers/gpu/drm/nouveau/core/include/nvif/class.h
deleted file mode 120000
index f1ac4859edd4..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/nvif/class.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../nvif/class.h \ No newline at end of file
diff --git a/drivers/gpu/drm/nouveau/core/include/nvif/event.h b/drivers/gpu/drm/nouveau/core/include/nvif/event.h
deleted file mode 120000
index 1b798538a725..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/nvif/event.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../nvif/event.h \ No newline at end of file
diff --git a/drivers/gpu/drm/nouveau/core/include/nvif/ioctl.h b/drivers/gpu/drm/nouveau/core/include/nvif/ioctl.h
deleted file mode 120000
index 8569c86907c5..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/nvif/ioctl.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../nvif/ioctl.h \ No newline at end of file
diff --git a/drivers/gpu/drm/nouveau/core/include/nvif/unpack.h b/drivers/gpu/drm/nouveau/core/include/nvif/unpack.h
deleted file mode 120000
index 69d99292bca4..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/nvif/unpack.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../nvif/unpack.h \ No newline at end of file
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bar.h b/drivers/gpu/drm/nouveau/core/include/subdev/bar.h
deleted file mode 100644
index 257ddf6d36d4..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bar.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __NOUVEAU_BAR_H__
-#define __NOUVEAU_BAR_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_mem;
-struct nouveau_vma;
-
-struct nouveau_bar {
- struct nouveau_subdev base;
-
- int (*alloc)(struct nouveau_bar *, struct nouveau_object *,
- struct nouveau_mem *, struct nouveau_object **);
-
- int (*kmap)(struct nouveau_bar *, struct nouveau_mem *,
- u32 flags, struct nouveau_vma *);
- int (*umap)(struct nouveau_bar *, struct nouveau_mem *,
- u32 flags, struct nouveau_vma *);
- void (*unmap)(struct nouveau_bar *, struct nouveau_vma *);
- void (*flush)(struct nouveau_bar *);
-
- /* whether the BAR supports to be ioremapped WC or should be uncached */
- bool iomap_uncached;
-};
-
-static inline struct nouveau_bar *
-nouveau_bar(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_BAR];
-}
-
-extern struct nouveau_oclass nv50_bar_oclass;
-extern struct nouveau_oclass nvc0_bar_oclass;
-extern struct nouveau_oclass gk20a_bar_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h
deleted file mode 100644
index 5bd1ca8cd20d..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __NOUVEAU_BIOS_H__
-#define __NOUVEAU_BIOS_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_bios {
- struct nouveau_subdev base;
- u32 size;
- u8 *data;
-
- u32 bmp_offset;
- u32 bit_offset;
-
- struct {
- u8 major;
- u8 chip;
- u8 minor;
- u8 micro;
- u8 patch;
- } version;
-};
-
-static inline struct nouveau_bios *
-nouveau_bios(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VBIOS];
-}
-
-u8 nvbios_checksum(const u8 *data, int size);
-u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
-
-extern struct nouveau_oclass nouveau_bios_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0205.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0205.h
deleted file mode 100644
index e171120cec81..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0205.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __NVBIOS_M0205_H__
-#define __NVBIOS_M0205_H__
-
-struct nvbios_M0205T {
- u16 freq;
-};
-
-u32 nvbios_M0205Te(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
-u32 nvbios_M0205Tp(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz,
- struct nvbios_M0205T *);
-
-struct nvbios_M0205E {
- u8 type;
-};
-
-u32 nvbios_M0205Ee(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u32 nvbios_M0205Ep(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_M0205E *);
-
-struct nvbios_M0205S {
- u8 data;
-};
-
-u32 nvbios_M0205Se(struct nouveau_bios *, int ent, int idx, u8 *ver, u8 *hdr);
-u32 nvbios_M0205Sp(struct nouveau_bios *, int ent, int idx, u8 *ver, u8 *hdr,
- struct nvbios_M0205S *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0209.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0209.h
deleted file mode 100644
index 67dc50d837bc..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0209.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __NVBIOS_M0209_H__
-#define __NVBIOS_M0209_H__
-
-u32 nvbios_M0209Te(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
-
-struct nvbios_M0209E {
- u8 v00_40;
- u8 bits;
- u8 modulo;
- u8 v02_40;
- u8 v02_07;
- u8 v03;
-};
-
-u32 nvbios_M0209Ee(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u32 nvbios_M0209Ep(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_M0209E *);
-
-struct nvbios_M0209S {
- u32 data[0x200];
-};
-
-u32 nvbios_M0209Se(struct nouveau_bios *, int ent, int idx, u8 *ver, u8 *hdr);
-u32 nvbios_M0209Sp(struct nouveau_bios *, int ent, int idx, u8 *ver, u8 *hdr,
- struct nvbios_M0209S *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h
deleted file mode 100644
index bba01ab1e049..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __NVBIOS_P0260_H__
-#define __NVBIOS_P0260_H__
-
-u32 nvbios_P0260Te(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
-
-struct nvbios_P0260E {
- u32 data;
-};
-
-u32 nvbios_P0260Ee(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u32 nvbios_P0260Ep(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
- struct nvbios_P0260E *);
-
-struct nvbios_P0260X {
- u32 data;
-};
-
-u32 nvbios_P0260Xe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u32 nvbios_P0260Xp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
- struct nvbios_P0260X *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h
deleted file mode 100644
index 662b20726851..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __NVBIOS_BOOST_H__
-#define __NVBIOS_BOOST_H__
-
-u16 nvbios_boostTe(struct nouveau_bios *, u8 *, u8 *, u8 *, u8 *, u8 *, u8 *);
-
-struct nvbios_boostE {
- u8 pstate;
- u32 min;
- u32 max;
-};
-
-u16 nvbios_boostEe(struct nouveau_bios *, int idx, u8 *, u8 *, u8 *, u8 *);
-u16 nvbios_boostEp(struct nouveau_bios *, int idx, u8 *, u8 *, u8 *, u8 *,
- struct nvbios_boostE *);
-u16 nvbios_boostEm(struct nouveau_bios *, u8, u8 *, u8 *, u8 *, u8 *,
- struct nvbios_boostE *);
-
-struct nvbios_boostS {
- u8 domain;
- u8 percent;
- u32 min;
- u32 max;
-};
-
-u16 nvbios_boostSe(struct nouveau_bios *, int, u16, u8 *, u8 *, u8, u8);
-u16 nvbios_boostSp(struct nouveau_bios *, int, u16, u8 *, u8 *, u8, u8,
- struct nvbios_boostS *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h
deleted file mode 100644
index a80a43809883..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __NVBIOS_CSTEP_H__
-#define __NVBIOS_CSTEP_H__
-
-u16 nvbios_cstepTe(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
-
-struct nvbios_cstepE {
- u8 pstate;
- u8 index;
-};
-
-u16 nvbios_cstepEe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u16 nvbios_cstepEp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
- struct nvbios_cstepE *);
-u16 nvbios_cstepEm(struct nouveau_bios *, u8 pstate, u8 *ver, u8 *hdr,
- struct nvbios_cstepE *);
-
-struct nvbios_cstepX {
- u32 freq;
- u8 unkn[2];
- u8 voltage;
-};
-
-u16 nvbios_cstepXe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u16 nvbios_cstepXp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
- struct nvbios_cstepX *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/disp.h
deleted file mode 100644
index c35937e2f6a4..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/disp.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __NVBIOS_DISP_H__
-#define __NVBIOS_DISP_H__
-
-u16 nvbios_disp_table(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *sub);
-
-struct nvbios_disp {
- u16 data;
-};
-
-u16 nvbios_disp_entry(struct nouveau_bios *, u8 idx,
- u8 *ver, u8 *hdr__, u8 *sub);
-u16 nvbios_disp_parse(struct nouveau_bios *, u8 idx,
- u8 *ver, u8 *hdr__, u8 *sub,
- struct nvbios_disp *);
-
-struct nvbios_outp {
- u16 type;
- u16 mask;
- u16 script[3];
-};
-
-u16 nvbios_outp_entry(struct nouveau_bios *, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_outp_parse(struct nouveau_bios *, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_outp *);
-u16 nvbios_outp_match(struct nouveau_bios *, u16 type, u16 mask,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_outp *);
-
-
-struct nvbios_ocfg {
- u16 match;
- u16 clkcmp[2];
-};
-
-u16 nvbios_ocfg_entry(struct nouveau_bios *, u16 outp, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_ocfg_parse(struct nouveau_bios *, u16 outp, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ocfg *);
-u16 nvbios_ocfg_match(struct nouveau_bios *, u16 outp, u16 type,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ocfg *);
-u16 nvbios_oclk_match(struct nouveau_bios *, u16 cmp, u32 khz);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h
deleted file mode 100644
index 728206e21777..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __NVBIOS_DP_H__
-#define __NVBIOS_DP_H__
-
-struct nvbios_dpout {
- u16 type;
- u16 mask;
- u8 flags;
- u32 script[5];
- u32 lnkcmp;
-};
-
-u16 nvbios_dpout_parse(struct nouveau_bios *, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_dpout *);
-u16 nvbios_dpout_match(struct nouveau_bios *, u16 type, u16 mask,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_dpout *);
-
-struct nvbios_dpcfg {
- u8 pc;
- u8 dc;
- u8 pe;
- u8 tx_pu;
-};
-
-u16
-nvbios_dpcfg_parse(struct nouveau_bios *, u16 outp, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_dpcfg *);
-u16
-nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 pc, u8 vs, u8 pe,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_dpcfg *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h
deleted file mode 100644
index 5572e60414e8..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/mxm.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __NVBIOS_MXM_H__
-#define __NVBIOS_MXM_H__
-
-u16 mxm_table(struct nouveau_bios *, u8 *ver, u8 *hdr);
-
-u8 mxm_sor_map(struct nouveau_bios *, u8 conn);
-u8 mxm_ddc_map(struct nouveau_bios *, u8 port);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h
deleted file mode 100644
index b18413d951e5..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __NVBIOS_NPDE_H__
-#define __NVBIOS_NPDE_H__
-
-struct nvbios_npdeT {
- u32 image_size;
- bool last;
-};
-
-u32 nvbios_npdeTe(struct nouveau_bios *, u32);
-u32 nvbios_npdeTp(struct nouveau_bios *, u32, struct nvbios_npdeT *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h
deleted file mode 100644
index 47e021d3e20d..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __NVBIOS_RAMMAP_H__
-#define __NVBIOS_RAMMAP_H__
-
-struct nvbios_ramcfg;
-
-u32 nvbios_rammapTe(struct nouveau_bios *, u8 *ver, u8 *hdr,
- u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
-
-u32 nvbios_rammapEe(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u32 nvbios_rammapEp(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ramcfg *);
-u32 nvbios_rammapEm(struct nouveau_bios *, u16 mhz,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ramcfg *);
-
-u32 nvbios_rammapSe(struct nouveau_bios *, u32 data,
- u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
- u8 *ver, u8 *hdr);
-u32 nvbios_rammapSp(struct nouveau_bios *, u32 data,
- u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
- u8 *ver, u8 *hdr,
- struct nvbios_ramcfg *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h
deleted file mode 100644
index 76d914b67ab5..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __NVBIOS_TIMING_H__
-#define __NVBIOS_TIMING_H__
-
-struct nvbios_ramcfg;
-
-u16 nvbios_timingTe(struct nouveau_bios *,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
-u16 nvbios_timingEe(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_timingEp(struct nouveau_bios *, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ramcfg *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h
deleted file mode 100644
index ad5a8f20e113..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __NVBIOS_VMAP_H__
-#define __NVBIOS_VMAP_H__
-
-struct nouveau_bios;
-
-struct nvbios_vmap {
-};
-
-u16 nvbios_vmap_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_vmap_parse(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_vmap *);
-
-struct nvbios_vmap_entry {
- u8 unk0;
- u8 link;
- u32 min;
- u32 max;
- s32 arg[6];
-};
-
-u16 nvbios_vmap_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *len);
-u16 nvbios_vmap_entry_parse(struct nouveau_bios *, int idx, u8 *ver, u8 *len,
- struct nvbios_vmap_entry *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h
deleted file mode 100644
index 6a11dcd59770..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __NVBIOS_VOLT_H__
-#define __NVBIOS_VOLT_H__
-
-struct nouveau_bios;
-
-struct nvbios_volt {
- u8 vidmask;
- u32 min;
- u32 max;
- u32 base;
- s16 step;
-};
-
-u16 nvbios_volt_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_volt_parse(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_volt *);
-
-struct nvbios_volt_entry {
- u32 voltage;
- u8 vid;
-};
-
-u16 nvbios_volt_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *len);
-u16 nvbios_volt_entry_parse(struct nouveau_bios *, int idx, u8 *ver, u8 *len,
- struct nvbios_volt_entry *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bus.h b/drivers/gpu/drm/nouveau/core/include/subdev/bus.h
deleted file mode 100644
index 697f7ce70aab..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bus.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __NOUVEAU_BUS_H__
-#define __NOUVEAU_BUS_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_bus_intr {
- u32 stat;
- u32 unit;
-};
-
-struct nouveau_bus {
- struct nouveau_subdev base;
- int (*hwsq_exec)(struct nouveau_bus *, u32 *, u32);
- u32 hwsq_size;
-};
-
-static inline struct nouveau_bus *
-nouveau_bus(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_BUS];
-}
-
-#define nouveau_bus_create(p, e, o, d) \
- nouveau_subdev_create_((p), (e), (o), 0, "PBUS", "master", \
- sizeof(**d), (void **)d)
-#define nouveau_bus_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_bus_init(p) \
- nouveau_subdev_init(&(p)->base)
-#define nouveau_bus_fini(p, s) \
- nouveau_subdev_fini(&(p)->base, (s))
-
-#define _nouveau_bus_dtor _nouveau_subdev_dtor
-#define _nouveau_bus_init _nouveau_subdev_init
-#define _nouveau_bus_fini _nouveau_subdev_fini
-
-extern struct nouveau_oclass *nv04_bus_oclass;
-extern struct nouveau_oclass *nv31_bus_oclass;
-extern struct nouveau_oclass *nv50_bus_oclass;
-extern struct nouveau_oclass *nv94_bus_oclass;
-extern struct nouveau_oclass *nvc0_bus_oclass;
-
-/* interface to sequencer */
-struct nouveau_hwsq;
-int nouveau_hwsq_init(struct nouveau_bus *, struct nouveau_hwsq **);
-int nouveau_hwsq_fini(struct nouveau_hwsq **, bool exec);
-void nouveau_hwsq_wr32(struct nouveau_hwsq *, u32 addr, u32 data);
-void nouveau_hwsq_setf(struct nouveau_hwsq *, u8 flag, int data);
-void nouveau_hwsq_wait(struct nouveau_hwsq *, u8 flag, u8 data);
-void nouveau_hwsq_nsec(struct nouveau_hwsq *, u32 nsec);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
deleted file mode 100644
index 36ed035d4d42..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
+++ /dev/null
@@ -1,166 +0,0 @@
-#ifndef __NOUVEAU_CLOCK_H__
-#define __NOUVEAU_CLOCK_H__
-
-#include <core/device.h>
-#include <core/subdev.h>
-
-struct nouveau_pll_vals;
-struct nvbios_pll;
-
-enum nv_clk_src {
- nv_clk_src_crystal,
- nv_clk_src_href,
-
- nv_clk_src_hclk,
- nv_clk_src_hclkm3,
- nv_clk_src_hclkm3d2,
- nv_clk_src_hclkm2d3, /* NVAA */
- nv_clk_src_hclkm4, /* NVAA */
- nv_clk_src_cclk, /* NVAA */
-
- nv_clk_src_host,
-
- nv_clk_src_sppll0,
- nv_clk_src_sppll1,
-
- nv_clk_src_mpllsrcref,
- nv_clk_src_mpllsrc,
- nv_clk_src_mpll,
- nv_clk_src_mdiv,
-
- nv_clk_src_core,
- nv_clk_src_core_intm,
- nv_clk_src_shader,
-
- nv_clk_src_mem,
-
- nv_clk_src_gpc,
- nv_clk_src_rop,
- nv_clk_src_hubk01,
- nv_clk_src_hubk06,
- nv_clk_src_hubk07,
- nv_clk_src_copy,
- nv_clk_src_daemon,
- nv_clk_src_disp,
- nv_clk_src_vdec,
-
- nv_clk_src_dom6,
-
- nv_clk_src_max,
-};
-
-struct nouveau_cstate {
- struct list_head head;
- u8 voltage;
- u32 domain[nv_clk_src_max];
-};
-
-struct nouveau_pstate {
- struct list_head head;
- struct list_head list; /* c-states */
- struct nouveau_cstate base;
- u8 pstate;
- u8 fanspeed;
-};
-
-struct nouveau_clock {
- struct nouveau_subdev base;
-
- struct nouveau_clocks *domains;
- struct nouveau_pstate bstate;
-
- struct list_head states;
- int state_nr;
-
- struct work_struct work;
- wait_queue_head_t wait;
- atomic_t waiting;
-
- struct nvkm_notify pwrsrc_ntfy;
- int pwrsrc;
- int pstate; /* current */
- int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
- int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
- int astate; /* perfmon adjustment (base) */
- int tstate; /* thermal adjustment (max-) */
- int dstate; /* display adjustment (min+) */
-
- bool allow_reclock;
-
- int (*read)(struct nouveau_clock *, enum nv_clk_src);
- int (*calc)(struct nouveau_clock *, struct nouveau_cstate *);
- int (*prog)(struct nouveau_clock *);
- void (*tidy)(struct nouveau_clock *);
-
- /*XXX: die, these are here *only* to support the completely
- * bat-shit insane what-was-nouveau_hw.c code
- */
- int (*pll_calc)(struct nouveau_clock *, struct nvbios_pll *,
- int clk, struct nouveau_pll_vals *pv);
- int (*pll_prog)(struct nouveau_clock *, u32 reg1,
- struct nouveau_pll_vals *pv);
-};
-
-static inline struct nouveau_clock *
-nouveau_clock(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_CLOCK];
-}
-
-struct nouveau_clocks {
- enum nv_clk_src name;
- u8 bios; /* 0xff for none */
-#define NVKM_CLK_DOM_FLAG_CORE 0x01
- u8 flags;
- const char *mname;
- int mdiv;
-};
-
-#define nouveau_clock_create(p,e,o,i,r,s,n,d) \
- nouveau_clock_create_((p), (e), (o), (i), (r), (s), (n), sizeof(**d), \
- (void **)d)
-#define nouveau_clock_destroy(p) ({ \
- struct nouveau_clock *clk = (p); \
- _nouveau_clock_dtor(nv_object(clk)); \
-})
-#define nouveau_clock_init(p) ({ \
- struct nouveau_clock *clk = (p); \
- _nouveau_clock_init(nv_object(clk)); \
-})
-#define nouveau_clock_fini(p,s) ({ \
- struct nouveau_clock *clk = (p); \
- _nouveau_clock_fini(nv_object(clk), (s)); \
-})
-
-int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *,
- struct nouveau_clocks *, struct nouveau_pstate *,
- int, bool, int, void **);
-void _nouveau_clock_dtor(struct nouveau_object *);
-int _nouveau_clock_init(struct nouveau_object *);
-int _nouveau_clock_fini(struct nouveau_object *, bool);
-
-extern struct nouveau_oclass nv04_clock_oclass;
-extern struct nouveau_oclass nv40_clock_oclass;
-extern struct nouveau_oclass *nv50_clock_oclass;
-extern struct nouveau_oclass *nv84_clock_oclass;
-extern struct nouveau_oclass *nvaa_clock_oclass;
-extern struct nouveau_oclass nva3_clock_oclass;
-extern struct nouveau_oclass nvc0_clock_oclass;
-extern struct nouveau_oclass nve0_clock_oclass;
-extern struct nouveau_oclass gk20a_clock_oclass;
-
-int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq);
-int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
- int clk, struct nouveau_pll_vals *);
-int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
- struct nouveau_pll_vals *);
-int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
- int clk, struct nouveau_pll_vals *);
-
-int nouveau_clock_ustate(struct nouveau_clock *, int req, int pwr);
-int nouveau_clock_astate(struct nouveau_clock *, int req, int rel);
-int nouveau_clock_dstate(struct nouveau_clock *, int req, int rel);
-int nouveau_clock_tstate(struct nouveau_clock *, int req, int rel);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
deleted file mode 100644
index e007a9d44683..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __NOUVEAU_DEVINIT_H__
-#define __NOUVEAU_DEVINIT_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_devinit {
- struct nouveau_subdev base;
- bool post;
- void (*meminit)(struct nouveau_devinit *);
- int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq);
- u32 (*mmio)(struct nouveau_devinit *, u32 addr);
-};
-
-static inline struct nouveau_devinit *
-nouveau_devinit(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_DEVINIT];
-}
-
-extern struct nouveau_oclass *nv04_devinit_oclass;
-extern struct nouveau_oclass *nv05_devinit_oclass;
-extern struct nouveau_oclass *nv10_devinit_oclass;
-extern struct nouveau_oclass *nv1a_devinit_oclass;
-extern struct nouveau_oclass *nv20_devinit_oclass;
-extern struct nouveau_oclass *nv50_devinit_oclass;
-extern struct nouveau_oclass *nv84_devinit_oclass;
-extern struct nouveau_oclass *nv98_devinit_oclass;
-extern struct nouveau_oclass *nva3_devinit_oclass;
-extern struct nouveau_oclass *nvaf_devinit_oclass;
-extern struct nouveau_oclass *nvc0_devinit_oclass;
-extern struct nouveau_oclass *gm107_devinit_oclass;
-extern struct nouveau_oclass *gm204_devinit_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
deleted file mode 100644
index 8d0032f15205..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
+++ /dev/null
@@ -1,159 +0,0 @@
-#ifndef __NOUVEAU_FB_H__
-#define __NOUVEAU_FB_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-#include <core/mm.h>
-
-#include <subdev/vm.h>
-
-/* memory type/access flags, do not match hardware values */
-#define NV_MEM_ACCESS_RO 1
-#define NV_MEM_ACCESS_WO 2
-#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
-#define NV_MEM_ACCESS_SYS 4
-#define NV_MEM_ACCESS_VM 8
-#define NV_MEM_ACCESS_NOSNOOP 16
-
-#define NV_MEM_TARGET_VRAM 0
-#define NV_MEM_TARGET_PCI 1
-#define NV_MEM_TARGET_PCI_NOSNOOP 2
-#define NV_MEM_TARGET_VM 3
-#define NV_MEM_TARGET_GART 4
-
-#define NV_MEM_TYPE_VM 0x7f
-#define NV_MEM_COMP_VM 0x03
-
-struct nouveau_mem {
- struct drm_device *dev;
-
- struct nouveau_vma bar_vma;
- struct nouveau_vma vma[2];
- u8 page_shift;
-
- struct nouveau_mm_node *tag;
- struct list_head regions;
- dma_addr_t *pages;
- u32 memtype;
- u64 offset;
- u64 size;
- struct sg_table *sg;
-};
-
-struct nouveau_fb_tile {
- struct nouveau_mm_node *tag;
- u32 addr;
- u32 limit;
- u32 pitch;
- u32 zcomp;
-};
-
-struct nouveau_fb {
- struct nouveau_subdev base;
-
- bool (*memtype_valid)(struct nouveau_fb *, u32 memtype);
-
- struct nouveau_ram *ram;
-
- struct nouveau_mm vram;
- struct nouveau_mm tags;
-
- struct {
- struct nouveau_fb_tile region[16];
- int regions;
- void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
- void (*comp)(struct nouveau_fb *, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *);
- void (*fini)(struct nouveau_fb *, int i,
- struct nouveau_fb_tile *);
- void (*prog)(struct nouveau_fb *, int i,
- struct nouveau_fb_tile *);
- } tile;
-};
-
-static inline struct nouveau_fb *
-nouveau_fb(void *obj)
-{
- /* fbram uses this before device subdev pointer is valid */
- if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
- nv_subidx(obj) == NVDEV_SUBDEV_FB)
- return obj;
-
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
-}
-
-extern struct nouveau_oclass *nv04_fb_oclass;
-extern struct nouveau_oclass *nv10_fb_oclass;
-extern struct nouveau_oclass *nv1a_fb_oclass;
-extern struct nouveau_oclass *nv20_fb_oclass;
-extern struct nouveau_oclass *nv25_fb_oclass;
-extern struct nouveau_oclass *nv30_fb_oclass;
-extern struct nouveau_oclass *nv35_fb_oclass;
-extern struct nouveau_oclass *nv36_fb_oclass;
-extern struct nouveau_oclass *nv40_fb_oclass;
-extern struct nouveau_oclass *nv41_fb_oclass;
-extern struct nouveau_oclass *nv44_fb_oclass;
-extern struct nouveau_oclass *nv46_fb_oclass;
-extern struct nouveau_oclass *nv47_fb_oclass;
-extern struct nouveau_oclass *nv49_fb_oclass;
-extern struct nouveau_oclass *nv4e_fb_oclass;
-extern struct nouveau_oclass *nv50_fb_oclass;
-extern struct nouveau_oclass *nv84_fb_oclass;
-extern struct nouveau_oclass *nva3_fb_oclass;
-extern struct nouveau_oclass *nvaa_fb_oclass;
-extern struct nouveau_oclass *nvaf_fb_oclass;
-extern struct nouveau_oclass *nvc0_fb_oclass;
-extern struct nouveau_oclass *nve0_fb_oclass;
-extern struct nouveau_oclass *gk20a_fb_oclass;
-extern struct nouveau_oclass *gm107_fb_oclass;
-
-#include <subdev/bios/ramcfg.h>
-
-struct nouveau_ram_data {
- struct list_head head;
- struct nvbios_ramcfg bios;
- u32 freq;
-};
-
-struct nouveau_ram {
- struct nouveau_object base;
- enum {
- NV_MEM_TYPE_UNKNOWN = 0,
- NV_MEM_TYPE_STOLEN,
- NV_MEM_TYPE_SGRAM,
- NV_MEM_TYPE_SDRAM,
- NV_MEM_TYPE_DDR1,
- NV_MEM_TYPE_DDR2,
- NV_MEM_TYPE_DDR3,
- NV_MEM_TYPE_GDDR2,
- NV_MEM_TYPE_GDDR3,
- NV_MEM_TYPE_GDDR4,
- NV_MEM_TYPE_GDDR5
- } type;
- u64 stolen;
- u64 size;
- u32 tags;
-
- int ranks;
- int parts;
- int part_mask;
-
- int (*get)(struct nouveau_fb *, u64 size, u32 align,
- u32 size_nc, u32 type, struct nouveau_mem **);
- void (*put)(struct nouveau_fb *, struct nouveau_mem **);
-
- int (*calc)(struct nouveau_fb *, u32 freq);
- int (*prog)(struct nouveau_fb *);
- void (*tidy)(struct nouveau_fb *);
- u32 freq;
- u32 mr[16];
- u32 mr1_nuts;
-
- struct nouveau_ram_data *next;
- struct nouveau_ram_data former;
- struct nouveau_ram_data xition;
- struct nouveau_ram_data target;
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fuse.h b/drivers/gpu/drm/nouveau/core/include/subdev/fuse.h
deleted file mode 100644
index 2b1ddb2a9a7d..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fuse.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __NOUVEAU_FUSE_H__
-#define __NOUVEAU_FUSE_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_fuse {
- struct nouveau_subdev base;
-};
-
-static inline struct nouveau_fuse *
-nouveau_fuse(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FUSE];
-}
-
-#define nouveau_fuse_create(p, e, o, d) \
- nouveau_fuse_create_((p), (e), (o), sizeof(**d), (void **)d)
-
-int nouveau_fuse_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_fuse_dtor(struct nouveau_object *);
-int _nouveau_fuse_init(struct nouveau_object *);
-#define _nouveau_fuse_fini _nouveau_subdev_fini
-
-extern struct nouveau_oclass g80_fuse_oclass;
-extern struct nouveau_oclass gf100_fuse_oclass;
-extern struct nouveau_oclass gm107_fuse_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
deleted file mode 100644
index f855140dbcb7..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __NOUVEAU_GPIO_H__
-#define __NOUVEAU_GPIO_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-#include <core/event.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/gpio.h>
-
-struct nvkm_gpio_ntfy_req {
-#define NVKM_GPIO_HI 0x01
-#define NVKM_GPIO_LO 0x02
-#define NVKM_GPIO_TOGGLED 0x03
- u8 mask;
- u8 line;
-};
-
-struct nvkm_gpio_ntfy_rep {
- u8 mask;
-};
-
-struct nouveau_gpio {
- struct nouveau_subdev base;
-
- struct nvkm_event event;
-
- void (*reset)(struct nouveau_gpio *, u8 func);
- int (*find)(struct nouveau_gpio *, int idx, u8 tag, u8 line,
- struct dcb_gpio_func *);
- int (*set)(struct nouveau_gpio *, int idx, u8 tag, u8 line, int state);
- int (*get)(struct nouveau_gpio *, int idx, u8 tag, u8 line);
-};
-
-static inline struct nouveau_gpio *
-nouveau_gpio(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_GPIO];
-}
-
-extern struct nouveau_oclass *nv10_gpio_oclass;
-extern struct nouveau_oclass *nv50_gpio_oclass;
-extern struct nouveau_oclass *nv94_gpio_oclass;
-extern struct nouveau_oclass *nvd0_gpio_oclass;
-extern struct nouveau_oclass *nve0_gpio_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
deleted file mode 100644
index d94ccacb40bf..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
+++ /dev/null
@@ -1,136 +0,0 @@
-#ifndef __NOUVEAU_I2C_H__
-#define __NOUVEAU_I2C_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/i2c.h>
-
-#define NV_I2C_PORT(n) (0x00 + (n))
-#define NV_I2C_AUX(n) (0x10 + (n))
-#define NV_I2C_EXT(n) (0x20 + (n))
-#define NV_I2C_DEFAULT(n) (0x80 + (n))
-
-#define NV_I2C_TYPE_DCBI2C(n) (0x0000 | (n))
-#define NV_I2C_TYPE_EXTDDC(e) (0x0005 | (e) << 8)
-#define NV_I2C_TYPE_EXTAUX(e) (0x0006 | (e) << 8)
-
-struct nvkm_i2c_ntfy_req {
-#define NVKM_I2C_PLUG 0x01
-#define NVKM_I2C_UNPLUG 0x02
-#define NVKM_I2C_IRQ 0x04
-#define NVKM_I2C_DONE 0x08
-#define NVKM_I2C_ANY 0x0f
- u8 mask;
- u8 port;
-};
-
-struct nvkm_i2c_ntfy_rep {
- u8 mask;
-};
-
-struct nouveau_i2c_port {
- struct nouveau_object base;
- struct i2c_adapter adapter;
- struct mutex mutex;
-
- struct list_head head;
- u8 index;
- int aux;
-
- const struct nouveau_i2c_func *func;
-};
-
-struct nouveau_i2c_func {
- void (*drive_scl)(struct nouveau_i2c_port *, int);
- void (*drive_sda)(struct nouveau_i2c_port *, int);
- int (*sense_scl)(struct nouveau_i2c_port *);
- int (*sense_sda)(struct nouveau_i2c_port *);
-
- int (*aux)(struct nouveau_i2c_port *, bool, u8, u32, u8 *, u8);
- int (*pattern)(struct nouveau_i2c_port *, int pattern);
- int (*lnk_ctl)(struct nouveau_i2c_port *, int nr, int bw, bool enh);
- int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe);
-};
-
-struct nouveau_i2c_board_info {
- struct i2c_board_info dev;
- u8 udelay; /* set to 0 to use the standard delay */
-};
-
-struct nouveau_i2c {
- struct nouveau_subdev base;
- struct nvkm_event event;
-
- struct nouveau_i2c_port *(*find)(struct nouveau_i2c *, u8 index);
- struct nouveau_i2c_port *(*find_type)(struct nouveau_i2c *, u16 type);
- int (*acquire_pad)(struct nouveau_i2c_port *, unsigned long timeout);
- void (*release_pad)(struct nouveau_i2c_port *);
- int (*acquire)(struct nouveau_i2c_port *, unsigned long timeout);
- void (*release)(struct nouveau_i2c_port *);
- int (*identify)(struct nouveau_i2c *, int index,
- const char *what, struct nouveau_i2c_board_info *,
- bool (*match)(struct nouveau_i2c_port *,
- struct i2c_board_info *, void *), void *);
-
- wait_queue_head_t wait;
- struct list_head ports;
-};
-
-static inline struct nouveau_i2c *
-nouveau_i2c(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_I2C];
-}
-
-extern struct nouveau_oclass *nv04_i2c_oclass;
-extern struct nouveau_oclass *nv4e_i2c_oclass;
-extern struct nouveau_oclass *nv50_i2c_oclass;
-extern struct nouveau_oclass *nv94_i2c_oclass;
-extern struct nouveau_oclass *nvd0_i2c_oclass;
-extern struct nouveau_oclass *gf117_i2c_oclass;
-extern struct nouveau_oclass *nve0_i2c_oclass;
-extern struct nouveau_oclass *gm204_i2c_oclass;
-
-static inline int
-nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg)
-{
- u8 val;
- struct i2c_msg msgs[] = {
- { .addr = addr, .flags = 0, .len = 1, .buf = &reg },
- { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
- };
-
- int ret = i2c_transfer(&port->adapter, msgs, 2);
- if (ret != 2)
- return -EIO;
-
- return val;
-}
-
-static inline int
-nv_wri2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg, u8 val)
-{
- u8 buf[2] = { reg, val };
- struct i2c_msg msgs[] = {
- { .addr = addr, .flags = 0, .len = 2, .buf = buf },
- };
-
- int ret = i2c_transfer(&port->adapter, msgs, 1);
- if (ret != 1)
- return -EIO;
-
- return 0;
-}
-
-static inline bool
-nv_probe_i2c(struct nouveau_i2c_port *port, u8 addr)
-{
- return nv_rdi2cr(port, addr, 0) >= 0;
-}
-
-int nv_rdaux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size);
-int nv_wraux(struct nouveau_i2c_port *, u32 addr, u8 *data, u8 size);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
deleted file mode 100644
index 31df634c0fdc..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __NOUVEAU_IBUS_H__
-#define __NOUVEAU_IBUS_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_ibus {
- struct nouveau_subdev base;
-};
-
-static inline struct nouveau_ibus *
-nouveau_ibus(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_IBUS];
-}
-
-#define nouveau_ibus_create(p,e,o,d) \
- nouveau_subdev_create_((p), (e), (o), 0, "PIBUS", "ibus", \
- sizeof(**d), (void **)d)
-#define nouveau_ibus_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_ibus_init(p) \
- nouveau_subdev_init(&(p)->base)
-#define nouveau_ibus_fini(p,s) \
- nouveau_subdev_fini(&(p)->base, (s))
-
-#define _nouveau_ibus_dtor _nouveau_subdev_dtor
-#define _nouveau_ibus_init _nouveau_subdev_init
-#define _nouveau_ibus_fini _nouveau_subdev_fini
-
-extern struct nouveau_oclass nvc0_ibus_oclass;
-extern struct nouveau_oclass nve0_ibus_oclass;
-extern struct nouveau_oclass gk20a_ibus_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h b/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h
deleted file mode 100644
index c1df26f3230c..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/instmem.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __NOUVEAU_INSTMEM_H__
-#define __NOUVEAU_INSTMEM_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-#include <core/mm.h>
-
-struct nouveau_instobj {
- struct nouveau_object base;
- struct list_head head;
- u32 *suspend;
- u64 addr;
- u32 size;
-};
-
-static inline struct nouveau_instobj *
-nv_memobj(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(obj, NV_MEMOBJ_CLASS)))
- nv_assert("BAD CAST -> NvMemObj, %08x", nv_hclass(obj));
-#endif
- return obj;
-}
-
-struct nouveau_instmem {
- struct nouveau_subdev base;
- struct list_head list;
-
- u32 reserved;
- int (*alloc)(struct nouveau_instmem *, struct nouveau_object *,
- u32 size, u32 align, struct nouveau_object **);
-};
-
-static inline struct nouveau_instmem *
-nouveau_instmem(void *obj)
-{
- /* nv04/nv40 impls need to create objects in their constructor,
- * which is before the subdev pointer is valid
- */
- if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
- nv_subidx(obj) == NVDEV_SUBDEV_INSTMEM)
- return obj;
-
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_INSTMEM];
-}
-
-extern struct nouveau_oclass *nv04_instmem_oclass;
-extern struct nouveau_oclass *nv40_instmem_oclass;
-extern struct nouveau_oclass *nv50_instmem_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltc.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltc.h
deleted file mode 100644
index b909a7363f6b..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ltc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __NOUVEAU_LTC_H__
-#define __NOUVEAU_LTC_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-#define NOUVEAU_LTC_MAX_ZBC_CNT 16
-
-struct nouveau_mm_node;
-
-struct nouveau_ltc {
- struct nouveau_subdev base;
-
- int (*tags_alloc)(struct nouveau_ltc *, u32 count,
- struct nouveau_mm_node **);
- void (*tags_free)(struct nouveau_ltc *, struct nouveau_mm_node **);
- void (*tags_clear)(struct nouveau_ltc *, u32 first, u32 count);
-
- int zbc_min;
- int zbc_max;
- int (*zbc_color_get)(struct nouveau_ltc *, int index, const u32[4]);
- int (*zbc_depth_get)(struct nouveau_ltc *, int index, const u32);
-};
-
-static inline struct nouveau_ltc *
-nouveau_ltc(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_LTC];
-}
-
-extern struct nouveau_oclass *gf100_ltc_oclass;
-extern struct nouveau_oclass *gk104_ltc_oclass;
-extern struct nouveau_oclass *gm107_ltc_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
deleted file mode 100644
index 568e4dfc5e9e..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __NOUVEAU_MC_H__
-#define __NOUVEAU_MC_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_mc {
- struct nouveau_subdev base;
- bool use_msi;
- unsigned int irq;
- void (*unk260)(struct nouveau_mc *, u32);
-};
-
-static inline struct nouveau_mc *
-nouveau_mc(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
-}
-
-extern struct nouveau_oclass *nv04_mc_oclass;
-extern struct nouveau_oclass *nv40_mc_oclass;
-extern struct nouveau_oclass *nv44_mc_oclass;
-extern struct nouveau_oclass *nv4c_mc_oclass;
-extern struct nouveau_oclass *nv50_mc_oclass;
-extern struct nouveau_oclass *nv94_mc_oclass;
-extern struct nouveau_oclass *nv98_mc_oclass;
-extern struct nouveau_oclass *nvc0_mc_oclass;
-extern struct nouveau_oclass *nvc3_mc_oclass;
-extern struct nouveau_oclass *gk20a_mc_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h b/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h
deleted file mode 100644
index b93b152cb566..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/mxm.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __NOUVEAU_MXM_H__
-#define __NOUVEAU_MXM_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-#define MXM_SANITISE_DCB 0x00000001
-
-struct nouveau_mxm {
- struct nouveau_subdev base;
- u32 action;
- u8 *mxms;
-};
-
-static inline struct nouveau_mxm *
-nouveau_mxm(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MXM];
-}
-
-#define nouveau_mxm_create(p,e,o,d) \
- nouveau_mxm_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_mxm_init(p) \
- nouveau_subdev_init(&(p)->base)
-#define nouveau_mxm_fini(p,s) \
- nouveau_subdev_fini(&(p)->base, (s))
-int nouveau_mxm_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void nouveau_mxm_destroy(struct nouveau_mxm *);
-
-#define _nouveau_mxm_dtor _nouveau_subdev_dtor
-#define _nouveau_mxm_init _nouveau_subdev_init
-#define _nouveau_mxm_fini _nouveau_subdev_fini
-
-extern struct nouveau_oclass nv50_mxm_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
deleted file mode 100644
index f2427bf5aeed..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __NOUVEAU_PWR_H__
-#define __NOUVEAU_PWR_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_pwr {
- struct nouveau_subdev base;
-
- struct {
- u32 base;
- u32 size;
- } send;
-
- struct {
- u32 base;
- u32 size;
-
- struct work_struct work;
- wait_queue_head_t wait;
- u32 process;
- u32 message;
- u32 data[2];
- } recv;
-
- int (*message)(struct nouveau_pwr *, u32[2], u32, u32, u32, u32);
- void (*pgob)(struct nouveau_pwr *, bool);
-};
-
-static inline struct nouveau_pwr *
-nouveau_pwr(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_PWR];
-}
-
-extern struct nouveau_oclass *nva3_pwr_oclass;
-extern struct nouveau_oclass *nvc0_pwr_oclass;
-extern struct nouveau_oclass *nvd0_pwr_oclass;
-extern struct nouveau_oclass *gk104_pwr_oclass;
-extern struct nouveau_oclass *nv108_pwr_oclass;
-
-/* interface to MEMX process running on PPWR */
-struct nouveau_memx;
-int nouveau_memx_init(struct nouveau_pwr *, struct nouveau_memx **);
-int nouveau_memx_fini(struct nouveau_memx **, bool exec);
-void nouveau_memx_wr32(struct nouveau_memx *, u32 addr, u32 data);
-void nouveau_memx_wait(struct nouveau_memx *,
- u32 addr, u32 mask, u32 data, u32 nsec);
-void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec);
-void nouveau_memx_wait_vblank(struct nouveau_memx *);
-void nouveau_memx_train(struct nouveau_memx *);
-int nouveau_memx_train_result(struct nouveau_pwr *, u32 *, int);
-void nouveau_memx_block(struct nouveau_memx *);
-void nouveau_memx_unblock(struct nouveau_memx *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
deleted file mode 100644
index a437597dcafc..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef __NOUVEAU_THERM_H__
-#define __NOUVEAU_THERM_H__
-
-#include <core/device.h>
-#include <core/subdev.h>
-
-enum nouveau_therm_fan_mode {
- NOUVEAU_THERM_CTRL_NONE = 0,
- NOUVEAU_THERM_CTRL_MANUAL = 1,
- NOUVEAU_THERM_CTRL_AUTO = 2,
-};
-
-enum nouveau_therm_attr_type {
- NOUVEAU_THERM_ATTR_FAN_MIN_DUTY = 0,
- NOUVEAU_THERM_ATTR_FAN_MAX_DUTY = 1,
- NOUVEAU_THERM_ATTR_FAN_MODE = 2,
-
- NOUVEAU_THERM_ATTR_THRS_FAN_BOOST = 10,
- NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST = 11,
- NOUVEAU_THERM_ATTR_THRS_DOWN_CLK = 12,
- NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST = 13,
- NOUVEAU_THERM_ATTR_THRS_CRITICAL = 14,
- NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST = 15,
- NOUVEAU_THERM_ATTR_THRS_SHUTDOWN = 16,
- NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
-};
-
-struct nouveau_therm {
- struct nouveau_subdev base;
-
- int (*pwm_ctrl)(struct nouveau_therm *, int line, bool);
- int (*pwm_get)(struct nouveau_therm *, int line, u32 *, u32 *);
- int (*pwm_set)(struct nouveau_therm *, int line, u32, u32);
- int (*pwm_clock)(struct nouveau_therm *, int line);
-
- int (*fan_get)(struct nouveau_therm *);
- int (*fan_set)(struct nouveau_therm *, int);
- int (*fan_sense)(struct nouveau_therm *);
-
- int (*temp_get)(struct nouveau_therm *);
-
- int (*attr_get)(struct nouveau_therm *, enum nouveau_therm_attr_type);
- int (*attr_set)(struct nouveau_therm *,
- enum nouveau_therm_attr_type, int);
-};
-
-static inline struct nouveau_therm *
-nouveau_therm(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_THERM];
-}
-
-#define nouveau_therm_create(p,e,o,d) \
- nouveau_therm_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_therm_destroy(p) ({ \
- struct nouveau_therm *therm = (p); \
- _nouveau_therm_dtor(nv_object(therm)); \
-})
-#define nouveau_therm_init(p) ({ \
- struct nouveau_therm *therm = (p); \
- _nouveau_therm_init(nv_object(therm)); \
-})
-#define nouveau_therm_fini(p,s) ({ \
- struct nouveau_therm *therm = (p); \
- _nouveau_therm_init(nv_object(therm), (s)); \
-})
-
-int nouveau_therm_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_therm_dtor(struct nouveau_object *);
-int _nouveau_therm_init(struct nouveau_object *);
-int _nouveau_therm_fini(struct nouveau_object *, bool);
-
-int nouveau_therm_cstate(struct nouveau_therm *, int, int);
-
-extern struct nouveau_oclass nv40_therm_oclass;
-extern struct nouveau_oclass nv50_therm_oclass;
-extern struct nouveau_oclass nv84_therm_oclass;
-extern struct nouveau_oclass nva3_therm_oclass;
-extern struct nouveau_oclass nvd0_therm_oclass;
-extern struct nouveau_oclass gm107_therm_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h
deleted file mode 100644
index db9be803a874..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef __NOUVEAU_TIMER_H__
-#define __NOUVEAU_TIMER_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_alarm {
- struct list_head head;
- u64 timestamp;
- void (*func)(struct nouveau_alarm *);
-};
-
-static inline void
-nouveau_alarm_init(struct nouveau_alarm *alarm,
- void (*func)(struct nouveau_alarm *))
-{
- INIT_LIST_HEAD(&alarm->head);
- alarm->func = func;
-}
-
-bool nouveau_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data);
-bool nouveau_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data);
-bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data);
-void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *);
-void nouveau_timer_alarm_cancel(void *, struct nouveau_alarm *);
-
-#define NV_WAIT_DEFAULT 2000000000ULL
-#define nv_wait(o,a,m,v) \
- nouveau_timer_wait_eq((o), NV_WAIT_DEFAULT, (a), (m), (v))
-#define nv_wait_ne(o,a,m,v) \
- nouveau_timer_wait_ne((o), NV_WAIT_DEFAULT, (a), (m), (v))
-#define nv_wait_cb(o,c,d) \
- nouveau_timer_wait_cb((o), NV_WAIT_DEFAULT, (c), (d))
-
-struct nouveau_timer {
- struct nouveau_subdev base;
- u64 (*read)(struct nouveau_timer *);
- void (*alarm)(struct nouveau_timer *, u64 time, struct nouveau_alarm *);
- void (*alarm_cancel)(struct nouveau_timer *, struct nouveau_alarm *);
-};
-
-static inline struct nouveau_timer *
-nouveau_timer(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_TIMER];
-}
-
-#define nouveau_timer_create(p,e,o,d) \
- nouveau_subdev_create_((p), (e), (o), 0, "PTIMER", "timer", \
- sizeof(**d), (void **)d)
-#define nouveau_timer_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_timer_init(p) \
- nouveau_subdev_init(&(p)->base)
-#define nouveau_timer_fini(p,s) \
- nouveau_subdev_fini(&(p)->base, (s))
-
-int nouveau_timer_create_(struct nouveau_object *, struct nouveau_engine *,
- struct nouveau_oclass *, int size, void **);
-
-extern struct nouveau_oclass nv04_timer_oclass;
-extern struct nouveau_oclass gk20a_timer_oclass;
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h b/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
deleted file mode 100644
index c9509039f94b..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2010 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#ifndef __NOUVEAU_VM_H__
-#define __NOUVEAU_VM_H__
-
-#include <core/object.h>
-#include <core/subdev.h>
-#include <core/device.h>
-#include <core/mm.h>
-
-struct nouveau_vm_pgt {
- struct nouveau_gpuobj *obj[2];
- u32 refcount[2];
-};
-
-struct nouveau_vm_pgd {
- struct list_head head;
- struct nouveau_gpuobj *obj;
-};
-
-struct nouveau_gpuobj;
-struct nouveau_mem;
-
-struct nouveau_vma {
- struct list_head head;
- int refcount;
- struct nouveau_vm *vm;
- struct nouveau_mm_node *node;
- u64 offset;
- u32 access;
-};
-
-struct nouveau_vm {
- struct nouveau_vmmgr *vmm;
- struct nouveau_mm mm;
- struct kref refcount;
-
- struct list_head pgd_list;
- atomic_t engref[NVDEV_SUBDEV_NR];
-
- struct nouveau_vm_pgt *pgt;
- u32 fpde;
- u32 lpde;
-};
-
-struct nouveau_vmmgr {
- struct nouveau_subdev base;
-
- u64 limit;
- u8 dma_bits;
- u32 pgt_bits;
- u8 spg_shift;
- u8 lpg_shift;
-
- int (*create)(struct nouveau_vmmgr *, u64 offset, u64 length,
- u64 mm_offset, struct nouveau_vm **);
-
- void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2]);
- void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *,
- struct nouveau_mem *, u32 pte, u32 cnt,
- u64 phys, u64 delta);
- void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *,
- struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
- void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt);
- void (*flush)(struct nouveau_vm *);
-};
-
-static inline struct nouveau_vmmgr *
-nouveau_vmmgr(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VM];
-}
-
-#define nouveau_vmmgr_create(p,e,o,i,f,d) \
- nouveau_subdev_create((p), (e), (o), 0, (i), (f), (d))
-#define nouveau_vmmgr_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_vmmgr_init(p) \
- nouveau_subdev_init(&(p)->base)
-#define nouveau_vmmgr_fini(p,s) \
- nouveau_subdev_fini(&(p)->base, (s))
-
-#define _nouveau_vmmgr_dtor _nouveau_subdev_dtor
-#define _nouveau_vmmgr_init _nouveau_subdev_init
-#define _nouveau_vmmgr_fini _nouveau_subdev_fini
-
-extern struct nouveau_oclass nv04_vmmgr_oclass;
-extern struct nouveau_oclass nv41_vmmgr_oclass;
-extern struct nouveau_oclass nv44_vmmgr_oclass;
-extern struct nouveau_oclass nv50_vmmgr_oclass;
-extern struct nouveau_oclass nvc0_vmmgr_oclass;
-
-int nv04_vm_create(struct nouveau_vmmgr *, u64, u64, u64,
- struct nouveau_vm **);
-void nv04_vmmgr_dtor(struct nouveau_object *);
-
-/* nouveau_vm.c */
-int nouveau_vm_create(struct nouveau_vmmgr *, u64 offset, u64 length,
- u64 mm_offset, u32 block, struct nouveau_vm **);
-int nouveau_vm_new(struct nouveau_device *, u64 offset, u64 length,
- u64 mm_offset, struct nouveau_vm **);
-int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **,
- struct nouveau_gpuobj *pgd);
-int nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift,
- u32 access, struct nouveau_vma *);
-void nouveau_vm_put(struct nouveau_vma *);
-void nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *);
-void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *);
-void nouveau_vm_unmap(struct nouveau_vma *);
-void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h b/drivers/gpu/drm/nouveau/core/include/subdev/volt.h
deleted file mode 100644
index 67db5e58880d..000000000000
--- a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef __NOUVEAU_VOLT_H__
-#define __NOUVEAU_VOLT_H__
-
-#include <core/subdev.h>
-#include <core/device.h>
-
-struct nouveau_voltage {
- u32 uv;
- u8 id;
-};
-
-struct nouveau_volt {
- struct nouveau_subdev base;
-
- int (*vid_get)(struct nouveau_volt *);
- int (*get)(struct nouveau_volt *);
- int (*vid_set)(struct nouveau_volt *, u8 vid);
- int (*set)(struct nouveau_volt *, u32 uv);
- int (*set_id)(struct nouveau_volt *, u8 id, int condition);
-
- u8 vid_mask;
- u8 vid_nr;
- struct {
- u32 uv;
- u8 vid;
- } vid[256];
-};
-
-static inline struct nouveau_volt *
-nouveau_volt(void *obj)
-{
- return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VOLT];
-}
-
-#define nouveau_volt_create(p, e, o, d) \
- nouveau_volt_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_volt_destroy(p) ({ \
- struct nouveau_volt *v = (p); \
- _nouveau_volt_dtor(nv_object(v)); \
-})
-#define nouveau_volt_init(p) ({ \
- struct nouveau_volt *v = (p); \
- _nouveau_volt_init(nv_object(v)); \
-})
-#define nouveau_volt_fini(p,s) \
- nouveau_subdev_fini((p), (s))
-
-int nouveau_volt_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_volt_dtor(struct nouveau_object *);
-int _nouveau_volt_init(struct nouveau_object *);
-#define _nouveau_volt_fini _nouveau_subdev_fini
-
-extern struct nouveau_oclass nv40_volt_oclass;
-extern struct nouveau_oclass gk20a_volt_oclass;
-
-int nouveau_voltgpio_init(struct nouveau_volt *);
-int nouveau_voltgpio_get(struct nouveau_volt *);
-int nouveau_voltgpio_set(struct nouveau_volt *, u8);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
deleted file mode 100644
index b1adc69efd88..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <core/object.h>
-
-#include <subdev/fb.h>
-#include <subdev/vm.h>
-
-#include "priv.h"
-
-struct nouveau_barobj {
- struct nouveau_object base;
- struct nouveau_vma vma;
- void __iomem *iomem;
-};
-
-static int
-nouveau_barobj_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_bar *bar = (void *)engine;
- struct nouveau_mem *mem = data;
- struct nouveau_barobj *barobj;
- int ret;
-
- ret = nouveau_object_create(parent, engine, oclass, 0, &barobj);
- *pobject = nv_object(barobj);
- if (ret)
- return ret;
-
- ret = bar->kmap(bar, mem, NV_MEM_ACCESS_RW, &barobj->vma);
- if (ret)
- return ret;
-
- barobj->iomem = ioremap(nv_device_resource_start(device, 3) +
- (u32)barobj->vma.offset, mem->size << 12);
- if (!barobj->iomem) {
- nv_warn(bar, "PRAMIN ioremap failed\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void
-nouveau_barobj_dtor(struct nouveau_object *object)
-{
- struct nouveau_bar *bar = (void *)object->engine;
- struct nouveau_barobj *barobj = (void *)object;
- if (barobj->vma.node) {
- if (barobj->iomem)
- iounmap(barobj->iomem);
- bar->unmap(bar, &barobj->vma);
- }
- nouveau_object_destroy(&barobj->base);
-}
-
-static u32
-nouveau_barobj_rd32(struct nouveau_object *object, u64 addr)
-{
- struct nouveau_barobj *barobj = (void *)object;
- return ioread32_native(barobj->iomem + addr);
-}
-
-static void
-nouveau_barobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
-{
- struct nouveau_barobj *barobj = (void *)object;
- iowrite32_native(data, barobj->iomem + addr);
-}
-
-static struct nouveau_oclass
-nouveau_barobj_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nouveau_barobj_ctor,
- .dtor = nouveau_barobj_dtor,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
- .rd32 = nouveau_barobj_rd32,
- .wr32 = nouveau_barobj_wr32,
- },
-};
-
-int
-nouveau_bar_alloc(struct nouveau_bar *bar, struct nouveau_object *parent,
- struct nouveau_mem *mem, struct nouveau_object **pobject)
-{
- struct nouveau_object *engine = nv_object(bar);
- struct nouveau_object *gpuobj;
- int ret = nouveau_object_ctor(parent, engine, &nouveau_barobj_oclass,
- mem, 0, &gpuobj);
- if (ret == 0)
- *pobject = gpuobj;
- return ret;
-}
-
-int
-nouveau_bar_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
-{
- struct nouveau_bar *bar;
- int ret;
-
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "BARCTL",
- "bar", length, pobject);
- bar = *pobject;
- if (ret)
- return ret;
-
- return 0;
-}
-
-void
-nouveau_bar_destroy(struct nouveau_bar *bar)
-{
- nouveau_subdev_destroy(&bar->base);
-}
-
-void
-_nouveau_bar_dtor(struct nouveau_object *object)
-{
- struct nouveau_bar *bar = (void *)object;
- nouveau_bar_destroy(bar);
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
deleted file mode 100644
index 05a278bab247..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <core/gpuobj.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <subdev/vm.h>
-
-#include "priv.h"
-
-struct nvc0_bar_priv_vm {
- struct nouveau_gpuobj *mem;
- struct nouveau_gpuobj *pgd;
- struct nouveau_vm *vm;
-};
-
-struct nvc0_bar_priv {
- struct nouveau_bar base;
- spinlock_t lock;
- struct nvc0_bar_priv_vm bar[2];
-};
-
-static int
-nvc0_bar_kmap(struct nouveau_bar *bar, struct nouveau_mem *mem,
- u32 flags, struct nouveau_vma *vma)
-{
- struct nvc0_bar_priv *priv = (void *)bar;
- int ret;
-
- ret = nouveau_vm_get(priv->bar[0].vm, mem->size << 12, 12, flags, vma);
- if (ret)
- return ret;
-
- nouveau_vm_map(vma, mem);
- return 0;
-}
-
-static int
-nvc0_bar_umap(struct nouveau_bar *bar, struct nouveau_mem *mem,
- u32 flags, struct nouveau_vma *vma)
-{
- struct nvc0_bar_priv *priv = (void *)bar;
- int ret;
-
- ret = nouveau_vm_get(priv->bar[1].vm, mem->size << 12,
- mem->page_shift, flags, vma);
- if (ret)
- return ret;
-
- nouveau_vm_map(vma, mem);
- return 0;
-}
-
-static void
-nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
-{
- nouveau_vm_unmap(vma);
- nouveau_vm_put(vma);
-}
-
-static int
-nvc0_bar_init_vm(struct nvc0_bar_priv *priv, struct nvc0_bar_priv_vm *bar_vm,
- int bar_nr)
-{
- struct nouveau_device *device = nv_device(&priv->base);
- struct nouveau_vm *vm;
- resource_size_t bar_len;
- int ret;
-
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
- &bar_vm->mem);
- if (ret)
- return ret;
-
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
- &bar_vm->pgd);
- if (ret)
- return ret;
-
- bar_len = nv_device_resource_len(device, bar_nr);
-
- ret = nouveau_vm_new(device, 0, bar_len, 0, &vm);
- if (ret)
- return ret;
-
- atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
-
- /*
- * Bootstrap page table lookup.
- */
- if (bar_nr == 3) {
- ret = nouveau_gpuobj_new(nv_object(priv), NULL,
- (bar_len >> 12) * 8, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC,
- &vm->pgt[0].obj[0]);
- vm->pgt[0].refcount[0] = 1;
- if (ret)
- return ret;
- }
-
- ret = nouveau_vm_ref(vm, &bar_vm->vm, bar_vm->pgd);
- nouveau_vm_ref(NULL, &vm, NULL);
- if (ret)
- return ret;
-
- nv_wo32(bar_vm->mem, 0x0200, lower_32_bits(bar_vm->pgd->addr));
- nv_wo32(bar_vm->mem, 0x0204, upper_32_bits(bar_vm->pgd->addr));
- nv_wo32(bar_vm->mem, 0x0208, lower_32_bits(bar_len - 1));
- nv_wo32(bar_vm->mem, 0x020c, upper_32_bits(bar_len - 1));
-
- return 0;
-}
-
-int
-nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nouveau_device *device = nv_device(parent);
- struct nvc0_bar_priv *priv;
- bool has_bar3 = nv_device_resource_len(device, 3) != 0;
- int ret;
-
- ret = nouveau_bar_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- /* BAR3 */
- if (has_bar3) {
- ret = nvc0_bar_init_vm(priv, &priv->bar[0], 3);
- if (ret)
- return ret;
- priv->base.alloc = nouveau_bar_alloc;
- priv->base.kmap = nvc0_bar_kmap;
- }
-
- /* BAR1 */
- ret = nvc0_bar_init_vm(priv, &priv->bar[1], 1);
- if (ret)
- return ret;
-
- priv->base.umap = nvc0_bar_umap;
- priv->base.unmap = nvc0_bar_unmap;
- priv->base.flush = nv84_bar_flush;
- spin_lock_init(&priv->lock);
- return 0;
-}
-
-void
-nvc0_bar_dtor(struct nouveau_object *object)
-{
- struct nvc0_bar_priv *priv = (void *)object;
-
- nouveau_vm_ref(NULL, &priv->bar[1].vm, priv->bar[1].pgd);
- nouveau_gpuobj_ref(NULL, &priv->bar[1].pgd);
- nouveau_gpuobj_ref(NULL, &priv->bar[1].mem);
-
- if (priv->bar[0].vm) {
- nouveau_gpuobj_ref(NULL, &priv->bar[0].vm->pgt[0].obj[0]);
- nouveau_vm_ref(NULL, &priv->bar[0].vm, priv->bar[0].pgd);
- }
- nouveau_gpuobj_ref(NULL, &priv->bar[0].pgd);
- nouveau_gpuobj_ref(NULL, &priv->bar[0].mem);
-
- nouveau_bar_destroy(&priv->base);
-}
-
-int
-nvc0_bar_init(struct nouveau_object *object)
-{
- struct nvc0_bar_priv *priv = (void *)object;
- int ret;
-
- ret = nouveau_bar_init(&priv->base);
- if (ret)
- return ret;
-
- nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
- nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
-
- nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12);
- if (priv->bar[0].mem)
- nv_wr32(priv, 0x001714,
- 0xc0000000 | priv->bar[0].mem->addr >> 12);
- return 0;
-}
-
-struct nouveau_oclass
-nvc0_bar_oclass = {
- .handle = NV_SUBDEV(BAR, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_bar_ctor,
- .dtor = nvc0_bar_dtor,
- .init = nvc0_bar_init,
- .fini = _nouveau_bar_fini,
- },
-};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/core/subdev/bar/priv.h
deleted file mode 100644
index 3ee8b1476d00..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/priv.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __NVKM_BAR_PRIV_H__
-#define __NVKM_BAR_PRIV_H__
-
-#include <subdev/bar.h>
-
-#define nouveau_bar_create(p,e,o,d) \
- nouveau_bar_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_bar_init(p) \
- nouveau_subdev_init(&(p)->base)
-#define nouveau_bar_fini(p,s) \
- nouveau_subdev_fini(&(p)->base, (s))
-
-int nouveau_bar_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void nouveau_bar_destroy(struct nouveau_bar *);
-
-void _nouveau_bar_dtor(struct nouveau_object *);
-#define _nouveau_bar_init _nouveau_subdev_init
-#define _nouveau_bar_fini _nouveau_subdev_fini
-
-int nouveau_bar_alloc(struct nouveau_bar *, struct nouveau_object *,
- struct nouveau_mem *, struct nouveau_object **);
-
-void nv84_bar_flush(struct nouveau_bar *);
-
-int nvc0_bar_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nvc0_bar_dtor(struct nouveau_object *);
-int nvc0_bar_init(struct nouveau_object *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h
deleted file mode 100644
index 4d7602450a20..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __NVKM_BUS_NV04_H__
-#define __NVKM_BUS_NV04_H__
-
-#include <subdev/bus.h>
-
-struct nv04_bus_priv {
- struct nouveau_bus base;
-};
-
-int nv04_bus_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-int nv50_bus_init(struct nouveau_object *);
-void nv50_bus_intr(struct nouveau_subdev *);
-
-struct nv04_bus_impl {
- struct nouveau_oclass base;
- void (*intr)(struct nouveau_subdev *);
- int (*hwsq_exec)(struct nouveau_bus *, u32 *, u32);
- u32 hwsq_size;
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h
deleted file mode 100644
index f10917d789e8..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __NVKM_CLK_NV50_H__
-#define __NVKM_CLK_NV50_H__
-
-#include <subdev/bus.h>
-#include <subdev/bus/hwsq.h>
-#include <subdev/clock.h>
-
-struct nv50_clock_hwsq {
- struct hwsq base;
- struct hwsq_reg r_fifo;
- struct hwsq_reg r_spll[2];
- struct hwsq_reg r_nvpll[2];
- struct hwsq_reg r_divs;
- struct hwsq_reg r_mast;
-};
-
-struct nv50_clock_priv {
- struct nouveau_clock base;
- struct nv50_clock_hwsq hwsq;
-};
-
-int nv50_clock_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-struct nv50_clock_oclass {
- struct nouveau_oclass base;
- struct nouveau_clocks *domains;
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h
deleted file mode 100644
index a45a1038b12f..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __NVKM_CLK_NVA3_H__
-#define __NVKM_CLK_NVA3_H__
-
-#include <subdev/clock.h>
-
-struct nva3_clock_info {
- u32 clk;
- u32 pll;
- enum {
- NVA3_HOST_277,
- NVA3_HOST_CLK,
- } host_out;
- u32 fb_delay;
-};
-
-int nva3_pll_info(struct nouveau_clock *, int, u32, u32,
- struct nva3_clock_info *);
-int nva3_clock_pre(struct nouveau_clock *clk, unsigned long *flags);
-void nva3_clock_post(struct nouveau_clock *clk, unsigned long *flags);
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h b/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
deleted file mode 100644
index 445b14c33a98..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __NOUVEAU_PLL_H__
-#define __NOUVEAU_PLL_H__
-
-int nv04_pll_calc(struct nouveau_subdev *, struct nvbios_pll *, u32 freq,
- int *N1, int *M1, int *N2, int *M2, int *P);
-int nva3_pll_calc(struct nouveau_subdev *, struct nvbios_pll *, u32 freq,
- int *N, int *fN, int *M, int *P);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.h
deleted file mode 100644
index 23470a57510c..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __NVKM_DEVINIT_NV04_H__
-#define __NVKM_DEVINIT_NV04_H__
-
-#include "priv.h"
-
-struct nv04_devinit_priv {
- struct nouveau_devinit base;
- u8 owner;
-};
-
-int nv04_devinit_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv04_devinit_dtor(struct nouveau_object *);
-int nv04_devinit_init(struct nouveau_object *);
-int nv04_devinit_fini(struct nouveau_object *, bool);
-int nv04_devinit_pll_set(struct nouveau_devinit *, u32, u32);
-
-void setPLL_single(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
-void setPLL_double_highregs(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
-void setPLL_double_lowregs(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
deleted file mode 100644
index f412bb7f780e..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __NVKM_DEVINIT_NV50_H__
-#define __NVKM_DEVINIT_NV50_H__
-
-#include "priv.h"
-
-struct nv50_devinit_priv {
- struct nouveau_devinit base;
- u32 r001540;
-};
-
-int nv50_devinit_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-int nv50_devinit_init(struct nouveau_object *);
-int nv50_devinit_pll_set(struct nouveau_devinit *, u32, u32);
-
-int nva3_devinit_pll_set(struct nouveau_devinit *, u32, u32);
-
-int nvc0_devinit_pll_set(struct nouveau_devinit *, u32, u32);
-
-u64 gm107_devinit_disable(struct nouveau_devinit *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
deleted file mode 100644
index cbcd51852472..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __NVKM_DEVINIT_PRIV_H__
-#define __NVKM_DEVINIT_PRIV_H__
-
-#include <subdev/bios.h>
-#include <subdev/bios/pll.h>
-#include <subdev/bios/init.h>
-#include <subdev/clock/pll.h>
-#include <subdev/devinit.h>
-
-struct nouveau_devinit_impl {
- struct nouveau_oclass base;
- void (*meminit)(struct nouveau_devinit *);
- int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq);
- u64 (*disable)(struct nouveau_devinit *);
- u32 (*mmio)(struct nouveau_devinit *, u32);
- int (*post)(struct nouveau_subdev *, bool);
-};
-
-#define nouveau_devinit_create(p,e,o,d) \
- nouveau_devinit_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_devinit_destroy(p) ({ \
- struct nouveau_devinit *d = (p); \
- _nouveau_devinit_dtor(nv_object(d)); \
-})
-#define nouveau_devinit_init(p) ({ \
- struct nouveau_devinit *d = (p); \
- _nouveau_devinit_init(nv_object(d)); \
-})
-#define nouveau_devinit_fini(p,s) ({ \
- struct nouveau_devinit *d = (p); \
- _nouveau_devinit_fini(nv_object(d), (s)); \
-})
-
-int nouveau_devinit_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_devinit_dtor(struct nouveau_object *);
-int _nouveau_devinit_init(struct nouveau_object *);
-int _nouveau_devinit_fini(struct nouveau_object *, bool suspend);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h
deleted file mode 100644
index 06ce71f87a74..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __NVKM_FB_NV04_H__
-#define __NVKM_FB_NV04_H__
-
-#include "priv.h"
-
-struct nv04_fb_priv {
- struct nouveau_fb base;
-};
-
-int nv04_fb_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-struct nv04_fb_impl {
- struct nouveau_fb_impl base;
- struct {
- int regions;
- void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
- void (*comp)(struct nouveau_fb *, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *);
- void (*fini)(struct nouveau_fb *, int i,
- struct nouveau_fb_tile *);
- void (*prog)(struct nouveau_fb *, int i,
- struct nouveau_fb_tile *);
- } tile;
-};
-
-void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
-void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
-void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
-void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
-void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int nv30_fb_init(struct nouveau_object *);
-void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
-
-void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *);
-
-int nv41_fb_init(struct nouveau_object *);
-void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int nv44_fb_init(struct nouveau_object *);
-void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
- u32 pitch, u32 flags, struct nouveau_fb_tile *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h
deleted file mode 100644
index 581f808527f2..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __NVKM_FB_NV40_H__
-#define __NVKM_FB_NV40_H__
-
-#include "priv.h"
-
-struct nv40_ram {
- struct nouveau_ram base;
- u32 ctrl;
- u32 coef;
-};
-
-
-int nv40_ram_calc(struct nouveau_fb *, u32);
-int nv40_ram_prog(struct nouveau_fb *);
-void nv40_ram_tidy(struct nouveau_fb *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h
deleted file mode 100644
index c5e5a888c607..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __NVKM_FB_NV50_H__
-#define __NVKM_FB_NV50_H__
-
-#include "priv.h"
-
-struct nv50_fb_priv {
- struct nouveau_fb base;
- struct page *r100c08_page;
- dma_addr_t r100c08;
-};
-
-int nv50_fb_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv50_fb_dtor(struct nouveau_object *);
-int nv50_fb_init(struct nouveau_object *);
-
-struct nv50_fb_impl {
- struct nouveau_fb_impl base;
- u32 trap;
-};
-
-#define nv50_ram_create(p,e,o,d) \
- nv50_ram_create_((p), (e), (o), sizeof(**d), (void **)d)
-int nv50_ram_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-int nv50_ram_get(struct nouveau_fb *, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **);
-void nv50_ram_put(struct nouveau_fb *, struct nouveau_mem **);
-void __nv50_ram_put(struct nouveau_fb *, struct nouveau_mem *);
-extern int nv50_fb_memtype[0x80];
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h
deleted file mode 100644
index 705a06d755ad..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __NVKM_RAM_NVC0_H__
-#define __NVKM_RAM_NVC0_H__
-
-#include "priv.h"
-#include "nv50.h"
-
-struct nvc0_fb_priv {
- struct nouveau_fb base;
- struct page *r100c10_page;
- dma_addr_t r100c10;
-};
-
-int nvc0_fb_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nvc0_fb_dtor(struct nouveau_object *);
-int nvc0_fb_init(struct nouveau_object *);
-bool nvc0_fb_memtype_valid(struct nouveau_fb *, u32);
-
-
-#define nvc0_ram_create(p,e,o,m,d) \
- nvc0_ram_create_((p), (e), (o), (m), sizeof(**d), (void **)d)
-int nvc0_ram_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u32, int, void **);
-int nvc0_ram_get(struct nouveau_fb *, u64, u32, u32, u32,
- struct nouveau_mem **);
-void nvc0_ram_put(struct nouveau_fb *, struct nouveau_mem **);
-
-int nve0_ram_init(struct nouveau_object*);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
deleted file mode 100644
index 283863f7aa9b..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef __NVKM_FB_PRIV_H__
-#define __NVKM_FB_PRIV_H__
-
-#include <subdev/fb.h>
-
-#define nouveau_ram_create(p,e,o,d) \
- nouveau_object_create_((p), (e), (o), 0, sizeof(**d), (void **)d)
-#define nouveau_ram_destroy(p) \
- nouveau_object_destroy(&(p)->base)
-#define nouveau_ram_init(p) \
- nouveau_object_init(&(p)->base)
-#define nouveau_ram_fini(p,s) \
- nouveau_object_fini(&(p)->base, (s))
-
-#define nouveau_ram_create_(p,e,o,s,d) \
- nouveau_object_create_((p), (e), (o), 0, (s), (void **)d)
-#define _nouveau_ram_dtor nouveau_object_destroy
-#define _nouveau_ram_init nouveau_object_init
-#define _nouveau_ram_fini nouveau_object_fini
-
-extern struct nouveau_oclass nv04_ram_oclass;
-extern struct nouveau_oclass nv10_ram_oclass;
-extern struct nouveau_oclass nv1a_ram_oclass;
-extern struct nouveau_oclass nv20_ram_oclass;
-extern struct nouveau_oclass nv40_ram_oclass;
-extern struct nouveau_oclass nv41_ram_oclass;
-extern struct nouveau_oclass nv44_ram_oclass;
-extern struct nouveau_oclass nv49_ram_oclass;
-extern struct nouveau_oclass nv4e_ram_oclass;
-extern struct nouveau_oclass nv50_ram_oclass;
-extern struct nouveau_oclass nva3_ram_oclass;
-extern struct nouveau_oclass nvaa_ram_oclass;
-extern struct nouveau_oclass nvc0_ram_oclass;
-extern struct nouveau_oclass nve0_ram_oclass;
-extern struct nouveau_oclass gk20a_ram_oclass;
-extern struct nouveau_oclass gm107_ram_oclass;
-
-int nouveau_sddr2_calc(struct nouveau_ram *ram);
-int nouveau_sddr3_calc(struct nouveau_ram *ram);
-int nouveau_gddr3_calc(struct nouveau_ram *ram);
-int nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts);
-
-#define nouveau_fb_create(p,e,c,d) \
- nouveau_fb_create_((p), (e), (c), sizeof(**d), (void **)d)
-#define nouveau_fb_destroy(p) ({ \
- struct nouveau_fb *pfb = (p); \
- _nouveau_fb_dtor(nv_object(pfb)); \
-})
-#define nouveau_fb_init(p) ({ \
- struct nouveau_fb *pfb = (p); \
- _nouveau_fb_init(nv_object(pfb)); \
-})
-#define nouveau_fb_fini(p,s) ({ \
- struct nouveau_fb *pfb = (p); \
- _nouveau_fb_fini(nv_object(pfb), (s)); \
-})
-
-int nouveau_fb_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_fb_dtor(struct nouveau_object *);
-int _nouveau_fb_init(struct nouveau_object *);
-int _nouveau_fb_fini(struct nouveau_object *, bool);
-
-struct nouveau_fb_impl {
- struct nouveau_oclass base;
- struct nouveau_oclass *ram;
- bool (*memtype)(struct nouveau_fb *, u32);
-};
-
-bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
-bool nv50_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
-
-struct nouveau_bios;
-int nouveau_fb_bios_memtype(struct nouveau_bios *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fuse/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fuse/priv.h
deleted file mode 100644
index d2085411a5cb..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/fuse/priv.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __NVKM_FUSE_PRIV_H__
-#define __NVKM_FUSE_PRIV_H__
-
-#include <subdev/fuse.h>
-
-int _nouveau_fuse_init(struct nouveau_object *object);
-void _nouveau_fuse_dtor(struct nouveau_object *object);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h b/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h
deleted file mode 100644
index bff98b86e2b5..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef __NVKM_GPIO_H__
-#define __NVKM_GPIO_H__
-
-#include <subdev/gpio.h>
-
-#define nouveau_gpio_create(p,e,o,d) \
- nouveau_gpio_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_gpio_destroy(p) ({ \
- struct nouveau_gpio *gpio = (p); \
- _nouveau_gpio_dtor(nv_object(gpio)); \
-})
-#define nouveau_gpio_init(p) ({ \
- struct nouveau_gpio *gpio = (p); \
- _nouveau_gpio_init(nv_object(gpio)); \
-})
-#define nouveau_gpio_fini(p,s) ({ \
- struct nouveau_gpio *gpio = (p); \
- _nouveau_gpio_fini(nv_object(gpio), (s)); \
-})
-
-int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-int _nouveau_gpio_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void _nouveau_gpio_dtor(struct nouveau_object *);
-int _nouveau_gpio_init(struct nouveau_object *);
-int _nouveau_gpio_fini(struct nouveau_object *, bool);
-
-struct nouveau_gpio_impl {
- struct nouveau_oclass base;
- int lines;
-
- /* read and ack pending interrupts, returning only data
- * for lines that have not been masked off, while still
- * performing the ack for anything that was pending.
- */
- void (*intr_stat)(struct nouveau_gpio *, u32 *, u32 *);
-
- /* mask on/off interrupts for hi/lo transitions on a
- * given set of gpio lines
- */
- void (*intr_mask)(struct nouveau_gpio *, u32, u32, u32);
-
- /* configure gpio direction and output value */
- int (*drive)(struct nouveau_gpio *, int line, int dir, int out);
-
- /* sense current state of given gpio line */
- int (*sense)(struct nouveau_gpio *, int line);
-
- /*XXX*/
- void (*reset)(struct nouveau_gpio *, u8);
-};
-
-void nv50_gpio_reset(struct nouveau_gpio *, u8);
-int nv50_gpio_drive(struct nouveau_gpio *, int, int, int);
-int nv50_gpio_sense(struct nouveau_gpio *, int);
-
-void nv94_gpio_intr_stat(struct nouveau_gpio *, u32 *, u32 *);
-void nv94_gpio_intr_mask(struct nouveau_gpio *, u32, u32, u32);
-
-void nvd0_gpio_reset(struct nouveau_gpio *, u8);
-int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int);
-int nvd0_gpio_sense(struct nouveau_gpio *, int);
-
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
deleted file mode 100644
index 9ef965692fb1..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __NV50_I2C_H__
-#define __NV50_I2C_H__
-
-#include "priv.h"
-
-struct nv50_i2c_priv {
- struct nouveau_i2c base;
-};
-
-struct nv50_i2c_port {
- struct nouveau_i2c_port base;
- u32 addr;
- u32 state;
-};
-
-extern const u32 nv50_i2c_addr[];
-extern const int nv50_i2c_addr_nr;
-int nv50_i2c_port_init(struct nouveau_object *);
-int nv50_i2c_sense_scl(struct nouveau_i2c_port *);
-int nv50_i2c_sense_sda(struct nouveau_i2c_port *);
-void nv50_i2c_drive_scl(struct nouveau_i2c_port *, int state);
-void nv50_i2c_drive_sda(struct nouveau_i2c_port *, int state);
-
-int nv94_aux_port_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv94_i2c_acquire(struct nouveau_i2c_port *);
-void nv94_i2c_release(struct nouveau_i2c_port *);
-
-int nvd0_i2c_port_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
deleted file mode 100644
index 4fe7ae3fde4e..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#ifndef __NVKM_I2C_H__
-#define __NVKM_I2C_H__
-
-#include <subdev/i2c.h>
-
-extern struct nouveau_oclass nv04_i2c_pad_oclass;
-extern struct nouveau_oclass nv94_i2c_pad_oclass;
-extern struct nouveau_oclass gm204_i2c_pad_oclass;
-
-#define nouveau_i2c_port_create(p,e,o,i,a,f,d) \
- nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \
- sizeof(**d), (void **)d)
-#define nouveau_i2c_port_destroy(p) ({ \
- struct nouveau_i2c_port *port = (p); \
- _nouveau_i2c_port_dtor(nv_object(i2c)); \
-})
-#define nouveau_i2c_port_init(p) \
- nouveau_object_init(&(p)->base)
-#define nouveau_i2c_port_fini(p,s) \
- nouveau_object_fini(&(p)->base, (s))
-
-int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u8,
- const struct i2c_algorithm *,
- const struct nouveau_i2c_func *,
- int, void **);
-void _nouveau_i2c_port_dtor(struct nouveau_object *);
-#define _nouveau_i2c_port_init nouveau_object_init
-int _nouveau_i2c_port_fini(struct nouveau_object *, bool);
-
-#define nouveau_i2c_create(p,e,o,d) \
- nouveau_i2c_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_i2c_destroy(p) ({ \
- struct nouveau_i2c *i2c = (p); \
- _nouveau_i2c_dtor(nv_object(i2c)); \
-})
-#define nouveau_i2c_init(p) ({ \
- struct nouveau_i2c *i2c = (p); \
- _nouveau_i2c_init(nv_object(i2c)); \
-})
-#define nouveau_i2c_fini(p,s) ({ \
- struct nouveau_i2c *i2c = (p); \
- _nouveau_i2c_fini(nv_object(i2c), (s)); \
-})
-
-int nouveau_i2c_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-int _nouveau_i2c_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void _nouveau_i2c_dtor(struct nouveau_object *);
-int _nouveau_i2c_init(struct nouveau_object *);
-int _nouveau_i2c_fini(struct nouveau_object *, bool);
-
-extern struct nouveau_oclass nouveau_anx9805_sclass[];
-extern struct nouveau_oclass nvd0_i2c_sclass[];
-
-extern const struct i2c_algorithm nouveau_i2c_bit_algo;
-extern const struct i2c_algorithm nouveau_i2c_aux_algo;
-
-struct nouveau_i2c_impl {
- struct nouveau_oclass base;
-
- /* supported i2c port classes */
- struct nouveau_oclass *sclass;
- struct nouveau_oclass *pad_x;
- struct nouveau_oclass *pad_s;
-
- /* number of native dp aux channels present */
- int aux;
-
- /* read and ack pending interrupts, returning only data
- * for ports that have not been masked off, while still
- * performing the ack for anything that was pending.
- */
- void (*aux_stat)(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *);
-
- /* mask on/off interrupt types for a given set of auxch
- */
- void (*aux_mask)(struct nouveau_i2c *, u32, u32, u32);
-};
-
-void nv94_aux_stat(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *);
-void nv94_aux_mask(struct nouveau_i2c *, u32, u32, u32);
-
-void nve0_aux_stat(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *);
-void nve0_aux_mask(struct nouveau_i2c *, u32, u32, u32);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
deleted file mode 100644
index 095fbc6fc099..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __NV04_INSTMEM_H__
-#define __NV04_INSTMEM_H__
-
-#include <core/gpuobj.h>
-#include <core/ramht.h>
-#include <core/mm.h>
-
-#include "priv.h"
-
-extern struct nouveau_instobj_impl nv04_instobj_oclass;
-
-struct nv04_instmem_priv {
- struct nouveau_instmem base;
-
- void __iomem *iomem;
- struct nouveau_mm heap;
-
- struct nouveau_gpuobj *vbios;
- struct nouveau_ramht *ramht;
- struct nouveau_gpuobj *ramro;
- struct nouveau_gpuobj *ramfc;
-};
-
-static inline struct nv04_instmem_priv *
-nv04_instmem(void *obj)
-{
- return (void *)nouveau_instmem(obj);
-}
-
-struct nv04_instobj_priv {
- struct nouveau_instobj base;
- struct nouveau_mm_node *mem;
-};
-
-void nv04_instmem_dtor(struct nouveau_object *);
-
-int nv04_instmem_alloc(struct nouveau_instmem *, struct nouveau_object *,
- u32 size, u32 align, struct nouveau_object **pobject);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/core/subdev/instmem/priv.h
deleted file mode 100644
index 8d67dedc5bb2..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/priv.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __NVKM_INSTMEM_PRIV_H__
-#define __NVKM_INSTMEM_PRIV_H__
-
-#include <subdev/instmem.h>
-
-struct nouveau_instobj_impl {
- struct nouveau_oclass base;
-};
-
-struct nouveau_instobj_args {
- u32 size;
- u32 align;
-};
-
-#define nouveau_instobj_create(p,e,o,d) \
- nouveau_instobj_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_instobj_destroy(p) ({ \
- struct nouveau_instobj *iobj = (p); \
- _nouveau_instobj_dtor(nv_object(iobj)); \
-})
-#define nouveau_instobj_init(p) \
- nouveau_object_init(&(p)->base)
-#define nouveau_instobj_fini(p,s) \
- nouveau_object_fini(&(p)->base, (s))
-
-int nouveau_instobj_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_instobj_dtor(struct nouveau_object *);
-#define _nouveau_instobj_init nouveau_object_init
-#define _nouveau_instobj_fini nouveau_object_fini
-
-struct nouveau_instmem_impl {
- struct nouveau_oclass base;
- struct nouveau_oclass *instobj;
-};
-
-#define nouveau_instmem_create(p,e,o,d) \
- nouveau_instmem_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_instmem_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_instmem_init(p) ({ \
- struct nouveau_instmem *imem = (p); \
- _nouveau_instmem_init(nv_object(imem)); \
-})
-#define nouveau_instmem_fini(p,s) ({ \
- struct nouveau_instmem *imem = (p); \
- _nouveau_instmem_fini(nv_object(imem), (s)); \
-})
-
-int nouveau_instmem_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-#define _nouveau_instmem_dtor _nouveau_subdev_dtor
-int _nouveau_instmem_init(struct nouveau_object *);
-int _nouveau_instmem_fini(struct nouveau_object *, bool);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h
deleted file mode 100644
index 4d9ea46c47c2..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __NVKM_MC_NV04_H__
-#define __NVKM_MC_NV04_H__
-
-#include "priv.h"
-
-struct nv04_mc_priv {
- struct nouveau_mc base;
-};
-
-int nv04_mc_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-
-extern const struct nouveau_mc_intr nv04_mc_intr[];
-int nv04_mc_init(struct nouveau_object *);
-void nv40_mc_msi_rearm(struct nouveau_mc *);
-int nv44_mc_init(struct nouveau_object *object);
-int nv50_mc_init(struct nouveau_object *);
-extern const struct nouveau_mc_intr nv50_mc_intr[];
-extern const struct nouveau_mc_intr nvc0_mc_intr[];
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/core/subdev/mc/priv.h
deleted file mode 100644
index 911e66392587..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/priv.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __NVKM_MC_PRIV_H__
-#define __NVKM_MC_PRIV_H__
-
-#include <subdev/mc.h>
-
-#define nouveau_mc_create(p,e,o,d) \
- nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_mc_destroy(p) ({ \
- struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
-})
-#define nouveau_mc_init(p) ({ \
- struct nouveau_mc *pmc = (p); _nouveau_mc_init(nv_object(pmc)); \
-})
-#define nouveau_mc_fini(p,s) ({ \
- struct nouveau_mc *pmc = (p); _nouveau_mc_fini(nv_object(pmc), (s)); \
-})
-
-int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-void _nouveau_mc_dtor(struct nouveau_object *);
-int _nouveau_mc_init(struct nouveau_object *);
-int _nouveau_mc_fini(struct nouveau_object *, bool);
-
-struct nouveau_mc_intr {
- u32 stat;
- u32 unit;
-};
-
-struct nouveau_mc_oclass {
- struct nouveau_oclass base;
- const struct nouveau_mc_intr *intr;
- void (*msi_rearm)(struct nouveau_mc *);
- void (*unk260)(struct nouveau_mc *, u32);
-};
-
-void nvc0_mc_unk260(struct nouveau_mc *, u32);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h b/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h
deleted file mode 100644
index 5e0be0c591ca..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __NVMXM_MXMS_H__
-#define __NVMXM_MXMS_H__
-
-struct mxms_odev {
- u8 outp_type;
- u8 conn_type;
- u8 ddc_port;
- u8 dig_conn;
-};
-
-void mxms_output_device(struct nouveau_mxm *, u8 *, struct mxms_odev *);
-
-u16 mxms_version(struct nouveau_mxm *);
-u16 mxms_headerlen(struct nouveau_mxm *);
-u16 mxms_structlen(struct nouveau_mxm *);
-bool mxms_checksum(struct nouveau_mxm *);
-bool mxms_valid(struct nouveau_mxm *);
-
-bool mxms_foreach(struct nouveau_mxm *, u8,
- bool (*)(struct nouveau_mxm *, u8 *, void *), void *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c
deleted file mode 100644
index 0ab55f27ec45..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <subdev/timer.h>
-
-#include "priv.h"
-
-static void
-nouveau_pwr_pgob(struct nouveau_pwr *ppwr, bool enable)
-{
- const struct nvkm_pwr_impl *impl = (void *)nv_oclass(ppwr);
- if (impl->pgob)
- impl->pgob(ppwr, enable);
-}
-
-static int
-nouveau_pwr_send(struct nouveau_pwr *ppwr, u32 reply[2],
- u32 process, u32 message, u32 data0, u32 data1)
-{
- struct nouveau_subdev *subdev = nv_subdev(ppwr);
- u32 addr;
-
- /* wait for a free slot in the fifo */
- addr = nv_rd32(ppwr, 0x10a4a0);
- if (!nv_wait_ne(ppwr, 0x10a4b0, 0xffffffff, addr ^ 8))
- return -EBUSY;
-
- /* we currently only support a single process at a time waiting
- * on a synchronous reply, take the PPWR mutex and tell the
- * receive handler what we're waiting for
- */
- if (reply) {
- mutex_lock(&subdev->mutex);
- ppwr->recv.message = message;
- ppwr->recv.process = process;
- }
-
- /* acquire data segment access */
- do {
- nv_wr32(ppwr, 0x10a580, 0x00000001);
- } while (nv_rd32(ppwr, 0x10a580) != 0x00000001);
-
- /* write the packet */
- nv_wr32(ppwr, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) +
- ppwr->send.base));
- nv_wr32(ppwr, 0x10a1c4, process);
- nv_wr32(ppwr, 0x10a1c4, message);
- nv_wr32(ppwr, 0x10a1c4, data0);
- nv_wr32(ppwr, 0x10a1c4, data1);
- nv_wr32(ppwr, 0x10a4a0, (addr + 1) & 0x0f);
-
- /* release data segment access */
- nv_wr32(ppwr, 0x10a580, 0x00000000);
-
- /* wait for reply, if requested */
- if (reply) {
- wait_event(ppwr->recv.wait, (ppwr->recv.process == 0));
- reply[0] = ppwr->recv.data[0];
- reply[1] = ppwr->recv.data[1];
- mutex_unlock(&subdev->mutex);
- }
-
- return 0;
-}
-
-static void
-nouveau_pwr_recv(struct work_struct *work)
-{
- struct nouveau_pwr *ppwr =
- container_of(work, struct nouveau_pwr, recv.work);
- u32 process, message, data0, data1;
-
- /* nothing to do if GET == PUT */
- u32 addr = nv_rd32(ppwr, 0x10a4cc);
- if (addr == nv_rd32(ppwr, 0x10a4c8))
- return;
-
- /* acquire data segment access */
- do {
- nv_wr32(ppwr, 0x10a580, 0x00000002);
- } while (nv_rd32(ppwr, 0x10a580) != 0x00000002);
-
- /* read the packet */
- nv_wr32(ppwr, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) +
- ppwr->recv.base));
- process = nv_rd32(ppwr, 0x10a1c4);
- message = nv_rd32(ppwr, 0x10a1c4);
- data0 = nv_rd32(ppwr, 0x10a1c4);
- data1 = nv_rd32(ppwr, 0x10a1c4);
- nv_wr32(ppwr, 0x10a4cc, (addr + 1) & 0x0f);
-
- /* release data segment access */
- nv_wr32(ppwr, 0x10a580, 0x00000000);
-
- /* wake process if it's waiting on a synchronous reply */
- if (ppwr->recv.process) {
- if (process == ppwr->recv.process &&
- message == ppwr->recv.message) {
- ppwr->recv.data[0] = data0;
- ppwr->recv.data[1] = data1;
- ppwr->recv.process = 0;
- wake_up(&ppwr->recv.wait);
- return;
- }
- }
-
- /* right now there's no other expected responses from the engine,
- * so assume that any unexpected message is an error.
- */
- nv_warn(ppwr, "%c%c%c%c 0x%08x 0x%08x 0x%08x 0x%08x\n",
- (char)((process & 0x000000ff) >> 0),
- (char)((process & 0x0000ff00) >> 8),
- (char)((process & 0x00ff0000) >> 16),
- (char)((process & 0xff000000) >> 24),
- process, message, data0, data1);
-}
-
-static void
-nouveau_pwr_intr(struct nouveau_subdev *subdev)
-{
- struct nouveau_pwr *ppwr = (void *)subdev;
- u32 disp = nv_rd32(ppwr, 0x10a01c);
- u32 intr = nv_rd32(ppwr, 0x10a008) & disp & ~(disp >> 16);
-
- if (intr & 0x00000020) {
- u32 stat = nv_rd32(ppwr, 0x10a16c);
- if (stat & 0x80000000) {
- nv_error(ppwr, "UAS fault at 0x%06x addr 0x%08x\n",
- stat & 0x00ffffff, nv_rd32(ppwr, 0x10a168));
- nv_wr32(ppwr, 0x10a16c, 0x00000000);
- intr &= ~0x00000020;
- }
- }
-
- if (intr & 0x00000040) {
- schedule_work(&ppwr->recv.work);
- nv_wr32(ppwr, 0x10a004, 0x00000040);
- intr &= ~0x00000040;
- }
-
- if (intr & 0x00000080) {
- nv_info(ppwr, "wr32 0x%06x 0x%08x\n", nv_rd32(ppwr, 0x10a7a0),
- nv_rd32(ppwr, 0x10a7a4));
- nv_wr32(ppwr, 0x10a004, 0x00000080);
- intr &= ~0x00000080;
- }
-
- if (intr) {
- nv_error(ppwr, "intr 0x%08x\n", intr);
- nv_wr32(ppwr, 0x10a004, intr);
- }
-}
-
-int
-_nouveau_pwr_fini(struct nouveau_object *object, bool suspend)
-{
- struct nouveau_pwr *ppwr = (void *)object;
-
- nv_wr32(ppwr, 0x10a014, 0x00000060);
- flush_work(&ppwr->recv.work);
-
- return nouveau_subdev_fini(&ppwr->base, suspend);
-}
-
-int
-_nouveau_pwr_init(struct nouveau_object *object)
-{
- const struct nvkm_pwr_impl *impl = (void *)object->oclass;
- struct nouveau_pwr *ppwr = (void *)object;
- int ret, i;
-
- ret = nouveau_subdev_init(&ppwr->base);
- if (ret)
- return ret;
-
- nv_subdev(ppwr)->intr = nouveau_pwr_intr;
- ppwr->message = nouveau_pwr_send;
- ppwr->pgob = nouveau_pwr_pgob;
-
- /* prevent previous ucode from running, wait for idle, reset */
- nv_wr32(ppwr, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */
- nv_wait(ppwr, 0x10a04c, 0xffffffff, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x00002000, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x00002000, 0x00002000);
- nv_rd32(ppwr, 0x000200);
- nv_wait(ppwr, 0x10a10c, 0x00000006, 0x00000000);
-
- /* upload data segment */
- nv_wr32(ppwr, 0x10a1c0, 0x01000000);
- for (i = 0; i < impl->data.size / 4; i++)
- nv_wr32(ppwr, 0x10a1c4, impl->data.data[i]);
-
- /* upload code segment */
- nv_wr32(ppwr, 0x10a180, 0x01000000);
- for (i = 0; i < impl->code.size / 4; i++) {
- if ((i & 0x3f) == 0)
- nv_wr32(ppwr, 0x10a188, i >> 6);
- nv_wr32(ppwr, 0x10a184, impl->code.data[i]);
- }
-
- /* start it running */
- nv_wr32(ppwr, 0x10a10c, 0x00000000);
- nv_wr32(ppwr, 0x10a104, 0x00000000);
- nv_wr32(ppwr, 0x10a100, 0x00000002);
-
- /* wait for valid host->pwr ring configuration */
- if (!nv_wait_ne(ppwr, 0x10a4d0, 0xffffffff, 0x00000000))
- return -EBUSY;
- ppwr->send.base = nv_rd32(ppwr, 0x10a4d0) & 0x0000ffff;
- ppwr->send.size = nv_rd32(ppwr, 0x10a4d0) >> 16;
-
- /* wait for valid pwr->host ring configuration */
- if (!nv_wait_ne(ppwr, 0x10a4dc, 0xffffffff, 0x00000000))
- return -EBUSY;
- ppwr->recv.base = nv_rd32(ppwr, 0x10a4dc) & 0x0000ffff;
- ppwr->recv.size = nv_rd32(ppwr, 0x10a4dc) >> 16;
-
- nv_wr32(ppwr, 0x10a010, 0x000000e0);
- return 0;
-}
-
-int
-nouveau_pwr_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
-{
- struct nouveau_pwr *ppwr;
- int ret;
-
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PPWR",
- "pwr", length, pobject);
- ppwr = *pobject;
- if (ret)
- return ret;
-
- INIT_WORK(&ppwr->recv.work, nouveau_pwr_recv);
- init_waitqueue_head(&ppwr->recv.wait);
- return 0;
-}
-
-int
-_nouveau_pwr_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
-{
- struct nouveau_pwr *ppwr;
- int ret = nouveau_pwr_create(parent, engine, oclass, &ppwr);
- *pobject = nv_object(ppwr);
- return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
deleted file mode 100644
index 7a9299d7159f..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef __NVKM_PWR_MEMX_H__
-#define __NVKM_PWR_MEMX_H__
-
-#include "priv.h"
-
-struct nouveau_memx {
- struct nouveau_pwr *ppwr;
- u32 base;
- u32 size;
- struct {
- u32 mthd;
- u32 size;
- u32 data[64];
- } c;
-};
-
-static void
-memx_out(struct nouveau_memx *memx)
-{
- struct nouveau_pwr *ppwr = memx->ppwr;
- int i;
-
- if (memx->c.mthd) {
- nv_wr32(ppwr, 0x10a1c4, (memx->c.size << 16) | memx->c.mthd);
- for (i = 0; i < memx->c.size; i++)
- nv_wr32(ppwr, 0x10a1c4, memx->c.data[i]);
- memx->c.mthd = 0;
- memx->c.size = 0;
- }
-}
-
-static void
-memx_cmd(struct nouveau_memx *memx, u32 mthd, u32 size, u32 data[])
-{
- if ((memx->c.size + size >= ARRAY_SIZE(memx->c.data)) ||
- (memx->c.mthd && memx->c.mthd != mthd))
- memx_out(memx);
- memcpy(&memx->c.data[memx->c.size], data, size * sizeof(data[0]));
- memx->c.size += size;
- memx->c.mthd = mthd;
-}
-
-int
-nouveau_memx_init(struct nouveau_pwr *ppwr, struct nouveau_memx **pmemx)
-{
- struct nouveau_memx *memx;
- u32 reply[2];
- int ret;
-
- ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO,
- MEMX_INFO_DATA, 0);
- if (ret)
- return ret;
-
- memx = *pmemx = kzalloc(sizeof(*memx), GFP_KERNEL);
- if (!memx)
- return -ENOMEM;
- memx->ppwr = ppwr;
- memx->base = reply[0];
- memx->size = reply[1];
-
- /* acquire data segment access */
- do {
- nv_wr32(ppwr, 0x10a580, 0x00000003);
- } while (nv_rd32(ppwr, 0x10a580) != 0x00000003);
- nv_wr32(ppwr, 0x10a1c0, 0x01000000 | memx->base);
-
- return 0;
-}
-
-int
-nouveau_memx_fini(struct nouveau_memx **pmemx, bool exec)
-{
- struct nouveau_memx *memx = *pmemx;
- struct nouveau_pwr *ppwr = memx->ppwr;
- u32 finish, reply[2];
-
- /* flush the cache... */
- memx_out(memx);
-
- /* release data segment access */
- finish = nv_rd32(ppwr, 0x10a1c0) & 0x00ffffff;
- nv_wr32(ppwr, 0x10a580, 0x00000000);
-
- /* call MEMX process to execute the script, and wait for reply */
- if (exec) {
- ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_EXEC,
- memx->base, finish);
- }
-
- nv_debug(memx->ppwr, "Exec took %uns, PPWR_IN %08x\n",
- reply[0], reply[1]);
- kfree(memx);
- return 0;
-}
-
-void
-nouveau_memx_wr32(struct nouveau_memx *memx, u32 addr, u32 data)
-{
- nv_debug(memx->ppwr, "R[%06x] = 0x%08x\n", addr, data);
- memx_cmd(memx, MEMX_WR32, 2, (u32[]){ addr, data });
-}
-
-void
-nouveau_memx_wait(struct nouveau_memx *memx,
- u32 addr, u32 mask, u32 data, u32 nsec)
-{
- nv_debug(memx->ppwr, "R[%06x] & 0x%08x == 0x%08x, %d us\n",
- addr, mask, data, nsec);
- memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, mask, data, nsec });
- memx_out(memx); /* fuc can't handle multiple */
-}
-
-void
-nouveau_memx_nsec(struct nouveau_memx *memx, u32 nsec)
-{
- nv_debug(memx->ppwr, " DELAY = %d ns\n", nsec);
- memx_cmd(memx, MEMX_DELAY, 1, (u32[]){ nsec });
- memx_out(memx); /* fuc can't handle multiple */
-}
-
-void
-nouveau_memx_wait_vblank(struct nouveau_memx *memx)
-{
- struct nouveau_pwr *ppwr = memx->ppwr;
- u32 heads, x, y, px = 0;
- int i, head_sync;
-
- if (nv_device(ppwr)->chipset < 0xd0) {
- heads = nv_rd32(ppwr, 0x610050);
- for (i = 0; i < 2; i++) {
- /* Heuristic: sync to head with biggest resolution */
- if (heads & (2 << (i << 3))) {
- x = nv_rd32(ppwr, 0x610b40 + (0x540 * i));
- y = (x & 0xffff0000) >> 16;
- x &= 0x0000ffff;
- if ((x * y) > px) {
- px = (x * y);
- head_sync = i;
- }
- }
- }
- }
-
- if (px == 0) {
- nv_debug(memx->ppwr, "WAIT VBLANK !NO ACTIVE HEAD\n");
- return;
- }
-
- nv_debug(memx->ppwr, "WAIT VBLANK HEAD%d\n", head_sync);
- memx_cmd(memx, MEMX_VBLANK, 1, (u32[]){ head_sync });
- memx_out(memx); /* fuc can't handle multiple */
-}
-
-void
-nouveau_memx_train(struct nouveau_memx *memx)
-{
- nv_debug(memx->ppwr, " MEM TRAIN\n");
- memx_cmd(memx, MEMX_TRAIN, 0, NULL);
-}
-
-int
-nouveau_memx_train_result(struct nouveau_pwr *ppwr, u32 *res, int rsize)
-{
- u32 reply[2], base, size, i;
- int ret;
-
- ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO,
- MEMX_INFO_TRAIN, 0);
- if (ret)
- return ret;
-
- base = reply[0];
- size = reply[1] >> 2;
- if (size > rsize)
- return -ENOMEM;
-
- /* read the packet */
- nv_wr32(ppwr, 0x10a1c0, 0x02000000 | base);
-
- for (i = 0; i < size; i++)
- res[i] = nv_rd32(ppwr, 0x10a1c4);
-
- return 0;
-}
-
-void
-nouveau_memx_block(struct nouveau_memx *memx)
-{
- nv_debug(memx->ppwr, " HOST BLOCKED\n");
- memx_cmd(memx, MEMX_ENTER, 0, NULL);
-}
-
-void
-nouveau_memx_unblock(struct nouveau_memx *memx)
-{
- nv_debug(memx->ppwr, " HOST UNBLOCKED\n");
- memx_cmd(memx, MEMX_LEAVE, 0, NULL);
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/priv.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/priv.h
deleted file mode 100644
index 3814a341db32..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/priv.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __NVKM_PWR_PRIV_H__
-#define __NVKM_PWR_PRIV_H__
-
-#include <subdev/pwr.h>
-#include <subdev/pwr/fuc/os.h>
-
-#define nouveau_pwr_create(p, e, o, d) \
- nouveau_pwr_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_pwr_destroy(p) \
- nouveau_subdev_destroy(&(p)->base)
-#define nouveau_pwr_init(p) ({ \
- struct nouveau_pwr *_ppwr = (p); \
- _nouveau_pwr_init(nv_object(_ppwr)); \
-})
-#define nouveau_pwr_fini(p,s) ({ \
- struct nouveau_pwr *_ppwr = (p); \
- _nouveau_pwr_fini(nv_object(_ppwr), (s)); \
-})
-
-int nouveau_pwr_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
-
-int _nouveau_pwr_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-#define _nouveau_pwr_dtor _nouveau_subdev_dtor
-int _nouveau_pwr_init(struct nouveau_object *);
-int _nouveau_pwr_fini(struct nouveau_object *, bool);
-
-struct nvkm_pwr_impl {
- struct nouveau_oclass base;
- struct {
- u32 *data;
- u32 size;
- } code;
- struct {
- u32 *data;
- u32 size;
- } data;
-
- void (*pgob)(struct nouveau_pwr *, bool);
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
deleted file mode 100644
index 7dba8c281a0b..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
+++ /dev/null
@@ -1,159 +0,0 @@
-#ifndef __NVTHERM_PRIV_H__
-#define __NVTHERM_PRIV_H__
-
-/*
- * Copyright 2012 The Nouveau community
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Martin Peres
- */
-
-#include <subdev/therm.h>
-
-#include <subdev/bios/extdev.h>
-#include <subdev/bios/gpio.h>
-#include <subdev/bios/perf.h>
-#include <subdev/bios/therm.h>
-#include <subdev/timer.h>
-
-struct nouveau_fan {
- struct nouveau_therm *parent;
- const char *type;
-
- struct nvbios_therm_fan bios;
- struct nvbios_perf_fan perf;
-
- struct nouveau_alarm alarm;
- spinlock_t lock;
- int percent;
-
- int (*get)(struct nouveau_therm *therm);
- int (*set)(struct nouveau_therm *therm, int percent);
-
- struct dcb_gpio_func tach;
-};
-
-enum nouveau_therm_thrs_direction {
- NOUVEAU_THERM_THRS_FALLING = 0,
- NOUVEAU_THERM_THRS_RISING = 1
-};
-
-enum nouveau_therm_thrs_state {
- NOUVEAU_THERM_THRS_LOWER = 0,
- NOUVEAU_THERM_THRS_HIGHER = 1
-};
-
-enum nouveau_therm_thrs {
- NOUVEAU_THERM_THRS_FANBOOST = 0,
- NOUVEAU_THERM_THRS_DOWNCLOCK = 1,
- NOUVEAU_THERM_THRS_CRITICAL = 2,
- NOUVEAU_THERM_THRS_SHUTDOWN = 3,
- NOUVEAU_THERM_THRS_NR
-};
-
-struct nouveau_therm_priv {
- struct nouveau_therm base;
-
- /* automatic thermal management */
- struct nouveau_alarm alarm;
- spinlock_t lock;
- struct nouveau_therm_trip_point *last_trip;
- int mode;
- int cstate;
- int suspend;
-
- /* bios */
- struct nvbios_therm_sensor bios_sensor;
-
- /* fan priv */
- struct nouveau_fan *fan;
-
- /* alarms priv */
- struct {
- spinlock_t alarm_program_lock;
- struct nouveau_alarm therm_poll_alarm;
- enum nouveau_therm_thrs_state alarm_state[NOUVEAU_THERM_THRS_NR];
- void (*program_alarms)(struct nouveau_therm *);
- } sensor;
-
- /* what should be done if the card overheats */
- struct {
- void (*downclock)(struct nouveau_therm *, bool active);
- void (*pause)(struct nouveau_therm *, bool active);
- } emergency;
-
- /* ic */
- struct i2c_client *ic;
-};
-
-int nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode);
-int nouveau_therm_attr_get(struct nouveau_therm *therm,
- enum nouveau_therm_attr_type type);
-int nouveau_therm_attr_set(struct nouveau_therm *therm,
- enum nouveau_therm_attr_type type, int value);
-
-void nouveau_therm_ic_ctor(struct nouveau_therm *therm);
-
-int nouveau_therm_sensor_ctor(struct nouveau_therm *therm);
-
-int nouveau_therm_fan_ctor(struct nouveau_therm *therm);
-int nouveau_therm_fan_init(struct nouveau_therm *therm);
-int nouveau_therm_fan_fini(struct nouveau_therm *therm, bool suspend);
-int nouveau_therm_fan_get(struct nouveau_therm *therm);
-int nouveau_therm_fan_set(struct nouveau_therm *therm, bool now, int percent);
-int nouveau_therm_fan_user_get(struct nouveau_therm *therm);
-int nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent);
-
-int nouveau_therm_fan_sense(struct nouveau_therm *therm);
-
-int nouveau_therm_preinit(struct nouveau_therm *);
-
-int nouveau_therm_sensor_init(struct nouveau_therm *therm);
-int nouveau_therm_sensor_fini(struct nouveau_therm *therm, bool suspend);
-void nouveau_therm_sensor_preinit(struct nouveau_therm *);
-void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm,
- enum nouveau_therm_thrs thrs,
- enum nouveau_therm_thrs_state st);
-enum nouveau_therm_thrs_state
-nouveau_therm_sensor_get_threshold_state(struct nouveau_therm *therm,
- enum nouveau_therm_thrs thrs);
-void nouveau_therm_sensor_event(struct nouveau_therm *therm,
- enum nouveau_therm_thrs thrs,
- enum nouveau_therm_thrs_direction dir);
-void nouveau_therm_program_alarms_polling(struct nouveau_therm *therm);
-
-void nv40_therm_intr(struct nouveau_subdev *);
-int nv50_fan_pwm_ctrl(struct nouveau_therm *, int, bool);
-int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *);
-int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32);
-int nv50_fan_pwm_clock(struct nouveau_therm *, int);
-int nv84_temp_get(struct nouveau_therm *therm);
-void nv84_sensor_setup(struct nouveau_therm *therm);
-int nv84_therm_fini(struct nouveau_object *object, bool suspend);
-
-int nva3_therm_fan_sense(struct nouveau_therm *);
-
-int nvd0_therm_init(struct nouveau_object *object);
-
-int nouveau_fanpwm_create(struct nouveau_therm *, struct dcb_gpio_func *);
-int nouveau_fantog_create(struct nouveau_therm *, struct dcb_gpio_func *);
-int nouveau_fannil_create(struct nouveau_therm *);
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c b/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
deleted file mode 100644
index f75a683bd47a..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright 2010 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <core/gpuobj.h>
-#include <core/mm.h>
-
-#include <subdev/fb.h>
-#include <subdev/vm.h>
-
-void
-nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
-{
- struct nouveau_vm *vm = vma->vm;
- struct nouveau_vmmgr *vmm = vm->vmm;
- struct nouveau_mm_node *r;
- int big = vma->node->type != vmm->spg_shift;
- u32 offset = vma->node->offset + (delta >> 12);
- u32 bits = vma->node->type - 12;
- u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vmm->pgt_bits - bits);
- u32 end, len;
-
- delta = 0;
- list_for_each_entry(r, &node->regions, rl_entry) {
- u64 phys = (u64)r->offset << 12;
- u32 num = r->length >> bits;
-
- while (num) {
- struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big];
-
- end = (pte + num);
- if (unlikely(end >= max))
- end = max;
- len = end - pte;
-
- vmm->map(vma, pgt, node, pte, len, phys, delta);
-
- num -= len;
- pte += len;
- if (unlikely(end >= max)) {
- phys += len << (bits + 12);
- pde++;
- pte = 0;
- }
-
- delta += (u64)len << vma->node->type;
- }
- }
-
- vmm->flush(vm);
-}
-
-static void
-nouveau_vm_map_sg_table(struct nouveau_vma *vma, u64 delta, u64 length,
- struct nouveau_mem *mem)
-{
- struct nouveau_vm *vm = vma->vm;
- struct nouveau_vmmgr *vmm = vm->vmm;
- int big = vma->node->type != vmm->spg_shift;
- u32 offset = vma->node->offset + (delta >> 12);
- u32 bits = vma->node->type - 12;
- u32 num = length >> vma->node->type;
- u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vmm->pgt_bits - bits);
- unsigned m, sglen;
- u32 end, len;
- int i;
- struct scatterlist *sg;
-
- for_each_sg(mem->sg->sgl, sg, mem->sg->nents, i) {
- struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big];
- sglen = sg_dma_len(sg) >> PAGE_SHIFT;
-
- end = pte + sglen;
- if (unlikely(end >= max))
- end = max;
- len = end - pte;
-
- for (m = 0; m < len; m++) {
- dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
-
- vmm->map_sg(vma, pgt, mem, pte, 1, &addr);
- num--;
- pte++;
-
- if (num == 0)
- goto finish;
- }
- if (unlikely(end >= max)) {
- pde++;
- pte = 0;
- }
- if (m < sglen) {
- for (; m < sglen; m++) {
- dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
-
- vmm->map_sg(vma, pgt, mem, pte, 1, &addr);
- num--;
- pte++;
- if (num == 0)
- goto finish;
- }
- }
-
- }
-finish:
- vmm->flush(vm);
-}
-
-static void
-nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
- struct nouveau_mem *mem)
-{
- struct nouveau_vm *vm = vma->vm;
- struct nouveau_vmmgr *vmm = vm->vmm;
- dma_addr_t *list = mem->pages;
- int big = vma->node->type != vmm->spg_shift;
- u32 offset = vma->node->offset + (delta >> 12);
- u32 bits = vma->node->type - 12;
- u32 num = length >> vma->node->type;
- u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vmm->pgt_bits - bits);
- u32 end, len;
-
- while (num) {
- struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big];
-
- end = (pte + num);
- if (unlikely(end >= max))
- end = max;
- len = end - pte;
-
- vmm->map_sg(vma, pgt, mem, pte, len, list);
-
- num -= len;
- pte += len;
- list += len;
- if (unlikely(end >= max)) {
- pde++;
- pte = 0;
- }
- }
-
- vmm->flush(vm);
-}
-
-void
-nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_mem *node)
-{
- if (node->sg)
- nouveau_vm_map_sg_table(vma, 0, node->size << 12, node);
- else
- if (node->pages)
- nouveau_vm_map_sg(vma, 0, node->size << 12, node);
- else
- nouveau_vm_map_at(vma, 0, node);
-}
-
-void
-nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
-{
- struct nouveau_vm *vm = vma->vm;
- struct nouveau_vmmgr *vmm = vm->vmm;
- int big = vma->node->type != vmm->spg_shift;
- u32 offset = vma->node->offset + (delta >> 12);
- u32 bits = vma->node->type - 12;
- u32 num = length >> vma->node->type;
- u32 pde = (offset >> vmm->pgt_bits) - vm->fpde;
- u32 pte = (offset & ((1 << vmm->pgt_bits) - 1)) >> bits;
- u32 max = 1 << (vmm->pgt_bits - bits);
- u32 end, len;
-
- while (num) {
- struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big];
-
- end = (pte + num);
- if (unlikely(end >= max))
- end = max;
- len = end - pte;
-
- vmm->unmap(pgt, pte, len);
-
- num -= len;
- pte += len;
- if (unlikely(end >= max)) {
- pde++;
- pte = 0;
- }
- }
-
- vmm->flush(vm);
-}
-
-void
-nouveau_vm_unmap(struct nouveau_vma *vma)
-{
- nouveau_vm_unmap_at(vma, 0, (u64)vma->node->length << 12);
-}
-
-static void
-nouveau_vm_unmap_pgt(struct nouveau_vm *vm, int big, u32 fpde, u32 lpde)
-{
- struct nouveau_vmmgr *vmm = vm->vmm;
- struct nouveau_vm_pgd *vpgd;
- struct nouveau_vm_pgt *vpgt;
- struct nouveau_gpuobj *pgt;
- u32 pde;
-
- for (pde = fpde; pde <= lpde; pde++) {
- vpgt = &vm->pgt[pde - vm->fpde];
- if (--vpgt->refcount[big])
- continue;
-
- pgt = vpgt->obj[big];
- vpgt->obj[big] = NULL;
-
- list_for_each_entry(vpgd, &vm->pgd_list, head) {
- vmm->map_pgt(vpgd->obj, pde, vpgt->obj);
- }
-
- mutex_unlock(&nv_subdev(vmm)->mutex);
- nouveau_gpuobj_ref(NULL, &pgt);
- mutex_lock(&nv_subdev(vmm)->mutex);
- }
-}
-
-static int
-nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type)
-{
- struct nouveau_vmmgr *vmm = vm->vmm;
- struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
- struct nouveau_vm_pgd *vpgd;
- struct nouveau_gpuobj *pgt;
- int big = (type != vmm->spg_shift);
- u32 pgt_size;
- int ret;
-
- pgt_size = (1 << (vmm->pgt_bits + 12)) >> type;
- pgt_size *= 8;
-
- mutex_unlock(&nv_subdev(vmm)->mutex);
- ret = nouveau_gpuobj_new(nv_object(vm->vmm), NULL, pgt_size, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &pgt);
- mutex_lock(&nv_subdev(vmm)->mutex);
- if (unlikely(ret))
- return ret;
-
- /* someone beat us to filling the PDE while we didn't have the lock */
- if (unlikely(vpgt->refcount[big]++)) {
- mutex_unlock(&nv_subdev(vmm)->mutex);
- nouveau_gpuobj_ref(NULL, &pgt);
- mutex_lock(&nv_subdev(vmm)->mutex);
- return 0;
- }
-
- vpgt->obj[big] = pgt;
- list_for_each_entry(vpgd, &vm->pgd_list, head) {
- vmm->map_pgt(vpgd->obj, pde, vpgt->obj);
- }
-
- return 0;
-}
-
-int
-nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift,
- u32 access, struct nouveau_vma *vma)
-{
- struct nouveau_vmmgr *vmm = vm->vmm;
- u32 align = (1 << page_shift) >> 12;
- u32 msize = size >> 12;
- u32 fpde, lpde, pde;
- int ret;
-
- mutex_lock(&nv_subdev(vmm)->mutex);
- ret = nouveau_mm_head(&vm->mm, 0, page_shift, msize, msize, align,
- &vma->node);
- if (unlikely(ret != 0)) {
- mutex_unlock(&nv_subdev(vmm)->mutex);
- return ret;
- }
-
- fpde = (vma->node->offset >> vmm->pgt_bits);
- lpde = (vma->node->offset + vma->node->length - 1) >> vmm->pgt_bits;
-
- for (pde = fpde; pde <= lpde; pde++) {
- struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
- int big = (vma->node->type != vmm->spg_shift);
-
- if (likely(vpgt->refcount[big])) {
- vpgt->refcount[big]++;
- continue;
- }
-
- ret = nouveau_vm_map_pgt(vm, pde, vma->node->type);
- if (ret) {
- if (pde != fpde)
- nouveau_vm_unmap_pgt(vm, big, fpde, pde - 1);
- nouveau_mm_free(&vm->mm, &vma->node);
- mutex_unlock(&nv_subdev(vmm)->mutex);
- return ret;
- }
- }
- mutex_unlock(&nv_subdev(vmm)->mutex);
-
- vma->vm = NULL;
- nouveau_vm_ref(vm, &vma->vm, NULL);
- vma->offset = (u64)vma->node->offset << 12;
- vma->access = access;
- return 0;
-}
-
-void
-nouveau_vm_put(struct nouveau_vma *vma)
-{
- struct nouveau_vm *vm = vma->vm;
- struct nouveau_vmmgr *vmm = vm->vmm;
- u32 fpde, lpde;
-
- if (unlikely(vma->node == NULL))
- return;
- fpde = (vma->node->offset >> vmm->pgt_bits);
- lpde = (vma->node->offset + vma->node->length - 1) >> vmm->pgt_bits;
-
- mutex_lock(&nv_subdev(vmm)->mutex);
- nouveau_vm_unmap_pgt(vm, vma->node->type != vmm->spg_shift, fpde, lpde);
- nouveau_mm_free(&vm->mm, &vma->node);
- mutex_unlock(&nv_subdev(vmm)->mutex);
-
- nouveau_vm_ref(NULL, &vma->vm, NULL);
-}
-
-int
-nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
- u64 mm_offset, u32 block, struct nouveau_vm **pvm)
-{
- struct nouveau_vm *vm;
- u64 mm_length = (offset + length) - mm_offset;
- int ret;
-
- vm = kzalloc(sizeof(*vm), GFP_KERNEL);
- if (!vm)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&vm->pgd_list);
- vm->vmm = vmm;
- kref_init(&vm->refcount);
- vm->fpde = offset >> (vmm->pgt_bits + 12);
- vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12);
-
- vm->pgt = vzalloc((vm->lpde - vm->fpde + 1) * sizeof(*vm->pgt));
- if (!vm->pgt) {
- kfree(vm);
- return -ENOMEM;
- }
-
- ret = nouveau_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12,
- block >> 12);
- if (ret) {
- vfree(vm->pgt);
- kfree(vm);
- return ret;
- }
-
- *pvm = vm;
-
- return 0;
-}
-
-int
-nouveau_vm_new(struct nouveau_device *device, u64 offset, u64 length,
- u64 mm_offset, struct nouveau_vm **pvm)
-{
- struct nouveau_vmmgr *vmm = nouveau_vmmgr(device);
- return vmm->create(vmm, offset, length, mm_offset, pvm);
-}
-
-static int
-nouveau_vm_link(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd)
-{
- struct nouveau_vmmgr *vmm = vm->vmm;
- struct nouveau_vm_pgd *vpgd;
- int i;
-
- if (!pgd)
- return 0;
-
- vpgd = kzalloc(sizeof(*vpgd), GFP_KERNEL);
- if (!vpgd)
- return -ENOMEM;
-
- nouveau_gpuobj_ref(pgd, &vpgd->obj);
-
- mutex_lock(&nv_subdev(vmm)->mutex);
- for (i = vm->fpde; i <= vm->lpde; i++)
- vmm->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj);
- list_add(&vpgd->head, &vm->pgd_list);
- mutex_unlock(&nv_subdev(vmm)->mutex);
- return 0;
-}
-
-static void
-nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd)
-{
- struct nouveau_vmmgr *vmm = vm->vmm;
- struct nouveau_vm_pgd *vpgd, *tmp;
- struct nouveau_gpuobj *pgd = NULL;
-
- if (!mpgd)
- return;
-
- mutex_lock(&nv_subdev(vmm)->mutex);
- list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
- if (vpgd->obj == mpgd) {
- pgd = vpgd->obj;
- list_del(&vpgd->head);
- kfree(vpgd);
- break;
- }
- }
- mutex_unlock(&nv_subdev(vmm)->mutex);
-
- nouveau_gpuobj_ref(NULL, &pgd);
-}
-
-static void
-nouveau_vm_del(struct kref *kref)
-{
- struct nouveau_vm *vm = container_of(kref, typeof(*vm), refcount);
- struct nouveau_vm_pgd *vpgd, *tmp;
-
- list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
- nouveau_vm_unlink(vm, vpgd->obj);
- }
-
- nouveau_mm_fini(&vm->mm);
- vfree(vm->pgt);
- kfree(vm);
-}
-
-int
-nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr,
- struct nouveau_gpuobj *pgd)
-{
- if (ref) {
- int ret = nouveau_vm_link(ref, pgd);
- if (ret)
- return ret;
-
- kref_get(&ref->refcount);
- }
-
- if (*ptr) {
- nouveau_vm_unlink(*ptr, pgd);
- kref_put(&(*ptr)->refcount, nouveau_vm_del);
- }
-
- *ptr = ref;
- return 0;
-}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h
deleted file mode 100644
index ec42d4bc86a6..000000000000
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __NV04_VMMGR_PRIV__
-#define __NV04_VMMGR_PRIV__
-
-#include <subdev/vm.h>
-
-struct nv04_vmmgr_priv {
- struct nouveau_vmmgr base;
- struct nouveau_vm *vm;
- dma_addr_t null;
- void *nullp;
-};
-
-static inline struct nv04_vmmgr_priv *
-nv04_vmmgr(void *obj)
-{
- return (void *)nouveau_vmmgr(obj);
-}
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/dispnv04/Makefile b/drivers/gpu/drm/nouveau/dispnv04/Kbuild
index 424a489d0f03..424a489d0f03 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/Makefile
+++ b/drivers/gpu/drm/nouveau/dispnv04/Kbuild
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 38402ade6835..542bb266a0ab 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -41,7 +41,7 @@
#include "disp.h"
#include <subdev/bios/pll.h>
-#include <subdev/clock.h>
+#include <subdev/clk.h>
static int
nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -112,12 +112,12 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod
{
struct drm_device *dev = crtc->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_bios *bios = nvkm_bios(&drm->device);
- struct nouveau_clock *clk = nvkm_clock(&drm->device);
+ struct nvkm_bios *bios = nvxx_bios(&drm->device);
+ struct nvkm_clk *clk = nvxx_clk(&drm->device);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index];
- struct nouveau_pll_vals *pv = &regp->pllvals;
+ struct nvkm_pll_vals *pv = &regp->pllvals;
struct nvbios_pll pll_lim;
if (nvbios_pll_parse(bios, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/dac.c b/drivers/gpu/drm/nouveau/dispnv04/dac.c
index 2d8056cde996..d7b495a5f30c 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/dac.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/dac.c
@@ -66,7 +66,7 @@ int nv04_dac_output_offset(struct drm_encoder *encoder)
static int sample_load_twice(struct drm_device *dev, bool sense[2])
{
struct nvif_device *device = &nouveau_drm(dev)->device;
- struct nouveau_timer *ptimer = nvkm_timer(device);
+ struct nvkm_timer *ptimer = nvxx_timer(device);
int i;
for (i = 0; i < 2; i++) {
@@ -80,17 +80,17 @@ static int sample_load_twice(struct drm_device *dev, bool sense[2])
* use a 10ms timeout (guards against crtc being inactive, in
* which case blank state would never change)
*/
- if (!nouveau_timer_wait_eq(ptimer, 10000000,
- NV_PRMCIO_INP0__COLOR,
- 0x00000001, 0x00000000))
+ if (!nvkm_timer_wait_eq(ptimer, 10000000,
+ NV_PRMCIO_INP0__COLOR,
+ 0x00000001, 0x00000000))
return -EBUSY;
- if (!nouveau_timer_wait_eq(ptimer, 10000000,
- NV_PRMCIO_INP0__COLOR,
- 0x00000001, 0x00000001))
+ if (!nvkm_timer_wait_eq(ptimer, 10000000,
+ NV_PRMCIO_INP0__COLOR,
+ 0x00000001, 0x00000001))
return -EBUSY;
- if (!nouveau_timer_wait_eq(ptimer, 10000000,
- NV_PRMCIO_INP0__COLOR,
- 0x00000001, 0x00000000))
+ if (!nvkm_timer_wait_eq(ptimer, 10000000,
+ NV_PRMCIO_INP0__COLOR,
+ 0x00000001, 0x00000000))
return -EBUSY;
udelay(100);
@@ -232,7 +232,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
struct drm_device *dev = encoder->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &nouveau_drm(dev)->device;
- struct nouveau_gpio *gpio = nvkm_gpio(device);
+ struct nvkm_gpio *gpio = nvxx_gpio(device);
struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder);
uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
index 42a5435259f7..f6ca343fd34a 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
@@ -623,9 +623,9 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder)
struct drm_device *dev = encoder->dev;
struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
- struct nouveau_i2c_port *port = i2c->find(i2c, 2);
- struct nouveau_i2c_board_info info[] = {
+ struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
+ struct nvkm_i2c_port *port = i2c->find(i2c, 2);
+ struct nvkm_i2c_board_info info[] = {
{
{
.type = "sil164",
diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c
index 3d0afa1c6cff..f96237ef2a6b 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c
@@ -32,28 +32,10 @@
#include "nouveau_connector.h"
int
-nv04_display_early_init(struct drm_device *dev)
-{
- /* ensure vblank interrupts are off, they can't be enabled until
- * drm_vblank has been initialised
- */
- NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
- if (nv_two_heads(dev))
- NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
-
- return 0;
-}
-
-void
-nv04_display_late_takedown(struct drm_device *dev)
-{
-}
-
-int
nv04_display_create(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
+ struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
struct dcb_table *dcb = &drm->vbios.dcb;
struct drm_connector *connector, *ct;
struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.h b/drivers/gpu/drm/nouveau/dispnv04/disp.h
index 17b899d9aba3..c910c5d5c662 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/disp.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/disp.h
@@ -36,7 +36,7 @@ struct nv04_crtc_reg {
/* PRAMDAC regs */
uint32_t nv10_cursync;
- struct nouveau_pll_vals pllvals;
+ struct nvkm_pll_vals pllvals;
uint32_t ramdac_gen_ctrl;
uint32_t ramdac_630;
uint32_t ramdac_634;
@@ -90,8 +90,6 @@ nv04_display(struct drm_device *dev)
}
/* nv04_display.c */
-int nv04_display_early_init(struct drm_device *);
-void nv04_display_late_takedown(struct drm_device *);
int nv04_display_create(struct drm_device *);
void nv04_display_destroy(struct drm_device *);
int nv04_display_init(struct drm_device *);
@@ -172,7 +170,7 @@ nouveau_bios_run_init_table(struct drm_device *dev, u16 table,
struct dcb_output *outp, int crtc)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_bios *bios = nvkm_bios(&drm->device);
+ struct nvkm_bios *bios = nvxx_bios(&drm->device);
struct nvbios_init init = {
.subdev = nv_subdev(bios),
.bios = bios,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c
index 3d4c19300768..42e07afc4c2b 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/hw.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c
@@ -130,7 +130,7 @@ NVBlankScreen(struct drm_device *dev, int head, bool blank)
static void
nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
- uint32_t pll2, struct nouveau_pll_vals *pllvals)
+ uint32_t pll2, struct nvkm_pll_vals *pllvals)
{
struct nouveau_drm *drm = nouveau_drm(dev);
@@ -162,11 +162,11 @@ nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
int
nouveau_hw_get_pllvals(struct drm_device *dev, enum nvbios_pll_type plltype,
- struct nouveau_pll_vals *pllvals)
+ struct nvkm_pll_vals *pllvals)
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->device;
- struct nouveau_bios *bios = nvkm_bios(device);
+ struct nvkm_bios *bios = nvxx_bios(device);
uint32_t reg1, pll1, pll2 = 0;
struct nvbios_pll pll_lim;
int ret;
@@ -202,7 +202,7 @@ nouveau_hw_get_pllvals(struct drm_device *dev, enum nvbios_pll_type plltype,
}
int
-nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv)
+nouveau_hw_pllvals_to_clk(struct nvkm_pll_vals *pv)
{
/* Avoid divide by zero if called at an inappropriate time */
if (!pv->M1 || !pv->M2)
@@ -214,7 +214,7 @@ nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv)
int
nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
{
- struct nouveau_pll_vals pllvals;
+ struct nvkm_pll_vals pllvals;
int ret;
if (plltype == PLL_MEMORY &&
@@ -253,10 +253,10 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->device;
- struct nouveau_clock *clk = nvkm_clock(device);
- struct nouveau_bios *bios = nvkm_bios(device);
+ struct nvkm_clk *clk = nvxx_clk(device);
+ struct nvkm_bios *bios = nvxx_bios(device);
struct nvbios_pll pll_lim;
- struct nouveau_pll_vals pv;
+ struct nvkm_pll_vals pv;
enum nvbios_pll_type pll = head ? PLL_VPLL1 : PLL_VPLL0;
if (nvbios_pll_parse(bios, pll, &pll_lim))
@@ -463,7 +463,7 @@ nv_load_state_ramdac(struct drm_device *dev, int head,
struct nv04_mode_state *state)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_clock *clk = nvkm_clock(&drm->device);
+ struct nvkm_clk *clk = nvxx_clk(&drm->device);
struct nv04_crtc_reg *regp = &state->crtc_reg[head];
uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
int i;
@@ -661,7 +661,7 @@ nv_load_state_ext(struct drm_device *dev, int head,
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->device;
- struct nouveau_timer *ptimer = nvkm_timer(device);
+ struct nvkm_timer *ptimer = nvxx_timer(device);
struct nv04_crtc_reg *regp = &state->crtc_reg[head];
uint32_t reg900;
int i;
@@ -741,8 +741,8 @@ nv_load_state_ext(struct drm_device *dev, int head,
if (drm->device.info.family < NV_DEVICE_INFO_V0_KELVIN) {
/* Not waiting for vertical retrace before modifying
CRE_53/CRE_54 causes lockups. */
- nouveau_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
- nouveau_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
+ nvkm_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8);
+ nvkm_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
}
wr_cio_state(dev, head, regp, NV_CIO_CRE_42);
diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.h b/drivers/gpu/drm/nouveau/dispnv04/hw.h
index 7f53c571f31f..6c796178bf0c 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/hw.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/hw.h
@@ -42,8 +42,8 @@ uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index);
void NVSetOwner(struct drm_device *, int owner);
void NVBlankScreen(struct drm_device *, int head, bool blank);
int nouveau_hw_get_pllvals(struct drm_device *, enum nvbios_pll_type plltype,
- struct nouveau_pll_vals *pllvals);
-int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals);
+ struct nvkm_pll_vals *pllvals);
+int nouveau_hw_pllvals_to_clk(struct nvkm_pll_vals *pllvals);
int nouveau_hw_get_clock(struct drm_device *, enum nvbios_pll_type plltype);
void nouveau_hw_save_vga_fonts(struct drm_device *, bool save);
void nouveau_hw_save_state(struct drm_device *, int head,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
index 8061d8d0ce79..d9664b37def1 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
@@ -35,7 +35,7 @@
#include <drm/i2c/ch7006.h>
-static struct nouveau_i2c_board_info nv04_tv_encoder_info[] = {
+static struct nvkm_i2c_board_info nv04_tv_encoder_info[] = {
{
{
I2C_BOARD_INFO("ch7006", 0x75),
@@ -54,7 +54,7 @@ static struct nouveau_i2c_board_info nv04_tv_encoder_info[] = {
int nv04_tv_identify(struct drm_device *dev, int i2c_index)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
+ struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
return i2c->identify(i2c, i2c_index, "TV encoder",
nv04_tv_encoder_info, NULL, NULL);
@@ -204,8 +204,8 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry)
struct drm_encoder *encoder;
struct drm_device *dev = connector->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
- struct nouveau_i2c_port *port = i2c->find(i2c, entry->i2c_index);
+ struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
+ struct nvkm_i2c_port *port = i2c->find(i2c, entry->i2c_index);
int type, ret;
/* Ensure that we can talk to this encoder */
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
index 72d2ab04db47..731d74efc1e5 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
@@ -46,7 +46,7 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_gpio *gpio = nvkm_gpio(&drm->device);
+ struct nvkm_gpio *gpio = nvxx_gpio(&drm->device);
uint32_t testval, regoffset = nv04_dac_output_offset(encoder);
uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end,
fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c;
@@ -133,14 +133,14 @@ get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
struct nvif_device *device = &drm->device;
/* Zotac FX5200 */
- if (nv_device_match(nvkm_object(device), 0x0322, 0x19da, 0x1035) ||
- nv_device_match(nvkm_object(device), 0x0322, 0x19da, 0x2035)) {
+ if (nv_device_match(nvxx_object(device), 0x0322, 0x19da, 0x1035) ||
+ nv_device_match(nvxx_object(device), 0x0322, 0x19da, 0x2035)) {
*pin_mask = 0xc;
return false;
}
/* MSI nForce2 IGP */
- if (nv_device_match(nvkm_object(device), 0x01f0, 0x1462, 0x5710)) {
+ if (nv_device_match(nvxx_object(device), 0x01f0, 0x1462, 0x5710)) {
*pin_mask = 0xc;
return false;
}
@@ -370,7 +370,7 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_gpio *gpio = nvkm_gpio(&drm->device);
+ struct nvkm_gpio *gpio = nvxx_gpio(&drm->device);
struct nv17_tv_state *regs = &to_tv_enc(encoder)->state;
struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h
index 4e308eacb27a..5ad17fc36ae3 100644
--- a/drivers/gpu/drm/nouveau/nvif/class.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/class.h
@@ -122,18 +122,21 @@ struct nv_device_v0 {
#define NV_DEVICE_V0_DISABLE_CORE 0x0000000000000008ULL
#define NV_DEVICE_V0_DISABLE_DISP 0x0000000000010000ULL
#define NV_DEVICE_V0_DISABLE_FIFO 0x0000000000020000ULL
-#define NV_DEVICE_V0_DISABLE_GRAPH 0x0000000100000000ULL
+#define NV_DEVICE_V0_DISABLE_GR 0x0000000100000000ULL
#define NV_DEVICE_V0_DISABLE_MPEG 0x0000000200000000ULL
#define NV_DEVICE_V0_DISABLE_ME 0x0000000400000000ULL
#define NV_DEVICE_V0_DISABLE_VP 0x0000000800000000ULL
-#define NV_DEVICE_V0_DISABLE_CRYPT 0x0000001000000000ULL
+#define NV_DEVICE_V0_DISABLE_CIPHER 0x0000001000000000ULL
#define NV_DEVICE_V0_DISABLE_BSP 0x0000002000000000ULL
-#define NV_DEVICE_V0_DISABLE_PPP 0x0000004000000000ULL
-#define NV_DEVICE_V0_DISABLE_COPY0 0x0000008000000000ULL
-#define NV_DEVICE_V0_DISABLE_COPY1 0x0000010000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSPPP 0x0000004000000000ULL
+#define NV_DEVICE_V0_DISABLE_CE0 0x0000008000000000ULL
+#define NV_DEVICE_V0_DISABLE_CE1 0x0000010000000000ULL
#define NV_DEVICE_V0_DISABLE_VIC 0x0000020000000000ULL
-#define NV_DEVICE_V0_DISABLE_VENC 0x0000040000000000ULL
-#define NV_DEVICE_V0_DISABLE_COPY2 0x0000080000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSENC 0x0000040000000000ULL
+#define NV_DEVICE_V0_DISABLE_CE2 0x0000080000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSVLD 0x0000100000000000ULL
+#define NV_DEVICE_V0_DISABLE_SEC 0x0000200000000000ULL
+#define NV_DEVICE_V0_DISABLE_MSPDEC 0x0000400000000000ULL
__u64 disable; /* disable particular subsystems */
__u64 debug0; /* as above, but *internal* ids, and *NOT* ABI */
};
@@ -346,9 +349,9 @@ struct nv50_channel_gpfifo_v0 {
struct kepler_channel_gpfifo_a_v0 {
__u8 version;
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR 0x01
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_VP 0x02
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_PPP 0x04
-#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_BSP 0x08
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPDEC 0x02
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPPP 0x04
+#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSVLD 0x08
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0 0x10
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1 0x20
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40
diff --git a/drivers/gpu/drm/nouveau/nvif/client.h b/drivers/gpu/drm/nouveau/include/nvif/client.h
index 28352f0882ec..eca648ef0f7a 100644
--- a/drivers/gpu/drm/nouveau/nvif/client.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/client.h
@@ -1,7 +1,7 @@
#ifndef __NVIF_CLIENT_H__
#define __NVIF_CLIENT_H__
-#include "object.h"
+#include <nvif/object.h>
struct nvif_client {
struct nvif_object base;
@@ -31,9 +31,9 @@ int nvif_client_resume(struct nvif_client *);
/*XXX*/
#include <core/client.h>
-#define nvkm_client(a) ({ \
+#define nvxx_client(a) ({ \
struct nvif_client *_client = nvif_client(nvif_object(a)); \
- nouveau_client(_client->base.priv); \
+ nvkm_client(_client->base.priv); \
})
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h
new file mode 100644
index 000000000000..88553a741ab7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvif/device.h
@@ -0,0 +1,61 @@
+#ifndef __NVIF_DEVICE_H__
+#define __NVIF_DEVICE_H__
+
+#include <nvif/object.h>
+#include <nvif/class.h>
+
+struct nvif_device {
+ struct nvif_object base;
+ struct nvif_object *object; /*XXX: hack for nvif_object() */
+ struct nv_device_info_v0 info;
+};
+
+static inline struct nvif_device *
+nvif_device(struct nvif_object *object)
+{
+ while (object && object->oclass != 0x0080 /*XXX: NV_DEVICE_CLASS*/ )
+ object = object->parent;
+ return (void *)object;
+}
+
+int nvif_device_init(struct nvif_object *, void (*dtor)(struct nvif_device *),
+ u32 handle, u32 oclass, void *, u32,
+ struct nvif_device *);
+void nvif_device_fini(struct nvif_device *);
+int nvif_device_new(struct nvif_object *, u32 handle, u32 oclass,
+ void *, u32, struct nvif_device **);
+void nvif_device_ref(struct nvif_device *, struct nvif_device **);
+
+/*XXX*/
+#include <subdev/bios.h>
+#include <subdev/fb.h>
+#include <subdev/mmu.h>
+#include <subdev/bar.h>
+#include <subdev/gpio.h>
+#include <subdev/clk.h>
+#include <subdev/i2c.h>
+#include <subdev/timer.h>
+#include <subdev/therm.h>
+
+#define nvxx_device(a) nv_device(nvxx_object((a)))
+#define nvxx_bios(a) nvkm_bios(nvxx_device(a))
+#define nvxx_fb(a) nvkm_fb(nvxx_device(a))
+#define nvxx_mmu(a) nvkm_mmu(nvxx_device(a))
+#define nvxx_bar(a) nvkm_bar(nvxx_device(a))
+#define nvxx_gpio(a) nvkm_gpio(nvxx_device(a))
+#define nvxx_clk(a) nvkm_clk(nvxx_device(a))
+#define nvxx_i2c(a) nvkm_i2c(nvxx_device(a))
+#define nvxx_timer(a) nvkm_timer(nvxx_device(a))
+#define nvxx_wait(a,b,c,d) nv_wait(nvxx_timer(a), (b), (c), (d))
+#define nvxx_wait_cb(a,b,c) nv_wait_cb(nvxx_timer(a), (b), (c))
+#define nvxx_therm(a) nvkm_therm(nvxx_device(a))
+
+#include <core/device.h>
+#include <engine/fifo.h>
+#include <engine/gr.h>
+#include <engine/sw.h>
+
+#define nvxx_fifo(a) nvkm_fifo(nvxx_device(a))
+#define nvxx_fifo_chan(a) ((struct nvkm_fifo_chan *)nvxx_object(a))
+#define nvxx_gr(a) ((struct nvkm_gr *)nvkm_engine(nvxx_object(a), NVDEV_ENGINE_GR))
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvif/driver.h b/drivers/gpu/drm/nouveau/include/nvif/driver.h
index 8bd39e69229c..8bd39e69229c 100644
--- a/drivers/gpu/drm/nouveau/nvif/driver.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driver.h
diff --git a/drivers/gpu/drm/nouveau/nvif/event.h b/drivers/gpu/drm/nouveau/include/nvif/event.h
index 21764499b4be..21764499b4be 100644
--- a/drivers/gpu/drm/nouveau/nvif/event.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/event.h
diff --git a/drivers/gpu/drm/nouveau/nvif/ioctl.h b/drivers/gpu/drm/nouveau/include/nvif/ioctl.h
index 4cd8e323b23d..4cd8e323b23d 100644
--- a/drivers/gpu/drm/nouveau/nvif/ioctl.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/ioctl.h
diff --git a/drivers/gpu/drm/nouveau/nvif/list.h b/drivers/gpu/drm/nouveau/include/nvif/list.h
index 8af5d144ecb0..8af5d144ecb0 100644
--- a/drivers/gpu/drm/nouveau/nvif/list.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/list.h
diff --git a/drivers/gpu/drm/nouveau/nvif/notify.h b/drivers/gpu/drm/nouveau/include/nvif/notify.h
index 9ebfa3b45e76..9ebfa3b45e76 100644
--- a/drivers/gpu/drm/nouveau/nvif/notify.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/notify.h
diff --git a/drivers/gpu/drm/nouveau/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h
index fe519179b76c..04c874707b96 100644
--- a/drivers/gpu/drm/nouveau/nvif/object.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/object.h
@@ -70,6 +70,6 @@ void nvif_object_unmap(struct nvif_object *);
/*XXX*/
#include <core/object.h>
-#define nvkm_object(a) ((struct nouveau_object *)nvif_object(a)->priv)
+#define nvxx_object(a) ((struct nvkm_object *)nvif_object(a)->priv)
#endif
diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/include/nvif/os.h
index bdd05ee7ec72..bdd05ee7ec72 100644
--- a/drivers/gpu/drm/nouveau/core/os.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/os.h
diff --git a/drivers/gpu/drm/nouveau/nvif/unpack.h b/drivers/gpu/drm/nouveau/include/nvif/unpack.h
index 5933188b4a77..5933188b4a77 100644
--- a/drivers/gpu/drm/nouveau/nvif/unpack.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/unpack.h
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
new file mode 100644
index 000000000000..a35b38244502
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
@@ -0,0 +1,55 @@
+#ifndef __NVKM_CLIENT_H__
+#define __NVKM_CLIENT_H__
+#include <core/namedb.h>
+
+struct nvkm_client {
+ struct nvkm_namedb namedb;
+ struct nvkm_handle *root;
+ struct nvkm_object *device;
+ char name[32];
+ u32 debug;
+ struct nvkm_vm *vm;
+ bool super;
+ void *data;
+
+ int (*ntfy)(const void *, u32, const void *, u32);
+ struct nvkm_client_notify *notify[16];
+};
+
+static inline struct nvkm_client *
+nv_client(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_CLIENT_CLASS)))
+ nv_assert("BAD CAST -> NvClient, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline struct nvkm_client *
+nvkm_client(void *obj)
+{
+ struct nvkm_object *client = nv_object(obj);
+ while (client && !(nv_iclass(client, NV_CLIENT_CLASS)))
+ client = client->parent;
+ return (void *)client;
+}
+
+#define nvkm_client_create(n,c,oc,od,d) \
+ nvkm_client_create_((n), (c), (oc), (od), sizeof(**d), (void **)d)
+
+int nvkm_client_create_(const char *name, u64 device, const char *cfg,
+ const char *dbg, int, void **);
+#define nvkm_client_destroy(p) \
+ nvkm_namedb_destroy(&(p)->base)
+
+int nvkm_client_init(struct nvkm_client *);
+int nvkm_client_fini(struct nvkm_client *, bool suspend);
+const char *nvkm_client_name(void *obj);
+
+int nvkm_client_notify_new(struct nvkm_object *, struct nvkm_event *,
+ void *data, u32 size);
+int nvkm_client_notify_del(struct nvkm_client *, int index);
+int nvkm_client_notify_get(struct nvkm_client *, int index);
+int nvkm_client_notify_put(struct nvkm_client *, int index);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/debug.h b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h
index 8092e2e90323..d07cb860b56c 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/debug.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h
@@ -1,6 +1,5 @@
-#ifndef __NOUVEAU_DEBUG_H__
-#define __NOUVEAU_DEBUG_H__
-
+#ifndef __NVKM_DEBUG_H__
+#define __NVKM_DEBUG_H__
extern int nv_info_debug_level;
#define NV_DBG_FATAL 0
@@ -16,5 +15,4 @@ extern int nv_info_debug_level;
#define NV_DBG_INFO_SILENT NV_DBG_DEBUG
#define nv_debug_level(a) nv_info_debug_level = NV_DBG_INFO_##a
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
new file mode 100644
index 000000000000..333db33a162c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -0,0 +1,101 @@
+#ifndef __NVKM_DEVICE_H__
+#define __NVKM_DEVICE_H__
+#include <core/engine.h>
+#include <core/event.h>
+
+struct nvkm_device {
+ struct nvkm_engine engine;
+ struct list_head head;
+
+ struct pci_dev *pdev;
+ struct platform_device *platformdev;
+ u64 handle;
+
+ struct nvkm_event event;
+
+ const char *cfgopt;
+ const char *dbgopt;
+ const char *name;
+ const char *cname;
+ u64 disable_mask;
+
+ enum {
+ NV_04 = 0x04,
+ NV_10 = 0x10,
+ NV_11 = 0x11,
+ NV_20 = 0x20,
+ NV_30 = 0x30,
+ NV_40 = 0x40,
+ NV_50 = 0x50,
+ NV_C0 = 0xc0,
+ NV_E0 = 0xe0,
+ GM100 = 0x110,
+ } card_type;
+ u32 chipset;
+ u8 chiprev;
+ u32 crystal;
+
+ struct nvkm_oclass *oclass[NVDEV_SUBDEV_NR];
+ struct nvkm_object *subdev[NVDEV_SUBDEV_NR];
+
+ struct {
+ struct notifier_block nb;
+ } acpi;
+};
+
+struct nvkm_device *nvkm_device_find(u64 name);
+int nvkm_device_list(u64 *name, int size);
+
+struct nvkm_device *nv_device(void *obj);
+
+static inline bool
+nv_device_match(struct nvkm_object *object, u16 dev, u16 ven, u16 sub)
+{
+ struct nvkm_device *device = nv_device(object);
+ return device->pdev->device == dev &&
+ device->pdev->subsystem_vendor == ven &&
+ device->pdev->subsystem_device == sub;
+}
+
+static inline bool
+nv_device_is_pci(struct nvkm_device *device)
+{
+ return device->pdev != NULL;
+}
+
+static inline bool
+nv_device_is_cpu_coherent(struct nvkm_device *device)
+{
+ return (!IS_ENABLED(CONFIG_ARM) && nv_device_is_pci(device));
+}
+
+static inline struct device *
+nv_device_base(struct nvkm_device *device)
+{
+ return nv_device_is_pci(device) ? &device->pdev->dev :
+ &device->platformdev->dev;
+}
+
+resource_size_t
+nv_device_resource_start(struct nvkm_device *device, unsigned int bar);
+
+resource_size_t
+nv_device_resource_len(struct nvkm_device *device, unsigned int bar);
+
+int
+nv_device_get_irq(struct nvkm_device *device, bool stall);
+
+struct platform_device;
+
+enum nv_bus_type {
+ NVKM_BUS_PCI,
+ NVKM_BUS_PLATFORM,
+};
+
+#define nvkm_device_create(p,t,n,s,c,d,u) \
+ nvkm_device_create_((void *)(p), (t), (n), (s), (c), (d), \
+ sizeof(**u), (void **)u)
+int nvkm_device_create_(void *, enum nv_bus_type type, u64 name,
+ const char *sname, const char *cfg, const char *dbg,
+ int, void **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h b/drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h
new file mode 100644
index 000000000000..60c5888b5df3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/devidx.h
@@ -0,0 +1,62 @@
+#ifndef __NVKM_DEVIDX_H__
+#define __NVKM_DEVIDX_H__
+enum nvkm_devidx {
+ NVDEV_ENGINE_DEVICE,
+ NVDEV_SUBDEV_VBIOS,
+
+ /* All subdevs from DEVINIT to DEVINIT_LAST will be created before
+ * *any* of them are initialised. This subdev category is used
+ * for any subdevs that the VBIOS init table parsing may call out
+ * to during POST.
+ */
+ NVDEV_SUBDEV_DEVINIT,
+ NVDEV_SUBDEV_IBUS,
+ NVDEV_SUBDEV_GPIO,
+ NVDEV_SUBDEV_I2C,
+ NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_I2C,
+
+ /* This grouping of subdevs are initialised right after they've
+ * been created, and are allowed to assume any subdevs in the
+ * list above them exist and have been initialised.
+ */
+ NVDEV_SUBDEV_FUSE,
+ NVDEV_SUBDEV_MXM,
+ NVDEV_SUBDEV_MC,
+ NVDEV_SUBDEV_BUS,
+ NVDEV_SUBDEV_TIMER,
+ NVDEV_SUBDEV_FB,
+ NVDEV_SUBDEV_LTC,
+ NVDEV_SUBDEV_INSTMEM,
+ NVDEV_SUBDEV_MMU,
+ NVDEV_SUBDEV_BAR,
+ NVDEV_SUBDEV_PMU,
+ NVDEV_SUBDEV_VOLT,
+ NVDEV_SUBDEV_THERM,
+ NVDEV_SUBDEV_CLK,
+
+ NVDEV_ENGINE_FIRST,
+ NVDEV_ENGINE_DMAOBJ = NVDEV_ENGINE_FIRST,
+ NVDEV_ENGINE_IFB,
+ NVDEV_ENGINE_FIFO,
+ NVDEV_ENGINE_SW,
+ NVDEV_ENGINE_GR,
+ NVDEV_ENGINE_MPEG,
+ NVDEV_ENGINE_ME,
+ NVDEV_ENGINE_VP,
+ NVDEV_ENGINE_CIPHER,
+ NVDEV_ENGINE_BSP,
+ NVDEV_ENGINE_MSPPP,
+ NVDEV_ENGINE_CE0,
+ NVDEV_ENGINE_CE1,
+ NVDEV_ENGINE_CE2,
+ NVDEV_ENGINE_VIC,
+ NVDEV_ENGINE_MSENC,
+ NVDEV_ENGINE_DISP,
+ NVDEV_ENGINE_PM,
+ NVDEV_ENGINE_MSVLD,
+ NVDEV_ENGINE_SEC,
+ NVDEV_ENGINE_MSPDEC,
+
+ NVDEV_SUBDEV_NR,
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
new file mode 100644
index 000000000000..1bf2e8eb4268
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
@@ -0,0 +1,51 @@
+#ifndef __NVKM_ENGCTX_H__
+#define __NVKM_ENGCTX_H__
+#include <core/gpuobj.h>
+
+#include <subdev/mmu.h>
+
+#define NV_ENGCTX_(eng,var) (NV_ENGCTX_CLASS | ((var) << 8) | (eng))
+#define NV_ENGCTX(name,var) NV_ENGCTX_(NVDEV_ENGINE_##name, (var))
+
+struct nvkm_engctx {
+ struct nvkm_gpuobj gpuobj;
+ struct nvkm_vma vma;
+ struct list_head head;
+ unsigned long save;
+ u64 addr;
+};
+
+static inline struct nvkm_engctx *
+nv_engctx(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_ENGCTX_CLASS)))
+ nv_assert("BAD CAST -> NvEngCtx, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_engctx_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create_((p), (e), (c), (g), (s), (a), (f), \
+ sizeof(**d), (void **)d)
+
+int nvkm_engctx_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, struct nvkm_object *,
+ u32 size, u32 align, u32 flags,
+ int length, void **data);
+void nvkm_engctx_destroy(struct nvkm_engctx *);
+int nvkm_engctx_init(struct nvkm_engctx *);
+int nvkm_engctx_fini(struct nvkm_engctx *, bool suspend);
+
+int _nvkm_engctx_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void _nvkm_engctx_dtor(struct nvkm_object *);
+int _nvkm_engctx_init(struct nvkm_object *);
+int _nvkm_engctx_fini(struct nvkm_object *, bool suspend);
+#define _nvkm_engctx_rd32 _nvkm_gpuobj_rd32
+#define _nvkm_engctx_wr32 _nvkm_gpuobj_wr32
+
+struct nvkm_object *nvkm_engctx_get(struct nvkm_engine *, u64 addr);
+void nvkm_engctx_put(struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
new file mode 100644
index 000000000000..faf0fd2f0638
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
@@ -0,0 +1,56 @@
+#ifndef __NVKM_ENGINE_H__
+#define __NVKM_ENGINE_H__
+#include <core/subdev.h>
+
+#define NV_ENGINE_(eng,var) (NV_ENGINE_CLASS | ((var) << 8) | (eng))
+#define NV_ENGINE(name,var) NV_ENGINE_(NVDEV_ENGINE_##name, (var))
+
+struct nvkm_engine {
+ struct nvkm_subdev subdev;
+ struct nvkm_oclass *cclass;
+ struct nvkm_oclass *sclass;
+
+ struct list_head contexts;
+ spinlock_t lock;
+
+ void (*tile_prog)(struct nvkm_engine *, int region);
+ int (*tlb_flush)(struct nvkm_engine *);
+};
+
+static inline struct nvkm_engine *
+nv_engine(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_ENGINE_CLASS)))
+ nv_assert("BAD CAST -> NvEngine, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+static inline int
+nv_engidx(struct nvkm_engine *engine)
+{
+ return nv_subidx(&engine->subdev);
+}
+
+struct nvkm_engine *nvkm_engine(void *obj, int idx);
+
+#define nvkm_engine_create(p,e,c,d,i,f,r) \
+ nvkm_engine_create_((p), (e), (c), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+
+#define nvkm_engine_destroy(p) \
+ nvkm_subdev_destroy(&(p)->subdev)
+#define nvkm_engine_init(p) \
+ nvkm_subdev_init(&(p)->subdev)
+#define nvkm_engine_fini(p,s) \
+ nvkm_subdev_fini(&(p)->subdev, (s))
+
+int nvkm_engine_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, bool, const char *,
+ const char *, int, void **);
+
+#define _nvkm_engine_dtor _nvkm_subdev_dtor
+#define _nvkm_engine_init _nvkm_subdev_init
+#define _nvkm_engine_fini _nvkm_subdev_fini
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h b/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h
new file mode 100644
index 000000000000..e76f76f115e9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/enum.h
@@ -0,0 +1,21 @@
+#ifndef __NVKM_ENUM_H__
+#define __NVKM_ENUM_H__
+#include <core/os.h>
+
+struct nvkm_enum {
+ u32 value;
+ const char *name;
+ const void *data;
+ u32 data2;
+};
+
+const struct nvkm_enum *nvkm_enum_find(const struct nvkm_enum *, u32 value);
+const struct nvkm_enum *nvkm_enum_print(const struct nvkm_enum *, u32 value);
+
+struct nvkm_bitfield {
+ u32 mask;
+ const char *name;
+};
+
+void nvkm_bitfield_print(const struct nvkm_bitfield *, u32 value);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/event.h b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
index 92876528972f..b98fe2de546a 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/event.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
@@ -1,15 +1,8 @@
#ifndef __NVKM_EVENT_H__
#define __NVKM_EVENT_H__
-
-#include <core/notify.h>
-
-struct nvkm_event_func {
- int (*ctor)(struct nouveau_object *, void *data, u32 size,
- struct nvkm_notify *);
- void (*send)(void *data, u32 size, struct nvkm_notify *);
- void (*init)(struct nvkm_event *, int type, int index);
- void (*fini)(struct nvkm_event *, int type, int index);
-};
+#include <core/os.h>
+struct nvkm_notify;
+struct nvkm_object;
struct nvkm_event {
const struct nvkm_event_func *func;
@@ -23,13 +16,19 @@ struct nvkm_event {
int *refs;
};
-int nvkm_event_init(const struct nvkm_event_func *func,
- int types_nr, int index_nr,
- struct nvkm_event *);
+struct nvkm_event_func {
+ int (*ctor)(struct nvkm_object *, void *data, u32 size,
+ struct nvkm_notify *);
+ void (*send)(void *data, u32 size, struct nvkm_notify *);
+ void (*init)(struct nvkm_event *, int type, int index);
+ void (*fini)(struct nvkm_event *, int type, int index);
+};
+
+int nvkm_event_init(const struct nvkm_event_func *func, int types_nr,
+ int index_nr, struct nvkm_event *);
void nvkm_event_fini(struct nvkm_event *);
void nvkm_event_get(struct nvkm_event *, u32 types, int index);
void nvkm_event_put(struct nvkm_event *, u32 types, int index);
void nvkm_event_send(struct nvkm_event *, u32 types, int index,
void *data, u32 size);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
new file mode 100644
index 000000000000..e0187e7abb6e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
@@ -0,0 +1,64 @@
+#ifndef __NVKM_GPUOBJ_H__
+#define __NVKM_GPUOBJ_H__
+#include <core/object.h>
+#include <core/mm.h>
+struct nvkm_vma;
+struct nvkm_vm;
+
+#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001
+#define NVOBJ_FLAG_ZERO_FREE 0x00000002
+#define NVOBJ_FLAG_HEAP 0x00000004
+
+struct nvkm_gpuobj {
+ struct nvkm_object object;
+ struct nvkm_object *parent;
+ struct nvkm_mm_node *node;
+ struct nvkm_mm heap;
+
+ u32 flags;
+ u64 addr;
+ u32 size;
+};
+
+static inline struct nvkm_gpuobj *
+nv_gpuobj(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_GPUOBJ_CLASS)))
+ nv_assert("BAD CAST -> NvGpuObj, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_gpuobj_create(p,e,c,v,g,s,a,f,d) \
+ nvkm_gpuobj_create_((p), (e), (c), (v), (g), (s), (a), (f), \
+ sizeof(**d), (void **)d)
+#define nvkm_gpuobj_init(p) nvkm_object_init(&(p)->object)
+#define nvkm_gpuobj_fini(p,s) nvkm_object_fini(&(p)->object, (s))
+int nvkm_gpuobj_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
+ struct nvkm_object *, u32 size, u32 align,
+ u32 flags, int length, void **);
+void nvkm_gpuobj_destroy(struct nvkm_gpuobj *);
+
+int nvkm_gpuobj_new(struct nvkm_object *, struct nvkm_object *, u32 size,
+ u32 align, u32 flags, struct nvkm_gpuobj **);
+int nvkm_gpuobj_dup(struct nvkm_object *, struct nvkm_gpuobj *,
+ struct nvkm_gpuobj **);
+int nvkm_gpuobj_map(struct nvkm_gpuobj *, u32 acc, struct nvkm_vma *);
+int nvkm_gpuobj_map_vm(struct nvkm_gpuobj *, struct nvkm_vm *, u32 access,
+ struct nvkm_vma *);
+void nvkm_gpuobj_unmap(struct nvkm_vma *);
+
+static inline void
+nvkm_gpuobj_ref(struct nvkm_gpuobj *obj, struct nvkm_gpuobj **ref)
+{
+ nvkm_object_ref(&obj->object, (struct nvkm_object **)ref);
+}
+
+void _nvkm_gpuobj_dtor(struct nvkm_object *);
+int _nvkm_gpuobj_init(struct nvkm_object *);
+int _nvkm_gpuobj_fini(struct nvkm_object *, bool);
+u32 _nvkm_gpuobj_rd32(struct nvkm_object *, u64);
+void _nvkm_gpuobj_wr32(struct nvkm_object *, u64, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h b/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
new file mode 100644
index 000000000000..67f384d0916c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_HANDLE_H__
+#define __NVKM_HANDLE_H__
+#include <core/os.h>
+struct nvkm_object;
+
+struct nvkm_handle {
+ struct nvkm_namedb *namedb;
+ struct list_head node;
+
+ struct list_head head;
+ struct list_head tree;
+ u32 name;
+ u32 priv;
+
+ u8 route;
+ u64 token;
+
+ struct nvkm_handle *parent;
+ struct nvkm_object *object;
+};
+
+int nvkm_handle_create(struct nvkm_object *, u32 parent, u32 handle,
+ struct nvkm_object *, struct nvkm_handle **);
+void nvkm_handle_destroy(struct nvkm_handle *);
+int nvkm_handle_init(struct nvkm_handle *);
+int nvkm_handle_fini(struct nvkm_handle *, bool suspend);
+
+struct nvkm_object *nvkm_handle_ref(struct nvkm_object *, u32 name);
+
+struct nvkm_handle *nvkm_handle_get_class(struct nvkm_object *, u16);
+struct nvkm_handle *nvkm_handle_get_vinst(struct nvkm_object *, u64);
+struct nvkm_handle *nvkm_handle_get_cinst(struct nvkm_object *, u32);
+void nvkm_handle_put(struct nvkm_handle *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h
new file mode 100644
index 000000000000..88971eb37afa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ioctl.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_IOCTL_H__
+#define __NVKM_IOCTL_H__
+#include <core/os.h>
+struct nvkm_client;
+
+int nvkm_ioctl(struct nvkm_client *, bool, void *, u32, void **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h
new file mode 100644
index 000000000000..096eb1a623ee
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/mm.h
@@ -0,0 +1,40 @@
+#ifndef __NVKM_MM_H__
+#define __NVKM_MM_H__
+#include <core/os.h>
+
+struct nvkm_mm_node {
+ struct list_head nl_entry;
+ struct list_head fl_entry;
+ struct list_head rl_entry;
+
+#define NVKM_MM_HEAP_ANY 0x00
+ u8 heap;
+#define NVKM_MM_TYPE_NONE 0x00
+#define NVKM_MM_TYPE_HOLE 0xff
+ u8 type;
+ u32 offset;
+ u32 length;
+};
+
+struct nvkm_mm {
+ struct list_head nodes;
+ struct list_head free;
+
+ u32 block_size;
+ int heap_nodes;
+};
+
+static inline bool
+nvkm_mm_initialised(struct nvkm_mm *mm)
+{
+ return mm->block_size != 0;
+}
+
+int nvkm_mm_init(struct nvkm_mm *, u32 offset, u32 length, u32 block);
+int nvkm_mm_fini(struct nvkm_mm *);
+int nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
+ u32 size_min, u32 align, struct nvkm_mm_node **);
+int nvkm_mm_tail(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
+ u32 size_min, u32 align, struct nvkm_mm_node **);
+void nvkm_mm_free(struct nvkm_mm *, struct nvkm_mm_node **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h b/drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h
new file mode 100644
index 000000000000..4cfe16fcde9b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/namedb.h
@@ -0,0 +1,53 @@
+#ifndef __NVKM_NAMEDB_H__
+#define __NVKM_NAMEDB_H__
+#include <core/parent.h>
+struct nvkm_handle;
+
+struct nvkm_namedb {
+ struct nvkm_parent parent;
+ rwlock_t lock;
+ struct list_head list;
+};
+
+static inline struct nvkm_namedb *
+nv_namedb(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_NAMEDB_CLASS)))
+ nv_assert("BAD CAST -> NvNameDB, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_namedb_create(p,e,c,v,s,m,d) \
+ nvkm_namedb_create_((p), (e), (c), (v), (s), (m), \
+ sizeof(**d), (void **)d)
+#define nvkm_namedb_init(p) \
+ nvkm_parent_init(&(p)->parent)
+#define nvkm_namedb_fini(p,s) \
+ nvkm_parent_fini(&(p)->parent, (s))
+#define nvkm_namedb_destroy(p) \
+ nvkm_parent_destroy(&(p)->parent)
+
+int nvkm_namedb_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
+ struct nvkm_oclass *, u64 engcls,
+ int size, void **);
+
+int _nvkm_namedb_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+#define _nvkm_namedb_dtor _nvkm_parent_dtor
+#define _nvkm_namedb_init _nvkm_parent_init
+#define _nvkm_namedb_fini _nvkm_parent_fini
+
+int nvkm_namedb_insert(struct nvkm_namedb *, u32 name, struct nvkm_object *,
+ struct nvkm_handle *);
+void nvkm_namedb_remove(struct nvkm_handle *);
+
+struct nvkm_handle *nvkm_namedb_get(struct nvkm_namedb *, u32);
+struct nvkm_handle *nvkm_namedb_get_class(struct nvkm_namedb *, u16);
+struct nvkm_handle *nvkm_namedb_get_vinst(struct nvkm_namedb *, u64);
+struct nvkm_handle *nvkm_namedb_get_cinst(struct nvkm_namedb *, u32);
+void nvkm_namedb_put(struct nvkm_handle *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/notify.h b/drivers/gpu/drm/nouveau/include/nvkm/core/notify.h
index a7c3c5f578cc..753d08c1767b 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/notify.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/notify.h
@@ -1,5 +1,7 @@
#ifndef __NVKM_NOTIFY_H__
#define __NVKM_NOTIFY_H__
+#include <core/os.h>
+struct nvkm_object;
struct nvkm_notify {
struct nvkm_event *event;
@@ -25,7 +27,7 @@ struct nvkm_notify {
const void *data;
};
-int nvkm_notify_init(struct nouveau_object *, struct nvkm_event *,
+int nvkm_notify_init(struct nvkm_object *, struct nvkm_event *,
int (*func)(struct nvkm_notify *), bool work,
void *data, u32 size, u32 reply,
struct nvkm_notify *);
@@ -33,5 +35,4 @@ void nvkm_notify_fini(struct nvkm_notify *);
void nvkm_notify_get(struct nvkm_notify *);
void nvkm_notify_put(struct nvkm_notify *);
void nvkm_notify_send(struct nvkm_notify *, void *data, u32 size);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h
index 2e2afa502c99..6e3cd3908400 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/object.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h
@@ -1,6 +1,5 @@
-#ifndef __NOUVEAU_OBJECT_H__
-#define __NOUVEAU_OBJECT_H__
-
+#ifndef __NVKM_OBJECT_H__
+#define __NVKM_OBJECT_H__
#include <core/os.h>
#include <core/printk.h>
@@ -14,52 +13,52 @@
#define NV_ENGCTX_CLASS 0x01000000
#define NV_OBJECT_CLASS 0x0000ffff
-struct nouveau_object {
- struct nouveau_oclass *oclass;
- struct nouveau_object *parent;
- struct nouveau_object *engine;
+struct nvkm_object {
+ struct nvkm_oclass *oclass;
+ struct nvkm_object *parent;
+ struct nvkm_engine *engine;
atomic_t refcount;
atomic_t usecount;
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
-#define NOUVEAU_OBJECT_MAGIC 0x75ef0bad
+#define NVKM_OBJECT_MAGIC 0x75ef0bad
struct list_head list;
u32 _magic;
#endif
};
-static inline struct nouveau_object *
+static inline struct nvkm_object *
nv_object(void *obj)
{
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
if (likely(obj)) {
- struct nouveau_object *object = obj;
- if (unlikely(object->_magic != NOUVEAU_OBJECT_MAGIC))
+ struct nvkm_object *object = obj;
+ if (unlikely(object->_magic != NVKM_OBJECT_MAGIC))
nv_assert("BAD CAST -> NvObject, invalid magic");
}
#endif
return obj;
}
-#define nouveau_object_create(p,e,c,s,d) \
- nouveau_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d)
-int nouveau_object_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u32, int size, void **);
-void nouveau_object_destroy(struct nouveau_object *);
-int nouveau_object_init(struct nouveau_object *);
-int nouveau_object_fini(struct nouveau_object *, bool suspend);
+#define nvkm_object_create(p,e,c,s,d) \
+ nvkm_object_create_((p), (e), (c), (s), sizeof(**d), (void **)d)
+int nvkm_object_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32, int size, void **);
+void nvkm_object_destroy(struct nvkm_object *);
+int nvkm_object_init(struct nvkm_object *);
+int nvkm_object_fini(struct nvkm_object *, bool suspend);
-int _nouveau_object_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
+int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
-extern struct nouveau_ofuncs nouveau_object_ofuncs;
+extern struct nvkm_ofuncs nvkm_object_ofuncs;
/* Don't allocate dynamically, because lockdep needs lock_class_keys to be in
* ".data". */
-struct nouveau_oclass {
+struct nvkm_oclass {
u32 handle;
- struct nouveau_ofuncs * const ofuncs;
- struct nouveau_omthds * const omthds;
+ struct nvkm_ofuncs * const ofuncs;
+ struct nvkm_omthds * const omthds;
struct lock_class_key lock_class_key;
};
@@ -68,58 +67,57 @@ struct nouveau_oclass {
#define nv_iclass(o,i) (nv_hclass(o) & (i))
#define nv_mclass(o) nv_iclass(o, NV_OBJECT_CLASS)
-static inline struct nouveau_object *
-nv_pclass(struct nouveau_object *parent, u32 oclass)
+static inline struct nvkm_object *
+nv_pclass(struct nvkm_object *parent, u32 oclass)
{
while (parent && !nv_iclass(parent, oclass))
parent = parent->parent;
return parent;
}
-struct nouveau_omthds {
+struct nvkm_omthds {
u32 start;
u32 limit;
- int (*call)(struct nouveau_object *, u32, void *, u32);
+ int (*call)(struct nvkm_object *, u32, void *, u32);
};
struct nvkm_event;
-struct nouveau_ofuncs {
- int (*ctor)(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *data, u32 size,
- struct nouveau_object **);
- void (*dtor)(struct nouveau_object *);
- int (*init)(struct nouveau_object *);
- int (*fini)(struct nouveau_object *, bool suspend);
- int (*mthd)(struct nouveau_object *, u32, void *, u32);
- int (*ntfy)(struct nouveau_object *, u32, struct nvkm_event **);
- int (* map)(struct nouveau_object *, u64 *, u32 *);
- u8 (*rd08)(struct nouveau_object *, u64 offset);
- u16 (*rd16)(struct nouveau_object *, u64 offset);
- u32 (*rd32)(struct nouveau_object *, u64 offset);
- void (*wr08)(struct nouveau_object *, u64 offset, u8 data);
- void (*wr16)(struct nouveau_object *, u64 offset, u16 data);
- void (*wr32)(struct nouveau_object *, u64 offset, u32 data);
+struct nvkm_ofuncs {
+ int (*ctor)(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *data, u32 size,
+ struct nvkm_object **);
+ void (*dtor)(struct nvkm_object *);
+ int (*init)(struct nvkm_object *);
+ int (*fini)(struct nvkm_object *, bool suspend);
+ int (*mthd)(struct nvkm_object *, u32, void *, u32);
+ int (*ntfy)(struct nvkm_object *, u32, struct nvkm_event **);
+ int (* map)(struct nvkm_object *, u64 *, u32 *);
+ u8 (*rd08)(struct nvkm_object *, u64 offset);
+ u16 (*rd16)(struct nvkm_object *, u64 offset);
+ u32 (*rd32)(struct nvkm_object *, u64 offset);
+ void (*wr08)(struct nvkm_object *, u64 offset, u8 data);
+ void (*wr16)(struct nvkm_object *, u64 offset, u16 data);
+ void (*wr32)(struct nvkm_object *, u64 offset, u32 data);
};
-static inline struct nouveau_ofuncs *
+static inline struct nvkm_ofuncs *
nv_ofuncs(void *obj)
{
return nv_oclass(obj)->ofuncs;
}
-int nouveau_object_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nouveau_object_ref(struct nouveau_object *, struct nouveau_object **);
-int nouveau_object_inc(struct nouveau_object *);
-int nouveau_object_dec(struct nouveau_object *, bool suspend);
-
-void nouveau_object_debug(void);
+int nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **);
+int nvkm_object_inc(struct nvkm_object *);
+int nvkm_object_dec(struct nvkm_object *, bool suspend);
+void nvkm_object_debug(void);
static inline int
nv_exec(void *obj, u32 mthd, void *data, u32 size)
{
- struct nouveau_omthds *method = nv_oclass(obj)->omthds;
+ struct nvkm_omthds *method = nv_oclass(obj)->omthds;
while (method && method->call) {
if (mthd >= method->start && mthd <= method->limit)
@@ -202,5 +200,4 @@ nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
}
return 0;
}
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/option.h b/drivers/gpu/drm/nouveau/include/nvkm/core/option.h
new file mode 100644
index 000000000000..532bfa8e3f72
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/option.h
@@ -0,0 +1,17 @@
+#ifndef __NVKM_OPTION_H__
+#define __NVKM_OPTION_H__
+#include <core/os.h>
+
+const char *nvkm_stropt(const char *optstr, const char *opt, int *len);
+bool nvkm_boolopt(const char *optstr, const char *opt, bool value);
+int nvkm_dbgopt(const char *optstr, const char *sub);
+
+/* compares unterminated string 'str' with zero-terminated string 'cmp' */
+static inline int
+strncasecmpz(const char *str, const char *cmp, size_t len)
+{
+ if (strlen(cmp) != len)
+ return len;
+ return strncasecmp(str, cmp, len);
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/os.h b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h
new file mode 100644
index 000000000000..cd57e238ddd3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/os.h
@@ -0,0 +1,4 @@
+#ifndef __NVKM_OS_H__
+#define __NVKM_OS_H__
+#include <nvif/os.h>
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/parent.h b/drivers/gpu/drm/nouveau/include/nvkm/core/parent.h
new file mode 100644
index 000000000000..837e4fe966a5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/parent.h
@@ -0,0 +1,58 @@
+#ifndef __NVKM_PARENT_H__
+#define __NVKM_PARENT_H__
+#include <core/object.h>
+
+struct nvkm_sclass {
+ struct nvkm_sclass *sclass;
+ struct nvkm_engine *engine;
+ struct nvkm_oclass *oclass;
+};
+
+struct nvkm_parent {
+ struct nvkm_object object;
+
+ struct nvkm_sclass *sclass;
+ u64 engine;
+
+ int (*context_attach)(struct nvkm_object *, struct nvkm_object *);
+ int (*context_detach)(struct nvkm_object *, bool suspend,
+ struct nvkm_object *);
+
+ int (*object_attach)(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 name);
+ void (*object_detach)(struct nvkm_object *parent, int cookie);
+};
+
+static inline struct nvkm_parent *
+nv_parent(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!(nv_iclass(obj, NV_PARENT_CLASS))))
+ nv_assert("BAD CAST -> NvParent, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+#define nvkm_parent_create(p,e,c,v,s,m,d) \
+ nvkm_parent_create_((p), (e), (c), (v), (s), (m), \
+ sizeof(**d), (void **)d)
+#define nvkm_parent_init(p) \
+ nvkm_object_init(&(p)->object)
+#define nvkm_parent_fini(p,s) \
+ nvkm_object_fini(&(p)->object, (s))
+
+int nvkm_parent_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
+ struct nvkm_oclass *, u64 engcls,
+ int size, void **);
+void nvkm_parent_destroy(struct nvkm_parent *);
+
+void _nvkm_parent_dtor(struct nvkm_object *);
+#define _nvkm_parent_init nvkm_object_init
+#define _nvkm_parent_fini nvkm_object_fini
+
+int nvkm_parent_sclass(struct nvkm_object *, u16 handle,
+ struct nvkm_object **pengine,
+ struct nvkm_oclass **poclass);
+int nvkm_parent_lclass(struct nvkm_object *, u32 *, int);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/printk.h b/drivers/gpu/drm/nouveau/include/nvkm/core/printk.h
index 451b6ed20b7e..83648177059f 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/printk.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/printk.h
@@ -1,13 +1,11 @@
-#ifndef __NOUVEAU_PRINTK_H__
-#define __NOUVEAU_PRINTK_H__
-
+#ifndef __NVKM_PRINTK_H__
+#define __NVKM_PRINTK_H__
#include <core/os.h>
#include <core/debug.h>
-
-struct nouveau_object;
+struct nvkm_object;
void __printf(3, 4)
-nv_printk_(struct nouveau_object *, int, const char *, ...);
+nv_printk_(struct nvkm_object *, int, const char *, ...);
#define nv_printk(o,l,f,a...) do { \
if (NV_DBG_##l <= CONFIG_NOUVEAU_DEBUG) \
@@ -21,12 +19,11 @@ nv_printk_(struct nouveau_object *, int, const char *, ...);
#define nv_debug(o,f,a...) nv_printk((o), DEBUG, f, ##a)
#define nv_trace(o,f,a...) nv_printk((o), TRACE, f, ##a)
#define nv_spam(o,f,a...) nv_printk((o), SPAM, f, ##a)
-#define nv_ioctl(o,f,a...) nv_trace(nouveau_client(o), "ioctl: "f, ##a)
+#define nv_ioctl(o,f,a...) nv_trace(nvkm_client(o), "ioctl: "f, ##a)
#define nv_assert(f,a...) do { \
if (NV_DBG_FATAL <= CONFIG_NOUVEAU_DEBUG) \
nv_printk_(NULL, NV_DBG_FATAL, f "\n", ##a); \
BUG_ON(1); \
} while(0)
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h
new file mode 100644
index 000000000000..cc132eaa10cc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/ramht.h
@@ -0,0 +1,20 @@
+#ifndef __NVKM_RAMHT_H__
+#define __NVKM_RAMHT_H__
+#include <core/gpuobj.h>
+
+struct nvkm_ramht {
+ struct nvkm_gpuobj gpuobj;
+ int bits;
+};
+
+int nvkm_ramht_insert(struct nvkm_ramht *, int chid, u32 handle, u32 context);
+void nvkm_ramht_remove(struct nvkm_ramht *, int cookie);
+int nvkm_ramht_new(struct nvkm_object *, struct nvkm_object *, u32 size,
+ u32 align, struct nvkm_ramht **);
+
+static inline void
+nvkm_ramht_ref(struct nvkm_ramht *obj, struct nvkm_ramht **ref)
+{
+ nvkm_gpuobj_ref(&obj->gpuobj, (struct nvkm_gpuobj **)ref);
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
index e9632e931616..6fdc39116aac 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/subdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -1,23 +1,23 @@
-#ifndef __NOUVEAU_SUBDEV_H__
-#define __NOUVEAU_SUBDEV_H__
-
+#ifndef __NVKM_SUBDEV_H__
+#define __NVKM_SUBDEV_H__
#include <core/object.h>
+#include <core/devidx.h>
#define NV_SUBDEV_(sub,var) (NV_SUBDEV_CLASS | ((var) << 8) | (sub))
#define NV_SUBDEV(name,var) NV_SUBDEV_(NVDEV_SUBDEV_##name, (var))
-struct nouveau_subdev {
- struct nouveau_object base;
+struct nvkm_subdev {
+ struct nvkm_object object;
struct mutex mutex;
const char *name;
void __iomem *mmio;
u32 debug;
u32 unit;
- void (*intr)(struct nouveau_subdev *);
+ void (*intr)(struct nvkm_subdev *);
};
-static inline struct nouveau_subdev *
+static inline struct nvkm_subdev *
nv_subdev(void *obj)
{
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
@@ -28,27 +28,29 @@ nv_subdev(void *obj)
}
static inline int
-nv_subidx(struct nouveau_object *object)
+nv_subidx(struct nvkm_subdev *subdev)
{
- return nv_hclass(nv_subdev(object)) & 0xff;
+ return nv_hclass(subdev) & 0xff;
}
-#define nouveau_subdev_create(p,e,o,v,s,f,d) \
- nouveau_subdev_create_((p), (e), (o), (v), (s), (f), \
+struct nvkm_subdev *nvkm_subdev(void *obj, int idx);
+
+#define nvkm_subdev_create(p,e,o,v,s,f,d) \
+ nvkm_subdev_create_((p), (e), (o), (v), (s), (f), \
sizeof(**d),(void **)d)
-int nouveau_subdev_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, u32 pclass,
+int nvkm_subdev_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32 pclass,
const char *sname, const char *fname,
int size, void **);
-void nouveau_subdev_destroy(struct nouveau_subdev *);
-int nouveau_subdev_init(struct nouveau_subdev *);
-int nouveau_subdev_fini(struct nouveau_subdev *, bool suspend);
-void nouveau_subdev_reset(struct nouveau_object *);
+void nvkm_subdev_destroy(struct nvkm_subdev *);
+int nvkm_subdev_init(struct nvkm_subdev *);
+int nvkm_subdev_fini(struct nvkm_subdev *, bool suspend);
+void nvkm_subdev_reset(struct nvkm_object *);
-void _nouveau_subdev_dtor(struct nouveau_object *);
-int _nouveau_subdev_init(struct nouveau_object *);
-int _nouveau_subdev_fini(struct nouveau_object *, bool suspend);
+void _nvkm_subdev_dtor(struct nvkm_object *);
+int _nvkm_subdev_init(struct nvkm_object *);
+int _nvkm_subdev_fini(struct nvkm_object *, bool suspend);
#define s_printk(s,l,f,a...) do { \
if ((s)->debug >= OS_DBG_##l) { \
@@ -59,7 +61,7 @@ int _nouveau_subdev_fini(struct nouveau_object *, bool suspend);
static inline u8
nv_rd08(void *obj, u32 addr)
{
- struct nouveau_subdev *subdev = nv_subdev(obj);
+ struct nvkm_subdev *subdev = nv_subdev(obj);
u8 data = ioread8(subdev->mmio + addr);
nv_spam(subdev, "nv_rd08 0x%06x 0x%02x\n", addr, data);
return data;
@@ -68,7 +70,7 @@ nv_rd08(void *obj, u32 addr)
static inline u16
nv_rd16(void *obj, u32 addr)
{
- struct nouveau_subdev *subdev = nv_subdev(obj);
+ struct nvkm_subdev *subdev = nv_subdev(obj);
u16 data = ioread16_native(subdev->mmio + addr);
nv_spam(subdev, "nv_rd16 0x%06x 0x%04x\n", addr, data);
return data;
@@ -77,7 +79,7 @@ nv_rd16(void *obj, u32 addr)
static inline u32
nv_rd32(void *obj, u32 addr)
{
- struct nouveau_subdev *subdev = nv_subdev(obj);
+ struct nvkm_subdev *subdev = nv_subdev(obj);
u32 data = ioread32_native(subdev->mmio + addr);
nv_spam(subdev, "nv_rd32 0x%06x 0x%08x\n", addr, data);
return data;
@@ -86,7 +88,7 @@ nv_rd32(void *obj, u32 addr)
static inline void
nv_wr08(void *obj, u32 addr, u8 data)
{
- struct nouveau_subdev *subdev = nv_subdev(obj);
+ struct nvkm_subdev *subdev = nv_subdev(obj);
nv_spam(subdev, "nv_wr08 0x%06x 0x%02x\n", addr, data);
iowrite8(data, subdev->mmio + addr);
}
@@ -94,7 +96,7 @@ nv_wr08(void *obj, u32 addr, u8 data)
static inline void
nv_wr16(void *obj, u32 addr, u16 data)
{
- struct nouveau_subdev *subdev = nv_subdev(obj);
+ struct nvkm_subdev *subdev = nv_subdev(obj);
nv_spam(subdev, "nv_wr16 0x%06x 0x%04x\n", addr, data);
iowrite16_native(data, subdev->mmio + addr);
}
@@ -102,7 +104,7 @@ nv_wr16(void *obj, u32 addr, u16 data)
static inline void
nv_wr32(void *obj, u32 addr, u32 data)
{
- struct nouveau_subdev *subdev = nv_subdev(obj);
+ struct nvkm_subdev *subdev = nv_subdev(obj);
nv_spam(subdev, "nv_wr32 0x%06x 0x%08x\n", addr, data);
iowrite32_native(data, subdev->mmio + addr);
}
@@ -114,5 +116,4 @@ nv_mask(void *obj, u32 addr, u32 mask, u32 data)
nv_wr32(obj, addr, (temp & ~mask) | data);
return temp;
}
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h
new file mode 100644
index 000000000000..e489beef2b92
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/bsp.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_BSP_H__
+#define __NVKM_BSP_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g84_bsp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
new file mode 100644
index 000000000000..7e29c52617ea
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
@@ -0,0 +1,13 @@
+#ifndef __NVKM_CE_H__
+#define __NVKM_CE_H__
+#include <core/engine.h>
+
+void gt215_ce_intr(struct nvkm_subdev *);
+
+extern struct nvkm_oclass gt215_ce_oclass;
+extern struct nvkm_oclass gf100_ce0_oclass;
+extern struct nvkm_oclass gf100_ce1_oclass;
+extern struct nvkm_oclass gk104_ce0_oclass;
+extern struct nvkm_oclass gk104_ce1_oclass;
+extern struct nvkm_oclass gk104_ce2_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h
new file mode 100644
index 000000000000..57c29e91bad5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/cipher.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_CIPHER_H__
+#define __NVKM_CIPHER_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g84_cipher_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/device.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/device.h
index 672d3c8f4145..5d4805e67e76 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/device.h
@@ -27,7 +27,4 @@ int nv50_identify(struct nouveau_device *);
int nvc0_identify(struct nouveau_device *);
int nve0_identify(struct nouveau_device *);
int gm100_identify(struct nouveau_device *);
-
-struct nouveau_device *nouveau_device_find(u64 name);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
new file mode 100644
index 000000000000..a5e1ed81312f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_DISP_H__
+#define __NVKM_DISP_H__
+#include <core/engine.h>
+#include <core/event.h>
+
+struct nvkm_disp {
+ struct nvkm_engine base;
+
+ struct list_head outp;
+
+ struct nvkm_event hpd;
+ struct nvkm_event vblank;
+};
+
+static inline struct nvkm_disp *
+nvkm_disp(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_DISP);
+}
+
+extern struct nvkm_oclass *nv04_disp_oclass;
+extern struct nvkm_oclass *nv50_disp_oclass;
+extern struct nvkm_oclass *g84_disp_oclass;
+extern struct nvkm_oclass *gt200_disp_oclass;
+extern struct nvkm_oclass *g94_disp_oclass;
+extern struct nvkm_oclass *gt215_disp_oclass;
+extern struct nvkm_oclass *gf110_disp_oclass;
+extern struct nvkm_oclass *gk104_disp_oclass;
+extern struct nvkm_oclass *gk110_disp_oclass;
+extern struct nvkm_oclass *gm107_disp_oclass;
+extern struct nvkm_oclass *gm204_disp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h
new file mode 100644
index 000000000000..c4fce8afcf83
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/dmaobj.h
@@ -0,0 +1,26 @@
+#ifndef __NVKM_DMAOBJ_H__
+#define __NVKM_DMAOBJ_H__
+#include <core/engine.h>
+struct nvkm_gpuobj;
+
+struct nvkm_dmaobj {
+ struct nvkm_object base;
+ u32 target;
+ u32 access;
+ u64 start;
+ u64 limit;
+};
+
+struct nvkm_dmaeng {
+ struct nvkm_engine base;
+
+ /* creates a "physical" dma object from a struct nvkm_dmaobj */
+ int (*bind)(struct nvkm_dmaobj *dmaobj, struct nvkm_object *parent,
+ struct nvkm_gpuobj **);
+};
+
+extern struct nvkm_oclass *nv04_dmaeng_oclass;
+extern struct nvkm_oclass *nv50_dmaeng_oclass;
+extern struct nvkm_oclass *gf100_dmaeng_oclass;
+extern struct nvkm_oclass *gf110_dmaeng_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
new file mode 100644
index 000000000000..bd38cf9130fc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
@@ -0,0 +1,81 @@
+#ifndef __NVKM_FALCON_H__
+#define __NVKM_FALCON_H__
+#include <core/engctx.h>
+
+struct nvkm_falcon_chan {
+ struct nvkm_engctx base;
+};
+
+#define nvkm_falcon_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nvkm_falcon_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_falcon_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_falcon_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_falcon_context_ctor _nvkm_engctx_ctor
+#define _nvkm_falcon_context_dtor _nvkm_engctx_dtor
+#define _nvkm_falcon_context_init _nvkm_engctx_init
+#define _nvkm_falcon_context_fini _nvkm_engctx_fini
+#define _nvkm_falcon_context_rd32 _nvkm_engctx_rd32
+#define _nvkm_falcon_context_wr32 _nvkm_engctx_wr32
+
+struct nvkm_falcon_data {
+ bool external;
+};
+
+#include <core/engine.h>
+
+struct nvkm_falcon {
+ struct nvkm_engine base;
+
+ u32 addr;
+ u8 version;
+ u8 secret;
+
+ struct nvkm_gpuobj *core;
+ bool external;
+
+ struct {
+ u32 limit;
+ u32 *data;
+ u32 size;
+ } code;
+
+ struct {
+ u32 limit;
+ u32 *data;
+ u32 size;
+ } data;
+};
+
+#define nv_falcon(priv) (&(priv)->base)
+
+#define nvkm_falcon_create(p,e,c,b,d,i,f,r) \
+ nvkm_falcon_create_((p), (e), (c), (b), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+#define nvkm_falcon_destroy(p) \
+ nvkm_engine_destroy(&(p)->base)
+#define nvkm_falcon_init(p) ({ \
+ struct nvkm_falcon *falcon = (p); \
+ _nvkm_falcon_init(nv_object(falcon)); \
+})
+#define nvkm_falcon_fini(p,s) ({ \
+ struct nvkm_falcon *falcon = (p); \
+ _nvkm_falcon_fini(nv_object(falcon), (s)); \
+})
+
+int nvkm_falcon_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32, bool, const char *,
+ const char *, int, void **);
+
+void nvkm_falcon_intr(struct nvkm_subdev *subdev);
+
+#define _nvkm_falcon_dtor _nvkm_engine_dtor
+int _nvkm_falcon_init(struct nvkm_object *);
+int _nvkm_falcon_fini(struct nvkm_object *, bool);
+u32 _nvkm_falcon_rd32(struct nvkm_object *, u64);
+void _nvkm_falcon_wr32(struct nvkm_object *, u64, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
new file mode 100644
index 000000000000..05321ce7ab15
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
@@ -0,0 +1,126 @@
+#ifndef __NVKM_FIFO_H__
+#define __NVKM_FIFO_H__
+#include <core/namedb.h>
+
+struct nvkm_fifo_chan {
+ struct nvkm_namedb namedb;
+ struct nvkm_dmaobj *pushdma;
+ struct nvkm_gpuobj *pushgpu;
+ void __iomem *user;
+ u64 addr;
+ u32 size;
+ u16 chid;
+ atomic_t refcnt; /* NV04_NVSW_SET_REF */
+};
+
+static inline struct nvkm_fifo_chan *
+nvkm_fifo_chan(void *obj)
+{
+ return (void *)nv_namedb(obj);
+}
+
+#define nvkm_fifo_channel_create(p,e,c,b,a,s,n,m,d) \
+ nvkm_fifo_channel_create_((p), (e), (c), (b), (a), (s), (n), \
+ (m), sizeof(**d), (void **)d)
+#define nvkm_fifo_channel_init(p) \
+ nvkm_namedb_init(&(p)->namedb)
+#define nvkm_fifo_channel_fini(p,s) \
+ nvkm_namedb_fini(&(p)->namedb, (s))
+
+int nvkm_fifo_channel_create_(struct nvkm_object *,
+ struct nvkm_object *,
+ struct nvkm_oclass *,
+ int bar, u32 addr, u32 size, u32 push,
+ u64 engmask, int len, void **);
+void nvkm_fifo_channel_destroy(struct nvkm_fifo_chan *);
+
+#define _nvkm_fifo_channel_init _nvkm_namedb_init
+#define _nvkm_fifo_channel_fini _nvkm_namedb_fini
+
+void _nvkm_fifo_channel_dtor(struct nvkm_object *);
+int _nvkm_fifo_channel_map(struct nvkm_object *, u64 *, u32 *);
+u32 _nvkm_fifo_channel_rd32(struct nvkm_object *, u64);
+void _nvkm_fifo_channel_wr32(struct nvkm_object *, u64, u32);
+int _nvkm_fifo_channel_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
+
+#include <core/gpuobj.h>
+
+struct nvkm_fifo_base {
+ struct nvkm_gpuobj gpuobj;
+};
+
+#define nvkm_fifo_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_gpuobj_create((p), (e), (c), 0, (g), (s), (a), (f), (d))
+#define nvkm_fifo_context_destroy(p) \
+ nvkm_gpuobj_destroy(&(p)->gpuobj)
+#define nvkm_fifo_context_init(p) \
+ nvkm_gpuobj_init(&(p)->gpuobj)
+#define nvkm_fifo_context_fini(p,s) \
+ nvkm_gpuobj_fini(&(p)->gpuobj, (s))
+
+#define _nvkm_fifo_context_dtor _nvkm_gpuobj_dtor
+#define _nvkm_fifo_context_init _nvkm_gpuobj_init
+#define _nvkm_fifo_context_fini _nvkm_gpuobj_fini
+#define _nvkm_fifo_context_rd32 _nvkm_gpuobj_rd32
+#define _nvkm_fifo_context_wr32 _nvkm_gpuobj_wr32
+
+#include <core/engine.h>
+#include <core/event.h>
+
+struct nvkm_fifo {
+ struct nvkm_engine base;
+
+ struct nvkm_event cevent; /* channel creation event */
+ struct nvkm_event uevent; /* async user trigger */
+
+ struct nvkm_object **channel;
+ spinlock_t lock;
+ u16 min;
+ u16 max;
+
+ int (*chid)(struct nvkm_fifo *, struct nvkm_object *);
+ void (*pause)(struct nvkm_fifo *, unsigned long *);
+ void (*start)(struct nvkm_fifo *, unsigned long *);
+};
+
+static inline struct nvkm_fifo *
+nvkm_fifo(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_FIFO);
+}
+
+#define nvkm_fifo_create(o,e,c,fc,lc,d) \
+ nvkm_fifo_create_((o), (e), (c), (fc), (lc), sizeof(**d), (void **)d)
+#define nvkm_fifo_init(p) \
+ nvkm_engine_init(&(p)->base)
+#define nvkm_fifo_fini(p,s) \
+ nvkm_engine_fini(&(p)->base, (s))
+
+int nvkm_fifo_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int min, int max,
+ int size, void **);
+void nvkm_fifo_destroy(struct nvkm_fifo *);
+const char *
+nvkm_client_name_for_fifo_chid(struct nvkm_fifo *fifo, u32 chid);
+
+#define _nvkm_fifo_init _nvkm_engine_init
+#define _nvkm_fifo_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass *nv04_fifo_oclass;
+extern struct nvkm_oclass *nv10_fifo_oclass;
+extern struct nvkm_oclass *nv17_fifo_oclass;
+extern struct nvkm_oclass *nv40_fifo_oclass;
+extern struct nvkm_oclass *nv50_fifo_oclass;
+extern struct nvkm_oclass *g84_fifo_oclass;
+extern struct nvkm_oclass *gf100_fifo_oclass;
+extern struct nvkm_oclass *gk104_fifo_oclass;
+extern struct nvkm_oclass *gk20a_fifo_oclass;
+extern struct nvkm_oclass *gk208_fifo_oclass;
+
+int nvkm_fifo_uevent_ctor(struct nvkm_object *, void *, u32,
+ struct nvkm_notify *);
+void nvkm_fifo_uevent(struct nvkm_fifo *);
+
+void nv04_fifo_intr(struct nvkm_subdev *);
+int nv04_fifo_context_attach(struct nvkm_object *, struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h
new file mode 100644
index 000000000000..93ef1f2bfac4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h
@@ -0,0 +1,86 @@
+#ifndef __NVKM_GR_H__
+#define __NVKM_GR_H__
+#include <core/engctx.h>
+
+struct nvkm_gr_chan {
+ struct nvkm_engctx base;
+};
+
+#define nvkm_gr_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nvkm_gr_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_gr_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_gr_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_gr_context_dtor _nvkm_engctx_dtor
+#define _nvkm_gr_context_init _nvkm_engctx_init
+#define _nvkm_gr_context_fini _nvkm_engctx_fini
+#define _nvkm_gr_context_rd32 _nvkm_engctx_rd32
+#define _nvkm_gr_context_wr32 _nvkm_engctx_wr32
+
+#include <core/engine.h>
+
+struct nvkm_gr {
+ struct nvkm_engine base;
+
+ /* Returns chipset-specific counts of units packed into an u64.
+ */
+ u64 (*units)(struct nvkm_gr *);
+};
+
+static inline struct nvkm_gr *
+nvkm_gr(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_GR);
+}
+
+#define nvkm_gr_create(p,e,c,y,d) \
+ nvkm_engine_create((p), (e), (c), (y), "PGR", "graphics", (d))
+#define nvkm_gr_destroy(d) \
+ nvkm_engine_destroy(&(d)->base)
+#define nvkm_gr_init(d) \
+ nvkm_engine_init(&(d)->base)
+#define nvkm_gr_fini(d,s) \
+ nvkm_engine_fini(&(d)->base, (s))
+
+#define _nvkm_gr_dtor _nvkm_engine_dtor
+#define _nvkm_gr_init _nvkm_engine_init
+#define _nvkm_gr_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass nv04_gr_oclass;
+extern struct nvkm_oclass nv10_gr_oclass;
+extern struct nvkm_oclass nv20_gr_oclass;
+extern struct nvkm_oclass nv25_gr_oclass;
+extern struct nvkm_oclass nv2a_gr_oclass;
+extern struct nvkm_oclass nv30_gr_oclass;
+extern struct nvkm_oclass nv34_gr_oclass;
+extern struct nvkm_oclass nv35_gr_oclass;
+extern struct nvkm_oclass nv40_gr_oclass;
+extern struct nvkm_oclass nv50_gr_oclass;
+extern struct nvkm_oclass *gf100_gr_oclass;
+extern struct nvkm_oclass *gf108_gr_oclass;
+extern struct nvkm_oclass *gf104_gr_oclass;
+extern struct nvkm_oclass *gf110_gr_oclass;
+extern struct nvkm_oclass *gf117_gr_oclass;
+extern struct nvkm_oclass *gf119_gr_oclass;
+extern struct nvkm_oclass *gk104_gr_oclass;
+extern struct nvkm_oclass *gk20a_gr_oclass;
+extern struct nvkm_oclass *gk110_gr_oclass;
+extern struct nvkm_oclass *gk110b_gr_oclass;
+extern struct nvkm_oclass *gk208_gr_oclass;
+extern struct nvkm_oclass *gm107_gr_oclass;
+
+#include <core/enum.h>
+
+extern const struct nvkm_bitfield nv04_gr_nsource[];
+extern struct nvkm_ofuncs nv04_gr_ofuncs;
+bool nv04_gr_idle(void *obj);
+
+extern const struct nvkm_bitfield nv10_gr_intr_name[];
+extern const struct nvkm_bitfield nv10_gr_nstatus[];
+
+extern const struct nvkm_enum nv50_data_error_names[];
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h
new file mode 100644
index 000000000000..4e500b398064
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/mpeg.h
@@ -0,0 +1,62 @@
+#ifndef __NVKM_MPEG_H__
+#define __NVKM_MPEG_H__
+#include <core/engctx.h>
+
+struct nvkm_mpeg_chan {
+ struct nvkm_engctx base;
+};
+
+#define nvkm_mpeg_context_create(p,e,c,g,s,a,f,d) \
+ nvkm_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nvkm_mpeg_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_mpeg_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_mpeg_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_mpeg_context_dtor _nvkm_engctx_dtor
+#define _nvkm_mpeg_context_init _nvkm_engctx_init
+#define _nvkm_mpeg_context_fini _nvkm_engctx_fini
+#define _nvkm_mpeg_context_rd32 _nvkm_engctx_rd32
+#define _nvkm_mpeg_context_wr32 _nvkm_engctx_wr32
+
+#include <core/engine.h>
+
+struct nvkm_mpeg {
+ struct nvkm_engine base;
+};
+
+#define nvkm_mpeg_create(p,e,c,d) \
+ nvkm_engine_create((p), (e), (c), true, "PMPEG", "mpeg", (d))
+#define nvkm_mpeg_destroy(d) \
+ nvkm_engine_destroy(&(d)->base)
+#define nvkm_mpeg_init(d) \
+ nvkm_engine_init(&(d)->base)
+#define nvkm_mpeg_fini(d,s) \
+ nvkm_engine_fini(&(d)->base, (s))
+
+#define _nvkm_mpeg_dtor _nvkm_engine_dtor
+#define _nvkm_mpeg_init _nvkm_engine_init
+#define _nvkm_mpeg_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass nv31_mpeg_oclass;
+extern struct nvkm_oclass nv40_mpeg_oclass;
+extern struct nvkm_oclass nv44_mpeg_oclass;
+extern struct nvkm_oclass nv50_mpeg_oclass;
+extern struct nvkm_oclass g84_mpeg_oclass;
+extern struct nvkm_ofuncs nv31_mpeg_ofuncs;
+extern struct nvkm_oclass nv31_mpeg_cclass;
+extern struct nvkm_oclass nv31_mpeg_sclass[];
+extern struct nvkm_oclass nv40_mpeg_sclass[];
+void nv31_mpeg_intr(struct nvkm_subdev *);
+void nv31_mpeg_tile_prog(struct nvkm_engine *, int);
+int nv31_mpeg_init(struct nvkm_object *);
+
+extern struct nvkm_ofuncs nv50_mpeg_ofuncs;
+int nv50_mpeg_context_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv50_mpeg_intr(struct nvkm_subdev *);
+int nv50_mpeg_init(struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h
new file mode 100644
index 000000000000..54b7672eed9c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/mspdec.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_MSPDEC_H__
+#define __NVKM_MSPDEC_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_mspdec_oclass;
+extern struct nvkm_oclass gf100_mspdec_oclass;
+extern struct nvkm_oclass gk104_mspdec_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h
new file mode 100644
index 000000000000..c6c69d0a8d01
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/msppp.h
@@ -0,0 +1,6 @@
+#ifndef __NVKM_MSPPP_H__
+#define __NVKM_MSPPP_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_msppp_oclass;
+extern struct nvkm_oclass gf100_msppp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h
new file mode 100644
index 000000000000..1f193b7bd6c5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/msvld.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_MSVLD_H__
+#define __NVKM_MSVLD_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_msvld_oclass;
+extern struct nvkm_oclass gf100_msvld_oclass;
+extern struct nvkm_oclass gk104_msvld_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h
new file mode 100644
index 000000000000..93181bbf0f63
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/pm.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_PM_H__
+#define __NVKM_PM_H__
+#include <core/engine.h>
+
+struct nvkm_perfdom;
+struct nvkm_perfctr;
+struct nvkm_pm {
+ struct nvkm_engine base;
+
+ struct nvkm_perfctx *context;
+ void *profile_data;
+
+ struct list_head domains;
+ u32 sequence;
+
+ /*XXX: temp for daemon backend */
+ u32 pwr[8];
+ u32 last;
+};
+
+static inline struct nvkm_pm *
+nvkm_pm(void *obj)
+{
+ return (void *)nvkm_engine(obj, NVDEV_ENGINE_PM);
+}
+
+extern struct nvkm_oclass *nv40_pm_oclass;
+extern struct nvkm_oclass *nv50_pm_oclass;
+extern struct nvkm_oclass *g84_pm_oclass;
+extern struct nvkm_oclass *gt215_pm_oclass;
+extern struct nvkm_oclass gf100_pm_oclass;
+extern struct nvkm_oclass gk104_pm_oclass;
+extern struct nvkm_oclass gk110_pm_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h
new file mode 100644
index 000000000000..44590a2a479d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/sec.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_SEC_H__
+#define __NVKM_SEC_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g98_sec_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h
new file mode 100644
index 000000000000..a529013c92ab
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/sw.h
@@ -0,0 +1,50 @@
+#ifndef __NVKM_SW_H__
+#define __NVKM_SW_H__
+#include <core/engctx.h>
+
+struct nvkm_sw_chan {
+ struct nvkm_engctx base;
+
+ int (*flip)(void *);
+ void *flip_data;
+};
+
+#define nvkm_sw_context_create(p,e,c,d) \
+ nvkm_engctx_create((p), (e), (c), (p), 0, 0, 0, (d))
+#define nvkm_sw_context_destroy(d) \
+ nvkm_engctx_destroy(&(d)->base)
+#define nvkm_sw_context_init(d) \
+ nvkm_engctx_init(&(d)->base)
+#define nvkm_sw_context_fini(d,s) \
+ nvkm_engctx_fini(&(d)->base, (s))
+
+#define _nvkm_sw_context_dtor _nvkm_engctx_dtor
+#define _nvkm_sw_context_init _nvkm_engctx_init
+#define _nvkm_sw_context_fini _nvkm_engctx_fini
+
+#include <core/engine.h>
+
+struct nvkm_sw {
+ struct nvkm_engine base;
+};
+
+#define nvkm_sw_create(p,e,c,d) \
+ nvkm_engine_create((p), (e), (c), true, "SW", "software", (d))
+#define nvkm_sw_destroy(d) \
+ nvkm_engine_destroy(&(d)->base)
+#define nvkm_sw_init(d) \
+ nvkm_engine_init(&(d)->base)
+#define nvkm_sw_fini(d,s) \
+ nvkm_engine_fini(&(d)->base, (s))
+
+#define _nvkm_sw_dtor _nvkm_engine_dtor
+#define _nvkm_sw_init _nvkm_engine_init
+#define _nvkm_sw_fini _nvkm_engine_fini
+
+extern struct nvkm_oclass *nv04_sw_oclass;
+extern struct nvkm_oclass *nv10_sw_oclass;
+extern struct nvkm_oclass *nv50_sw_oclass;
+extern struct nvkm_oclass *gf100_sw_oclass;
+
+void nv04_sw_intr(struct nvkm_subdev *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h
new file mode 100644
index 000000000000..7851f18c5add
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/vp.h
@@ -0,0 +1,5 @@
+#ifndef __NVKM_VP_H__
+#define __NVKM_VP_H__
+#include <core/engine.h>
+extern struct nvkm_oclass g84_vp_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h
new file mode 100644
index 000000000000..7a216cca2865
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h
@@ -0,0 +1,35 @@
+#ifndef __NVKM_XTENSA_H__
+#define __NVKM_XTENSA_H__
+#include <core/engine.h>
+struct nvkm_gpuobj;
+
+struct nvkm_xtensa {
+ struct nvkm_engine base;
+
+ u32 addr;
+ struct nvkm_gpuobj *gpu_fw;
+ u32 fifo_val;
+ u32 unkd28;
+};
+
+#define nvkm_xtensa_create(p,e,c,b,d,i,f,r) \
+ nvkm_xtensa_create_((p), (e), (c), (b), (d), (i), (f), \
+ sizeof(**r),(void **)r)
+
+int _nvkm_xtensa_engctx_ctor(struct nvkm_object *,
+ struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+
+void _nvkm_xtensa_intr(struct nvkm_subdev *);
+int nvkm_xtensa_create_(struct nvkm_object *,
+ struct nvkm_object *,
+ struct nvkm_oclass *, u32, bool,
+ const char *, const char *,
+ int, void **);
+#define _nvkm_xtensa_dtor _nvkm_engine_dtor
+int _nvkm_xtensa_init(struct nvkm_object *);
+int _nvkm_xtensa_fini(struct nvkm_object *, bool);
+u32 _nvkm_xtensa_rd32(struct nvkm_object *, u64);
+void _nvkm_xtensa_wr32(struct nvkm_object *, u64, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
new file mode 100644
index 000000000000..c7a007b8bc10
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
@@ -0,0 +1,33 @@
+#ifndef __NVKM_BAR_H__
+#define __NVKM_BAR_H__
+#include <core/subdev.h>
+struct nvkm_mem;
+struct nvkm_vma;
+
+struct nvkm_bar {
+ struct nvkm_subdev base;
+
+ int (*alloc)(struct nvkm_bar *, struct nvkm_object *,
+ struct nvkm_mem *, struct nvkm_object **);
+
+ int (*kmap)(struct nvkm_bar *, struct nvkm_mem *, u32 flags,
+ struct nvkm_vma *);
+ int (*umap)(struct nvkm_bar *, struct nvkm_mem *, u32 flags,
+ struct nvkm_vma *);
+ void (*unmap)(struct nvkm_bar *, struct nvkm_vma *);
+ void (*flush)(struct nvkm_bar *);
+
+ /* whether the BAR supports to be ioremapped WC or should be uncached */
+ bool iomap_uncached;
+};
+
+static inline struct nvkm_bar *
+nvkm_bar(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_BAR);
+}
+
+extern struct nvkm_oclass nv50_bar_oclass;
+extern struct nvkm_oclass gf100_bar_oclass;
+extern struct nvkm_oclass gk20a_bar_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h
new file mode 100644
index 000000000000..cef287e0bbf2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_BIOS_H__
+#define __NVKM_BIOS_H__
+#include <core/subdev.h>
+
+struct nvkm_bios {
+ struct nvkm_subdev base;
+ u32 size;
+ u8 *data;
+
+ u32 bmp_offset;
+ u32 bit_offset;
+
+ struct {
+ u8 major;
+ u8 chip;
+ u8 minor;
+ u8 micro;
+ u8 patch;
+ } version;
+};
+
+static inline struct nvkm_bios *
+nvkm_bios(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_VBIOS);
+}
+
+u8 nvbios_checksum(const u8 *data, int size);
+u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
+
+extern struct nvkm_oclass nvkm_bios_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0203.h
index 1f84d3612dd8..cf202c793a1d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0203.h
@@ -1,14 +1,13 @@
#ifndef __NVBIOS_M0203_H__
#define __NVBIOS_M0203_H__
-
struct nvbios_M0203T {
#define M0203T_TYPE_RAMCFG 0x00
u8 type;
u16 pointer;
};
-u32 nvbios_M0203Te(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u32 nvbios_M0203Tp(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+u32 nvbios_M0203Te(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_M0203Tp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_M0203T *);
struct nvbios_M0203E {
@@ -22,10 +21,9 @@ struct nvbios_M0203E {
u8 group;
};
-u32 nvbios_M0203Ee(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u32 nvbios_M0203Ep(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
+u32 nvbios_M0203Ee(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_M0203Ep(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_M0203E *);
-u32 nvbios_M0203Em(struct nouveau_bios *, u8 ramcfg, u8 *ver, u8 *hdr,
+u32 nvbios_M0203Em(struct nvkm_bios *, u8 ramcfg, u8 *ver, u8 *hdr,
struct nvbios_M0203E *);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h
new file mode 100644
index 000000000000..d34608ff241e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0205.h
@@ -0,0 +1,29 @@
+#ifndef __NVBIOS_M0205_H__
+#define __NVBIOS_M0205_H__
+struct nvbios_M0205T {
+ u16 freq;
+};
+
+u32 nvbios_M0205Te(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+u32 nvbios_M0205Tp(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz,
+ struct nvbios_M0205T *);
+
+struct nvbios_M0205E {
+ u8 type;
+};
+
+u32 nvbios_M0205Ee(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_M0205Ep(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_M0205E *);
+
+struct nvbios_M0205S {
+ u8 data;
+};
+
+u32 nvbios_M0205Se(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_M0205Sp(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_M0205S *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h
new file mode 100644
index 000000000000..c7ff8d9526e7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/M0209.h
@@ -0,0 +1,27 @@
+#ifndef __NVBIOS_M0209_H__
+#define __NVBIOS_M0209_H__
+u32 nvbios_M0209Te(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+
+struct nvbios_M0209E {
+ u8 v00_40;
+ u8 bits;
+ u8 modulo;
+ u8 v02_40;
+ u8 v02_07;
+ u8 v03;
+};
+
+u32 nvbios_M0209Ee(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_M0209Ep(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_M0209E *);
+
+struct nvbios_M0209S {
+ u32 data[0x200];
+};
+
+u32 nvbios_M0209Se(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_M0209Sp(struct nvkm_bios *, int ent, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_M0209S *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h
new file mode 100644
index 000000000000..1c1c52eac97d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/P0260.h
@@ -0,0 +1,21 @@
+#ifndef __NVBIOS_P0260_H__
+#define __NVBIOS_P0260_H__
+u32 nvbios_P0260Te(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
+
+struct nvbios_P0260E {
+ u32 data;
+};
+
+u32 nvbios_P0260Ee(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_P0260Ep(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_P0260E *);
+
+struct nvbios_P0260X {
+ u32 data;
+};
+
+u32 nvbios_P0260Xe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_P0260Xp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_P0260X *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bit.h
index 73f060b07981..6711732b7cb1 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bit.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bit.h
@@ -1,6 +1,5 @@
#ifndef __NVBIOS_BIT_H__
#define __NVBIOS_BIT_H__
-
struct bit_entry {
u8 id;
u8 version;
@@ -8,6 +7,5 @@ struct bit_entry {
u16 offset;
};
-int bit_entry(struct nouveau_bios *, u8 id, struct bit_entry *);
-
+int bit_entry(struct nvkm_bios *, u8 id, struct bit_entry *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bmp.h
index 10e4dbca649a..4107aa546a21 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/bmp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/bmp.h
@@ -1,8 +1,7 @@
#ifndef __NVBIOS_BMP_H__
#define __NVBIOS_BMP_H__
-
static inline u16
-bmp_version(struct nouveau_bios *bios)
+bmp_version(struct nvkm_bios *bios)
{
if (bios->bmp_offset) {
return nv_ro08(bios, bios->bmp_offset + 5) << 8 |
@@ -13,7 +12,7 @@ bmp_version(struct nouveau_bios *bios)
}
static inline u16
-bmp_mem_init_table(struct nouveau_bios *bios)
+bmp_mem_init_table(struct nvkm_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nv_ro16(bios, bios->bmp_offset + 24);
@@ -21,7 +20,7 @@ bmp_mem_init_table(struct nouveau_bios *bios)
}
static inline u16
-bmp_sdr_seq_table(struct nouveau_bios *bios)
+bmp_sdr_seq_table(struct nvkm_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nv_ro16(bios, bios->bmp_offset + 26);
@@ -29,11 +28,10 @@ bmp_sdr_seq_table(struct nouveau_bios *bios)
}
static inline u16
-bmp_ddr_seq_table(struct nouveau_bios *bios)
+bmp_ddr_seq_table(struct nvkm_bios *bios)
{
if (bmp_version(bios) >= 0x0300)
return nv_ro16(bios, bios->bmp_offset + 28);
return 0x0000;
}
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h
new file mode 100644
index 000000000000..934b0ae5521d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/boost.h
@@ -0,0 +1,27 @@
+#ifndef __NVBIOS_BOOST_H__
+#define __NVBIOS_BOOST_H__
+u16 nvbios_boostTe(struct nvkm_bios *, u8 *, u8 *, u8 *, u8 *, u8 *, u8 *);
+
+struct nvbios_boostE {
+ u8 pstate;
+ u32 min;
+ u32 max;
+};
+
+u16 nvbios_boostEe(struct nvkm_bios *, int idx, u8 *, u8 *, u8 *, u8 *);
+u16 nvbios_boostEp(struct nvkm_bios *, int idx, u8 *, u8 *, u8 *, u8 *,
+ struct nvbios_boostE *);
+u16 nvbios_boostEm(struct nvkm_bios *, u8, u8 *, u8 *, u8 *, u8 *,
+ struct nvbios_boostE *);
+
+struct nvbios_boostS {
+ u8 domain;
+ u8 percent;
+ u32 min;
+ u32 max;
+};
+
+u16 nvbios_boostSe(struct nvkm_bios *, int, u16, u8 *, u8 *, u8, u8);
+u16 nvbios_boostSp(struct nvkm_bios *, int, u16, u8 *, u8 *, u8, u8,
+ struct nvbios_boostS *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
index f3930c27cb7a..e8e77ee24776 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
@@ -1,6 +1,5 @@
#ifndef __NVBIOS_CONN_H__
#define __NVBIOS_CONN_H__
-
enum dcb_connector_type {
DCB_CONNECTOR_VGA = 0x00,
DCB_CONNECTOR_TV_0 = 0x10,
@@ -25,8 +24,8 @@ enum dcb_connector_type {
struct nvbios_connT {
};
-u32 nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u32 nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+u32 nvbios_connTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_connTp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_connT *info);
struct nvbios_connE {
@@ -39,8 +38,7 @@ struct nvbios_connE {
u8 lcdid;
};
-u32 nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr);
-u32 nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr,
+u32 nvbios_connEe(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *hdr);
+u32 nvbios_connEp(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *hdr,
struct nvbios_connE *info);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h
new file mode 100644
index 000000000000..2f0e0c8e83be
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/cstep.h
@@ -0,0 +1,26 @@
+#ifndef __NVBIOS_CSTEP_H__
+#define __NVBIOS_CSTEP_H__
+u16 nvbios_cstepTe(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
+
+struct nvbios_cstepE {
+ u8 pstate;
+ u8 index;
+};
+
+u16 nvbios_cstepEe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u16 nvbios_cstepEp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_cstepE *);
+u16 nvbios_cstepEm(struct nvkm_bios *, u8 pstate, u8 *ver, u8 *hdr,
+ struct nvbios_cstepE *);
+
+struct nvbios_cstepX {
+ u32 freq;
+ u8 unkn[2];
+ u8 voltage;
+};
+
+u16 nvbios_cstepXe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u16 nvbios_cstepXp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
+ struct nvbios_cstepX *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
index 123270e9813a..4892a65ddd48 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dcb.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
@@ -1,8 +1,5 @@
#ifndef __NVBIOS_DCB_H__
#define __NVBIOS_DCB_H__
-
-struct nouveau_bios;
-
enum dcb_output_type {
DCB_OUTPUT_ANALOG = 0x0,
DCB_OUTPUT_TV = 0x1,
@@ -57,13 +54,12 @@ struct dcb_output {
bool i2c_upper_default;
};
-u16 dcb_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
-u16 dcb_outp(struct nouveau_bios *, u8 idx, u8 *ver, u8 *len);
-u16 dcb_outp_parse(struct nouveau_bios *, u8 idx, u8 *, u8 *,
+u16 dcb_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *ent, u8 *len);
+u16 dcb_outp(struct nvkm_bios *, u8 idx, u8 *ver, u8 *len);
+u16 dcb_outp_parse(struct nvkm_bios *, u8 idx, u8 *, u8 *,
struct dcb_output *);
-u16 dcb_outp_match(struct nouveau_bios *, u16 type, u16 mask, u8 *, u8 *,
+u16 dcb_outp_match(struct nvkm_bios *, u16 type, u16 mask, u8 *, u8 *,
struct dcb_output *);
-int dcb_outp_foreach(struct nouveau_bios *, void *data, int (*exec)
- (struct nouveau_bios *, void *, int index, u16 entry));
-
+int dcb_outp_foreach(struct nvkm_bios *, void *data, int (*exec)
+ (struct nvkm_bios *, void *, int index, u16 entry));
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
new file mode 100644
index 000000000000..db10c11f0595
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
@@ -0,0 +1,39 @@
+#ifndef __NVBIOS_DISP_H__
+#define __NVBIOS_DISP_H__
+u16 nvbios_disp_table(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *sub);
+
+struct nvbios_disp {
+ u16 data;
+};
+
+u16 nvbios_disp_entry(struct nvkm_bios *, u8 idx, u8 *ver, u8 *hdr, u8 *sub);
+u16 nvbios_disp_parse(struct nvkm_bios *, u8 idx, u8 *ver, u8 *hdr, u8 *sub,
+ struct nvbios_disp *);
+
+struct nvbios_outp {
+ u16 type;
+ u16 mask;
+ u16 script[3];
+};
+
+u16 nvbios_outp_entry(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_outp_parse(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
+u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
+
+struct nvbios_ocfg {
+ u16 match;
+ u16 clkcmp[2];
+};
+
+u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h
new file mode 100644
index 000000000000..b4d39df70d4e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dp.h
@@ -0,0 +1,31 @@
+#ifndef __NVBIOS_DP_H__
+#define __NVBIOS_DP_H__
+struct nvbios_dpout {
+ u16 type;
+ u16 mask;
+ u8 flags;
+ u32 script[5];
+ u32 lnkcmp;
+};
+
+u16 nvbios_dpout_parse(struct nvkm_bios *, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_dpout *);
+u16 nvbios_dpout_match(struct nvkm_bios *, u16 type, u16 mask,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_dpout *);
+
+struct nvbios_dpcfg {
+ u8 pc;
+ u8 dc;
+ u8 pe;
+ u8 tx_pu;
+};
+
+u16
+nvbios_dpcfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *);
+u16
+nvbios_dpcfg_match(struct nvkm_bios *, u16 outp, u8 pc, u8 vs, u8 pe,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/extdev.h
index 949fee3af8fb..6d3bedc633b3 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/extdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/extdev.h
@@ -1,8 +1,5 @@
#ifndef __NVBIOS_EXTDEV_H__
#define __NVBIOS_EXTDEV_H__
-
-struct nouveau_bios;
-
enum nvbios_extdev_type {
NVBIOS_EXTDEV_LM89 = 0x02,
NVBIOS_EXTDEV_VT1103M = 0x40,
@@ -20,11 +17,9 @@ struct nvbios_extdev_func {
};
int
-nvbios_extdev_parse(struct nouveau_bios *, int, struct nvbios_extdev_func *);
+nvbios_extdev_parse(struct nvkm_bios *, int, struct nvbios_extdev_func *);
int
-nvbios_extdev_find(struct nouveau_bios *, enum nvbios_extdev_type,
+nvbios_extdev_find(struct nvkm_bios *, enum nvbios_extdev_type,
struct nvbios_extdev_func *);
-
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/fan.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/fan.h
index 119d0874e041..693ea7d9ec43 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/fan.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/fan.h
@@ -1,8 +1,6 @@
#ifndef __NVBIOS_FAN_H__
#define __NVBIOS_FAN_H__
-
#include <subdev/bios/therm.h>
-u16 nvbios_fan_parse(struct nouveau_bios *bios, struct nvbios_therm_fan *fan);
-
+u16 nvbios_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index c7b2e586be0b..33be260ddd38 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -1,6 +1,5 @@
#ifndef __NVBIOS_GPIO_H__
#define __NVBIOS_GPIO_H__
-
enum dcb_gpio_func_name {
DCB_GPIO_PANEL_POWER = 0x01,
DCB_GPIO_TVDAC0 = 0x0c,
@@ -38,11 +37,10 @@ struct dcb_gpio_func {
u8 param;
};
-u16 dcb_gpio_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len);
-u16 dcb_gpio_parse(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len,
+u16 dcb_gpio_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dcb_gpio_entry(struct nvkm_bios *, int idx, int ent, u8 *ver, u8 *len);
+u16 dcb_gpio_parse(struct nvkm_bios *, int idx, int ent, u8 *ver, u8 *len,
struct dcb_gpio_func *);
-u16 dcb_gpio_match(struct nouveau_bios *, int idx, u8 func, u8 line,
+u16 dcb_gpio_match(struct nvkm_bios *, int idx, u8 func, u8 line,
u8 *ver, u8 *len, struct dcb_gpio_func *);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/i2c.h
index c9bb112895af..85c529ecf9b1 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/i2c.h
@@ -1,8 +1,5 @@
#ifndef __NVBIOS_I2C_H__
#define __NVBIOS_I2C_H__
-
-struct nouveau_bios;
-
enum dcb_i2c_type {
/* matches bios type field prior to ccb 4.1 */
DCB_I2C_NV04_BIT = 0x00,
@@ -22,8 +19,7 @@ struct dcb_i2c_entry {
u8 auxch;
};
-u16 dcb_i2c_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 dcb_i2c_entry(struct nouveau_bios *, u8 index, u8 *ver, u8 *len);
-int dcb_i2c_parse(struct nouveau_bios *, u8 index, struct dcb_i2c_entry *);
-
+u16 dcb_i2c_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 dcb_i2c_entry(struct nvkm_bios *, u8 index, u8 *ver, u8 *len);
+int dcb_i2c_parse(struct nvkm_bios *, u8 index, struct dcb_i2c_entry *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/image.h
index 3348b4580843..e15d63b9a5eb 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/image.h
@@ -1,6 +1,5 @@
#ifndef __NVBIOS_IMAGE_H__
#define __NVBIOS_IMAGE_H__
-
struct nvbios_image {
u32 base;
u32 size;
@@ -8,6 +7,5 @@ struct nvbios_image {
bool last;
};
-bool nvbios_image(struct nouveau_bios *, int, struct nvbios_image *);
-
+bool nvbios_image(struct nvkm_bios *, int, struct nvbios_image *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/init.h
index ca2f6bf37f46..578a667eed3b 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/init.h
@@ -1,9 +1,8 @@
#ifndef __NVBIOS_INIT_H__
#define __NVBIOS_INIT_H__
-
struct nvbios_init {
- struct nouveau_subdev *subdev;
- struct nouveau_bios *bios;
+ struct nvkm_subdev *subdev;
+ struct nvkm_bios *bios;
u16 offset;
struct dcb_output *outp;
int crtc;
@@ -17,6 +16,5 @@ struct nvbios_init {
};
int nvbios_exec(struct nvbios_init *);
-int nvbios_init(struct nouveau_subdev *, bool execute);
-
+int nvbios_init(struct nvkm_subdev *, bool execute);
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h
new file mode 100644
index 000000000000..4e31b64c5edf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/mxm.h
@@ -0,0 +1,6 @@
+#ifndef __NVBIOS_MXM_H__
+#define __NVBIOS_MXM_H__
+u16 mxm_table(struct nvkm_bios *, u8 *ver, u8 *hdr);
+u8 mxm_sor_map(struct nvkm_bios *, u8 conn);
+u8 mxm_ddc_map(struct nvkm_bios *, u8 port);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h
new file mode 100644
index 000000000000..64a59549b7ea
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/npde.h
@@ -0,0 +1,10 @@
+#ifndef __NVBIOS_NPDE_H__
+#define __NVBIOS_NPDE_H__
+struct nvbios_npdeT {
+ u32 image_size;
+ bool last;
+};
+
+u32 nvbios_npdeTe(struct nvkm_bios *, u32);
+u32 nvbios_npdeTp(struct nvkm_bios *, u32, struct nvbios_npdeT *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pcir.h
index 3d634a06dca1..e85931541f4f 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pcir.h
@@ -1,6 +1,5 @@
#ifndef __NVBIOS_PCIR_H__
#define __NVBIOS_PCIR_H__
-
struct nvbios_pcirT {
u16 vendor_id;
u16 device_id;
@@ -11,8 +10,7 @@ struct nvbios_pcirT {
bool last;
};
-u32 nvbios_pcirTe(struct nouveau_bios *, u32, u8 *ver, u16 *hdr);
-u32 nvbios_pcirTp(struct nouveau_bios *, u32, u8 *ver, u16 *hdr,
+u32 nvbios_pcirTe(struct nvkm_bios *, u32, u8 *ver, u16 *hdr);
+u32 nvbios_pcirTp(struct nvkm_bios *, u32, u8 *ver, u16 *hdr,
struct nvbios_pcirT *);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
index 16ff06ec2a88..7cc2becabc69 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/perf.h
@@ -1,9 +1,6 @@
#ifndef __NVBIOS_PERF_H__
#define __NVBIOS_PERF_H__
-
-struct nouveau_bios;
-
-u16 nvbios_perf_table(struct nouveau_bios *, u8 *ver, u8 *hdr,
+u16 nvbios_perf_table(struct nvkm_bios *, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
struct nvbios_perfE {
@@ -18,9 +15,9 @@ struct nvbios_perfE {
u32 script;
};
-u16 nvbios_perf_entry(struct nouveau_bios *, int idx,
+u16 nvbios_perf_entry(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 nvbios_perfEp(struct nouveau_bios *, int idx,
+u16 nvbios_perfEp(struct nvkm_bios *, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_perfE *);
struct nvbios_perfS {
@@ -31,17 +28,14 @@ struct nvbios_perfS {
};
};
-u32 nvbios_perfSe(struct nouveau_bios *, u32 data, int idx,
+u32 nvbios_perfSe(struct nvkm_bios *, u32 data, int idx,
u8 *ver, u8 *hdr, u8 cnt, u8 len);
-u32 nvbios_perfSp(struct nouveau_bios *, u32 data, int idx,
+u32 nvbios_perfSp(struct nvkm_bios *, u32 data, int idx,
u8 *ver, u8 *hdr, u8 cnt, u8 len, struct nvbios_perfS *);
struct nvbios_perf_fan {
u32 pwm_divisor;
};
-int
-nvbios_perf_fan_parse(struct nouveau_bios *, struct nvbios_perf_fan *);
-
-
+int nvbios_perf_fan_parse(struct nvkm_bios *, struct nvbios_perf_fan *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pll.h
index b2f3d4d0aa49..5a69978d1e3b 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pll.h
@@ -1,8 +1,7 @@
#ifndef __NVBIOS_PLL_H__
#define __NVBIOS_PLL_H__
-
/*XXX: kill me */
-struct nouveau_pll_vals {
+struct nvkm_pll_vals {
union {
struct {
#ifdef __BIG_ENDIAN
@@ -20,10 +19,8 @@ struct nouveau_pll_vals {
int refclk;
};
-struct nouveau_bios;
-
/* these match types in pll limits table version 0x40,
- * nouveau uses them on all chipsets internally where a
+ * nvkm uses them on all chipsets internally where a
* specific pll needs to be referenced, but the exact
* register isn't known.
*/
@@ -74,6 +71,5 @@ struct nvbios_pll {
} vco1, vco2;
};
-int nvbios_pll_parse(struct nouveau_bios *, u32 type, struct nvbios_pll *);
-
+int nvbios_pll_parse(struct nvkm_bios *, u32 type, struct nvbios_pll *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
index 9de593deaea8..d606875c125a 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
@@ -1,11 +1,10 @@
#ifndef __NVBIOS_PMU_H__
#define __NVBIOS_PMU_H__
-
struct nvbios_pmuT {
};
-u32 nvbios_pmuTe(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u32 nvbios_pmuTp(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+u32 nvbios_pmuTe(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_pmuTp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_pmuT *);
struct nvbios_pmuE {
@@ -13,8 +12,8 @@ struct nvbios_pmuE {
u32 data;
};
-u32 nvbios_pmuEe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
-u32 nvbios_pmuEp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
+u32 nvbios_pmuEe(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_pmuEp(struct nvkm_bios *, int idx, u8 *ver, u8 *hdr,
struct nvbios_pmuE *);
struct nvbios_pmuR {
@@ -32,6 +31,5 @@ struct nvbios_pmuR {
u32 args_addr_pmu;
};
-bool nvbios_pmuRm(struct nouveau_bios *, u8 type, struct nvbios_pmuR *);
-
+bool nvbios_pmuRm(struct nvkm_bios *, u8 type, struct nvbios_pmuR *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 4a0e0ceb41ba..420426793880 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -1,8 +1,5 @@
#ifndef __NVBIOS_RAMCFG_H__
#define __NVBIOS_RAMCFG_H__
-
-struct nouveau_bios;
-
struct nvbios_ramcfg {
unsigned rammap_ver;
unsigned rammap_hdr;
@@ -139,7 +136,6 @@ struct nvbios_ramcfg {
};
};
-u8 nvbios_ramcfg_count(struct nouveau_bios *);
-u8 nvbios_ramcfg_index(struct nouveau_subdev *);
-
+u8 nvbios_ramcfg_count(struct nvkm_bios *);
+u8 nvbios_ramcfg_index(struct nvkm_subdev *);
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
new file mode 100644
index 000000000000..609a905ec780
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/rammap.h
@@ -0,0 +1,21 @@
+#ifndef __NVBIOS_RAMMAP_H__
+#define __NVBIOS_RAMMAP_H__
+#include <subdev/bios/ramcfg.h>
+
+u32 nvbios_rammapTe(struct nvkm_bios *, u8 *ver, u8 *hdr,
+ u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+
+u32 nvbios_rammapEe(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u32 nvbios_rammapEp(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
+u32 nvbios_rammapEm(struct nvkm_bios *, u16 mhz,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
+
+u32 nvbios_rammapSe(struct nvkm_bios *, u32 data,
+ u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
+ u8 *ver, u8 *hdr);
+u32 nvbios_rammapSp(struct nvkm_bios *, u32 data,
+ u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
+ u8 *ver, u8 *hdr, struct nvbios_ramcfg *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/therm.h
index 295d093f3b30..dd3ba960e75d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/therm.h
@@ -1,8 +1,5 @@
#ifndef __NVBIOS_THERM_H__
#define __NVBIOS_THERM_H__
-
-struct nouveau_bios;
-
struct nvbios_therm_threshold {
u8 temp;
u8 hysteresis;
@@ -30,8 +27,8 @@ enum nvbios_therm_fan_type {
};
/* no vbios have more than 6 */
-#define NOUVEAU_TEMP_FAN_TRIP_MAX 10
-struct nouveau_therm_trip_point {
+#define NVKM_TEMP_FAN_TRIP_MAX 10
+struct nvbios_therm_trip_point {
int fan_duty;
int temp;
int hysteresis;
@@ -55,7 +52,7 @@ struct nvbios_therm_fan {
u16 slow_down_period;
enum nvbios_therm_fan_mode fan_mode;
- struct nouveau_therm_trip_point trip[NOUVEAU_TEMP_FAN_TRIP_MAX];
+ struct nvbios_therm_trip_point trip[NVKM_TEMP_FAN_TRIP_MAX];
u8 nr_fan_trip;
u8 linear_min_temp;
u8 linear_max_temp;
@@ -67,11 +64,9 @@ enum nvbios_therm_domain {
};
int
-nvbios_therm_sensor_parse(struct nouveau_bios *, enum nvbios_therm_domain,
+nvbios_therm_sensor_parse(struct nvkm_bios *, enum nvbios_therm_domain,
struct nvbios_therm_sensor *);
int
-nvbios_therm_fan_parse(struct nouveau_bios *, struct nvbios_therm_fan *);
-
-
+nvbios_therm_fan_parse(struct nvkm_bios *, struct nvbios_therm_fan *);
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h
new file mode 100644
index 000000000000..339a826aa176
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/timing.h
@@ -0,0 +1,11 @@
+#ifndef __NVBIOS_TIMING_H__
+#define __NVBIOS_TIMING_H__
+#include <subdev/bios/ramcfg.h>
+
+u16 nvbios_timingTe(struct nvkm_bios *,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz);
+u16 nvbios_timingEe(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_timingEp(struct nvkm_bios *, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h
new file mode 100644
index 000000000000..6633c6db9281
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/vmap.h
@@ -0,0 +1,21 @@
+#ifndef __NVBIOS_VMAP_H__
+#define __NVBIOS_VMAP_H__
+struct nvbios_vmap {
+};
+
+u16 nvbios_vmap_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_vmap_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_vmap *);
+
+struct nvbios_vmap_entry {
+ u8 unk0;
+ u8 link;
+ u32 min;
+ u32 max;
+ s32 arg[6];
+};
+
+u16 nvbios_vmap_entry(struct nvkm_bios *, int idx, u8 *ver, u8 *len);
+u16 nvbios_vmap_entry_parse(struct nvkm_bios *, int idx, u8 *ver, u8 *len,
+ struct nvbios_vmap_entry *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
new file mode 100644
index 000000000000..eb2de4b85bbd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
@@ -0,0 +1,23 @@
+#ifndef __NVBIOS_VOLT_H__
+#define __NVBIOS_VOLT_H__
+struct nvbios_volt {
+ u8 vidmask;
+ u32 min;
+ u32 max;
+ u32 base;
+ s16 step;
+};
+
+u16 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+u16 nvbios_volt_parse(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+ struct nvbios_volt *);
+
+struct nvbios_volt_entry {
+ u32 voltage;
+ u8 vid;
+};
+
+u16 nvbios_volt_entry(struct nvkm_bios *, int idx, u8 *ver, u8 *len);
+u16 nvbios_volt_entry_parse(struct nvkm_bios *, int idx, u8 *ver, u8 *len,
+ struct nvbios_volt_entry *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/xpio.h
index 360baab52e4c..0c0fe234ff12 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/xpio.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/xpio.h
@@ -11,9 +11,8 @@ struct nvbios_xpio {
u8 flags;
};
-u16 dcb_xpio_table(struct nouveau_bios *, u8 idx,
+u16 dcb_xpio_table(struct nvkm_bios *, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
-u16 dcb_xpio_parse(struct nouveau_bios *, u8 idx,
+u16 dcb_xpio_parse(struct nvkm_bios *, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_xpio *);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
new file mode 100644
index 000000000000..fba83c04849e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
@@ -0,0 +1,50 @@
+#ifndef __NVKM_BUS_H__
+#define __NVKM_BUS_H__
+#include <core/subdev.h>
+
+struct nvkm_bus_intr {
+ u32 stat;
+ u32 unit;
+};
+
+struct nvkm_bus {
+ struct nvkm_subdev base;
+ int (*hwsq_exec)(struct nvkm_bus *, u32 *, u32);
+ u32 hwsq_size;
+};
+
+static inline struct nvkm_bus *
+nvkm_bus(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_BUS);
+}
+
+#define nvkm_bus_create(p, e, o, d) \
+ nvkm_subdev_create_((p), (e), (o), 0, "PBUS", "master", \
+ sizeof(**d), (void **)d)
+#define nvkm_bus_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_bus_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_bus_fini(p, s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+#define _nvkm_bus_dtor _nvkm_subdev_dtor
+#define _nvkm_bus_init _nvkm_subdev_init
+#define _nvkm_bus_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass *nv04_bus_oclass;
+extern struct nvkm_oclass *nv31_bus_oclass;
+extern struct nvkm_oclass *nv50_bus_oclass;
+extern struct nvkm_oclass *g94_bus_oclass;
+extern struct nvkm_oclass *gf100_bus_oclass;
+
+/* interface to sequencer */
+struct nvkm_hwsq;
+int nvkm_hwsq_init(struct nvkm_bus *, struct nvkm_hwsq **);
+int nvkm_hwsq_fini(struct nvkm_hwsq **, bool exec);
+void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data);
+void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data);
+void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data);
+void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h
new file mode 100644
index 000000000000..f5d303850d8c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/clk.h
@@ -0,0 +1,161 @@
+#ifndef __NVKM_CLK_H__
+#define __NVKM_CLK_H__
+#include <core/subdev.h>
+#include <core/notify.h>
+struct nvbios_pll;
+struct nvkm_pll_vals;
+
+enum nv_clk_src {
+ nv_clk_src_crystal,
+ nv_clk_src_href,
+
+ nv_clk_src_hclk,
+ nv_clk_src_hclkm3,
+ nv_clk_src_hclkm3d2,
+ nv_clk_src_hclkm2d3, /* NVAA */
+ nv_clk_src_hclkm4, /* NVAA */
+ nv_clk_src_cclk, /* NVAA */
+
+ nv_clk_src_host,
+
+ nv_clk_src_sppll0,
+ nv_clk_src_sppll1,
+
+ nv_clk_src_mpllsrcref,
+ nv_clk_src_mpllsrc,
+ nv_clk_src_mpll,
+ nv_clk_src_mdiv,
+
+ nv_clk_src_core,
+ nv_clk_src_core_intm,
+ nv_clk_src_shader,
+
+ nv_clk_src_mem,
+
+ nv_clk_src_gpc,
+ nv_clk_src_rop,
+ nv_clk_src_hubk01,
+ nv_clk_src_hubk06,
+ nv_clk_src_hubk07,
+ nv_clk_src_copy,
+ nv_clk_src_daemon,
+ nv_clk_src_disp,
+ nv_clk_src_vdec,
+
+ nv_clk_src_dom6,
+
+ nv_clk_src_max,
+};
+
+struct nvkm_cstate {
+ struct list_head head;
+ u8 voltage;
+ u32 domain[nv_clk_src_max];
+};
+
+struct nvkm_pstate {
+ struct list_head head;
+ struct list_head list; /* c-states */
+ struct nvkm_cstate base;
+ u8 pstate;
+ u8 fanspeed;
+};
+
+struct nvkm_domain {
+ enum nv_clk_src name;
+ u8 bios; /* 0xff for none */
+#define NVKM_CLK_DOM_FLAG_CORE 0x01
+ u8 flags;
+ const char *mname;
+ int mdiv;
+};
+
+struct nvkm_clk {
+ struct nvkm_subdev base;
+
+ struct nvkm_domain *domains;
+ struct nvkm_pstate bstate;
+
+ struct list_head states;
+ int state_nr;
+
+ struct work_struct work;
+ wait_queue_head_t wait;
+ atomic_t waiting;
+
+ struct nvkm_notify pwrsrc_ntfy;
+ int pwrsrc;
+ int pstate; /* current */
+ int ustate_ac; /* user-requested (-1 disabled, -2 perfmon) */
+ int ustate_dc; /* user-requested (-1 disabled, -2 perfmon) */
+ int astate; /* perfmon adjustment (base) */
+ int tstate; /* thermal adjustment (max-) */
+ int dstate; /* display adjustment (min+) */
+
+ bool allow_reclock;
+
+ int (*read)(struct nvkm_clk *, enum nv_clk_src);
+ int (*calc)(struct nvkm_clk *, struct nvkm_cstate *);
+ int (*prog)(struct nvkm_clk *);
+ void (*tidy)(struct nvkm_clk *);
+
+ /*XXX: die, these are here *only* to support the completely
+ * bat-shit insane what-was-nvkm_hw.c code
+ */
+ int (*pll_calc)(struct nvkm_clk *, struct nvbios_pll *, int clk,
+ struct nvkm_pll_vals *pv);
+ int (*pll_prog)(struct nvkm_clk *, u32 reg1, struct nvkm_pll_vals *pv);
+};
+
+static inline struct nvkm_clk *
+nvkm_clk(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_CLK);
+}
+
+#define nvkm_clk_create(p,e,o,i,r,s,n,d) \
+ nvkm_clk_create_((p), (e), (o), (i), (r), (s), (n), sizeof(**d), \
+ (void **)d)
+#define nvkm_clk_destroy(p) ({ \
+ struct nvkm_clk *clk = (p); \
+ _nvkm_clk_dtor(nv_object(clk)); \
+})
+#define nvkm_clk_init(p) ({ \
+ struct nvkm_clk *clk = (p); \
+ _nvkm_clk_init(nv_object(clk)); \
+})
+#define nvkm_clk_fini(p,s) ({ \
+ struct nvkm_clk *clk = (p); \
+ _nvkm_clk_fini(nv_object(clk), (s)); \
+})
+
+int nvkm_clk_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *,
+ struct nvkm_domain *, struct nvkm_pstate *,
+ int, bool, int, void **);
+void _nvkm_clk_dtor(struct nvkm_object *);
+int _nvkm_clk_init(struct nvkm_object *);
+int _nvkm_clk_fini(struct nvkm_object *, bool);
+
+extern struct nvkm_oclass nv04_clk_oclass;
+extern struct nvkm_oclass nv40_clk_oclass;
+extern struct nvkm_oclass *nv50_clk_oclass;
+extern struct nvkm_oclass *g84_clk_oclass;
+extern struct nvkm_oclass *mcp77_clk_oclass;
+extern struct nvkm_oclass gt215_clk_oclass;
+extern struct nvkm_oclass gf100_clk_oclass;
+extern struct nvkm_oclass gk104_clk_oclass;
+extern struct nvkm_oclass gk20a_clk_oclass;
+
+int nv04_clk_pll_set(struct nvkm_clk *, u32 type, u32 freq);
+int nv04_clk_pll_calc(struct nvkm_clk *, struct nvbios_pll *, int clk,
+ struct nvkm_pll_vals *);
+int nv04_clk_pll_prog(struct nvkm_clk *, u32 reg1, struct nvkm_pll_vals *);
+int gt215_clk_pll_calc(struct nvkm_clk *, struct nvbios_pll *,
+ int clk, struct nvkm_pll_vals *);
+
+int nvkm_clk_ustate(struct nvkm_clk *, int req, int pwr);
+int nvkm_clk_astate(struct nvkm_clk *, int req, int rel, bool wait);
+int nvkm_clk_dstate(struct nvkm_clk *, int req, int rel);
+int nvkm_clk_tstate(struct nvkm_clk *, int req, int rel);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h
new file mode 100644
index 000000000000..d1bbe0d62b35
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_DEVINIT_H__
+#define __NVKM_DEVINIT_H__
+#include <core/subdev.h>
+
+struct nvkm_devinit {
+ struct nvkm_subdev base;
+ bool post;
+ void (*meminit)(struct nvkm_devinit *);
+ int (*pll_set)(struct nvkm_devinit *, u32 type, u32 freq);
+ u32 (*mmio)(struct nvkm_devinit *, u32 addr);
+};
+
+static inline struct nvkm_devinit *
+nvkm_devinit(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_DEVINIT);
+}
+
+extern struct nvkm_oclass *nv04_devinit_oclass;
+extern struct nvkm_oclass *nv05_devinit_oclass;
+extern struct nvkm_oclass *nv10_devinit_oclass;
+extern struct nvkm_oclass *nv1a_devinit_oclass;
+extern struct nvkm_oclass *nv20_devinit_oclass;
+extern struct nvkm_oclass *nv50_devinit_oclass;
+extern struct nvkm_oclass *g84_devinit_oclass;
+extern struct nvkm_oclass *g98_devinit_oclass;
+extern struct nvkm_oclass *gt215_devinit_oclass;
+extern struct nvkm_oclass *mcp89_devinit_oclass;
+extern struct nvkm_oclass *gf100_devinit_oclass;
+extern struct nvkm_oclass *gm107_devinit_oclass;
+extern struct nvkm_oclass *gm204_devinit_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
new file mode 100644
index 000000000000..16da56cf43b0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
@@ -0,0 +1,154 @@
+#ifndef __NVKM_FB_H__
+#define __NVKM_FB_H__
+#include <core/subdev.h>
+
+#include <subdev/mmu.h>
+
+/* memory type/access flags, do not match hardware values */
+#define NV_MEM_ACCESS_RO 1
+#define NV_MEM_ACCESS_WO 2
+#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
+#define NV_MEM_ACCESS_SYS 4
+#define NV_MEM_ACCESS_VM 8
+#define NV_MEM_ACCESS_NOSNOOP 16
+
+#define NV_MEM_TARGET_VRAM 0
+#define NV_MEM_TARGET_PCI 1
+#define NV_MEM_TARGET_PCI_NOSNOOP 2
+#define NV_MEM_TARGET_VM 3
+#define NV_MEM_TARGET_GART 4
+
+#define NV_MEM_TYPE_VM 0x7f
+#define NV_MEM_COMP_VM 0x03
+
+struct nvkm_mem {
+ struct drm_device *dev;
+
+ struct nvkm_vma bar_vma;
+ struct nvkm_vma vma[2];
+ u8 page_shift;
+
+ struct nvkm_mm_node *tag;
+ struct list_head regions;
+ dma_addr_t *pages;
+ u32 memtype;
+ u64 offset;
+ u64 size;
+ struct sg_table *sg;
+};
+
+struct nvkm_fb_tile {
+ struct nvkm_mm_node *tag;
+ u32 addr;
+ u32 limit;
+ u32 pitch;
+ u32 zcomp;
+};
+
+struct nvkm_fb {
+ struct nvkm_subdev base;
+
+ bool (*memtype_valid)(struct nvkm_fb *, u32 memtype);
+
+ struct nvkm_ram *ram;
+
+ struct nvkm_mm vram;
+ struct nvkm_mm tags;
+
+ struct {
+ struct nvkm_fb_tile region[16];
+ int regions;
+ void (*init)(struct nvkm_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nvkm_fb_tile *);
+ void (*comp)(struct nvkm_fb *, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *);
+ void (*fini)(struct nvkm_fb *, int i, struct nvkm_fb_tile *);
+ void (*prog)(struct nvkm_fb *, int i, struct nvkm_fb_tile *);
+ } tile;
+};
+
+static inline struct nvkm_fb *
+nvkm_fb(void *obj)
+{
+ /* fbram uses this before device subdev pointer is valid */
+ if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
+ nv_subidx(obj) == NVDEV_SUBDEV_FB)
+ return obj;
+
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_FB);
+}
+
+extern struct nvkm_oclass *nv04_fb_oclass;
+extern struct nvkm_oclass *nv10_fb_oclass;
+extern struct nvkm_oclass *nv1a_fb_oclass;
+extern struct nvkm_oclass *nv20_fb_oclass;
+extern struct nvkm_oclass *nv25_fb_oclass;
+extern struct nvkm_oclass *nv30_fb_oclass;
+extern struct nvkm_oclass *nv35_fb_oclass;
+extern struct nvkm_oclass *nv36_fb_oclass;
+extern struct nvkm_oclass *nv40_fb_oclass;
+extern struct nvkm_oclass *nv41_fb_oclass;
+extern struct nvkm_oclass *nv44_fb_oclass;
+extern struct nvkm_oclass *nv46_fb_oclass;
+extern struct nvkm_oclass *nv47_fb_oclass;
+extern struct nvkm_oclass *nv49_fb_oclass;
+extern struct nvkm_oclass *nv4e_fb_oclass;
+extern struct nvkm_oclass *nv50_fb_oclass;
+extern struct nvkm_oclass *g84_fb_oclass;
+extern struct nvkm_oclass *gt215_fb_oclass;
+extern struct nvkm_oclass *mcp77_fb_oclass;
+extern struct nvkm_oclass *mcp89_fb_oclass;
+extern struct nvkm_oclass *gf100_fb_oclass;
+extern struct nvkm_oclass *gk104_fb_oclass;
+extern struct nvkm_oclass *gk20a_fb_oclass;
+extern struct nvkm_oclass *gm107_fb_oclass;
+
+#include <subdev/bios.h>
+#include <subdev/bios/ramcfg.h>
+
+struct nvkm_ram_data {
+ struct list_head head;
+ struct nvbios_ramcfg bios;
+ u32 freq;
+};
+
+struct nvkm_ram {
+ struct nvkm_object base;
+ enum {
+ NV_MEM_TYPE_UNKNOWN = 0,
+ NV_MEM_TYPE_STOLEN,
+ NV_MEM_TYPE_SGRAM,
+ NV_MEM_TYPE_SDRAM,
+ NV_MEM_TYPE_DDR1,
+ NV_MEM_TYPE_DDR2,
+ NV_MEM_TYPE_DDR3,
+ NV_MEM_TYPE_GDDR2,
+ NV_MEM_TYPE_GDDR3,
+ NV_MEM_TYPE_GDDR4,
+ NV_MEM_TYPE_GDDR5
+ } type;
+ u64 stolen;
+ u64 size;
+ u32 tags;
+
+ int ranks;
+ int parts;
+ int part_mask;
+
+ int (*get)(struct nvkm_fb *, u64 size, u32 align, u32 size_nc,
+ u32 type, struct nvkm_mem **);
+ void (*put)(struct nvkm_fb *, struct nvkm_mem **);
+
+ int (*calc)(struct nvkm_fb *, u32 freq);
+ int (*prog)(struct nvkm_fb *);
+ void (*tidy)(struct nvkm_fb *);
+ u32 freq;
+ u32 mr[16];
+ u32 mr1_nuts;
+
+ struct nvkm_ram_data *next;
+ struct nvkm_ram_data former;
+ struct nvkm_ram_data xition;
+ struct nvkm_ram_data target;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h
new file mode 100644
index 000000000000..a1384786adc9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fuse.h
@@ -0,0 +1,28 @@
+#ifndef __NVKM_FUSE_H__
+#define __NVKM_FUSE_H__
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nvkm_fuse {
+ struct nvkm_subdev base;
+};
+
+static inline struct nvkm_fuse *
+nvkm_fuse(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_FUSE);
+}
+
+#define nvkm_fuse_create(p, e, o, d) \
+ nvkm_fuse_create_((p), (e), (o), sizeof(**d), (void **)d)
+
+int nvkm_fuse_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_fuse_dtor(struct nvkm_object *);
+int _nvkm_fuse_init(struct nvkm_object *);
+#define _nvkm_fuse_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv50_fuse_oclass;
+extern struct nvkm_oclass gf100_fuse_oclass;
+extern struct nvkm_oclass gm107_fuse_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h
new file mode 100644
index 000000000000..ca5099a81b5a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gpio.h
@@ -0,0 +1,44 @@
+#ifndef __NVKM_GPIO_H__
+#define __NVKM_GPIO_H__
+#include <core/subdev.h>
+#include <core/event.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/gpio.h>
+
+struct nvkm_gpio_ntfy_req {
+#define NVKM_GPIO_HI 0x01
+#define NVKM_GPIO_LO 0x02
+#define NVKM_GPIO_TOGGLED 0x03
+ u8 mask;
+ u8 line;
+};
+
+struct nvkm_gpio_ntfy_rep {
+ u8 mask;
+};
+
+struct nvkm_gpio {
+ struct nvkm_subdev base;
+
+ struct nvkm_event event;
+
+ void (*reset)(struct nvkm_gpio *, u8 func);
+ int (*find)(struct nvkm_gpio *, int idx, u8 tag, u8 line,
+ struct dcb_gpio_func *);
+ int (*set)(struct nvkm_gpio *, int idx, u8 tag, u8 line, int state);
+ int (*get)(struct nvkm_gpio *, int idx, u8 tag, u8 line);
+};
+
+static inline struct nvkm_gpio *
+nvkm_gpio(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_GPIO);
+}
+
+extern struct nvkm_oclass *nv10_gpio_oclass;
+extern struct nvkm_oclass *nv50_gpio_oclass;
+extern struct nvkm_oclass *g94_gpio_oclass;
+extern struct nvkm_oclass *gf110_gpio_oclass;
+extern struct nvkm_oclass *gk104_gpio_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
new file mode 100644
index 000000000000..a2e33730f05e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
@@ -0,0 +1,135 @@
+#ifndef __NVKM_I2C_H__
+#define __NVKM_I2C_H__
+#include <core/subdev.h>
+#include <core/event.h>
+
+#include <subdev/bios.h>
+#include <subdev/bios/i2c.h>
+
+#define NV_I2C_PORT(n) (0x00 + (n))
+#define NV_I2C_AUX(n) (0x10 + (n))
+#define NV_I2C_EXT(n) (0x20 + (n))
+#define NV_I2C_DEFAULT(n) (0x80 + (n))
+
+#define NV_I2C_TYPE_DCBI2C(n) (0x0000 | (n))
+#define NV_I2C_TYPE_EXTDDC(e) (0x0005 | (e) << 8)
+#define NV_I2C_TYPE_EXTAUX(e) (0x0006 | (e) << 8)
+
+struct nvkm_i2c_ntfy_req {
+#define NVKM_I2C_PLUG 0x01
+#define NVKM_I2C_UNPLUG 0x02
+#define NVKM_I2C_IRQ 0x04
+#define NVKM_I2C_DONE 0x08
+#define NVKM_I2C_ANY 0x0f
+ u8 mask;
+ u8 port;
+};
+
+struct nvkm_i2c_ntfy_rep {
+ u8 mask;
+};
+
+struct nvkm_i2c_port {
+ struct nvkm_object base;
+ struct i2c_adapter adapter;
+ struct mutex mutex;
+
+ struct list_head head;
+ u8 index;
+ int aux;
+
+ const struct nvkm_i2c_func *func;
+};
+
+struct nvkm_i2c_func {
+ void (*drive_scl)(struct nvkm_i2c_port *, int);
+ void (*drive_sda)(struct nvkm_i2c_port *, int);
+ int (*sense_scl)(struct nvkm_i2c_port *);
+ int (*sense_sda)(struct nvkm_i2c_port *);
+
+ int (*aux)(struct nvkm_i2c_port *, bool, u8, u32, u8 *, u8);
+ int (*pattern)(struct nvkm_i2c_port *, int pattern);
+ int (*lnk_ctl)(struct nvkm_i2c_port *, int nr, int bw, bool enh);
+ int (*drv_ctl)(struct nvkm_i2c_port *, int lane, int sw, int pe);
+};
+
+struct nvkm_i2c_board_info {
+ struct i2c_board_info dev;
+ u8 udelay; /* set to 0 to use the standard delay */
+};
+
+struct nvkm_i2c {
+ struct nvkm_subdev base;
+ struct nvkm_event event;
+
+ struct nvkm_i2c_port *(*find)(struct nvkm_i2c *, u8 index);
+ struct nvkm_i2c_port *(*find_type)(struct nvkm_i2c *, u16 type);
+ int (*acquire_pad)(struct nvkm_i2c_port *, unsigned long timeout);
+ void (*release_pad)(struct nvkm_i2c_port *);
+ int (*acquire)(struct nvkm_i2c_port *, unsigned long timeout);
+ void (*release)(struct nvkm_i2c_port *);
+ int (*identify)(struct nvkm_i2c *, int index,
+ const char *what, struct nvkm_i2c_board_info *,
+ bool (*match)(struct nvkm_i2c_port *,
+ struct i2c_board_info *, void *),
+ void *);
+
+ wait_queue_head_t wait;
+ struct list_head ports;
+};
+
+static inline struct nvkm_i2c *
+nvkm_i2c(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_I2C);
+}
+
+extern struct nvkm_oclass *nv04_i2c_oclass;
+extern struct nvkm_oclass *nv4e_i2c_oclass;
+extern struct nvkm_oclass *nv50_i2c_oclass;
+extern struct nvkm_oclass *g94_i2c_oclass;
+extern struct nvkm_oclass *gf110_i2c_oclass;
+extern struct nvkm_oclass *gf117_i2c_oclass;
+extern struct nvkm_oclass *gk104_i2c_oclass;
+extern struct nvkm_oclass *gm204_i2c_oclass;
+
+static inline int
+nv_rdi2cr(struct nvkm_i2c_port *port, u8 addr, u8 reg)
+{
+ u8 val;
+ struct i2c_msg msgs[] = {
+ { .addr = addr, .flags = 0, .len = 1, .buf = &reg },
+ { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
+ };
+
+ int ret = i2c_transfer(&port->adapter, msgs, 2);
+ if (ret != 2)
+ return -EIO;
+
+ return val;
+}
+
+static inline int
+nv_wri2cr(struct nvkm_i2c_port *port, u8 addr, u8 reg, u8 val)
+{
+ u8 buf[2] = { reg, val };
+ struct i2c_msg msgs[] = {
+ { .addr = addr, .flags = 0, .len = 2, .buf = buf },
+ };
+
+ int ret = i2c_transfer(&port->adapter, msgs, 1);
+ if (ret != 1)
+ return -EIO;
+
+ return 0;
+}
+
+static inline bool
+nv_probe_i2c(struct nvkm_i2c_port *port, u8 addr)
+{
+ return nv_rdi2cr(port, addr, 0) >= 0;
+}
+
+int nv_rdaux(struct nvkm_i2c_port *, u32 addr, u8 *data, u8 size);
+int nv_wraux(struct nvkm_i2c_port *, u32 addr, u8 *data, u8 size);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
new file mode 100644
index 000000000000..2150d8af0040
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
@@ -0,0 +1,32 @@
+#ifndef __NVKM_IBUS_H__
+#define __NVKM_IBUS_H__
+#include <core/subdev.h>
+
+struct nvkm_ibus {
+ struct nvkm_subdev base;
+};
+
+static inline struct nvkm_ibus *
+nvkm_ibus(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_IBUS);
+}
+
+#define nvkm_ibus_create(p,e,o,d) \
+ nvkm_subdev_create_((p), (e), (o), 0, "PIBUS", "ibus", \
+ sizeof(**d), (void **)d)
+#define nvkm_ibus_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_ibus_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_ibus_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+#define _nvkm_ibus_dtor _nvkm_subdev_dtor
+#define _nvkm_ibus_init _nvkm_subdev_init
+#define _nvkm_ibus_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass gf100_ibus_oclass;
+extern struct nvkm_oclass gk104_ibus_oclass;
+extern struct nvkm_oclass gk20a_ibus_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
new file mode 100644
index 000000000000..d104c1aac807
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
@@ -0,0 +1,48 @@
+#ifndef __NVKM_INSTMEM_H__
+#define __NVKM_INSTMEM_H__
+#include <core/subdev.h>
+
+struct nvkm_instobj {
+ struct nvkm_object base;
+ struct list_head head;
+ u32 *suspend;
+ u64 addr;
+ u32 size;
+};
+
+static inline struct nvkm_instobj *
+nv_memobj(void *obj)
+{
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!nv_iclass(obj, NV_MEMOBJ_CLASS)))
+ nv_assert("BAD CAST -> NvMemObj, %08x", nv_hclass(obj));
+#endif
+ return obj;
+}
+
+struct nvkm_instmem {
+ struct nvkm_subdev base;
+ struct list_head list;
+
+ u32 reserved;
+ int (*alloc)(struct nvkm_instmem *, struct nvkm_object *,
+ u32 size, u32 align, struct nvkm_object **);
+};
+
+static inline struct nvkm_instmem *
+nvkm_instmem(void *obj)
+{
+ /* nv04/nv40 impls need to create objects in their constructor,
+ * which is before the subdev pointer is valid
+ */
+ if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
+ nv_subidx(obj) == NVDEV_SUBDEV_INSTMEM)
+ return obj;
+
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_INSTMEM);
+}
+
+extern struct nvkm_oclass *nv04_instmem_oclass;
+extern struct nvkm_oclass *nv40_instmem_oclass;
+extern struct nvkm_oclass *nv50_instmem_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
new file mode 100644
index 000000000000..cd5d29fc0565
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
@@ -0,0 +1,31 @@
+#ifndef __NVKM_LTC_H__
+#define __NVKM_LTC_H__
+#include <core/subdev.h>
+struct nvkm_mm_node;
+
+#define NVKM_LTC_MAX_ZBC_CNT 16
+
+struct nvkm_ltc {
+ struct nvkm_subdev base;
+
+ int (*tags_alloc)(struct nvkm_ltc *, u32 count,
+ struct nvkm_mm_node **);
+ void (*tags_free)(struct nvkm_ltc *, struct nvkm_mm_node **);
+ void (*tags_clear)(struct nvkm_ltc *, u32 first, u32 count);
+
+ int zbc_min;
+ int zbc_max;
+ int (*zbc_color_get)(struct nvkm_ltc *, int index, const u32[4]);
+ int (*zbc_depth_get)(struct nvkm_ltc *, int index, const u32);
+};
+
+static inline struct nvkm_ltc *
+nvkm_ltc(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_LTC);
+}
+
+extern struct nvkm_oclass *gf100_ltc_oclass;
+extern struct nvkm_oclass *gk104_ltc_oclass;
+extern struct nvkm_oclass *gm107_ltc_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
new file mode 100644
index 000000000000..055bea7702a1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
@@ -0,0 +1,28 @@
+#ifndef __NVKM_MC_H__
+#define __NVKM_MC_H__
+#include <core/subdev.h>
+
+struct nvkm_mc {
+ struct nvkm_subdev base;
+ bool use_msi;
+ unsigned int irq;
+ void (*unk260)(struct nvkm_mc *, u32);
+};
+
+static inline struct nvkm_mc *
+nvkm_mc(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_MC);
+}
+
+extern struct nvkm_oclass *nv04_mc_oclass;
+extern struct nvkm_oclass *nv40_mc_oclass;
+extern struct nvkm_oclass *nv44_mc_oclass;
+extern struct nvkm_oclass *nv4c_mc_oclass;
+extern struct nvkm_oclass *nv50_mc_oclass;
+extern struct nvkm_oclass *g94_mc_oclass;
+extern struct nvkm_oclass *g98_mc_oclass;
+extern struct nvkm_oclass *gf100_mc_oclass;
+extern struct nvkm_oclass *gf106_mc_oclass;
+extern struct nvkm_oclass *gk20a_mc_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
new file mode 100644
index 000000000000..3a5368776c31
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
@@ -0,0 +1,104 @@
+#ifndef __NVKM_MMU_H__
+#define __NVKM_MMU_H__
+#include <core/subdev.h>
+#include <core/mm.h>
+struct nvkm_device;
+struct nvkm_mem;
+
+struct nvkm_vm_pgt {
+ struct nvkm_gpuobj *obj[2];
+ u32 refcount[2];
+};
+
+struct nvkm_vm_pgd {
+ struct list_head head;
+ struct nvkm_gpuobj *obj;
+};
+
+struct nvkm_vma {
+ struct list_head head;
+ int refcount;
+ struct nvkm_vm *vm;
+ struct nvkm_mm_node *node;
+ u64 offset;
+ u32 access;
+};
+
+struct nvkm_vm {
+ struct nvkm_mmu *mmu;
+ struct nvkm_mm mm;
+ struct kref refcount;
+
+ struct list_head pgd_list;
+ atomic_t engref[NVDEV_SUBDEV_NR];
+
+ struct nvkm_vm_pgt *pgt;
+ u32 fpde;
+ u32 lpde;
+};
+
+struct nvkm_mmu {
+ struct nvkm_subdev base;
+
+ u64 limit;
+ u8 dma_bits;
+ u32 pgt_bits;
+ u8 spg_shift;
+ u8 lpg_shift;
+
+ int (*create)(struct nvkm_mmu *, u64 offset, u64 length,
+ u64 mm_offset, struct nvkm_vm **);
+
+ void (*map_pgt)(struct nvkm_gpuobj *pgd, u32 pde,
+ struct nvkm_gpuobj *pgt[2]);
+ void (*map)(struct nvkm_vma *, struct nvkm_gpuobj *,
+ struct nvkm_mem *, u32 pte, u32 cnt,
+ u64 phys, u64 delta);
+ void (*map_sg)(struct nvkm_vma *, struct nvkm_gpuobj *,
+ struct nvkm_mem *, u32 pte, u32 cnt, dma_addr_t *);
+ void (*unmap)(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt);
+ void (*flush)(struct nvkm_vm *);
+};
+
+static inline struct nvkm_mmu *
+nvkm_mmu(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_MMU);
+}
+
+#define nvkm_mmu_create(p,e,o,i,f,d) \
+ nvkm_subdev_create((p), (e), (o), 0, (i), (f), (d))
+#define nvkm_mmu_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_mmu_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_mmu_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+#define _nvkm_mmu_dtor _nvkm_subdev_dtor
+#define _nvkm_mmu_init _nvkm_subdev_init
+#define _nvkm_mmu_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv04_mmu_oclass;
+extern struct nvkm_oclass nv41_mmu_oclass;
+extern struct nvkm_oclass nv44_mmu_oclass;
+extern struct nvkm_oclass nv50_mmu_oclass;
+extern struct nvkm_oclass gf100_mmu_oclass;
+
+int nv04_vm_create(struct nvkm_mmu *, u64, u64, u64,
+ struct nvkm_vm **);
+void nv04_mmu_dtor(struct nvkm_object *);
+
+int nvkm_vm_create(struct nvkm_mmu *, u64 offset, u64 length, u64 mm_offset,
+ u32 block, struct nvkm_vm **);
+int nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset,
+ struct nvkm_vm **);
+int nvkm_vm_ref(struct nvkm_vm *, struct nvkm_vm **, struct nvkm_gpuobj *pgd);
+int nvkm_vm_get(struct nvkm_vm *, u64 size, u32 page_shift, u32 access,
+ struct nvkm_vma *);
+void nvkm_vm_put(struct nvkm_vma *);
+void nvkm_vm_map(struct nvkm_vma *, struct nvkm_mem *);
+void nvkm_vm_map_at(struct nvkm_vma *, u64 offset, struct nvkm_mem *);
+void nvkm_vm_unmap(struct nvkm_vma *);
+void nvkm_vm_unmap_at(struct nvkm_vma *, u64 offset, u64 length);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h
new file mode 100644
index 000000000000..fba613477b1a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mxm.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_MXM_H__
+#define __NVKM_MXM_H__
+#include <core/subdev.h>
+
+#define MXM_SANITISE_DCB 0x00000001
+
+struct nvkm_mxm {
+ struct nvkm_subdev base;
+ u32 action;
+ u8 *mxms;
+};
+
+static inline struct nvkm_mxm *
+nvkm_mxm(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_MXM);
+}
+
+#define nvkm_mxm_create(p,e,o,d) \
+ nvkm_mxm_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_mxm_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_mxm_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+int nvkm_mxm_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void nvkm_mxm_destroy(struct nvkm_mxm *);
+
+#define _nvkm_mxm_dtor _nvkm_subdev_dtor
+#define _nvkm_mxm_init _nvkm_subdev_init
+#define _nvkm_mxm_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv50_mxm_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
new file mode 100644
index 000000000000..7b86acc634a0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -0,0 +1,53 @@
+#ifndef __NVKM_PMU_H__
+#define __NVKM_PMU_H__
+#include <core/subdev.h>
+
+struct nvkm_pmu {
+ struct nvkm_subdev base;
+
+ struct {
+ u32 base;
+ u32 size;
+ } send;
+
+ struct {
+ u32 base;
+ u32 size;
+
+ struct work_struct work;
+ wait_queue_head_t wait;
+ u32 process;
+ u32 message;
+ u32 data[2];
+ } recv;
+
+ int (*message)(struct nvkm_pmu *, u32[2], u32, u32, u32, u32);
+ void (*pgob)(struct nvkm_pmu *, bool);
+};
+
+static inline struct nvkm_pmu *
+nvkm_pmu(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_PMU);
+}
+
+extern struct nvkm_oclass *gt215_pmu_oclass;
+extern struct nvkm_oclass *gf100_pmu_oclass;
+extern struct nvkm_oclass *gf110_pmu_oclass;
+extern struct nvkm_oclass *gk104_pmu_oclass;
+extern struct nvkm_oclass *gk208_pmu_oclass;
+extern struct nvkm_oclass *gk20a_pmu_oclass;
+
+/* interface to MEMX process running on PMU */
+struct nvkm_memx;
+int nvkm_memx_init(struct nvkm_pmu *, struct nvkm_memx **);
+int nvkm_memx_fini(struct nvkm_memx **, bool exec);
+void nvkm_memx_wr32(struct nvkm_memx *, u32 addr, u32 data);
+void nvkm_memx_wait(struct nvkm_memx *, u32 addr, u32 mask, u32 data, u32 nsec);
+void nvkm_memx_nsec(struct nvkm_memx *, u32 nsec);
+void nvkm_memx_wait_vblank(struct nvkm_memx *);
+void nvkm_memx_train(struct nvkm_memx *);
+int nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
+void nvkm_memx_block(struct nvkm_memx *);
+void nvkm_memx_unblock(struct nvkm_memx *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
new file mode 100644
index 000000000000..6662829b6db1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
@@ -0,0 +1,79 @@
+#ifndef __NVKM_THERM_H__
+#define __NVKM_THERM_H__
+#include <core/subdev.h>
+
+enum nvkm_therm_fan_mode {
+ NVKM_THERM_CTRL_NONE = 0,
+ NVKM_THERM_CTRL_MANUAL = 1,
+ NVKM_THERM_CTRL_AUTO = 2,
+};
+
+enum nvkm_therm_attr_type {
+ NVKM_THERM_ATTR_FAN_MIN_DUTY = 0,
+ NVKM_THERM_ATTR_FAN_MAX_DUTY = 1,
+ NVKM_THERM_ATTR_FAN_MODE = 2,
+
+ NVKM_THERM_ATTR_THRS_FAN_BOOST = 10,
+ NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST = 11,
+ NVKM_THERM_ATTR_THRS_DOWN_CLK = 12,
+ NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST = 13,
+ NVKM_THERM_ATTR_THRS_CRITICAL = 14,
+ NVKM_THERM_ATTR_THRS_CRITICAL_HYST = 15,
+ NVKM_THERM_ATTR_THRS_SHUTDOWN = 16,
+ NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
+};
+
+struct nvkm_therm {
+ struct nvkm_subdev base;
+
+ int (*pwm_ctrl)(struct nvkm_therm *, int line, bool);
+ int (*pwm_get)(struct nvkm_therm *, int line, u32 *, u32 *);
+ int (*pwm_set)(struct nvkm_therm *, int line, u32, u32);
+ int (*pwm_clock)(struct nvkm_therm *, int line);
+
+ int (*fan_get)(struct nvkm_therm *);
+ int (*fan_set)(struct nvkm_therm *, int);
+ int (*fan_sense)(struct nvkm_therm *);
+
+ int (*temp_get)(struct nvkm_therm *);
+
+ int (*attr_get)(struct nvkm_therm *, enum nvkm_therm_attr_type);
+ int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
+};
+
+static inline struct nvkm_therm *
+nvkm_therm(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_THERM);
+}
+
+#define nvkm_therm_create(p,e,o,d) \
+ nvkm_therm_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_therm_destroy(p) ({ \
+ struct nvkm_therm *therm = (p); \
+ _nvkm_therm_dtor(nv_object(therm)); \
+})
+#define nvkm_therm_init(p) ({ \
+ struct nvkm_therm *therm = (p); \
+ _nvkm_therm_init(nv_object(therm)); \
+})
+#define nvkm_therm_fini(p,s) ({ \
+ struct nvkm_therm *therm = (p); \
+ _nvkm_therm_init(nv_object(therm), (s)); \
+})
+
+int nvkm_therm_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_therm_dtor(struct nvkm_object *);
+int _nvkm_therm_init(struct nvkm_object *);
+int _nvkm_therm_fini(struct nvkm_object *, bool);
+
+int nvkm_therm_cstate(struct nvkm_therm *, int, int);
+
+extern struct nvkm_oclass nv40_therm_oclass;
+extern struct nvkm_oclass nv50_therm_oclass;
+extern struct nvkm_oclass g84_therm_oclass;
+extern struct nvkm_oclass gt215_therm_oclass;
+extern struct nvkm_oclass gf110_therm_oclass;
+extern struct nvkm_oclass gm107_therm_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
new file mode 100644
index 000000000000..4ad55082ef7a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
@@ -0,0 +1,61 @@
+#ifndef __NVKM_TIMER_H__
+#define __NVKM_TIMER_H__
+#include <core/subdev.h>
+
+struct nvkm_alarm {
+ struct list_head head;
+ u64 timestamp;
+ void (*func)(struct nvkm_alarm *);
+};
+
+static inline void
+nvkm_alarm_init(struct nvkm_alarm *alarm,
+ void (*func)(struct nvkm_alarm *))
+{
+ INIT_LIST_HEAD(&alarm->head);
+ alarm->func = func;
+}
+
+bool nvkm_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data);
+bool nvkm_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data);
+bool nvkm_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data);
+void nvkm_timer_alarm(void *, u32 nsec, struct nvkm_alarm *);
+void nvkm_timer_alarm_cancel(void *, struct nvkm_alarm *);
+
+#define NV_WAIT_DEFAULT 2000000000ULL
+#define nv_wait(o,a,m,v) \
+ nvkm_timer_wait_eq((o), NV_WAIT_DEFAULT, (a), (m), (v))
+#define nv_wait_ne(o,a,m,v) \
+ nvkm_timer_wait_ne((o), NV_WAIT_DEFAULT, (a), (m), (v))
+#define nv_wait_cb(o,c,d) \
+ nvkm_timer_wait_cb((o), NV_WAIT_DEFAULT, (c), (d))
+
+struct nvkm_timer {
+ struct nvkm_subdev base;
+ u64 (*read)(struct nvkm_timer *);
+ void (*alarm)(struct nvkm_timer *, u64 time, struct nvkm_alarm *);
+ void (*alarm_cancel)(struct nvkm_timer *, struct nvkm_alarm *);
+};
+
+static inline struct nvkm_timer *
+nvkm_timer(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_TIMER);
+}
+
+#define nvkm_timer_create(p,e,o,d) \
+ nvkm_subdev_create_((p), (e), (o), 0, "PTIMER", "timer", \
+ sizeof(**d), (void **)d)
+#define nvkm_timer_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_timer_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_timer_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+int nvkm_timer_create_(struct nvkm_object *, struct nvkm_engine *,
+ struct nvkm_oclass *, int size, void **);
+
+extern struct nvkm_oclass nv04_timer_oclass;
+extern struct nvkm_oclass gk20a_timer_oclass;
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vga.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/vga.h
index fee09ad818e4..fee09ad818e4 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/vga.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/vga.h
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
new file mode 100644
index 000000000000..e3d7243fbb1d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
@@ -0,0 +1,58 @@
+#ifndef __NVKM_VOLT_H__
+#define __NVKM_VOLT_H__
+#include <core/subdev.h>
+
+struct nvkm_voltage {
+ u32 uv;
+ u8 id;
+};
+
+struct nvkm_volt {
+ struct nvkm_subdev base;
+
+ int (*vid_get)(struct nvkm_volt *);
+ int (*get)(struct nvkm_volt *);
+ int (*vid_set)(struct nvkm_volt *, u8 vid);
+ int (*set)(struct nvkm_volt *, u32 uv);
+ int (*set_id)(struct nvkm_volt *, u8 id, int condition);
+
+ u8 vid_mask;
+ u8 vid_nr;
+ struct {
+ u32 uv;
+ u8 vid;
+ } vid[256];
+};
+
+static inline struct nvkm_volt *
+nvkm_volt(void *obj)
+{
+ return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_VOLT);
+}
+
+#define nvkm_volt_create(p, e, o, d) \
+ nvkm_volt_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_volt_destroy(p) ({ \
+ struct nvkm_volt *v = (p); \
+ _nvkm_volt_dtor(nv_object(v)); \
+})
+#define nvkm_volt_init(p) ({ \
+ struct nvkm_volt *v = (p); \
+ _nvkm_volt_init(nv_object(v)); \
+})
+#define nvkm_volt_fini(p,s) \
+ nvkm_subdev_fini((p), (s))
+
+int nvkm_volt_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_volt_dtor(struct nvkm_object *);
+int _nvkm_volt_init(struct nvkm_object *);
+#define _nvkm_volt_fini _nvkm_subdev_fini
+
+extern struct nvkm_oclass nv40_volt_oclass;
+extern struct nvkm_oclass gk20a_volt_oclass;
+
+int nvkm_voltgpio_init(struct nvkm_volt *);
+int nvkm_voltgpio_get(struct nvkm_volt *);
+int nvkm_voltgpio_set(struct nvkm_volt *, u8);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index d39a15000068..d8b0891a141c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -100,7 +100,7 @@ static void
nouveau_abi16_ntfy_fini(struct nouveau_abi16_chan *chan,
struct nouveau_abi16_ntfy *ntfy)
{
- nouveau_mm_free(&chan->heap, &ntfy->node);
+ nvkm_mm_free(&chan->heap, &ntfy->node);
list_del(&ntfy->head);
kfree(ntfy);
}
@@ -128,7 +128,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
}
if (chan->heap.block_size)
- nouveau_mm_fini(&chan->heap);
+ nvkm_mm_fini(&chan->heap);
/* destroy channel object, all children will be killed too */
if (chan->chan) {
@@ -164,8 +164,8 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->device;
- struct nouveau_timer *ptimer = nvkm_timer(device);
- struct nouveau_graph *graph = nvkm_gr(device);
+ struct nvkm_timer *ptimer = nvxx_timer(device);
+ struct nvkm_gr *gr = nvxx_gr(device);
struct drm_nouveau_getparam *getparam = data;
switch (getparam->param) {
@@ -173,19 +173,19 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
getparam->value = device->info.chipset;
break;
case NOUVEAU_GETPARAM_PCI_VENDOR:
- if (nv_device_is_pci(nvkm_device(device)))
+ if (nv_device_is_pci(nvxx_device(device)))
getparam->value = dev->pdev->vendor;
else
getparam->value = 0;
break;
case NOUVEAU_GETPARAM_PCI_DEVICE:
- if (nv_device_is_pci(nvkm_device(device)))
+ if (nv_device_is_pci(nvxx_device(device)))
getparam->value = dev->pdev->device;
else
getparam->value = 0;
break;
case NOUVEAU_GETPARAM_BUS_TYPE:
- if (!nv_device_is_pci(nvkm_device(device)))
+ if (!nv_device_is_pci(nvxx_device(device)))
getparam->value = 3;
else
if (drm_pci_device_is_agp(dev))
@@ -215,7 +215,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
getparam->value = 1;
break;
case NOUVEAU_GETPARAM_GRAPH_UNITS:
- getparam->value = graph->units ? graph->units(graph) : 0;
+ getparam->value = gr->units ? gr->units(gr) : 0;
break;
default:
NV_PRINTK(debug, cli, "unknown parameter %lld\n", getparam->param);
@@ -324,7 +324,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
if (ret)
goto done;
- ret = nouveau_mm_init(&chan->heap, 0, PAGE_SIZE, 1);
+ ret = nvkm_mm_init(&chan->heap, 0, PAGE_SIZE, 1);
done:
if (ret)
nouveau_abi16_chan_fini(abi16, chan);
@@ -448,8 +448,8 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
list_add(&ntfy->head, &chan->notifiers);
ntfy->handle = info->handle;
- ret = nouveau_mm_head(&chan->heap, 0, 1, info->size, info->size, 1,
- &ntfy->node);
+ ret = nvkm_mm_head(&chan->heap, 0, 1, info->size, info->size, 1,
+ &ntfy->node);
if (ret)
goto done;
@@ -527,7 +527,7 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
/* cleanup extra state if this object was a notifier */
list_for_each_entry(ntfy, &chan->notifiers, head) {
if (ntfy->handle == fini->handle) {
- nouveau_mm_free(&chan->heap, &ntfy->node);
+ nvkm_mm_free(&chan->heap, &ntfy->node);
list_del(&ntfy->head);
break;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h
index 39844e6bfbff..86eb1caf4957 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.h
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h
@@ -14,7 +14,7 @@ int nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS);
struct nouveau_abi16_ntfy {
struct list_head head;
- struct nouveau_mm_node *node;
+ struct nvkm_mm_node *node;
u32 handle;
};
@@ -23,8 +23,8 @@ struct nouveau_abi16_chan {
struct nouveau_channel *chan;
struct list_head notifiers;
struct nouveau_bo *ntfy;
- struct nouveau_vma ntfy_vma;
- struct nouveau_mm heap;
+ struct nvkm_vma ntfy_vma;
+ struct nvkm_mm heap;
};
struct nouveau_abi16 {
diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c
index 1f6f6ba6847a..0b5970955604 100644
--- a/drivers/gpu/drm/nouveau/nouveau_agp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_agp.c
@@ -45,8 +45,8 @@ get_agp_mode(struct nouveau_drm *drm, const struct drm_agp_info *info)
while (agpmode == -1 && quirk->hostbridge_vendor) {
if (info->id_vendor == quirk->hostbridge_vendor &&
info->id_device == quirk->hostbridge_device &&
- nvkm_device(device)->pdev->vendor == quirk->chip_vendor &&
- nvkm_device(device)->pdev->device == quirk->chip_device) {
+ nvxx_device(device)->pdev->vendor == quirk->chip_vendor &&
+ nvxx_device(device)->pdev->device == quirk->chip_device) {
agpmode = quirk->mode;
NV_INFO(drm, "Forcing agp mode to %dX. Use agpmode to override.\n",
agpmode);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 7df6acc8bb34..0190b69bbe25 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -2009,7 +2009,7 @@ uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev)
static bool NVInitVBIOS(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_bios *bios = nvkm_bios(&drm->device);
+ struct nvkm_bios *bios = nvxx_bios(&drm->device);
struct nvbios *legacy = &drm->vbios;
memset(legacy, 0, sizeof(struct nvbios));
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index bba2960d3dfb..77326e344dad 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -48,9 +48,9 @@ nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg,
{
struct nouveau_drm *drm = nouveau_drm(dev);
int i = reg - drm->tile.reg;
- struct nouveau_fb *pfb = nvkm_fb(&drm->device);
- struct nouveau_fb_tile *tile = &pfb->tile.region[i];
- struct nouveau_engine *engine;
+ struct nvkm_fb *pfb = nvxx_fb(&drm->device);
+ struct nvkm_fb_tile *tile = &pfb->tile.region[i];
+ struct nvkm_engine *engine;
nouveau_fence_unref(&reg->fence);
@@ -62,9 +62,9 @@ nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg,
pfb->tile.prog(pfb, i, tile);
- if ((engine = nouveau_engine(pfb, NVDEV_ENGINE_GR)))
+ if ((engine = nvkm_engine(pfb, NVDEV_ENGINE_GR)))
engine->tile_prog(engine, i);
- if ((engine = nouveau_engine(pfb, NVDEV_ENGINE_MPEG)))
+ if ((engine = nvkm_engine(pfb, NVDEV_ENGINE_MPEG)))
engine->tile_prog(engine, i);
}
@@ -105,7 +105,7 @@ nv10_bo_set_tiling(struct drm_device *dev, u32 addr,
u32 size, u32 pitch, u32 flags)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_fb *pfb = nvkm_fb(&drm->device);
+ struct nvkm_fb *pfb = nvxx_fb(&drm->device);
struct nouveau_drm_tile *tile, *found = NULL;
int i;
@@ -193,7 +193,7 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
int max_size;
if (drm->client.vm)
- lpg_shift = drm->client.vm->vmm->lpg_shift;
+ lpg_shift = drm->client.vm->mmu->lpg_shift;
max_size = INT_MAX & ~((1 << lpg_shift) - 1);
if (size <= 0 || size > max_size) {
@@ -214,13 +214,13 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
nvbo->tile_flags = tile_flags;
nvbo->bo.bdev = &drm->ttm.bdev;
- if (!nv_device_is_cpu_coherent(nvkm_device(&drm->device)))
+ if (!nv_device_is_cpu_coherent(nvxx_device(&drm->device)))
nvbo->force_coherent = flags & TTM_PL_FLAG_UNCACHED;
nvbo->page_shift = 12;
if (drm->client.vm) {
if (!(flags & TTM_PL_FLAG_TT) && size > 256 * 1024)
- nvbo->page_shift = drm->client.vm->vmm->lpg_shift;
+ nvbo->page_shift = drm->client.vm->mmu->lpg_shift;
}
nouveau_bo_fixup_align(nvbo, flags, &align, &size);
@@ -325,7 +325,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype, bool contig)
memtype == TTM_PL_FLAG_VRAM && contig) {
if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
if (bo->mem.mem_type == TTM_PL_VRAM) {
- struct nouveau_mem *mem = bo->mem.mm_node;
+ struct nvkm_mem *mem = bo->mem.mm_node;
if (!list_is_singular(&mem->regions))
evict = true;
}
@@ -459,7 +459,7 @@ void
nouveau_bo_sync_for_device(struct nouveau_bo *nvbo)
{
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
- struct nouveau_device *device = nvkm_device(&drm->device);
+ struct nvkm_device *device = nvxx_device(&drm->device);
struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm;
int i;
@@ -479,7 +479,7 @@ void
nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
{
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
- struct nouveau_device *device = nvkm_device(&drm->device);
+ struct nvkm_device *device = nvxx_device(&drm->device);
struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm;
int i;
@@ -533,20 +533,6 @@ _nouveau_bo_mem_index(struct nouveau_bo *nvbo, unsigned index, void *mem, u8 sz)
}
#define nouveau_bo_mem_index(o, i, m) _nouveau_bo_mem_index(o, i, m, sizeof(*m))
-u16
-nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index)
-{
- bool is_iomem;
- u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
-
- mem = nouveau_bo_mem_index(nvbo, index, mem);
-
- if (is_iomem)
- return ioread16_native((void __force __iomem *)mem);
- else
- return *mem;
-}
-
void
nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val)
{
@@ -634,7 +620,7 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
/* Some BARs do not support being ioremapped WC */
- if (nvkm_bar(&drm->device)->iomap_uncached) {
+ if (nvxx_bar(&drm->device)->iomap_uncached) {
man->available_caching = TTM_PL_FLAG_UNCACHED;
man->default_caching = TTM_PL_FLAG_UNCACHED;
}
@@ -709,7 +695,7 @@ static int
nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
- struct nouveau_mem *node = old_mem->mm_node;
+ struct nvkm_mem *node = old_mem->mm_node;
int ret = RING_SPACE(chan, 10);
if (ret == 0) {
BEGIN_NVC0(chan, NvSubCopy, 0x0400, 8);
@@ -741,7 +727,7 @@ static int
nvc0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
- struct nouveau_mem *node = old_mem->mm_node;
+ struct nvkm_mem *node = old_mem->mm_node;
u64 src_offset = node->vma[0].offset;
u64 dst_offset = node->vma[1].offset;
u32 page_count = new_mem->num_pages;
@@ -779,7 +765,7 @@ static int
nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
- struct nouveau_mem *node = old_mem->mm_node;
+ struct nvkm_mem *node = old_mem->mm_node;
u64 src_offset = node->vma[0].offset;
u64 dst_offset = node->vma[1].offset;
u32 page_count = new_mem->num_pages;
@@ -818,7 +804,7 @@ static int
nva3_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
- struct nouveau_mem *node = old_mem->mm_node;
+ struct nvkm_mem *node = old_mem->mm_node;
u64 src_offset = node->vma[0].offset;
u64 dst_offset = node->vma[1].offset;
u32 page_count = new_mem->num_pages;
@@ -856,7 +842,7 @@ static int
nv98_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
- struct nouveau_mem *node = old_mem->mm_node;
+ struct nvkm_mem *node = old_mem->mm_node;
int ret = RING_SPACE(chan, 7);
if (ret == 0) {
BEGIN_NV04(chan, NvSubCopy, 0x0320, 6);
@@ -874,7 +860,7 @@ static int
nv84_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
- struct nouveau_mem *node = old_mem->mm_node;
+ struct nvkm_mem *node = old_mem->mm_node;
int ret = RING_SPACE(chan, 7);
if (ret == 0) {
BEGIN_NV04(chan, NvSubCopy, 0x0304, 6);
@@ -908,12 +894,12 @@ static int
nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
{
- struct nouveau_mem *node = old_mem->mm_node;
+ struct nvkm_mem *node = old_mem->mm_node;
u64 length = (new_mem->num_pages << PAGE_SHIFT);
u64 src_offset = node->vma[0].offset;
u64 dst_offset = node->vma[1].offset;
int src_tiled = !!node->memtype;
- int dst_tiled = !!((struct nouveau_mem *)new_mem->mm_node)->memtype;
+ int dst_tiled = !!((struct nvkm_mem *)new_mem->mm_node)->memtype;
int ret;
while (length) {
@@ -1050,25 +1036,25 @@ static int
nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo,
struct ttm_mem_reg *mem)
{
- struct nouveau_mem *old_node = bo->mem.mm_node;
- struct nouveau_mem *new_node = mem->mm_node;
+ struct nvkm_mem *old_node = bo->mem.mm_node;
+ struct nvkm_mem *new_node = mem->mm_node;
u64 size = (u64)mem->num_pages << PAGE_SHIFT;
int ret;
- ret = nouveau_vm_get(drm->client.vm, size, old_node->page_shift,
- NV_MEM_ACCESS_RW, &old_node->vma[0]);
+ ret = nvkm_vm_get(drm->client.vm, size, old_node->page_shift,
+ NV_MEM_ACCESS_RW, &old_node->vma[0]);
if (ret)
return ret;
- ret = nouveau_vm_get(drm->client.vm, size, new_node->page_shift,
- NV_MEM_ACCESS_RW, &old_node->vma[1]);
+ ret = nvkm_vm_get(drm->client.vm, size, new_node->page_shift,
+ NV_MEM_ACCESS_RW, &old_node->vma[1]);
if (ret) {
- nouveau_vm_put(&old_node->vma[0]);
+ nvkm_vm_put(&old_node->vma[0]);
return ret;
}
- nouveau_vm_map(&old_node->vma[0], old_node);
- nouveau_vm_map(&old_node->vma[1], new_node);
+ nvkm_vm_map(&old_node->vma[0], old_node);
+ nvkm_vm_map(&old_node->vma[1], new_node);
return 0;
}
@@ -1083,7 +1069,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
int ret;
/* create temporary vmas for the transfer and attach them to the
- * old nouveau_mem node, these will get cleaned up after ttm has
+ * old nvkm_mem node, these will get cleaned up after ttm has
* destroyed the ttm_mem_reg
*/
if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
@@ -1245,7 +1231,7 @@ static void
nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
{
struct nouveau_bo *nvbo = nouveau_bo(bo);
- struct nouveau_vma *vma;
+ struct nvkm_vma *vma;
/* ttm can now (stupidly) pass the driver bos it didn't create... */
if (bo->destroy != nouveau_bo_del_ttm)
@@ -1254,10 +1240,10 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
list_for_each_entry(vma, &nvbo->vma_list, head) {
if (new_mem && new_mem->mem_type != TTM_PL_SYSTEM &&
(new_mem->mem_type == TTM_PL_VRAM ||
- nvbo->page_shift != vma->vm->vmm->lpg_shift)) {
- nouveau_vm_map(vma, new_mem->mm_node);
+ nvbo->page_shift != vma->vm->mmu->lpg_shift)) {
+ nvkm_vm_map(vma, new_mem->mm_node);
} else {
- nouveau_vm_unmap(vma);
+ nvkm_vm_unmap(vma);
}
}
}
@@ -1368,7 +1354,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
{
struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
struct nouveau_drm *drm = nouveau_bdev(bdev);
- struct nouveau_mem *node = mem->mm_node;
+ struct nvkm_mem *node = mem->mm_node;
int ret;
mem->bus.addr = NULL;
@@ -1396,10 +1382,10 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
/* fallthrough, tiled memory */
case TTM_PL_VRAM:
mem->bus.offset = mem->start << PAGE_SHIFT;
- mem->bus.base = nv_device_resource_start(nvkm_device(&drm->device), 1);
+ mem->bus.base = nv_device_resource_start(nvxx_device(&drm->device), 1);
mem->bus.is_iomem = true;
if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
- struct nouveau_bar *bar = nvkm_bar(&drm->device);
+ struct nvkm_bar *bar = nvxx_bar(&drm->device);
ret = bar->umap(bar, node, NV_MEM_ACCESS_RW,
&node->bar_vma);
@@ -1419,8 +1405,8 @@ static void
nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
{
struct nouveau_drm *drm = nouveau_bdev(bdev);
- struct nouveau_bar *bar = nvkm_bar(&drm->device);
- struct nouveau_mem *node = mem->mm_node;
+ struct nvkm_bar *bar = nvxx_bar(&drm->device);
+ struct nvkm_mem *node = mem->mm_node;
if (!node->bar_vma.node)
return;
@@ -1434,7 +1420,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct nvif_device *device = &drm->device;
- u32 mappable = nv_device_resource_len(nvkm_device(device), 1) >> PAGE_SHIFT;
+ u32 mappable = nv_device_resource_len(nvxx_device(device), 1) >> PAGE_SHIFT;
int i, ret;
/* as long as the bo isn't in vram, and isn't tiled, we've got
@@ -1479,7 +1465,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
{
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
- struct nouveau_device *device;
+ struct nvkm_device *device;
struct drm_device *dev;
struct device *pdev;
unsigned i;
@@ -1498,7 +1484,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
}
drm = nouveau_bdev(ttm->bdev);
- device = nvkm_device(&drm->device);
+ device = nvxx_device(&drm->device);
dev = drm->dev;
pdev = nv_device_base(device);
@@ -1553,7 +1539,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
{
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
- struct nouveau_device *device;
+ struct nvkm_device *device;
struct drm_device *dev;
struct device *pdev;
unsigned i;
@@ -1563,7 +1549,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
return;
drm = nouveau_bdev(ttm->bdev);
- device = nvkm_device(&drm->device);
+ device = nvxx_device(&drm->device);
dev = drm->dev;
pdev = nv_device_base(device);
@@ -1627,10 +1613,10 @@ struct ttm_bo_driver nouveau_bo_driver = {
.io_mem_free = &nouveau_ttm_io_mem_free,
};
-struct nouveau_vma *
-nouveau_bo_vma_find(struct nouveau_bo *nvbo, struct nouveau_vm *vm)
+struct nvkm_vma *
+nouveau_bo_vma_find(struct nouveau_bo *nvbo, struct nvkm_vm *vm)
{
- struct nouveau_vma *vma;
+ struct nvkm_vma *vma;
list_for_each_entry(vma, &nvbo->vma_list, head) {
if (vma->vm == vm)
return vma;
@@ -1640,21 +1626,21 @@ nouveau_bo_vma_find(struct nouveau_bo *nvbo, struct nouveau_vm *vm)
}
int
-nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm,
- struct nouveau_vma *vma)
+nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nvkm_vm *vm,
+ struct nvkm_vma *vma)
{
const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
int ret;
- ret = nouveau_vm_get(vm, size, nvbo->page_shift,
+ ret = nvkm_vm_get(vm, size, nvbo->page_shift,
NV_MEM_ACCESS_RW, vma);
if (ret)
return ret;
if ( nvbo->bo.mem.mem_type != TTM_PL_SYSTEM &&
(nvbo->bo.mem.mem_type == TTM_PL_VRAM ||
- nvbo->page_shift != vma->vm->vmm->lpg_shift))
- nouveau_vm_map(vma, nvbo->bo.mem.mm_node);
+ nvbo->page_shift != vma->vm->mmu->lpg_shift))
+ nvkm_vm_map(vma, nvbo->bo.mem.mm_node);
list_add_tail(&vma->head, &nvbo->vma_list);
vma->refcount = 1;
@@ -1662,12 +1648,12 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm,
}
void
-nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
+nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nvkm_vma *vma)
{
if (vma->node) {
if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM)
- nouveau_vm_unmap(vma);
- nouveau_vm_put(vma);
+ nvkm_vm_unmap(vma);
+ nvkm_vm_put(vma);
list_del(&vma->head);
}
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h
index 072222efeeb7..e42360983229 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -5,7 +5,7 @@
struct nouveau_channel;
struct nouveau_fence;
-struct nouveau_vma;
+struct nvkm_vma;
struct nouveau_bo {
struct ttm_buffer_object bo;
@@ -78,7 +78,6 @@ int nouveau_bo_unpin(struct nouveau_bo *);
int nouveau_bo_map(struct nouveau_bo *);
void nouveau_bo_unmap(struct nouveau_bo *);
void nouveau_bo_placement_set(struct nouveau_bo *, u32 type, u32 busy);
-u16 nouveau_bo_rd16(struct nouveau_bo *, unsigned index);
void nouveau_bo_wr16(struct nouveau_bo *, unsigned index, u16 val);
u32 nouveau_bo_rd32(struct nouveau_bo *, unsigned index);
void nouveau_bo_wr32(struct nouveau_bo *, unsigned index, u32 val);
@@ -88,12 +87,12 @@ int nouveau_bo_validate(struct nouveau_bo *, bool interruptible,
void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo);
void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo);
-struct nouveau_vma *
-nouveau_bo_vma_find(struct nouveau_bo *, struct nouveau_vm *);
+struct nvkm_vma *
+nouveau_bo_vma_find(struct nouveau_bo *, struct nvkm_vm *);
-int nouveau_bo_vma_add(struct nouveau_bo *, struct nouveau_vm *,
- struct nouveau_vma *);
-void nouveau_bo_vma_del(struct nouveau_bo *, struct nouveau_vma *);
+int nouveau_bo_vma_add(struct nouveau_bo *, struct nvkm_vm *,
+ struct nvkm_vma *);
+void nouveau_bo_vma_del(struct nouveau_bo *, struct nvkm_vma *);
/* TODO: submit equivalent to TTM generic API upstream? */
static inline void __iomem *
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index aff9099aae6c..e581f63cbf25 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -54,7 +54,7 @@ nouveau_channel_idle(struct nouveau_channel *chan)
if (ret)
NV_PRINTK(error, cli, "failed to idle channel 0x%08x [%s]\n",
- chan->object->handle, nvkm_client(&cli->base)->name);
+ chan->object->handle, nvxx_client(&cli->base)->name);
return ret;
}
@@ -88,7 +88,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
u32 handle, u32 size, struct nouveau_channel **pchan)
{
struct nouveau_cli *cli = (void *)nvif_client(&device->base);
- struct nouveau_vmmgr *vmm = nvkm_vmmgr(device);
+ struct nvkm_mmu *mmu = nvxx_mmu(device);
struct nv_dma_v0 args = {};
struct nouveau_channel *chan;
u32 target;
@@ -136,7 +136,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_VM;
args.start = 0;
- args.limit = cli->vm->vmm->limit - 1;
+ args.limit = cli->vm->mmu->limit - 1;
} else
if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) {
if (device->info.family == NV_DEVICE_INFO_V0_TNT) {
@@ -146,7 +146,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
*/
args.target = NV_DMA_V0_TARGET_PCI;
args.access = NV_DMA_V0_ACCESS_RDWR;
- args.start = nv_device_resource_start(nvkm_device(device), 1);
+ args.start = nv_device_resource_start(nvxx_device(device), 1);
args.limit = args.start + device->info.ram_user - 1;
} else {
args.target = NV_DMA_V0_TARGET_VRAM;
@@ -165,7 +165,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_RDWR;
args.start = 0;
- args.limit = vmm->limit - 1;
+ args.limit = mmu->limit - 1;
}
}
@@ -281,8 +281,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
{
struct nvif_device *device = chan->device;
struct nouveau_cli *cli = (void *)nvif_client(&device->base);
- struct nouveau_vmmgr *vmm = nvkm_vmmgr(device);
- struct nouveau_software_chan *swch;
+ struct nvkm_mmu *mmu = nvxx_mmu(device);
+ struct nvkm_sw_chan *swch;
struct nv_dma_v0 args = {};
int ret, i;
@@ -294,7 +294,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_VM;
args.start = 0;
- args.limit = cli->vm->vmm->limit - 1;
+ args.limit = cli->vm->mmu->limit - 1;
} else {
args.target = NV_DMA_V0_TARGET_VRAM;
args.access = NV_DMA_V0_ACCESS_RDWR;
@@ -312,7 +312,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_VM;
args.start = 0;
- args.limit = cli->vm->vmm->limit - 1;
+ args.limit = cli->vm->mmu->limit - 1;
} else
if (chan->drm->agp.stat == ENABLED) {
args.target = NV_DMA_V0_TARGET_AGP;
@@ -324,7 +324,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_RDWR;
args.start = 0;
- args.limit = vmm->limit - 1;
+ args.limit = mmu->limit - 1;
}
ret = nvif_object_init(chan->object, NULL, gart,
@@ -372,7 +372,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
if (ret)
return ret;
- swch = (void *)nvkm_object(&chan->nvsw)->parent;
+ swch = (void *)nvxx_object(&chan->nvsw)->parent;
swch->flip = nouveau_flip_complete;
swch->flip_data = chan;
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h
index 8309c24ee698..8b3640f69e4f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.h
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.h
@@ -16,7 +16,7 @@ struct nouveau_channel {
struct {
struct nouveau_bo *buffer;
- struct nouveau_vma vma;
+ struct nvkm_vma vma;
struct nvif_object ctxdma;
} push;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index c8ac9482cf2e..db7095ae4ebb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -115,7 +115,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
struct drm_device *dev = connector->dev;
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_gpio *gpio = nvkm_gpio(&drm->device);
+ struct nvkm_gpio *gpio = nvxx_gpio(&drm->device);
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
int i, panel = -ENODEV;
@@ -241,7 +241,7 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL;
struct nouveau_encoder *nv_partner;
- struct nouveau_i2c_port *i2c;
+ struct nvkm_i2c_port *i2c;
int type;
int ret;
enum drm_connector_status conn_status = connector_status_disconnected;
@@ -458,6 +458,28 @@ nouveau_connector_set_property(struct drm_connector *connector,
switch (value) {
case DRM_MODE_SCALE_NONE:
+ /* We allow 'None' for EDID modes, even on a fixed
+ * panel (some exist with support for lower refresh
+ * rates, which people might want to use for power
+ * saving purposes).
+ *
+ * Non-EDID modes will force the use of GPU scaling
+ * to the native mode regardless of this setting.
+ */
+ switch (nv_connector->type) {
+ case DCB_CONNECTOR_LVDS:
+ case DCB_CONNECTOR_LVDS_SPWG:
+ case DCB_CONNECTOR_eDP:
+ /* ... except prior to G80, where the code
+ * doesn't support such things.
+ */
+ if (disp->disp.oclass < NV50_DISP)
+ return -EINVAL;
+ break;
+ default:
+ break;
+ }
+ break;
case DRM_MODE_SCALE_FULLSCREEN:
case DRM_MODE_SCALE_CENTER:
case DRM_MODE_SCALE_ASPECT:
@@ -466,11 +488,6 @@ nouveau_connector_set_property(struct drm_connector *connector,
return -EINVAL;
}
- /* LVDS always needs gpu scaling */
- if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
- value == DRM_MODE_SCALE_NONE)
- return -EINVAL;
-
/* Changing between GPU and panel scaling requires a full
* modeset
*/
@@ -655,15 +672,15 @@ nouveau_connector_scaler_modes_add(struct drm_connector *connector)
while (mode->hdisplay) {
if (mode->hdisplay <= native->hdisplay &&
- mode->vdisplay <= native->vdisplay) {
+ mode->vdisplay <= native->vdisplay &&
+ (mode->hdisplay != native->hdisplay ||
+ mode->vdisplay != native->vdisplay)) {
m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay,
drm_mode_vrefresh(native), false,
false, false);
if (!m)
continue;
- m->type |= DRM_MODE_TYPE_DRIVER;
-
drm_mode_probed_add(connector, m);
modes++;
}
@@ -968,7 +985,7 @@ nouveau_connector_aux_xfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
struct nouveau_connector *nv_connector =
container_of(aux, typeof(*nv_connector), aux);
struct nouveau_encoder *nv_encoder;
- struct nouveau_i2c_port *port;
+ struct nvkm_i2c_port *port;
int ret;
nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP);
@@ -979,13 +996,13 @@ nouveau_connector_aux_xfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
if (msg->size == 0)
return msg->size;
- ret = nouveau_i2c(port)->acquire(port, 0);
+ ret = nvkm_i2c(port)->acquire(port, 0);
if (ret)
return ret;
ret = port->func->aux(port, false, msg->request, msg->address,
msg->buffer, msg->size);
- nouveau_i2c(port)->release(port);
+ nvkm_i2c(port)->release(port);
if (ret >= 0) {
msg->reply = ret;
return msg->size;
@@ -1180,36 +1197,61 @@ nouveau_connector_create(struct drm_device *dev, int index)
disp->color_vibrance_property,
150);
+ /* default scaling mode */
switch (nv_connector->type) {
- case DCB_CONNECTOR_VGA:
- if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
- drm_object_attach_property(&connector->base,
- dev->mode_config.scaling_mode_property,
- nv_connector->scaling_mode);
+ case DCB_CONNECTOR_LVDS:
+ case DCB_CONNECTOR_LVDS_SPWG:
+ case DCB_CONNECTOR_eDP:
+ /* see note in nouveau_connector_set_property() */
+ if (disp->disp.oclass < NV50_DISP) {
+ nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
+ break;
}
- /* fall-through */
+ nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
+ break;
+ default:
+ nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
+ break;
+ }
+
+ /* scaling mode property */
+ switch (nv_connector->type) {
case DCB_CONNECTOR_TV_0:
case DCB_CONNECTOR_TV_1:
case DCB_CONNECTOR_TV_3:
- nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
break;
+ case DCB_CONNECTOR_VGA:
+ if (disp->disp.oclass < NV50_DISP)
+ break; /* can only scale on DFPs */
+ /* fall-through */
default:
- nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
+ drm_object_attach_property(&connector->base, dev->mode_config.
+ scaling_mode_property,
+ nv_connector->scaling_mode);
+ break;
+ }
- drm_object_attach_property(&connector->base,
- dev->mode_config.scaling_mode_property,
- nv_connector->scaling_mode);
+ /* dithering properties */
+ switch (nv_connector->type) {
+ case DCB_CONNECTOR_TV_0:
+ case DCB_CONNECTOR_TV_1:
+ case DCB_CONNECTOR_TV_3:
+ case DCB_CONNECTOR_VGA:
+ break;
+ default:
if (disp->dithering_mode) {
- nv_connector->dithering_mode = DITHERING_MODE_AUTO;
drm_object_attach_property(&connector->base,
- disp->dithering_mode,
- nv_connector->dithering_mode);
+ disp->dithering_mode,
+ nv_connector->
+ dithering_mode);
+ nv_connector->dithering_mode = DITHERING_MODE_AUTO;
}
if (disp->dithering_depth) {
- nv_connector->dithering_depth = DITHERING_DEPTH_AUTO;
drm_object_attach_property(&connector->base,
- disp->dithering_depth,
- nv_connector->dithering_depth);
+ disp->dithering_depth,
+ nv_connector->
+ dithering_depth);
+ nv_connector->dithering_depth = DITHERING_DEPTH_AUTO;
}
break;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index 629a380c7085..7446ee66ea04 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -33,7 +33,7 @@
#include <drm/drm_dp_helper.h>
#include "nouveau_crtc.h"
-struct nouveau_i2c_port;
+struct nvkm_i2c_port;
enum nouveau_underscan_type {
UNDERSCAN_OFF,
@@ -72,6 +72,7 @@ struct nouveau_connector {
int dithering_mode;
int dithering_depth;
int scaling_mode;
+ bool scaling_full;
enum nouveau_underscan_type underscan;
u32 underscan_hborder;
u32 underscan_vborder;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index f8042433752b..860b0e2d4181 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -450,7 +450,7 @@ nouveau_display_create(struct drm_device *dev)
drm_mode_create_dvi_i_properties(dev);
dev->mode_config.funcs = &nouveau_mode_config_funcs;
- dev->mode_config.fb_base = nv_device_resource_start(nvkm_device(&drm->device), 1);
+ dev->mode_config.fb_base = nv_device_resource_start(nvxx_device(&drm->device), 1);
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
@@ -570,7 +570,8 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (nv_crtc->cursor.nvbo) {
- nouveau_bo_unmap(nv_crtc->cursor.nvbo);
+ if (nv_crtc->cursor.set_offset)
+ nouveau_bo_unmap(nv_crtc->cursor.nvbo);
nouveau_bo_unpin(nv_crtc->cursor.nvbo);
}
}
@@ -604,7 +605,7 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
continue;
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
- if (!ret)
+ if (!ret && nv_crtc->cursor.set_offset)
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
if (ret)
NV_ERROR(drm, "Could not pin/map cursor.\n");
@@ -637,7 +638,9 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
if (!nv_crtc->cursor.nvbo)
continue;
- nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
+
+ if (nv_crtc->cursor.set_offset)
+ nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
nv_crtc->cursor_saved_y);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
index be3d5947c6be..a6213e2425c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.h
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
@@ -1,14 +1,14 @@
#ifndef __NOUVEAU_DISPLAY_H__
#define __NOUVEAU_DISPLAY_H__
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
#include "nouveau_drm.h"
struct nouveau_framebuffer {
struct drm_framebuffer base;
struct nouveau_bo *nvbo;
- struct nouveau_vma vma;
+ struct nvkm_vma vma;
u32 r_handle;
u32 r_format;
u32 r_pitch;
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index 8508603cc8c3..6d9245aa81a6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -84,7 +84,7 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
{
struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base);
struct nouveau_bo *pb = chan->push.buffer;
- struct nouveau_vma *vma;
+ struct nvkm_vma *vma;
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
u64 offset;
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index c5137cccce7d..c3ef30b3a5ec 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -31,7 +31,7 @@
#include "nouveau_crtc.h"
static void
-nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch,
+nouveau_dp_probe_oui(struct drm_device *dev, struct nvkm_i2c_port *auxch,
u8 *dpcd)
{
struct nouveau_drm *drm = nouveau_drm(dev);
@@ -55,7 +55,7 @@ nouveau_dp_detect(struct nouveau_encoder *nv_encoder)
{
struct drm_device *dev = nv_encoder->base.base.dev;
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_i2c_port *auxch;
+ struct nvkm_i2c_port *auxch;
u8 *dpcd = nv_encoder->dp.dpcd;
int ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 65910e3aed0c..8763deb5188b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -52,6 +52,7 @@
#include "nouveau_debugfs.h"
#include "nouveau_usif.h"
#include "nouveau_connector.h"
+#include "nouveau_platform.h"
MODULE_PARM_DESC(config, "option string to pass to driver core");
static char *nouveau_config;
@@ -123,7 +124,7 @@ nouveau_cli_create(u64 name, const char *sname,
static void
nouveau_cli_destroy(struct nouveau_cli *cli)
{
- nouveau_vm_ref(NULL, &nvkm_client(&cli->base)->vm, NULL);
+ nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL);
nvif_client_fini(&cli->base);
usif_client_fini(cli);
}
@@ -133,7 +134,7 @@ nouveau_accel_fini(struct nouveau_drm *drm)
{
nouveau_channel_del(&drm->channel);
nvif_object_fini(&drm->ntfy);
- nouveau_gpuobj_ref(NULL, &drm->notify);
+ nvkm_gpuobj_ref(NULL, &drm->notify);
nvif_object_fini(&drm->nvsw);
nouveau_channel_del(&drm->cechan);
nvif_object_fini(&drm->ttm.copy);
@@ -230,7 +231,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
ret = nvif_object_init(drm->channel->object, NULL, NVDRM_NVSW,
nouveau_abi16_swclass(drm), NULL, 0, &drm->nvsw);
if (ret == 0) {
- struct nouveau_software_chan *swch;
+ struct nvkm_sw_chan *swch;
ret = RING_SPACE(drm->channel, 2);
if (ret == 0) {
if (device->info.family < NV_DEVICE_INFO_V0_FERMI) {
@@ -242,7 +243,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
OUT_RING (drm->channel, 0x001f0000);
}
}
- swch = (void *)nvkm_object(&drm->nvsw)->parent;
+ swch = (void *)nvxx_object(&drm->nvsw)->parent;
swch->flip = nouveau_flip_complete;
swch->flip_data = drm->channel;
}
@@ -254,8 +255,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
}
if (device->info.family < NV_DEVICE_INFO_V0_FERMI) {
- ret = nouveau_gpuobj_new(nvkm_object(&drm->device), NULL, 32,
- 0, 0, &drm->notify);
+ ret = nvkm_gpuobj_new(nvxx_object(&drm->device), NULL, 32,
+ 0, 0, &drm->notify);
if (ret) {
NV_ERROR(drm, "failed to allocate notifier, %d\n", ret);
nouveau_accel_fini(drm);
@@ -284,7 +285,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
static int nouveau_drm_probe(struct pci_dev *pdev,
const struct pci_device_id *pent)
{
- struct nouveau_device *device;
+ struct nvkm_device *device;
struct apertures_struct *aper;
bool boot = false;
int ret;
@@ -317,9 +318,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
remove_conflicting_framebuffers(aper, "nouveaufb", boot);
kfree(aper);
- ret = nouveau_device_create(pdev, NOUVEAU_BUS_PCI,
- nouveau_pci_name(pdev), pci_name(pdev),
- nouveau_config, nouveau_debug, &device);
+ ret = nvkm_device_create(pdev, NVKM_BUS_PCI,
+ nouveau_pci_name(pdev), pci_name(pdev),
+ nouveau_config, nouveau_debug, &device);
if (ret)
return ret;
@@ -327,7 +328,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
ret = drm_get_pci_dev(pdev, pent, &driver_pci);
if (ret) {
- nouveau_object_ref(NULL, (struct nouveau_object **)&device);
+ nvkm_object_ref(NULL, (struct nvkm_object **)&device);
return ret;
}
@@ -378,8 +379,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
dev->dev_private = drm;
drm->dev = dev;
- nvkm_client(&drm->client.base)->debug =
- nouveau_dbgopt(nouveau_debug, "DRM");
+ nvxx_client(&drm->client.base)->debug =
+ nvkm_dbgopt(nouveau_debug, "DRM");
INIT_LIST_HEAD(&drm->clients);
spin_lock_init(&drm->tile.lock);
@@ -434,12 +435,12 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
nouveau_agp_init(drm);
if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
- ret = nouveau_vm_new(nvkm_device(&drm->device), 0, (1ULL << 40),
- 0x1000, &drm->client.vm);
+ ret = nvkm_vm_new(nvxx_device(&drm->device), 0, (1ULL << 40),
+ 0x1000, &drm->client.vm);
if (ret)
goto fail_device;
- nvkm_client(&drm->client.base)->vm = drm->client.vm;
+ nvxx_client(&drm->client.base)->vm = drm->client.vm;
}
ret = nouveau_ttm_init(drm);
@@ -522,18 +523,17 @@ void
nouveau_drm_device_remove(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_client *client;
- struct nouveau_object *device;
+ struct nvkm_client *client;
+ struct nvkm_object *device;
dev->irq_enabled = false;
- client = nvkm_client(&drm->client.base);
+ client = nvxx_client(&drm->client.base);
device = client->device;
drm_put_dev(dev);
- nouveau_object_ref(NULL, &device);
- nouveau_object_debug();
+ nvkm_object_ref(NULL, &device);
+ nvkm_object_debug();
}
-EXPORT_SYMBOL(nouveau_drm_device_remove);
static void
nouveau_drm_remove(struct pci_dev *pdev)
@@ -831,14 +831,14 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
cli->base.super = false;
if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
- ret = nouveau_vm_new(nvkm_device(&drm->device), 0, (1ULL << 40),
- 0x1000, &cli->vm);
+ ret = nvkm_vm_new(nvxx_device(&drm->device), 0, (1ULL << 40),
+ 0x1000, &cli->vm);
if (ret) {
nouveau_cli_destroy(cli);
goto out_suspend;
}
- nvkm_client(&cli->base)->vm = cli->vm;
+ nvxx_client(&cli->base)->vm = cli->vm;
}
fpriv->driver_priv = cli;
@@ -1056,10 +1056,10 @@ nouveau_platform_device_create_(struct platform_device *pdev, int size,
struct drm_device *drm;
int err;
- err = nouveau_device_create_(pdev, NOUVEAU_BUS_PLATFORM,
- nouveau_platform_name(pdev),
- dev_name(&pdev->dev), nouveau_config,
- nouveau_debug, size, pobject);
+ err = nvkm_device_create_(pdev, NVKM_BUS_PLATFORM,
+ nouveau_platform_name(pdev),
+ dev_name(&pdev->dev), nouveau_config,
+ nouveau_debug, size, pobject);
if (err)
return ERR_PTR(err);
@@ -1079,11 +1079,10 @@ nouveau_platform_device_create_(struct platform_device *pdev, int size,
return drm;
err_free:
- nouveau_object_ref(NULL, (struct nouveau_object **)pobject);
+ nvkm_object_ref(NULL, (struct nvkm_object **)pobject);
return ERR_PTR(err);
}
-EXPORT_SYMBOL(nouveau_platform_device_create_);
static int __init
nouveau_drm_init(void)
@@ -1105,6 +1104,10 @@ nouveau_drm_init(void)
if (!nouveau_modeset)
return 0;
+#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
+ platform_driver_register(&nouveau_platform_driver);
+#endif
+
nouveau_register_dsm_handler();
return drm_pci_init(&driver_pci, &nouveau_drm_pci_driver);
}
@@ -1117,6 +1120,10 @@ nouveau_drm_exit(void)
drm_pci_exit(&driver_pci, &nouveau_drm_pci_driver);
nouveau_unregister_dsm_handler();
+
+#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
+ platform_driver_unregister(&nouveau_platform_driver);
+#endif
}
module_init(nouveau_drm_init);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 8ae36f265fb8..fc68f0973f9e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -80,7 +80,7 @@ enum nouveau_drm_handle {
struct nouveau_cli {
struct nvif_client base;
- struct nouveau_vm *vm; /*XXX*/
+ struct nvkm_vm *vm; /*XXX*/
struct list_head head;
struct mutex mutex;
void *abi16;
@@ -142,7 +142,7 @@ struct nouveau_drm {
/* context for accelerated drm-internal operations */
struct nouveau_channel *cechan;
struct nouveau_channel *channel;
- struct nouveau_gpuobj *notify;
+ struct nvkm_gpuobj *notify;
struct nouveau_fbdev *fbcon;
struct nvif_object nvsw;
struct nvif_object ntfy;
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index 5f0e37fc2849..c57a37e8e1eb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -34,14 +34,14 @@
#define NV_DPMS_CLEARED 0x80
-struct nouveau_i2c_port;
+struct nvkm_i2c_port;
struct nouveau_encoder {
struct drm_encoder_slave base;
struct dcb_output *dcb;
int or;
- struct nouveau_i2c_port *i2c;
+ struct nvkm_i2c_port *i2c;
/* different to drm_encoder.crtc, this reflects what's
* actually programmed on the hw, not the proposed crtc */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 3ed12a8cfc91..79924e4b1b49 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -370,6 +370,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
ret = -ENOMEM;
goto out_unlock;
}
+ info->skip_vt_switch = 1;
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
@@ -487,30 +488,17 @@ static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
.fb_probe = nouveau_fbcon_create,
};
-static void
-nouveau_fbcon_set_suspend_work(struct work_struct *work)
-{
- struct nouveau_fbdev *fbcon = container_of(work, typeof(*fbcon), work);
- console_lock();
- nouveau_fbcon_accel_restore(fbcon->dev);
- nouveau_fbcon_zfill(fbcon->dev, fbcon);
- fb_set_suspend(fbcon->helper.fbdev, FBINFO_STATE_RUNNING);
- console_unlock();
-}
-
void
nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
{
struct nouveau_drm *drm = nouveau_drm(dev);
if (drm->fbcon) {
- if (state == FBINFO_STATE_RUNNING) {
- schedule_work(&drm->fbcon->work);
- return;
- }
- flush_work(&drm->fbcon->work);
console_lock();
+ if (state == FBINFO_STATE_RUNNING)
+ nouveau_fbcon_accel_restore(dev);
fb_set_suspend(drm->fbcon->helper.fbdev, state);
- nouveau_fbcon_accel_save_disable(dev);
+ if (state != FBINFO_STATE_RUNNING)
+ nouveau_fbcon_accel_save_disable(dev);
console_unlock();
}
}
@@ -531,7 +519,6 @@ nouveau_fbcon_init(struct drm_device *dev)
if (!fbcon)
return -ENOMEM;
- INIT_WORK(&fbcon->work, nouveau_fbcon_set_suspend_work);
fbcon->dev = dev;
drm->fbcon = fbcon;
@@ -539,12 +526,12 @@ nouveau_fbcon_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &fbcon->helper,
dev->mode_config.num_crtc, 4);
- if (ret) {
- kfree(fbcon);
- return ret;
- }
+ if (ret)
+ goto free;
- drm_fb_helper_single_add_all_connectors(&fbcon->helper);
+ ret = drm_fb_helper_single_add_all_connectors(&fbcon->helper);
+ if (ret)
+ goto fini;
if (drm->device.info.ram_size <= 32 * 1024 * 1024)
preferred_bpp = 8;
@@ -557,8 +544,17 @@ nouveau_fbcon_init(struct drm_device *dev)
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);
- drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
+ ret = drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
+ if (ret)
+ goto fini;
+
return 0;
+
+fini:
+ drm_fb_helper_fini(&fbcon->helper);
+free:
+ kfree(fbcon);
+ return ret;
}
void
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
index 6208e70e4a1c..1e2e9e27a03b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
@@ -36,7 +36,6 @@ struct nouveau_fbdev {
struct nouveau_framebuffer nouveau_fb;
struct list_head fbdev_list;
struct drm_device *dev;
- struct work_struct work;
unsigned int saved_flags;
struct nvif_object surf2d;
struct nvif_object clip;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index f32a434724e3..c6d56bef5823 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -182,7 +182,7 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
else if (chan == chan->drm->channel)
strcpy(fctx->name, "generic kernel channel");
else
- strcpy(fctx->name, nvkm_client(&cli->base)->name);
+ strcpy(fctx->name, nvxx_client(&cli->base)->name);
kref_init(&fctx->fence_ref);
if (!priv->uevent)
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
index 96e461c6f68f..d9241d8247fb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -89,9 +89,9 @@ int nouveau_flip_complete(void *chan);
struct nv84_fence_chan {
struct nouveau_fence_chan base;
- struct nouveau_vma vma;
- struct nouveau_vma vma_gart;
- struct nouveau_vma dispc_vma[4];
+ struct nvkm_vma vma;
+ struct nvkm_vma vma_gart;
+ struct nvkm_vma dispc_vma[4];
};
struct nv84_fence_priv {
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index bf0f9e21d714..7c077fced1d1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -64,7 +64,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
- struct nouveau_vma *vma;
+ struct nvkm_vma *vma;
struct device *dev = drm->dev->dev;
int ret;
@@ -105,14 +105,14 @@ out:
static void
nouveau_gem_object_delete(void *data)
{
- struct nouveau_vma *vma = data;
- nouveau_vm_unmap(vma);
- nouveau_vm_put(vma);
+ struct nvkm_vma *vma = data;
+ nvkm_vm_unmap(vma);
+ nvkm_vm_put(vma);
kfree(vma);
}
static void
-nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
+nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nvkm_vma *vma)
{
const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM;
struct reservation_object *resv = nvbo->bo.resv;
@@ -135,8 +135,8 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
nouveau_fence_work(fence, nouveau_gem_object_delete, vma);
} else {
if (mapped)
- nouveau_vm_unmap(vma);
- nouveau_vm_put(vma);
+ nvkm_vm_unmap(vma);
+ nvkm_vm_put(vma);
kfree(vma);
}
}
@@ -148,7 +148,7 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct device *dev = drm->dev->dev;
- struct nouveau_vma *vma;
+ struct nvkm_vma *vma;
int ret;
if (!cli->vm)
@@ -222,7 +222,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
{
struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
- struct nouveau_vma *vma;
+ struct nvkm_vma *vma;
if (nvbo->bo.mem.mem_type == TTM_PL_TT)
rep->domain = NOUVEAU_GEM_DOMAIN_GART;
@@ -251,7 +251,7 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_cli *cli = nouveau_cli(file_priv);
- struct nouveau_fb *pfb = nvkm_fb(&drm->device);
+ struct nvkm_fb *pfb = nvxx_fb(&drm->device);
struct drm_nouveau_gem_new *req = data;
struct nouveau_bo *nvbo = NULL;
int ret = 0;
@@ -850,19 +850,6 @@ out_next:
return nouveau_abi16_put(abi16, ret);
}
-static inline uint32_t
-domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain)
-{
- uint32_t flags = 0;
-
- if (domain & NOUVEAU_GEM_DOMAIN_VRAM)
- flags |= TTM_PL_FLAG_VRAM;
- if (domain & NOUVEAU_GEM_DOMAIN_GART)
- flags |= TTM_PL_FLAG_TT;
-
- return flags;
-}
-
int
nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
struct drm_file *file_priv)
diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index afb36d66e78d..0dbe0060f86e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -40,7 +40,7 @@ nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
int temp = therm->temp_get(therm);
if (temp < 0)
@@ -66,10 +66,10 @@ nouveau_hwmon_temp1_auto_point1_temp(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000);
}
static ssize_t
nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
@@ -78,13 +78,13 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST,
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST,
value / 1000);
return count;
@@ -99,10 +99,10 @@ nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
}
static ssize_t
nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
@@ -111,13 +111,13 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST,
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST,
value / 1000);
return count;
@@ -131,10 +131,10 @@ nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
}
static ssize_t
nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
@@ -142,13 +142,13 @@ nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
return count;
}
@@ -162,10 +162,10 @@ nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
}
static ssize_t
nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
@@ -173,13 +173,13 @@ nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST,
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
value / 1000);
return count;
@@ -194,10 +194,10 @@ nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
}
static ssize_t
nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
@@ -206,13 +206,13 @@ nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL, value / 1000);
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL, value / 1000);
return count;
}
@@ -227,10 +227,10 @@ nouveau_hwmon_critical_temp_hyst(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST) * 1000);
}
static ssize_t
nouveau_hwmon_set_critical_temp_hyst(struct device *d,
@@ -240,13 +240,13 @@ nouveau_hwmon_set_critical_temp_hyst(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST,
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_CRITICAL_HYST,
value / 1000);
return count;
@@ -260,10 +260,10 @@ nouveau_hwmon_emergency_temp(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN) * 1000);
}
static ssize_t
nouveau_hwmon_set_emergency_temp(struct device *d, struct device_attribute *a,
@@ -272,13 +272,13 @@ nouveau_hwmon_set_emergency_temp(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN, value / 1000);
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN, value / 1000);
return count;
}
@@ -293,10 +293,10 @@ nouveau_hwmon_emergency_temp_hyst(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST) * 1000);
+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST) * 1000);
}
static ssize_t
nouveau_hwmon_set_emergency_temp_hyst(struct device *d,
@@ -306,13 +306,13 @@ nouveau_hwmon_set_emergency_temp_hyst(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
if (kstrtol(buf, 10, &value) == -EINVAL)
return count;
- therm->attr_set(therm, NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST,
+ therm->attr_set(therm, NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST,
value / 1000);
return count;
@@ -346,7 +346,7 @@ nouveau_hwmon_show_fan1_input(struct device *d, struct device_attribute *attr,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
return snprintf(buf, PAGE_SIZE, "%d\n", therm->fan_sense(therm));
}
@@ -359,10 +359,10 @@ nouveau_hwmon_get_pwm1_enable(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
int ret;
- ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MODE);
+ ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MODE);
if (ret < 0)
return ret;
@@ -375,7 +375,7 @@ nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
int ret;
@@ -383,7 +383,7 @@ nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a,
if (ret)
return ret;
- ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MODE, value);
+ ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MODE, value);
if (ret)
return ret;
else
@@ -398,7 +398,7 @@ nouveau_hwmon_get_pwm1(struct device *d, struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
int ret;
ret = therm->fan_get(therm);
@@ -414,7 +414,7 @@ nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
int ret = -ENODEV;
long value;
@@ -438,10 +438,10 @@ nouveau_hwmon_get_pwm1_min(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
int ret;
- ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY);
+ ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY);
if (ret < 0)
return ret;
@@ -454,14 +454,14 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
int ret;
if (kstrtol(buf, 10, &value) == -EINVAL)
return -EINVAL;
- ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MIN_DUTY, value);
+ ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MIN_DUTY, value);
if (ret < 0)
return ret;
@@ -478,10 +478,10 @@ nouveau_hwmon_get_pwm1_max(struct device *d,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
int ret;
- ret = therm->attr_get(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY);
+ ret = therm->attr_get(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY);
if (ret < 0)
return ret;
@@ -494,14 +494,14 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct device_attribute *a,
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
long value;
int ret;
if (kstrtol(buf, 10, &value) == -EINVAL)
return -EINVAL;
- ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MAX_DUTY, value);
+ ret = therm->attr_set(therm, NVKM_THERM_ATTR_FAN_MAX_DUTY, value);
if (ret < 0)
return ret;
@@ -561,7 +561,7 @@ nouveau_hwmon_init(struct drm_device *dev)
{
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
- struct nouveau_therm *therm = nvkm_therm(&drm->device);
+ struct nvkm_therm *therm = nvxx_therm(&drm->device);
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_nvif.c b/drivers/gpu/drm/nouveau/nouveau_nvif.c
index 6544b84f0303..ca0ad9d1563d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_nvif.c
+++ b/drivers/gpu/drm/nouveau/nouveau_nvif.c
@@ -60,22 +60,22 @@ nvkm_client_ioctl(void *priv, bool super, void *data, u32 size, void **hack)
static int
nvkm_client_resume(void *priv)
{
- return nouveau_client_init(priv);
+ return nvkm_client_init(priv);
}
static int
nvkm_client_suspend(void *priv)
{
- return nouveau_client_fini(priv, true);
+ return nvkm_client_fini(priv, true);
}
static void
-nvkm_client_fini(void *priv)
+nvkm_client_driver_fini(void *priv)
{
- struct nouveau_object *client = priv;
- nouveau_client_fini(nv_client(client), false);
+ struct nvkm_object *client = priv;
+ nvkm_client_fini(nv_client(client), false);
atomic_set(&client->refcount, 1);
- nouveau_object_ref(NULL, &client);
+ nvkm_object_ref(NULL, &client);
}
static int
@@ -107,13 +107,13 @@ nvkm_client_ntfy(const void *header, u32 length, const void *data, u32 size)
}
static int
-nvkm_client_init(const char *name, u64 device, const char *cfg,
- const char *dbg, void **ppriv)
+nvkm_client_driver_init(const char *name, u64 device, const char *cfg,
+ const char *dbg, void **ppriv)
{
- struct nouveau_client *client;
+ struct nvkm_client *client;
int ret;
- ret = nouveau_client_create(name, device, cfg, dbg, &client);
+ ret = nvkm_client_create(name, device, cfg, dbg, &client);
*ppriv = client;
if (ret)
return ret;
@@ -125,8 +125,8 @@ nvkm_client_init(const char *name, u64 device, const char *cfg,
const struct nvif_driver
nvif_driver_nvkm = {
.name = "nvkm",
- .init = nvkm_client_init,
- .fini = nvkm_client_fini,
+ .init = nvkm_client_driver_init,
+ .fini = nvkm_client_driver_fini,
.suspend = nvkm_client_suspend,
.resume = nvkm_client_resume,
.ioctl = nvkm_client_ioctl,
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c
index b307bbedd4c4..dc5900bf54ff 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.c
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.c
@@ -152,7 +152,7 @@ static int nouveau_platform_remove(struct platform_device *pdev)
{
struct drm_device *drm_dev = platform_get_drvdata(pdev);
struct nouveau_drm *drm = nouveau_drm(drm_dev);
- struct nouveau_device *device = nvkm_device(&drm->device);
+ struct nvkm_device *device = nvxx_device(&drm->device);
struct nouveau_platform_gpu *gpu = nv_device_to_platform(device)->gpu;
nouveau_drm_device_remove(drm_dev);
@@ -177,9 +177,3 @@ struct platform_driver nouveau_platform_driver = {
.probe = nouveau_platform_probe,
.remove = nouveau_platform_remove,
};
-
-module_platform_driver(nouveau_platform_driver);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.h b/drivers/gpu/drm/nouveau/nouveau_platform.h
index 58c28b5653d5..268bb7213681 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.h
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.h
@@ -28,6 +28,7 @@
struct reset_control;
struct clk;
struct regulator;
+struct platform_driver;
struct nouveau_platform_gpu {
struct reset_control *rst;
@@ -38,7 +39,7 @@ struct nouveau_platform_gpu {
};
struct nouveau_platform_device {
- struct nouveau_device device;
+ struct nvkm_device device;
struct nouveau_platform_gpu *gpu;
@@ -48,4 +49,6 @@ struct nouveau_platform_device {
#define nv_device_to_platform(d) \
container_of(d, struct nouveau_platform_device, device)
+extern struct platform_driver nouveau_platform_driver;
+
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
index 43a96b99e180..7226f1f60901 100644
--- a/drivers/gpu/drm/nouveau/nouveau_reg.h
+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
@@ -72,7 +72,7 @@
# define NV_RAMHT_CONTEXT_VALID (1<<31)
# define NV_RAMHT_CONTEXT_CHANNEL_SHIFT 24
# define NV_RAMHT_CONTEXT_ENGINE_SHIFT 16
-# define NV_RAMHT_CONTEXT_ENGINE_SOFTWARE 0
+# define NV_RAMHT_CONTEXT_ENGINE_SW 0
# define NV_RAMHT_CONTEXT_ENGINE_GRAPHICS 1
# define NV_RAMHT_CONTEXT_INSTANCE_SHIFT 0
# define NV40_RAMHT_CONTEXT_CHANNEL_SHIFT 23
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index 01707e7deaf5..8c3053a177d6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -9,8 +9,7 @@ struct nouveau_sgdma_be {
* nouve_bo.c works properly, otherwise have to move them here
*/
struct ttm_dma_tt ttm;
- struct drm_device *dev;
- struct nouveau_mem *node;
+ struct nvkm_mem *node;
};
static void
@@ -28,7 +27,7 @@ static int
nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
{
struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct nouveau_mem *node = mem->mm_node;
+ struct nvkm_mem *node = mem->mm_node;
if (ttm->sg) {
node->sg = ttm->sg;
@@ -39,7 +38,7 @@ nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
}
node->size = (mem->num_pages << PAGE_SHIFT) >> 12;
- nouveau_vm_map(&node->vma[0], node);
+ nvkm_vm_map(&node->vma[0], node);
nvbe->node = node;
return 0;
}
@@ -48,7 +47,7 @@ static int
nv04_sgdma_unbind(struct ttm_tt *ttm)
{
struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- nouveau_vm_unmap(&nvbe->node->vma[0]);
+ nvkm_vm_unmap(&nvbe->node->vma[0]);
return 0;
}
@@ -62,7 +61,7 @@ static int
nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
{
struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
- struct nouveau_mem *node = mem->mm_node;
+ struct nvkm_mem *node = mem->mm_node;
/* noop: bound in move_notify() */
if (ttm->sg) {
@@ -101,13 +100,17 @@ nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
if (!nvbe)
return NULL;
- nvbe->dev = drm->dev;
if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA)
nvbe->ttm.ttm.func = &nv04_sgdma_backend;
else
nvbe->ttm.ttm.func = &nv50_sgdma_backend;
if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page))
+ /*
+ * A failing ttm_dma_tt_init() will call ttm_tt_destroy()
+ * and thus our nouveau_sgdma_destroy() hook, so we don't need
+ * to free nvbe here.
+ */
return NULL;
return &nvbe->ttm.ttm;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
index 8fbbf3093d86..1ec8f38ae69a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
@@ -165,7 +165,7 @@ nouveau_sysfs_fini(struct drm_device *dev)
struct nvif_device *device = &drm->device;
if (sysfs && sysfs->ctrl.priv) {
- device_remove_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate);
+ device_remove_file(nv_device_base(nvxx_device(device)), &dev_attr_pstate);
nvif_object_fini(&sysfs->ctrl);
}
@@ -192,7 +192,7 @@ nouveau_sysfs_init(struct drm_device *dev)
NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0,
&sysfs->ctrl);
if (ret == 0)
- device_create_file(nv_device_base(nvkm_device(device)), &dev_attr_pstate);
+ device_create_file(nv_device_base(nvxx_device(device)), &dev_attr_pstate);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 3d1cfcb96b6b..273e50110ec3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -33,7 +33,7 @@ static int
nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
{
struct nouveau_drm *drm = nouveau_bdev(man->bdev);
- struct nouveau_fb *pfb = nvkm_fb(&drm->device);
+ struct nvkm_fb *pfb = nvxx_fb(&drm->device);
man->priv = pfb;
return 0;
}
@@ -46,16 +46,16 @@ nouveau_vram_manager_fini(struct ttm_mem_type_manager *man)
}
static inline void
-nouveau_mem_node_cleanup(struct nouveau_mem *node)
+nvkm_mem_node_cleanup(struct nvkm_mem *node)
{
if (node->vma[0].node) {
- nouveau_vm_unmap(&node->vma[0]);
- nouveau_vm_put(&node->vma[0]);
+ nvkm_vm_unmap(&node->vma[0]);
+ nvkm_vm_put(&node->vma[0]);
}
if (node->vma[1].node) {
- nouveau_vm_unmap(&node->vma[1]);
- nouveau_vm_put(&node->vma[1]);
+ nvkm_vm_unmap(&node->vma[1]);
+ nvkm_vm_put(&node->vma[1]);
}
}
@@ -64,9 +64,9 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
struct ttm_mem_reg *mem)
{
struct nouveau_drm *drm = nouveau_bdev(man->bdev);
- struct nouveau_fb *pfb = nvkm_fb(&drm->device);
- nouveau_mem_node_cleanup(mem->mm_node);
- pfb->ram->put(pfb, (struct nouveau_mem **)&mem->mm_node);
+ struct nvkm_fb *pfb = nvxx_fb(&drm->device);
+ nvkm_mem_node_cleanup(mem->mm_node);
+ pfb->ram->put(pfb, (struct nvkm_mem **)&mem->mm_node);
}
static int
@@ -76,9 +76,9 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
struct ttm_mem_reg *mem)
{
struct nouveau_drm *drm = nouveau_bdev(man->bdev);
- struct nouveau_fb *pfb = nvkm_fb(&drm->device);
+ struct nvkm_fb *pfb = nvxx_fb(&drm->device);
struct nouveau_bo *nvbo = nouveau_bo(bo);
- struct nouveau_mem *node;
+ struct nvkm_mem *node;
u32 size_nc = 0;
int ret;
@@ -103,9 +103,9 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
static void
nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
{
- struct nouveau_fb *pfb = man->priv;
- struct nouveau_mm *mm = &pfb->vram;
- struct nouveau_mm_node *r;
+ struct nvkm_fb *pfb = man->priv;
+ struct nvkm_mm *mm = &pfb->vram;
+ struct nvkm_mm_node *r;
u32 total = 0, free = 0;
mutex_lock(&nv_subdev(pfb)->mutex);
@@ -150,7 +150,7 @@ static void
nouveau_gart_manager_del(struct ttm_mem_type_manager *man,
struct ttm_mem_reg *mem)
{
- nouveau_mem_node_cleanup(mem->mm_node);
+ nvkm_mem_node_cleanup(mem->mm_node);
kfree(mem->mm_node);
mem->mm_node = NULL;
}
@@ -163,7 +163,7 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
{
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
- struct nouveau_mem *node;
+ struct nvkm_mem *node;
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
@@ -203,15 +203,15 @@ const struct ttm_mem_type_manager_func nouveau_gart_manager = {
};
/*XXX*/
-#include <core/subdev/vm/nv04.h>
+#include <subdev/mmu/nv04.h>
static int
nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
{
struct nouveau_drm *drm = nouveau_bdev(man->bdev);
- struct nouveau_vmmgr *vmm = nvkm_vmmgr(&drm->device);
- struct nv04_vmmgr_priv *priv = (void *)vmm;
- struct nouveau_vm *vm = NULL;
- nouveau_vm_ref(priv->vm, &vm, NULL);
+ struct nvkm_mmu *mmu = nvxx_mmu(&drm->device);
+ struct nv04_mmu_priv *priv = (void *)mmu;
+ struct nvkm_vm *vm = NULL;
+ nvkm_vm_ref(priv->vm, &vm, NULL);
man->priv = vm;
return 0;
}
@@ -219,8 +219,8 @@ nv04_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
static int
nv04_gart_manager_fini(struct ttm_mem_type_manager *man)
{
- struct nouveau_vm *vm = man->priv;
- nouveau_vm_ref(NULL, &vm, NULL);
+ struct nvkm_vm *vm = man->priv;
+ nvkm_vm_ref(NULL, &vm, NULL);
man->priv = NULL;
return 0;
}
@@ -228,9 +228,9 @@ nv04_gart_manager_fini(struct ttm_mem_type_manager *man)
static void
nv04_gart_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem)
{
- struct nouveau_mem *node = mem->mm_node;
+ struct nvkm_mem *node = mem->mm_node;
if (node->vma[0].node)
- nouveau_vm_put(&node->vma[0]);
+ nvkm_vm_put(&node->vma[0]);
kfree(mem->mm_node);
mem->mm_node = NULL;
}
@@ -241,7 +241,7 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man,
const struct ttm_place *place,
struct ttm_mem_reg *mem)
{
- struct nouveau_mem *node;
+ struct nvkm_mem *node;
int ret;
node = kzalloc(sizeof(*node), GFP_KERNEL);
@@ -250,8 +250,8 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man,
node->page_shift = 12;
- ret = nouveau_vm_get(man->priv, mem->num_pages << 12, node->page_shift,
- NV_MEM_ACCESS_RW, &node->vma[0]);
+ ret = nvkm_vm_get(man->priv, mem->num_pages << 12, node->page_shift,
+ NV_MEM_ACCESS_RW, &node->vma[0]);
if (ret) {
kfree(node);
return ret;
@@ -354,8 +354,8 @@ nouveau_ttm_init(struct nouveau_drm *drm)
u32 bits;
int ret;
- bits = nvkm_vmmgr(&drm->device)->dma_bits;
- if (nv_device_is_pci(nvkm_device(&drm->device))) {
+ bits = nvxx_mmu(&drm->device)->dma_bits;
+ if (nv_device_is_pci(nvxx_device(&drm->device))) {
if (drm->agp.stat == ENABLED ||
!pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits)))
bits = 32;
@@ -396,12 +396,12 @@ nouveau_ttm_init(struct nouveau_drm *drm)
return ret;
}
- drm->ttm.mtrr = arch_phys_wc_add(nv_device_resource_start(nvkm_device(&drm->device), 1),
- nv_device_resource_len(nvkm_device(&drm->device), 1));
+ drm->ttm.mtrr = arch_phys_wc_add(nv_device_resource_start(nvxx_device(&drm->device), 1),
+ nv_device_resource_len(nvxx_device(&drm->device), 1));
/* GART init */
if (drm->agp.stat != ENABLED) {
- drm->gem.gart_available = nvkm_vmmgr(&drm->device)->limit;
+ drm->gem.gart_available = nvxx_mmu(&drm->device)->limit;
} else {
drm->gem.gart_available = drm->agp.size;
}
diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c
index f9859deb108a..c2e05e64cd6f 100644
--- a/drivers/gpu/drm/nouveau/nv04_fence.c
+++ b/drivers/gpu/drm/nouveau/nv04_fence.c
@@ -57,7 +57,7 @@ nv04_fence_sync(struct nouveau_fence *fence,
static u32
nv04_fence_read(struct nouveau_channel *chan)
{
- struct nouveau_fifo_chan *fifo = nvkm_fifo_chan(chan);;
+ struct nvkm_fifo_chan *fifo = nvxx_fifo_chan(chan);;
return atomic_read(&fifo->refcnt);
}
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 490b90866baf..7da7958556a3 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -125,7 +125,6 @@ nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head,
struct nv50_curs {
struct nv50_pioc base;
- struct nouveau_bo *image;
};
static int
@@ -201,7 +200,7 @@ nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp)
nv50_chan_destroy(&dmac->base);
if (dmac->ptr) {
- struct pci_dev *pdev = nvkm_device(nvif_device(disp))->pdev;
+ struct pci_dev *pdev = nvxx_device(nvif_device(disp))->pdev;
pci_free_consistent(pdev, PAGE_SIZE, dmac->ptr, dmac->handle);
}
}
@@ -218,7 +217,7 @@ nv50_dmac_create(struct nvif_object *disp, const u32 *oclass, u8 head,
mutex_init(&dmac->lock);
- dmac->ptr = pci_alloc_consistent(nvkm_device(device)->pdev,
+ dmac->ptr = pci_alloc_consistent(nvxx_device(device)->pdev,
PAGE_SIZE, &dmac->handle);
if (!dmac->ptr)
return -ENOMEM;
@@ -421,9 +420,9 @@ evo_wait(void *evoc, int nr)
dmac->ptr[put] = 0x20000000;
nvif_wr32(&dmac->base.user, 0x0000, 0x00000000);
- if (!nvkm_wait(&dmac->base.user, 0x0004, ~0, 0x00000000)) {
+ if (!nvxx_wait(&dmac->base.user, 0x0004, ~0, 0x00000000)) {
mutex_unlock(&dmac->lock);
- nv_error(nvkm_object(&dmac->base.user), "channel stalled\n");
+ nv_error(nvxx_object(&dmac->base.user), "channel stalled\n");
return NULL;
}
@@ -481,7 +480,7 @@ evo_sync(struct drm_device *dev)
evo_data(push, 0x00000000);
evo_data(push, 0x00000000);
evo_kick(push, mast);
- if (nv_wait_cb(nvkm_device(device), evo_sync_wait, disp->sync))
+ if (nv_wait_cb(nvxx_device(device), evo_sync_wait, disp->sync))
return 0;
}
@@ -536,7 +535,7 @@ nv50_display_flip_stop(struct drm_crtc *crtc)
evo_kick(push, flip.chan);
}
- nv_wait_cb(nvkm_device(device), nv50_display_flip_wait, &flip);
+ nv_wait_cb(nvxx_device(device), nv50_display_flip_wait, &flip);
}
int
@@ -550,6 +549,10 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
u32 *push;
int ret;
+ if (crtc->primary->fb->width != fb->width ||
+ crtc->primary->fb->height != fb->height)
+ return -EINVAL;
+
swap_interval <<= 4;
if (swap_interval == 0)
swap_interval |= 0x100;
@@ -729,8 +732,11 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
* effectively handles NONE/FULL scaling
*/
nv_connector = nouveau_crtc_connector_get(nv_crtc);
- if (nv_connector && nv_connector->native_mode)
+ if (nv_connector && nv_connector->native_mode) {
mode = nv_connector->scaling_mode;
+ if (nv_connector->scaling_full) /* non-EDID LVDS/eDP mode */
+ mode = DRM_MODE_SCALE_FULLSCREEN;
+ }
if (mode != DRM_MODE_SCALE_NONE)
omode = nv_connector->native_mode;
@@ -917,29 +923,29 @@ static void
nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc)
{
struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
- struct nv50_curs *curs = nv50_curs(&nv_crtc->base);
u32 *push = evo_wait(mast, 16);
if (push) {
if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
evo_data(push, 0x85000000);
- evo_data(push, curs->image->bo.offset >> 8);
+ evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
} else
if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
evo_data(push, 0x85000000);
- evo_data(push, curs->image->bo.offset >> 8);
+ evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1);
evo_data(push, mast->base.vram.handle);
} else {
evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2);
evo_data(push, 0x85000000);
- evo_data(push, curs->image->bo.offset >> 8);
+ evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
evo_data(push, mast->base.vram.handle);
}
evo_kick(push, mast);
}
+ nv_crtc->cursor.visible = true;
}
static void
@@ -965,15 +971,15 @@ nv50_crtc_cursor_hide(struct nouveau_crtc *nv_crtc)
}
evo_kick(push, mast);
}
+ nv_crtc->cursor.visible = false;
}
static void
nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update)
{
struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
- struct nv50_curs *curs = nv50_curs(&nv_crtc->base);
- if (show && curs->image)
+ if (show && nv_crtc->cursor.nvbo)
nv50_crtc_cursor_show(nv_crtc);
else
nv50_crtc_cursor_hide(nv_crtc);
@@ -1273,7 +1279,6 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
uint32_t handle, uint32_t width, uint32_t height)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- struct nv50_curs *curs = nv50_curs(crtc);
struct drm_device *dev = crtc->dev;
struct drm_gem_object *gem = NULL;
struct nouveau_bo *nvbo = NULL;
@@ -1292,9 +1297,9 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
}
if (ret == 0) {
- if (curs->image)
- nouveau_bo_unpin(curs->image);
- nouveau_bo_ref(nvbo, &curs->image);
+ if (nv_crtc->cursor.nvbo)
+ nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+ nouveau_bo_ref(nvbo, &nv_crtc->cursor.nvbo);
}
drm_gem_object_unreference_unlocked(gem);
@@ -1305,10 +1310,14 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
static int
nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct nv50_curs *curs = nv50_curs(crtc);
struct nv50_chan *chan = nv50_chan(curs);
nvif_wr32(&chan->user, 0x0084, (y << 16) | (x & 0xffff));
nvif_wr32(&chan->user, 0x0080, 0x00000000);
+
+ nv_crtc->cursor_saved_x = x;
+ nv_crtc->cursor_saved_y = y;
return 0;
}
@@ -1330,6 +1339,14 @@ nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
}
static void
+nv50_crtc_cursor_restore(struct nouveau_crtc *nv_crtc, int x, int y)
+{
+ nv50_crtc_cursor_move(&nv_crtc->base, x, y);
+
+ nv50_crtc_cursor_show_hide(nv_crtc, true, true);
+}
+
+static void
nv50_crtc_destroy(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
@@ -1354,9 +1371,9 @@ nv50_crtc_destroy(struct drm_crtc *crtc)
nouveau_bo_ref(NULL, &head->image);
/*XXX: ditto */
- if (head->curs.image)
- nouveau_bo_unpin(head->curs.image);
- nouveau_bo_ref(NULL, &head->curs.image);
+ if (nv_crtc->cursor.nvbo)
+ nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+ nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
nouveau_bo_unmap(nv_crtc->lut.nvbo);
if (nv_crtc->lut.nvbo)
@@ -1406,6 +1423,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
head->base.set_color_vibrance = nv50_crtc_set_color_vibrance;
head->base.color_vibrance = 50;
head->base.vibrant_hue = 0;
+ head->base.cursor.set_pos = nv50_crtc_cursor_restore;
for (i = 0; i < 256; i++) {
head->base.lut.r[i] = i << 8;
head->base.lut.g[i] = i << 8;
@@ -1433,8 +1451,6 @@ nv50_crtc_create(struct drm_device *dev, int index)
if (ret)
goto out;
- nv50_crtc_lut_load(crtc);
-
/* allocate cursor resources */
ret = nv50_curs_create(disp->disp, index, &head->curs);
if (ret)
@@ -1466,6 +1482,41 @@ out:
}
/******************************************************************************
+ * Encoder helpers
+ *****************************************************************************/
+static bool
+nv50_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+ struct nouveau_connector *nv_connector;
+
+ nv_connector = nouveau_encoder_connector_get(nv_encoder);
+ if (nv_connector && nv_connector->native_mode) {
+ nv_connector->scaling_full = false;
+ if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) {
+ switch (nv_connector->type) {
+ case DCB_CONNECTOR_LVDS:
+ case DCB_CONNECTOR_LVDS_SPWG:
+ case DCB_CONNECTOR_eDP:
+ /* force use of scaler for non-edid modes */
+ if (adjusted_mode->type & DRM_MODE_TYPE_DRIVER)
+ return true;
+ nv_connector->scaling_full = true;
+ break;
+ default:
+ return true;
+ }
+ }
+
+ drm_mode_copy(adjusted_mode, nv_connector->native_mode);
+ }
+
+ return true;
+}
+
+/******************************************************************************
* DAC
*****************************************************************************/
static void
@@ -1492,26 +1543,6 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode)
nvif_mthd(disp->disp, 0, &args, sizeof(args));
}
-static bool
-nv50_dac_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct nouveau_connector *nv_connector;
-
- nv_connector = nouveau_encoder_connector_get(nv_encoder);
- if (nv_connector && nv_connector->native_mode) {
- if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
- int id = adjusted_mode->base.id;
- *adjusted_mode = *nv_connector->native_mode;
- adjusted_mode->base.id = id;
- }
- }
-
- return true;
-}
-
static void
nv50_dac_commit(struct drm_encoder *encoder)
{
@@ -1629,7 +1660,7 @@ nv50_dac_destroy(struct drm_encoder *encoder)
static const struct drm_encoder_helper_funcs nv50_dac_hfunc = {
.dpms = nv50_dac_dpms,
- .mode_fixup = nv50_dac_mode_fixup,
+ .mode_fixup = nv50_encoder_mode_fixup,
.prepare = nv50_dac_disconnect,
.commit = nv50_dac_commit,
.mode_set = nv50_dac_mode_set,
@@ -1646,7 +1677,7 @@ static int
nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
{
struct nouveau_drm *drm = nouveau_drm(connector->dev);
- struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
+ struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
int type = DRM_MODE_ENCODER_DAC;
@@ -1834,26 +1865,6 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
}
}
-static bool
-nv50_sor_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct nouveau_connector *nv_connector;
-
- nv_connector = nouveau_encoder_connector_get(nv_encoder);
- if (nv_connector && nv_connector->native_mode) {
- if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
- int id = adjusted_mode->base.id;
- *adjusted_mode = *nv_connector->native_mode;
- adjusted_mode->base.id = id;
- }
- }
-
- return true;
-}
-
static void
nv50_sor_ctrl(struct nouveau_encoder *nv_encoder, u32 mask, u32 data)
{
@@ -2035,7 +2046,7 @@ nv50_sor_destroy(struct drm_encoder *encoder)
static const struct drm_encoder_helper_funcs nv50_sor_hfunc = {
.dpms = nv50_sor_dpms,
- .mode_fixup = nv50_sor_mode_fixup,
+ .mode_fixup = nv50_encoder_mode_fixup,
.prepare = nv50_sor_disconnect,
.commit = nv50_sor_commit,
.mode_set = nv50_sor_mode_set,
@@ -2051,7 +2062,7 @@ static int
nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
{
struct nouveau_drm *drm = nouveau_drm(connector->dev);
- struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
+ struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
int type;
@@ -2112,18 +2123,8 @@ nv50_pior_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- struct nouveau_connector *nv_connector;
-
- nv_connector = nouveau_encoder_connector_get(nv_encoder);
- if (nv_connector && nv_connector->native_mode) {
- if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
- int id = adjusted_mode->base.id;
- *adjusted_mode = *nv_connector->native_mode;
- adjusted_mode->base.id = id;
- }
- }
-
+ if (!nv50_encoder_mode_fixup(encoder, mode, adjusted_mode))
+ return false;
adjusted_mode->clock *= 2;
return true;
}
@@ -2232,8 +2233,8 @@ static int
nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
{
struct nouveau_drm *drm = nouveau_drm(connector->dev);
- struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
- struct nouveau_i2c_port *ddc = NULL;
+ struct nvkm_i2c *i2c = nvxx_i2c(&drm->device);
+ struct nvkm_i2c_port *ddc = NULL;
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
int type;
@@ -2427,6 +2428,8 @@ nv50_display_init(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nv50_sync *sync = nv50_sync(crtc);
+
+ nv50_crtc_lut_load(crtc);
nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data);
}
diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c
index cb5b88938d45..bf429cabbaa8 100644
--- a/drivers/gpu/drm/nouveau/nv84_fence.c
+++ b/drivers/gpu/drm/nouveau/nv84_fence.c
@@ -213,7 +213,7 @@ nv84_fence_destroy(struct nouveau_drm *drm)
int
nv84_fence_create(struct nouveau_drm *drm)
{
- struct nouveau_fifo *pfifo = nvkm_fifo(&drm->device);
+ struct nvkm_fifo *pfifo = nvxx_fifo(&drm->device);
struct nv84_fence_priv *priv;
int ret;
diff --git a/drivers/gpu/drm/nouveau/nvif/Kbuild b/drivers/gpu/drm/nouveau/nvif/Kbuild
new file mode 100644
index 000000000000..ff8ed3a04d06
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvif/Kbuild
@@ -0,0 +1,4 @@
+nvif-y := nvif/object.o
+nvif-y += nvif/client.o
+nvif-y += nvif/device.o
+nvif-y += nvif/notify.o
diff --git a/drivers/gpu/drm/nouveau/nvif/client.c b/drivers/gpu/drm/nouveau/nvif/client.c
index 3f7ac5bc8e03..80b96844221e 100644
--- a/drivers/gpu/drm/nouveau/nvif/client.c
+++ b/drivers/gpu/drm/nouveau/nvif/client.c
@@ -22,9 +22,9 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-#include "client.h"
-#include "driver.h"
-#include "ioctl.h"
+#include <nvif/client.h>
+#include <nvif/driver.h>
+#include <nvif/ioctl.h>
int
nvif_client_ioctl(struct nvif_client *client, void *data, u32 size)
diff --git a/drivers/gpu/drm/nouveau/nvif/device.c b/drivers/gpu/drm/nouveau/nvif/device.c
index f477579725e3..6f72244c52cd 100644
--- a/drivers/gpu/drm/nouveau/nvif/device.c
+++ b/drivers/gpu/drm/nouveau/nvif/device.c
@@ -22,7 +22,7 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-#include "device.h"
+#include <nvif/device.h>
void
nvif_device_fini(struct nvif_device *device)
diff --git a/drivers/gpu/drm/nouveau/nvif/device.h b/drivers/gpu/drm/nouveau/nvif/device.h
deleted file mode 100644
index 43180f9fe630..000000000000
--- a/drivers/gpu/drm/nouveau/nvif/device.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __NVIF_DEVICE_H__
-#define __NVIF_DEVICE_H__
-
-#include "object.h"
-#include "class.h"
-
-struct nvif_device {
- struct nvif_object base;
- struct nvif_object *object; /*XXX: hack for nvif_object() */
- struct nv_device_info_v0 info;
-};
-
-static inline struct nvif_device *
-nvif_device(struct nvif_object *object)
-{
- while (object && object->oclass != 0x0080 /*XXX: NV_DEVICE_CLASS*/ )
- object = object->parent;
- return (void *)object;
-}
-
-int nvif_device_init(struct nvif_object *, void (*dtor)(struct nvif_device *),
- u32 handle, u32 oclass, void *, u32,
- struct nvif_device *);
-void nvif_device_fini(struct nvif_device *);
-int nvif_device_new(struct nvif_object *, u32 handle, u32 oclass,
- void *, u32, struct nvif_device **);
-void nvif_device_ref(struct nvif_device *, struct nvif_device **);
-
-/*XXX*/
-#include <subdev/bios.h>
-#include <subdev/fb.h>
-#include <subdev/vm.h>
-#include <subdev/bar.h>
-#include <subdev/gpio.h>
-#include <subdev/clock.h>
-#include <subdev/i2c.h>
-#include <subdev/timer.h>
-#include <subdev/therm.h>
-
-#define nvkm_device(a) nv_device(nvkm_object((a)))
-#define nvkm_bios(a) nouveau_bios(nvkm_device(a))
-#define nvkm_fb(a) nouveau_fb(nvkm_device(a))
-#define nvkm_vmmgr(a) nouveau_vmmgr(nvkm_device(a))
-#define nvkm_bar(a) nouveau_bar(nvkm_device(a))
-#define nvkm_gpio(a) nouveau_gpio(nvkm_device(a))
-#define nvkm_clock(a) nouveau_clock(nvkm_device(a))
-#define nvkm_i2c(a) nouveau_i2c(nvkm_device(a))
-#define nvkm_timer(a) nouveau_timer(nvkm_device(a))
-#define nvkm_wait(a,b,c,d) nv_wait(nvkm_timer(a), (b), (c), (d))
-#define nvkm_wait_cb(a,b,c) nv_wait_cb(nvkm_timer(a), (b), (c))
-#define nvkm_therm(a) nouveau_therm(nvkm_device(a))
-
-#include <engine/device.h>
-#include <engine/fifo.h>
-#include <engine/graph.h>
-#include <engine/software.h>
-
-#define nvkm_fifo(a) nouveau_fifo(nvkm_device(a))
-#define nvkm_fifo_chan(a) ((struct nouveau_fifo_chan *)nvkm_object(a))
-#define nvkm_gr(a) ((struct nouveau_graph *)nouveau_engine(nvkm_object(a), NVDEV_ENGINE_GR))
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c
index 0898c3155292..8e34748709a0 100644
--- a/drivers/gpu/drm/nouveau/nvif/notify.c
+++ b/drivers/gpu/drm/nouveau/nvif/notify.c
@@ -92,7 +92,7 @@ nvif_notify_func(struct nvif_notify *notify, bool keep)
{
int ret = notify->func(notify);
if (ret == NVIF_NOTIFY_KEEP ||
- !test_and_clear_bit(NVKM_NOTIFY_USER, &notify->flags)) {
+ !test_and_clear_bit(NVIF_NOTIFY_USER, &notify->flags)) {
if (!keep)
atomic_dec(&notify->putcnt);
else
diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c
index dd85b56f6aa5..3ab4e2f8cc12 100644
--- a/drivers/gpu/drm/nouveau/nvif/object.c
+++ b/drivers/gpu/drm/nouveau/nvif/object.c
@@ -22,10 +22,10 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-#include "object.h"
-#include "client.h"
-#include "driver.h"
-#include "ioctl.h"
+#include <nvif/object.h>
+#include <nvif/client.h>
+#include <nvif/driver.h>
+#include <nvif/ioctl.h>
int
nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack)
diff --git a/drivers/gpu/drm/nouveau/nvif/os.h b/drivers/gpu/drm/nouveau/nvif/os.h
deleted file mode 120000
index bd744b2cf5cf..000000000000
--- a/drivers/gpu/drm/nouveau/nvif/os.h
+++ /dev/null
@@ -1 +0,0 @@
-../core/os.h \ No newline at end of file
diff --git a/drivers/gpu/drm/nouveau/nvkm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/Kbuild
new file mode 100644
index 000000000000..2832147b676c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/Kbuild
@@ -0,0 +1,3 @@
+include $(src)/nvkm/core/Kbuild
+include $(src)/nvkm/subdev/Kbuild
+include $(src)/nvkm/engine/Kbuild
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/Kbuild b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild
new file mode 100644
index 000000000000..a2bdb2069113
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild
@@ -0,0 +1,17 @@
+nvkm-y := nvkm/core/client.o
+nvkm-y += nvkm/core/engctx.o
+nvkm-y += nvkm/core/engine.o
+nvkm-y += nvkm/core/enum.o
+nvkm-y += nvkm/core/event.o
+nvkm-y += nvkm/core/gpuobj.o
+nvkm-y += nvkm/core/handle.o
+nvkm-y += nvkm/core/ioctl.o
+nvkm-y += nvkm/core/mm.o
+nvkm-y += nvkm/core/namedb.o
+nvkm-y += nvkm/core/notify.o
+nvkm-y += nvkm/core/object.o
+nvkm-y += nvkm/core/option.o
+nvkm-y += nvkm/core/parent.o
+nvkm-y += nvkm/core/printk.o
+nvkm-y += nvkm/core/ramht.o
+nvkm-y += nvkm/core/subdev.o
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c
index e962433294c3..878a82f8f295 100644
--- a/drivers/gpu/drm/nouveau/core/core/client.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c
@@ -21,21 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
#include <core/client.h>
+#include <core/device.h>
#include <core/handle.h>
+#include <core/notify.h>
#include <core/option.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-#include <nvif/unpack.h>
+#include <nvif/class.h>
#include <nvif/event.h>
-
-#include <engine/device.h>
+#include <nvif/unpack.h>
struct nvkm_client_notify {
- struct nouveau_client *client;
+ struct nvkm_client *client;
struct nvkm_notify n;
u8 version;
u8 size;
@@ -48,12 +45,12 @@ static int
nvkm_client_notify(struct nvkm_notify *n)
{
struct nvkm_client_notify *notify = container_of(n, typeof(*notify), n);
- struct nouveau_client *client = notify->client;
+ struct nvkm_client *client = notify->client;
return client->ntfy(&notify->rep, notify->size, n->data, n->size);
}
int
-nvkm_client_notify_put(struct nouveau_client *client, int index)
+nvkm_client_notify_put(struct nvkm_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (client->notify[index]) {
@@ -65,7 +62,7 @@ nvkm_client_notify_put(struct nouveau_client *client, int index)
}
int
-nvkm_client_notify_get(struct nouveau_client *client, int index)
+nvkm_client_notify_get(struct nvkm_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (client->notify[index]) {
@@ -77,7 +74,7 @@ nvkm_client_notify_get(struct nouveau_client *client, int index)
}
int
-nvkm_client_notify_del(struct nouveau_client *client, int index)
+nvkm_client_notify_del(struct nvkm_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (client->notify[index]) {
@@ -91,10 +88,10 @@ nvkm_client_notify_del(struct nouveau_client *client, int index)
}
int
-nvkm_client_notify_new(struct nouveau_object *object,
+nvkm_client_notify_new(struct nvkm_object *object,
struct nvkm_event *event, void *data, u32 size)
{
- struct nouveau_client *client = nouveau_client(object);
+ struct nvkm_client *client = nvkm_client(object);
struct nvkm_client_notify *notify;
union {
struct nvif_notify_req_v0 v0;
@@ -142,7 +139,7 @@ nvkm_client_notify_new(struct nouveau_object *object,
}
static int
-nouveau_client_devlist(struct nouveau_object *object, void *data, u32 size)
+nvkm_client_mthd_devlist(struct nvkm_object *object, void *data, u32 size)
{
union {
struct nv_client_devlist_v0 v0;
@@ -154,8 +151,7 @@ nouveau_client_devlist(struct nouveau_object *object, void *data, u32 size)
nv_ioctl(object, "client devlist vers %d count %d\n",
args->v0.version, args->v0.count);
if (size == sizeof(args->v0.device[0]) * args->v0.count) {
- ret = nouveau_device_list(args->v0.device,
- args->v0.count);
+ ret = nvkm_device_list(args->v0.device, args->v0.count);
if (ret >= 0) {
args->v0.count = ret;
ret = 0;
@@ -169,12 +165,11 @@ nouveau_client_devlist(struct nouveau_object *object, void *data, u32 size)
}
static int
-nouveau_client_mthd(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
+nvkm_client_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
switch (mthd) {
case NV_CLIENT_DEVLIST:
- return nouveau_client_devlist(object, data, size);
+ return nvkm_client_mthd_devlist(object, data, size);
default:
break;
}
@@ -182,71 +177,71 @@ nouveau_client_mthd(struct nouveau_object *object, u32 mthd,
}
static void
-nouveau_client_dtor(struct nouveau_object *object)
+nvkm_client_dtor(struct nvkm_object *object)
{
- struct nouveau_client *client = (void *)object;
+ struct nvkm_client *client = (void *)object;
int i;
for (i = 0; i < ARRAY_SIZE(client->notify); i++)
nvkm_client_notify_del(client, i);
- nouveau_object_ref(NULL, &client->device);
- nouveau_handle_destroy(client->root);
- nouveau_namedb_destroy(&client->base);
+ nvkm_object_ref(NULL, &client->device);
+ nvkm_handle_destroy(client->root);
+ nvkm_namedb_destroy(&client->namedb);
}
-static struct nouveau_oclass
-nouveau_client_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
- .dtor = nouveau_client_dtor,
- .mthd = nouveau_client_mthd,
+static struct nvkm_oclass
+nvkm_client_oclass = {
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .dtor = nvkm_client_dtor,
+ .mthd = nvkm_client_mthd,
},
};
int
-nouveau_client_create_(const char *name, u64 devname, const char *cfg,
- const char *dbg, int length, void **pobject)
+nvkm_client_create_(const char *name, u64 devname, const char *cfg,
+ const char *dbg, int length, void **pobject)
{
- struct nouveau_object *device;
- struct nouveau_client *client;
+ struct nvkm_object *device;
+ struct nvkm_client *client;
int ret;
- device = (void *)nouveau_device_find(devname);
+ device = (void *)nvkm_device_find(devname);
if (!device)
return -ENODEV;
- ret = nouveau_namedb_create_(NULL, NULL, &nouveau_client_oclass,
- NV_CLIENT_CLASS, NULL,
- (1ULL << NVDEV_ENGINE_DEVICE),
- length, pobject);
+ ret = nvkm_namedb_create_(NULL, NULL, &nvkm_client_oclass,
+ NV_CLIENT_CLASS, NULL,
+ (1ULL << NVDEV_ENGINE_DEVICE),
+ length, pobject);
client = *pobject;
if (ret)
return ret;
- ret = nouveau_handle_create(nv_object(client), ~0, ~0,
- nv_object(client), &client->root);
+ ret = nvkm_handle_create(nv_object(client), ~0, ~0, nv_object(client),
+ &client->root);
if (ret)
return ret;
/* prevent init/fini being called, os in in charge of this */
atomic_set(&nv_object(client)->usecount, 2);
- nouveau_object_ref(device, &client->device);
+ nvkm_object_ref(device, &client->device);
snprintf(client->name, sizeof(client->name), "%s", name);
- client->debug = nouveau_dbgopt(dbg, "CLIENT");
+ client->debug = nvkm_dbgopt(dbg, "CLIENT");
return 0;
}
int
-nouveau_client_init(struct nouveau_client *client)
+nvkm_client_init(struct nvkm_client *client)
{
int ret;
nv_debug(client, "init running\n");
- ret = nouveau_handle_init(client->root);
+ ret = nvkm_handle_init(client->root);
nv_debug(client, "init completed with %d\n", ret);
return ret;
}
int
-nouveau_client_fini(struct nouveau_client *client, bool suspend)
+nvkm_client_fini(struct nvkm_client *client, bool suspend)
{
const char *name[2] = { "fini", "suspend" };
int ret, i;
@@ -255,16 +250,16 @@ nouveau_client_fini(struct nouveau_client *client, bool suspend)
for (i = 0; i < ARRAY_SIZE(client->notify); i++)
nvkm_client_notify_put(client, i);
nv_debug(client, "%s object\n", name[suspend]);
- ret = nouveau_handle_fini(client->root, suspend);
+ ret = nvkm_handle_fini(client->root, suspend);
nv_debug(client, "%s completed with %d\n", name[suspend], ret);
return ret;
}
const char *
-nouveau_client_name(void *obj)
+nvkm_client_name(void *obj)
{
const char *client_name = "unknown";
- struct nouveau_client *client = nouveau_client(obj);
+ struct nvkm_client *client = nvkm_client(obj);
if (client)
client_name = client->name;
return client_name;
diff --git a/drivers/gpu/drm/nouveau/core/core/engctx.c b/drivers/gpu/drm/nouveau/nvkm/core/engctx.c
index 84c71fad2b6c..fb2acbca75d9 100644
--- a/drivers/gpu/drm/nouveau/core/core/engctx.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/engctx.c
@@ -21,21 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
-#include <core/namedb.h>
-#include <core/handle.h>
-#include <core/client.h>
#include <core/engctx.h>
-
-#include <subdev/vm.h>
+#include <core/engine.h>
+#include <core/client.h>
static inline int
-nouveau_engctx_exists(struct nouveau_object *parent,
- struct nouveau_engine *engine, void **pobject)
+nvkm_engctx_exists(struct nvkm_object *parent,
+ struct nvkm_engine *engine, void **pobject)
{
- struct nouveau_engctx *engctx;
- struct nouveau_object *parctx;
+ struct nvkm_engctx *engctx;
+ struct nvkm_object *parctx;
list_for_each_entry(engctx, &engine->contexts, head) {
parctx = nv_pclass(nv_object(engctx), NV_PARENT_CLASS);
@@ -50,16 +45,13 @@ nouveau_engctx_exists(struct nouveau_object *parent,
}
int
-nouveau_engctx_create_(struct nouveau_object *parent,
- struct nouveau_object *engobj,
- struct nouveau_oclass *oclass,
- struct nouveau_object *pargpu,
- u32 size, u32 align, u32 flags,
- int length, void **pobject)
+nvkm_engctx_create_(struct nvkm_object *parent, struct nvkm_object *engobj,
+ struct nvkm_oclass *oclass, struct nvkm_object *pargpu,
+ u32 size, u32 align, u32 flags, int length, void **pobject)
{
- struct nouveau_client *client = nouveau_client(parent);
- struct nouveau_engine *engine = nv_engine(engobj);
- struct nouveau_object *engctx;
+ struct nvkm_client *client = nvkm_client(parent);
+ struct nvkm_engine *engine = nv_engine(engobj);
+ struct nvkm_object *engctx;
unsigned long save;
int ret;
@@ -67,7 +59,7 @@ nouveau_engctx_create_(struct nouveau_object *parent,
* and reference it instead of creating a new one
*/
spin_lock_irqsave(&engine->lock, save);
- ret = nouveau_engctx_exists(parent, engine, pobject);
+ ret = nvkm_engctx_exists(parent, engine, pobject);
spin_unlock_irqrestore(&engine->lock, save);
if (ret)
return ret;
@@ -76,13 +68,12 @@ nouveau_engctx_create_(struct nouveau_object *parent,
* objects backed by instance memory
*/
if (size) {
- ret = nouveau_gpuobj_create_(parent, engobj, oclass,
- NV_ENGCTX_CLASS,
- pargpu, size, align, flags,
- length, pobject);
+ ret = nvkm_gpuobj_create_(parent, engobj, oclass,
+ NV_ENGCTX_CLASS, pargpu, size,
+ align, flags, length, pobject);
} else {
- ret = nouveau_object_create_(parent, engobj, oclass,
- NV_ENGCTX_CLASS, length, pobject);
+ ret = nvkm_object_create_(parent, engobj, oclass,
+ NV_ENGCTX_CLASS, length, pobject);
}
engctx = *pobject;
@@ -94,15 +85,15 @@ nouveau_engctx_create_(struct nouveau_object *parent,
* it's not possible to allocate the object with it held.
*/
spin_lock_irqsave(&engine->lock, save);
- ret = nouveau_engctx_exists(parent, engine, pobject);
+ ret = nvkm_engctx_exists(parent, engine, pobject);
if (ret) {
spin_unlock_irqrestore(&engine->lock, save);
- nouveau_object_ref(NULL, &engctx);
+ nvkm_object_ref(NULL, &engctx);
return ret;
}
if (client->vm)
- atomic_inc(&client->vm->engref[nv_engidx(engobj)]);
+ atomic_inc(&client->vm->engref[nv_engidx(engine)]);
list_add(&nv_engctx(engctx)->head, &engine->contexts);
nv_engctx(engctx)->addr = ~0ULL;
spin_unlock_irqrestore(&engine->lock, save);
@@ -110,37 +101,36 @@ nouveau_engctx_create_(struct nouveau_object *parent,
}
void
-nouveau_engctx_destroy(struct nouveau_engctx *engctx)
+nvkm_engctx_destroy(struct nvkm_engctx *engctx)
{
- struct nouveau_object *engobj = nv_object(engctx)->engine;
- struct nouveau_engine *engine = nv_engine(engobj);
- struct nouveau_client *client = nouveau_client(engctx);
+ struct nvkm_engine *engine = engctx->gpuobj.object.engine;
+ struct nvkm_client *client = nvkm_client(engctx);
unsigned long save;
- nouveau_gpuobj_unmap(&engctx->vma);
+ nvkm_gpuobj_unmap(&engctx->vma);
spin_lock_irqsave(&engine->lock, save);
list_del(&engctx->head);
spin_unlock_irqrestore(&engine->lock, save);
if (client->vm)
- atomic_dec(&client->vm->engref[nv_engidx(engobj)]);
+ atomic_dec(&client->vm->engref[nv_engidx(engine)]);
- if (engctx->base.size)
- nouveau_gpuobj_destroy(&engctx->base);
+ if (engctx->gpuobj.size)
+ nvkm_gpuobj_destroy(&engctx->gpuobj);
else
- nouveau_object_destroy(&engctx->base.base);
+ nvkm_object_destroy(&engctx->gpuobj.object);
}
int
-nouveau_engctx_init(struct nouveau_engctx *engctx)
+nvkm_engctx_init(struct nvkm_engctx *engctx)
{
- struct nouveau_object *object = nv_object(engctx);
- struct nouveau_subdev *subdev = nv_subdev(object->engine);
- struct nouveau_object *parent;
- struct nouveau_subdev *pardev;
+ struct nvkm_object *object = nv_object(engctx);
+ struct nvkm_subdev *subdev = nv_subdev(object->engine);
+ struct nvkm_object *parent;
+ struct nvkm_subdev *pardev;
int ret;
- ret = nouveau_gpuobj_init(&engctx->base);
+ ret = nvkm_gpuobj_init(&engctx->gpuobj);
if (ret)
return ret;
@@ -163,12 +153,12 @@ nouveau_engctx_init(struct nouveau_engctx *engctx)
}
int
-nouveau_engctx_fini(struct nouveau_engctx *engctx, bool suspend)
+nvkm_engctx_fini(struct nvkm_engctx *engctx, bool suspend)
{
- struct nouveau_object *object = nv_object(engctx);
- struct nouveau_subdev *subdev = nv_subdev(object->engine);
- struct nouveau_object *parent;
- struct nouveau_subdev *pardev;
+ struct nvkm_object *object = nv_object(engctx);
+ struct nvkm_subdev *subdev = nv_subdev(object->engine);
+ struct nvkm_object *parent;
+ struct nvkm_subdev *pardev;
int ret = 0;
parent = nv_pclass(object->parent, NV_PARENT_CLASS);
@@ -186,47 +176,45 @@ nouveau_engctx_fini(struct nouveau_engctx *engctx, bool suspend)
}
nv_debug(parent, "detached %s context\n", subdev->name);
- return nouveau_gpuobj_fini(&engctx->base, suspend);
+ return nvkm_gpuobj_fini(&engctx->gpuobj, suspend);
}
int
-_nouveau_engctx_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+_nvkm_engctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_engctx *engctx;
+ struct nvkm_engctx *engctx;
int ret;
- ret = nouveau_engctx_create(parent, engine, oclass, NULL, 256, 256,
- NVOBJ_FLAG_ZERO_ALLOC, &engctx);
+ ret = nvkm_engctx_create(parent, engine, oclass, NULL, 256, 256,
+ NVOBJ_FLAG_ZERO_ALLOC, &engctx);
*pobject = nv_object(engctx);
return ret;
}
void
-_nouveau_engctx_dtor(struct nouveau_object *object)
+_nvkm_engctx_dtor(struct nvkm_object *object)
{
- nouveau_engctx_destroy(nv_engctx(object));
+ nvkm_engctx_destroy(nv_engctx(object));
}
int
-_nouveau_engctx_init(struct nouveau_object *object)
+_nvkm_engctx_init(struct nvkm_object *object)
{
- return nouveau_engctx_init(nv_engctx(object));
+ return nvkm_engctx_init(nv_engctx(object));
}
-
int
-_nouveau_engctx_fini(struct nouveau_object *object, bool suspend)
+_nvkm_engctx_fini(struct nvkm_object *object, bool suspend)
{
- return nouveau_engctx_fini(nv_engctx(object), suspend);
+ return nvkm_engctx_fini(nv_engctx(object), suspend);
}
-struct nouveau_object *
-nouveau_engctx_get(struct nouveau_engine *engine, u64 addr)
+struct nvkm_object *
+nvkm_engctx_get(struct nvkm_engine *engine, u64 addr)
{
- struct nouveau_engctx *engctx;
+ struct nvkm_engctx *engctx;
unsigned long flags;
spin_lock_irqsave(&engine->lock, flags);
@@ -241,11 +229,11 @@ nouveau_engctx_get(struct nouveau_engine *engine, u64 addr)
}
void
-nouveau_engctx_put(struct nouveau_object *object)
+nvkm_engctx_put(struct nvkm_object *object)
{
if (object) {
- struct nouveau_engine *engine = nv_engine(object->engine);
- struct nouveau_engctx *engctx = nv_engctx(object);
+ struct nvkm_engine *engine = nv_engine(object->engine);
+ struct nvkm_engctx *engctx = nv_engctx(object);
spin_unlock_irqrestore(&engine->lock, engctx->save);
}
}
diff --git a/drivers/gpu/drm/nouveau/core/core/engine.c b/drivers/gpu/drm/nouveau/nvkm/core/engine.c
index 1f6954ae9dd3..60820173c6aa 100644
--- a/drivers/gpu/drm/nouveau/core/core/engine.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/engine.c
@@ -21,33 +21,40 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/device.h>
#include <core/engine.h>
+#include <core/device.h>
#include <core/option.h>
+struct nvkm_engine *
+nvkm_engine(void *obj, int idx)
+{
+ obj = nvkm_subdev(obj, idx);
+ if (obj && nv_iclass(obj, NV_ENGINE_CLASS))
+ return nv_engine(obj);
+ return NULL;
+}
+
int
-nouveau_engine_create_(struct nouveau_object *parent,
- struct nouveau_object *engobj,
- struct nouveau_oclass *oclass, bool enable,
- const char *iname, const char *fname,
- int length, void **pobject)
+nvkm_engine_create_(struct nvkm_object *parent, struct nvkm_object *engobj,
+ struct nvkm_oclass *oclass, bool enable,
+ const char *iname, const char *fname,
+ int length, void **pobject)
{
- struct nouveau_engine *engine;
+ struct nvkm_engine *engine;
int ret;
- ret = nouveau_subdev_create_(parent, engobj, oclass, NV_ENGINE_CLASS,
- iname, fname, length, pobject);
+ ret = nvkm_subdev_create_(parent, engobj, oclass, NV_ENGINE_CLASS,
+ iname, fname, length, pobject);
engine = *pobject;
if (ret)
return ret;
if (parent) {
- struct nouveau_device *device = nv_device(parent);
- int engidx = nv_engidx(nv_object(engine));
+ struct nvkm_device *device = nv_device(parent);
+ int engidx = nv_engidx(engine);
if (device->disable_mask & (1ULL << engidx)) {
- if (!nouveau_boolopt(device->cfgopt, iname, false)) {
+ if (!nvkm_boolopt(device->cfgopt, iname, false)) {
nv_debug(engine, "engine disabled by hw/fw\n");
return -ENODEV;
}
@@ -55,7 +62,7 @@ nouveau_engine_create_(struct nouveau_object *parent,
nv_warn(engine, "ignoring hw/fw engine disable\n");
}
- if (!nouveau_boolopt(device->cfgopt, iname, enable)) {
+ if (!nvkm_boolopt(device->cfgopt, iname, enable)) {
if (!enable)
nv_warn(engine, "disabled, %s=1 to enable\n", iname);
return -ENODEV;
diff --git a/drivers/gpu/drm/nouveau/core/core/enum.c b/drivers/gpu/drm/nouveau/nvkm/core/enum.c
index dd434790ccc4..4f92bfc13d6b 100644
--- a/drivers/gpu/drm/nouveau/core/core/enum.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/enum.c
@@ -24,12 +24,10 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
-#include <core/os.h>
#include <core/enum.h>
-const struct nouveau_enum *
-nouveau_enum_find(const struct nouveau_enum *en, u32 value)
+const struct nvkm_enum *
+nvkm_enum_find(const struct nvkm_enum *en, u32 value)
{
while (en->name) {
if (en->value == value)
@@ -40,10 +38,10 @@ nouveau_enum_find(const struct nouveau_enum *en, u32 value)
return NULL;
}
-const struct nouveau_enum *
-nouveau_enum_print(const struct nouveau_enum *en, u32 value)
+const struct nvkm_enum *
+nvkm_enum_print(const struct nvkm_enum *en, u32 value)
{
- en = nouveau_enum_find(en, value);
+ en = nvkm_enum_find(en, value);
if (en)
pr_cont("%s", en->name);
else
@@ -52,7 +50,7 @@ nouveau_enum_print(const struct nouveau_enum *en, u32 value)
}
void
-nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
+nvkm_bitfield_print(const struct nvkm_bitfield *bf, u32 value)
{
while (bf->name) {
if (value & bf->mask) {
diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/nvkm/core/event.c
index 760947e380c9..4e8d3fa042df 100644
--- a/drivers/gpu/drm/nouveau/core/core/event.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/event.c
@@ -19,9 +19,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
-#include <core/object.h>
#include <core/event.h>
+#include <core/notify.h>
void
nvkm_event_put(struct nvkm_event *event, u32 types, int index)
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
new file mode 100644
index 000000000000..2eba801aae6f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include <core/gpuobj.h>
+#include <core/engine.h>
+
+#include <subdev/instmem.h>
+#include <subdev/bar.h>
+#include <subdev/mmu.h>
+
+void
+nvkm_gpuobj_destroy(struct nvkm_gpuobj *gpuobj)
+{
+ int i;
+
+ if (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE) {
+ for (i = 0; i < gpuobj->size; i += 4)
+ nv_wo32(gpuobj, i, 0x00000000);
+ }
+
+ if (gpuobj->node)
+ nvkm_mm_free(&nv_gpuobj(gpuobj->parent)->heap, &gpuobj->node);
+
+ if (gpuobj->heap.block_size)
+ nvkm_mm_fini(&gpuobj->heap);
+
+ nvkm_object_destroy(&gpuobj->object);
+}
+
+int
+nvkm_gpuobj_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 pclass,
+ struct nvkm_object *pargpu, u32 size, u32 align, u32 flags,
+ int length, void **pobject)
+{
+ struct nvkm_instmem *imem = nvkm_instmem(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
+ struct nvkm_gpuobj *gpuobj;
+ struct nvkm_mm *heap = NULL;
+ int ret, i;
+ u64 addr;
+
+ *pobject = NULL;
+
+ if (pargpu) {
+ while ((pargpu = nv_pclass(pargpu, NV_GPUOBJ_CLASS))) {
+ if (nv_gpuobj(pargpu)->heap.block_size)
+ break;
+ pargpu = pargpu->parent;
+ }
+
+ if (unlikely(pargpu == NULL)) {
+ nv_error(parent, "no gpuobj heap\n");
+ return -EINVAL;
+ }
+
+ addr = nv_gpuobj(pargpu)->addr;
+ heap = &nv_gpuobj(pargpu)->heap;
+ atomic_inc(&parent->refcount);
+ } else {
+ ret = imem->alloc(imem, parent, size, align, &parent);
+ pargpu = parent;
+ if (ret)
+ return ret;
+
+ addr = nv_memobj(pargpu)->addr;
+ size = nv_memobj(pargpu)->size;
+
+ if (bar && bar->alloc) {
+ struct nvkm_instobj *iobj = (void *)parent;
+ struct nvkm_mem **mem = (void *)(iobj + 1);
+ struct nvkm_mem *node = *mem;
+ if (!bar->alloc(bar, parent, node, &pargpu)) {
+ nvkm_object_ref(NULL, &parent);
+ parent = pargpu;
+ }
+ }
+ }
+
+ ret = nvkm_object_create_(parent, engine, oclass, pclass |
+ NV_GPUOBJ_CLASS, length, pobject);
+ nvkm_object_ref(NULL, &parent);
+ gpuobj = *pobject;
+ if (ret)
+ return ret;
+
+ gpuobj->parent = pargpu;
+ gpuobj->flags = flags;
+ gpuobj->addr = addr;
+ gpuobj->size = size;
+
+ if (heap) {
+ ret = nvkm_mm_head(heap, 0, 1, size, size, max(align, (u32)1),
+ &gpuobj->node);
+ if (ret)
+ return ret;
+
+ gpuobj->addr += gpuobj->node->offset;
+ }
+
+ if (gpuobj->flags & NVOBJ_FLAG_HEAP) {
+ ret = nvkm_mm_init(&gpuobj->heap, 0, gpuobj->size, 1);
+ if (ret)
+ return ret;
+ }
+
+ if (flags & NVOBJ_FLAG_ZERO_ALLOC) {
+ for (i = 0; i < gpuobj->size; i += 4)
+ nv_wo32(gpuobj, i, 0x00000000);
+ }
+
+ return ret;
+}
+
+struct nvkm_gpuobj_class {
+ struct nvkm_object *pargpu;
+ u64 size;
+ u32 align;
+ u32 flags;
+};
+
+static int
+_nvkm_gpuobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct nvkm_gpuobj_class *args = data;
+ struct nvkm_gpuobj *object;
+ int ret;
+
+ ret = nvkm_gpuobj_create(parent, engine, oclass, 0, args->pargpu,
+ args->size, args->align, args->flags,
+ &object);
+ *pobject = nv_object(object);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void
+_nvkm_gpuobj_dtor(struct nvkm_object *object)
+{
+ nvkm_gpuobj_destroy(nv_gpuobj(object));
+}
+
+int
+_nvkm_gpuobj_init(struct nvkm_object *object)
+{
+ return nvkm_gpuobj_init(nv_gpuobj(object));
+}
+
+int
+_nvkm_gpuobj_fini(struct nvkm_object *object, bool suspend)
+{
+ return nvkm_gpuobj_fini(nv_gpuobj(object), suspend);
+}
+
+u32
+_nvkm_gpuobj_rd32(struct nvkm_object *object, u64 addr)
+{
+ struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
+ struct nvkm_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
+ if (gpuobj->node)
+ addr += gpuobj->node->offset;
+ return pfuncs->rd32(gpuobj->parent, addr);
+}
+
+void
+_nvkm_gpuobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
+{
+ struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
+ struct nvkm_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
+ if (gpuobj->node)
+ addr += gpuobj->node->offset;
+ pfuncs->wr32(gpuobj->parent, addr, data);
+}
+
+static struct nvkm_oclass
+_nvkm_gpuobj_oclass = {
+ .handle = 0x00000000,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_gpuobj_ctor,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
+ },
+};
+
+int
+nvkm_gpuobj_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
+ u32 size, u32 align, u32 flags,
+ struct nvkm_gpuobj **pgpuobj)
+{
+ struct nvkm_object *engine = parent;
+ struct nvkm_gpuobj_class args = {
+ .pargpu = pargpu,
+ .size = size,
+ .align = align,
+ .flags = flags,
+ };
+
+ if (!nv_iclass(engine, NV_SUBDEV_CLASS))
+ engine = &engine->engine->subdev.object;
+ BUG_ON(engine == NULL);
+
+ return nvkm_object_ctor(parent, engine, &_nvkm_gpuobj_oclass,
+ &args, sizeof(args),
+ (struct nvkm_object **)pgpuobj);
+}
+
+int
+nvkm_gpuobj_map(struct nvkm_gpuobj *gpuobj, u32 access, struct nvkm_vma *vma)
+{
+ struct nvkm_bar *bar = nvkm_bar(gpuobj);
+ int ret = -EINVAL;
+
+ if (bar && bar->umap) {
+ struct nvkm_instobj *iobj = (void *)
+ nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
+ struct nvkm_mem **mem = (void *)(iobj + 1);
+ ret = bar->umap(bar, *mem, access, vma);
+ }
+
+ return ret;
+}
+
+int
+nvkm_gpuobj_map_vm(struct nvkm_gpuobj *gpuobj, struct nvkm_vm *vm,
+ u32 access, struct nvkm_vma *vma)
+{
+ struct nvkm_instobj *iobj = (void *)
+ nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
+ struct nvkm_mem **mem = (void *)(iobj + 1);
+ int ret;
+
+ ret = nvkm_vm_get(vm, gpuobj->size, 12, access, vma);
+ if (ret)
+ return ret;
+
+ nvkm_vm_map(vma, *mem);
+ return 0;
+}
+
+void
+nvkm_gpuobj_unmap(struct nvkm_vma *vma)
+{
+ if (vma->node) {
+ nvkm_vm_unmap(vma);
+ nvkm_vm_put(vma);
+ }
+}
+
+/* the below is basically only here to support sharing the paged dma object
+ * for PCI(E)GART on <=nv4x chipsets, and should *not* be expected to work
+ * anywhere else.
+ */
+
+static void
+nvkm_gpudup_dtor(struct nvkm_object *object)
+{
+ struct nvkm_gpuobj *gpuobj = (void *)object;
+ nvkm_object_ref(NULL, &gpuobj->parent);
+ nvkm_object_destroy(&gpuobj->object);
+}
+
+static struct nvkm_oclass
+nvkm_gpudup_oclass = {
+ .handle = NV_GPUOBJ_CLASS,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .dtor = nvkm_gpudup_dtor,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
+ },
+};
+
+int
+nvkm_gpuobj_dup(struct nvkm_object *parent, struct nvkm_gpuobj *base,
+ struct nvkm_gpuobj **pgpuobj)
+{
+ struct nvkm_gpuobj *gpuobj;
+ int ret;
+
+ ret = nvkm_object_create(parent, &parent->engine->subdev.object,
+ &nvkm_gpudup_oclass, 0, &gpuobj);
+ *pgpuobj = gpuobj;
+ if (ret)
+ return ret;
+
+ nvkm_object_ref(nv_object(base), &gpuobj->parent);
+ gpuobj->addr = base->addr;
+ gpuobj->size = base->size;
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/core/handle.c b/drivers/gpu/drm/nouveau/nvkm/core/handle.c
index 13f816cb08bd..dc7ff10ebe7b 100644
--- a/drivers/gpu/drm/nouveau/core/core/handle.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/handle.c
@@ -21,31 +21,29 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
#include <core/handle.h>
#include <core/client.h>
#define hprintk(h,l,f,a...) do { \
- struct nouveau_client *c = nouveau_client((h)->object); \
- struct nouveau_handle *p = (h)->parent; u32 n = p ? p->name : ~0; \
+ struct nvkm_client *c = nvkm_client((h)->object); \
+ struct nvkm_handle *p = (h)->parent; u32 n = p ? p->name : ~0; \
nv_printk((c), l, "0x%08x:0x%08x "f, n, (h)->name, ##a); \
} while(0)
int
-nouveau_handle_init(struct nouveau_handle *handle)
+nvkm_handle_init(struct nvkm_handle *handle)
{
- struct nouveau_handle *item;
+ struct nvkm_handle *item;
int ret;
hprintk(handle, TRACE, "init running\n");
- ret = nouveau_object_inc(handle->object);
+ ret = nvkm_object_inc(handle->object);
if (ret)
return ret;
hprintk(handle, TRACE, "init children\n");
list_for_each_entry(item, &handle->tree, head) {
- ret = nouveau_handle_init(item);
+ ret = nvkm_handle_init(item);
if (ret)
goto fail;
}
@@ -55,30 +53,30 @@ nouveau_handle_init(struct nouveau_handle *handle)
fail:
hprintk(handle, ERROR, "init failed with %d\n", ret);
list_for_each_entry_continue_reverse(item, &handle->tree, head) {
- nouveau_handle_fini(item, false);
+ nvkm_handle_fini(item, false);
}
- nouveau_object_dec(handle->object, false);
+ nvkm_object_dec(handle->object, false);
return ret;
}
int
-nouveau_handle_fini(struct nouveau_handle *handle, bool suspend)
+nvkm_handle_fini(struct nvkm_handle *handle, bool suspend)
{
static char *name[2] = { "fini", "suspend" };
- struct nouveau_handle *item;
+ struct nvkm_handle *item;
int ret;
hprintk(handle, TRACE, "%s children\n", name[suspend]);
list_for_each_entry(item, &handle->tree, head) {
- ret = nouveau_handle_fini(item, suspend);
+ ret = nvkm_handle_fini(item, suspend);
if (ret && suspend)
goto fail;
}
hprintk(handle, TRACE, "%s running\n", name[suspend]);
if (handle->object) {
- ret = nouveau_object_dec(handle->object, suspend);
+ ret = nvkm_object_dec(handle->object, suspend);
if (ret && suspend)
goto fail;
}
@@ -88,7 +86,7 @@ nouveau_handle_fini(struct nouveau_handle *handle, bool suspend)
fail:
hprintk(handle, ERROR, "%s failed with %d\n", name[suspend], ret);
list_for_each_entry_continue_reverse(item, &handle->tree, head) {
- int rret = nouveau_handle_init(item);
+ int rret = nvkm_handle_init(item);
if (rret)
hprintk(handle, FATAL, "failed to restart, %d\n", rret);
}
@@ -97,12 +95,11 @@ fail:
}
int
-nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
- struct nouveau_object *object,
- struct nouveau_handle **phandle)
+nvkm_handle_create(struct nvkm_object *parent, u32 _parent, u32 _handle,
+ struct nvkm_object *object, struct nvkm_handle **phandle)
{
- struct nouveau_object *namedb;
- struct nouveau_handle *handle;
+ struct nvkm_object *namedb;
+ struct nvkm_handle *handle;
int ret;
namedb = parent;
@@ -118,7 +115,7 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
handle->name = _handle;
handle->priv = ~0;
- ret = nouveau_namedb_insert(nv_namedb(namedb), _handle, object, handle);
+ ret = nvkm_namedb_insert(nv_namedb(namedb), _handle, object, handle);
if (ret) {
kfree(handle);
return ret;
@@ -127,7 +124,7 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
if (nv_parent(parent)->object_attach) {
ret = nv_parent(parent)->object_attach(parent, object, _handle);
if (ret < 0) {
- nouveau_handle_destroy(handle);
+ nvkm_handle_destroy(handle);
return ret;
}
@@ -138,10 +135,10 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
while (!nv_iclass(namedb, NV_CLIENT_CLASS))
namedb = namedb->parent;
- handle->parent = nouveau_namedb_get(nv_namedb(namedb), _parent);
+ handle->parent = nvkm_namedb_get(nv_namedb(namedb), _parent);
if (handle->parent) {
list_add(&handle->head, &handle->parent->tree);
- nouveau_namedb_put(handle->parent);
+ nvkm_namedb_put(handle->parent);
}
}
@@ -151,74 +148,74 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
}
void
-nouveau_handle_destroy(struct nouveau_handle *handle)
+nvkm_handle_destroy(struct nvkm_handle *handle)
{
- struct nouveau_handle *item, *temp;
+ struct nvkm_handle *item, *temp;
hprintk(handle, TRACE, "destroy running\n");
list_for_each_entry_safe(item, temp, &handle->tree, head) {
- nouveau_handle_destroy(item);
+ nvkm_handle_destroy(item);
}
list_del(&handle->head);
if (handle->priv != ~0) {
- struct nouveau_object *parent = handle->parent->object;
+ struct nvkm_object *parent = handle->parent->object;
nv_parent(parent)->object_detach(parent, handle->priv);
}
hprintk(handle, TRACE, "destroy completed\n");
- nouveau_namedb_remove(handle);
+ nvkm_namedb_remove(handle);
kfree(handle);
}
-struct nouveau_object *
-nouveau_handle_ref(struct nouveau_object *parent, u32 name)
+struct nvkm_object *
+nvkm_handle_ref(struct nvkm_object *parent, u32 name)
{
- struct nouveau_object *object = NULL;
- struct nouveau_handle *handle;
+ struct nvkm_object *object = NULL;
+ struct nvkm_handle *handle;
while (!nv_iclass(parent, NV_NAMEDB_CLASS))
parent = parent->parent;
- handle = nouveau_namedb_get(nv_namedb(parent), name);
+ handle = nvkm_namedb_get(nv_namedb(parent), name);
if (handle) {
- nouveau_object_ref(handle->object, &object);
- nouveau_namedb_put(handle);
+ nvkm_object_ref(handle->object, &object);
+ nvkm_namedb_put(handle);
}
return object;
}
-struct nouveau_handle *
-nouveau_handle_get_class(struct nouveau_object *engctx, u16 oclass)
+struct nvkm_handle *
+nvkm_handle_get_class(struct nvkm_object *engctx, u16 oclass)
{
- struct nouveau_namedb *namedb;
+ struct nvkm_namedb *namedb;
if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
- return nouveau_namedb_get_class(namedb, oclass);
+ return nvkm_namedb_get_class(namedb, oclass);
return NULL;
}
-struct nouveau_handle *
-nouveau_handle_get_vinst(struct nouveau_object *engctx, u64 vinst)
+struct nvkm_handle *
+nvkm_handle_get_vinst(struct nvkm_object *engctx, u64 vinst)
{
- struct nouveau_namedb *namedb;
+ struct nvkm_namedb *namedb;
if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
- return nouveau_namedb_get_vinst(namedb, vinst);
+ return nvkm_namedb_get_vinst(namedb, vinst);
return NULL;
}
-struct nouveau_handle *
-nouveau_handle_get_cinst(struct nouveau_object *engctx, u32 cinst)
+struct nvkm_handle *
+nvkm_handle_get_cinst(struct nvkm_object *engctx, u32 cinst)
{
- struct nouveau_namedb *namedb;
+ struct nvkm_namedb *namedb;
if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
- return nouveau_namedb_get_cinst(namedb, cinst);
+ return nvkm_namedb_get_cinst(namedb, cinst);
return NULL;
}
void
-nouveau_handle_put(struct nouveau_handle *handle)
+nvkm_handle_put(struct nvkm_handle *handle)
{
if (handle)
- nouveau_namedb_put(handle);
+ nvkm_namedb_put(handle);
}
diff --git a/drivers/gpu/drm/nouveau/core/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
index 692aa92dd850..4459ff5f4cb8 100644
--- a/drivers/gpu/drm/nouveau/core/core/ioctl.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
@@ -21,23 +21,19 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include <core/object.h>
-#include <core/parent.h>
+#include <core/ioctl.h>
+#include <core/client.h>
+#include <core/engine.h>
#include <core/handle.h>
#include <core/namedb.h>
-#include <core/client.h>
-#include <core/device.h>
-#include <core/ioctl.h>
-#include <core/event.h>
#include <nvif/unpack.h>
#include <nvif/ioctl.h>
static int
-nvkm_ioctl_nop(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_nop(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
+ struct nvkm_object *object = handle->object;
union {
struct nvif_ioctl_nop none;
} *args = data;
@@ -52,9 +48,9 @@ nvkm_ioctl_nop(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_sclass(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_sclass(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
+ struct nvkm_object *object = handle->object;
union {
struct nvif_ioctl_sclass_v0 v0;
} *args = data;
@@ -70,8 +66,8 @@ nvkm_ioctl_sclass(struct nouveau_handle *handle, void *data, u32 size)
nv_ioctl(object, "sclass vers %d count %d\n",
args->v0.version, args->v0.count);
if (size == args->v0.count * sizeof(args->v0.oclass[0])) {
- ret = nouveau_parent_lclass(object, args->v0.oclass,
- args->v0.count);
+ ret = nvkm_parent_lclass(object, args->v0.oclass,
+ args->v0.count);
if (ret >= 0) {
args->v0.count = ret;
ret = 0;
@@ -85,17 +81,17 @@ nvkm_ioctl_sclass(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_new(struct nouveau_handle *parent, void *data, u32 size)
+nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size)
{
union {
struct nvif_ioctl_new_v0 v0;
} *args = data;
- struct nouveau_client *client = nouveau_client(parent->object);
- struct nouveau_object *engctx = NULL;
- struct nouveau_object *object = NULL;
- struct nouveau_object *engine;
- struct nouveau_oclass *oclass;
- struct nouveau_handle *handle;
+ struct nvkm_client *client = nvkm_client(handle->object);
+ struct nvkm_object *engctx = NULL;
+ struct nvkm_object *object = NULL;
+ struct nvkm_parent *parent;
+ struct nvkm_object *engine;
+ struct nvkm_oclass *oclass;
u32 _handle, _oclass;
int ret;
@@ -108,19 +104,21 @@ nvkm_ioctl_new(struct nouveau_handle *parent, void *data, u32 size)
nv_ioctl(client, "new vers %d handle %08x class %08x "
"route %02x token %llx\n",
- args->v0.version, _handle, _oclass,
- args->v0.route, args->v0.token);
+ args->v0.version, _handle, _oclass,
+ args->v0.route, args->v0.token);
- if (!nv_iclass(parent->object, NV_PARENT_CLASS)) {
- nv_debug(parent->object, "cannot have children (ctor)\n");
+ if (!nv_iclass(handle->object, NV_PARENT_CLASS)) {
+ nv_debug(handle->object, "cannot have children (ctor)\n");
ret = -ENODEV;
goto fail_class;
}
+ parent = nv_parent(handle->object);
+
/* check that parent supports the requested subclass */
- ret = nouveau_parent_sclass(parent->object, _oclass, &engine, &oclass);
+ ret = nvkm_parent_sclass(&parent->object, _oclass, &engine, &oclass);
if (ret) {
- nv_debug(parent->object, "illegal class 0x%04x\n", _oclass);
+ nv_debug(parent, "illegal class 0x%04x\n", _oclass);
goto fail_class;
}
@@ -129,7 +127,7 @@ nvkm_ioctl_new(struct nouveau_handle *parent, void *data, u32 size)
* state calculated at init (ie. default context construction)
*/
if (engine) {
- ret = nouveau_object_inc(engine);
+ ret = nvkm_object_inc(engine);
if (ret)
goto fail_class;
}
@@ -138,53 +136,53 @@ nvkm_ioctl_new(struct nouveau_handle *parent, void *data, u32 size)
* between the parent and its children (eg. PGRAPH context)
*/
if (engine && nv_engine(engine)->cclass) {
- ret = nouveau_object_ctor(parent->object, engine,
- nv_engine(engine)->cclass,
- data, size, &engctx);
+ ret = nvkm_object_ctor(&parent->object, engine,
+ nv_engine(engine)->cclass,
+ data, size, &engctx);
if (ret)
goto fail_engctx;
} else {
- nouveau_object_ref(parent->object, &engctx);
+ nvkm_object_ref(&parent->object, &engctx);
}
/* finally, create new object and bind it to its handle */
- ret = nouveau_object_ctor(engctx, engine, oclass, data, size, &object);
+ ret = nvkm_object_ctor(engctx, engine, oclass, data, size, &object);
client->data = object;
if (ret)
goto fail_ctor;
- ret = nouveau_object_inc(object);
+ ret = nvkm_object_inc(object);
if (ret)
goto fail_init;
- ret = nouveau_handle_create(parent->object, parent->name,
- _handle, object, &handle);
+ ret = nvkm_handle_create(&parent->object, handle->name,
+ _handle, object, &handle);
if (ret)
goto fail_handle;
- ret = nouveau_handle_init(handle);
+ ret = nvkm_handle_init(handle);
handle->route = args->v0.route;
handle->token = args->v0.token;
if (ret)
- nouveau_handle_destroy(handle);
+ nvkm_handle_destroy(handle);
fail_handle:
- nouveau_object_dec(object, false);
+ nvkm_object_dec(object, false);
fail_init:
- nouveau_object_ref(NULL, &object);
+ nvkm_object_ref(NULL, &object);
fail_ctor:
- nouveau_object_ref(NULL, &engctx);
+ nvkm_object_ref(NULL, &engctx);
fail_engctx:
if (engine)
- nouveau_object_dec(engine, false);
+ nvkm_object_dec(engine, false);
fail_class:
return ret;
}
static int
-nvkm_ioctl_del(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_del(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
+ struct nvkm_object *object = handle->object;
union {
struct nvif_ioctl_del none;
} *args = data;
@@ -193,18 +191,18 @@ nvkm_ioctl_del(struct nouveau_handle *handle, void *data, u32 size)
nv_ioctl(object, "delete size %d\n", size);
if (nvif_unvers(args->none)) {
nv_ioctl(object, "delete\n");
- nouveau_handle_fini(handle, false);
- nouveau_handle_destroy(handle);
+ nvkm_handle_fini(handle, false);
+ nvkm_handle_destroy(handle);
}
return ret;
}
static int
-nvkm_ioctl_mthd(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
- struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs;
+ struct nvkm_object *object = handle->object;
+ struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
union {
struct nvif_ioctl_mthd_v0 v0;
} *args = data;
@@ -223,10 +221,10 @@ nvkm_ioctl_mthd(struct nouveau_handle *handle, void *data, u32 size)
static int
-nvkm_ioctl_rd(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_rd(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
- struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs;
+ struct nvkm_object *object = handle->object;
+ struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
union {
struct nvif_ioctl_rd_v0 v0;
} *args = data;
@@ -235,7 +233,7 @@ nvkm_ioctl_rd(struct nouveau_handle *handle, void *data, u32 size)
nv_ioctl(object, "rd size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "rd vers %d size %d addr %016llx\n",
- args->v0.version, args->v0.size, args->v0.addr);
+ args->v0.version, args->v0.size, args->v0.addr);
switch (args->v0.size) {
case 1:
if (ret = -ENODEV, ofuncs->rd08) {
@@ -265,10 +263,10 @@ nvkm_ioctl_rd(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_wr(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_wr(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
- struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs;
+ struct nvkm_object *object = handle->object;
+ struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
union {
struct nvif_ioctl_wr_v0 v0;
} *args = data;
@@ -308,10 +306,10 @@ nvkm_ioctl_wr(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_map(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
- struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs;
+ struct nvkm_object *object = handle->object;
+ struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
union {
struct nvif_ioctl_map_v0 v0;
} *args = data;
@@ -330,9 +328,9 @@ nvkm_ioctl_map(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_unmap(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_unmap(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
+ struct nvkm_object *object = handle->object;
union {
struct nvif_ioctl_unmap none;
} *args = data;
@@ -347,10 +345,10 @@ nvkm_ioctl_unmap(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_ntfy_new(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_object *object = handle->object;
- struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs;
+ struct nvkm_object *object = handle->object;
+ struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
union {
struct nvif_ioctl_ntfy_new_v0 v0;
} *args = data;
@@ -376,10 +374,10 @@ nvkm_ioctl_ntfy_new(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_ntfy_del(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_del(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_client *client = nouveau_client(handle->object);
- struct nouveau_object *object = handle->object;
+ struct nvkm_client *client = nvkm_client(handle->object);
+ struct nvkm_object *object = handle->object;
union {
struct nvif_ioctl_ntfy_del_v0 v0;
} *args = data;
@@ -396,10 +394,10 @@ nvkm_ioctl_ntfy_del(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_ntfy_get(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_get(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_client *client = nouveau_client(handle->object);
- struct nouveau_object *object = handle->object;
+ struct nvkm_client *client = nvkm_client(handle->object);
+ struct nvkm_object *object = handle->object;
union {
struct nvif_ioctl_ntfy_get_v0 v0;
} *args = data;
@@ -416,10 +414,10 @@ nvkm_ioctl_ntfy_get(struct nouveau_handle *handle, void *data, u32 size)
}
static int
-nvkm_ioctl_ntfy_put(struct nouveau_handle *handle, void *data, u32 size)
+nvkm_ioctl_ntfy_put(struct nvkm_handle *handle, void *data, u32 size)
{
- struct nouveau_client *client = nouveau_client(handle->object);
- struct nouveau_object *object = handle->object;
+ struct nvkm_client *client = nvkm_client(handle->object);
+ struct nvkm_object *object = handle->object;
union {
struct nvif_ioctl_ntfy_put_v0 v0;
} *args = data;
@@ -437,7 +435,7 @@ nvkm_ioctl_ntfy_put(struct nouveau_handle *handle, void *data, u32 size)
static struct {
int version;
- int (*func)(struct nouveau_handle *, void *, u32);
+ int (*func)(struct nvkm_handle *, void *, u32);
}
nvkm_ioctl_v0[] = {
{ 0x00, nvkm_ioctl_nop },
@@ -456,13 +454,12 @@ nvkm_ioctl_v0[] = {
};
static int
-nvkm_ioctl_path(struct nouveau_handle *parent, u32 type, u32 nr,
- u32 *path, void *data, u32 size,
- u8 owner, u8 *route, u64 *token)
+nvkm_ioctl_path(struct nvkm_handle *parent, u32 type, u32 nr, u32 *path,
+ void *data, u32 size, u8 owner, u8 *route, u64 *token)
{
- struct nouveau_handle *handle = parent;
- struct nouveau_namedb *namedb;
- struct nouveau_object *object;
+ struct nvkm_handle *handle = parent;
+ struct nvkm_namedb *namedb;
+ struct nvkm_object *object;
int ret;
while ((object = parent->object), nr--) {
@@ -473,16 +470,15 @@ nvkm_ioctl_path(struct nouveau_handle *parent, u32 type, u32 nr,
}
if (!(namedb = (void *)nv_pclass(object, NV_NAMEDB_CLASS)) ||
- !(handle = nouveau_namedb_get(namedb, path[nr]))) {
+ !(handle = nvkm_namedb_get(namedb, path[nr]))) {
nv_debug(object, "handle 0x%08x not found\n", path[nr]);
return -ENOENT;
}
- nouveau_namedb_put(handle);
+ nvkm_namedb_put(handle);
parent = handle;
}
- if (owner != NVIF_IOCTL_V0_OWNER_ANY &&
- owner != handle->route) {
+ if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != handle->route) {
nv_ioctl(object, "object route != owner\n");
return -EACCES;
}
@@ -490,16 +486,15 @@ nvkm_ioctl_path(struct nouveau_handle *parent, u32 type, u32 nr,
*token = handle->token;
if (ret = -EINVAL, type < ARRAY_SIZE(nvkm_ioctl_v0)) {
- if (nvkm_ioctl_v0[type].version == 0) {
+ if (nvkm_ioctl_v0[type].version == 0)
ret = nvkm_ioctl_v0[type].func(handle, data, size);
- }
}
return ret;
}
int
-nvkm_ioctl(struct nouveau_client *client, bool supervisor,
+nvkm_ioctl(struct nvkm_client *client, bool supervisor,
void *data, u32 size, void **hack)
{
union {
@@ -517,7 +512,7 @@ nvkm_ioctl(struct nouveau_client *client, bool supervisor,
ret = nvkm_ioctl_path(client->root, args->v0.type,
args->v0.path_nr, args->v0.path,
data, size, args->v0.owner,
- &args->v0.route, &args->v0.token);
+ &args->v0.route, &args->v0.token);
}
nv_ioctl(client, "return %d\n", ret);
@@ -525,6 +520,7 @@ nvkm_ioctl(struct nouveau_client *client, bool supervisor,
*hack = client->data;
client->data = NULL;
}
+
client->super = false;
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/core/core/mm.c b/drivers/gpu/drm/nouveau/nvkm/core/mm.c
index b4f5db66d5b5..7f458dfd5608 100644
--- a/drivers/gpu/drm/nouveau/core/core/mm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/mm.c
@@ -21,39 +21,37 @@
*
* Authors: Ben Skeggs
*/
+#include <core/mm.h>
-#include "core/os.h"
-#include "core/mm.h"
-
-#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \
- list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry)
+#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \
+ list_entry((root)->nl_entry.dir, struct nvkm_mm_node, nl_entry)
static void
-nouveau_mm_dump(struct nouveau_mm *mm, const char *header)
+nvkm_mm_dump(struct nvkm_mm *mm, const char *header)
{
- struct nouveau_mm_node *node;
+ struct nvkm_mm_node *node;
- printk(KERN_ERR "nouveau: %s\n", header);
- printk(KERN_ERR "nouveau: node list:\n");
+ printk(KERN_ERR "nvkm: %s\n", header);
+ printk(KERN_ERR "nvkm: node list:\n");
list_for_each_entry(node, &mm->nodes, nl_entry) {
- printk(KERN_ERR "nouveau: \t%08x %08x %d\n",
+ printk(KERN_ERR "nvkm: \t%08x %08x %d\n",
node->offset, node->length, node->type);
}
- printk(KERN_ERR "nouveau: free list:\n");
+ printk(KERN_ERR "nvkm: free list:\n");
list_for_each_entry(node, &mm->free, fl_entry) {
- printk(KERN_ERR "nouveau: \t%08x %08x %d\n",
+ printk(KERN_ERR "nvkm: \t%08x %08x %d\n",
node->offset, node->length, node->type);
}
}
void
-nouveau_mm_free(struct nouveau_mm *mm, struct nouveau_mm_node **pthis)
+nvkm_mm_free(struct nvkm_mm *mm, struct nvkm_mm_node **pthis)
{
- struct nouveau_mm_node *this = *pthis;
+ struct nvkm_mm_node *this = *pthis;
if (this) {
- struct nouveau_mm_node *prev = node(this, prev);
- struct nouveau_mm_node *next = node(this, next);
+ struct nvkm_mm_node *prev = node(this, prev);
+ struct nvkm_mm_node *next = node(this, next);
if (prev && prev->type == NVKM_MM_TYPE_NONE) {
prev->length += this->length;
@@ -84,10 +82,10 @@ nouveau_mm_free(struct nouveau_mm *mm, struct nouveau_mm_node **pthis)
*pthis = NULL;
}
-static struct nouveau_mm_node *
-region_head(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
+static struct nvkm_mm_node *
+region_head(struct nvkm_mm *mm, struct nvkm_mm_node *a, u32 size)
{
- struct nouveau_mm_node *b;
+ struct nvkm_mm_node *b;
if (a->length == size)
return a;
@@ -105,14 +103,15 @@ region_head(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
list_add_tail(&b->nl_entry, &a->nl_entry);
if (b->type == NVKM_MM_TYPE_NONE)
list_add_tail(&b->fl_entry, &a->fl_entry);
+
return b;
}
int
-nouveau_mm_head(struct nouveau_mm *mm, u8 heap, u8 type, u32 size_max,
- u32 size_min, u32 align, struct nouveau_mm_node **pnode)
+nvkm_mm_head(struct nvkm_mm *mm, u8 heap, u8 type, u32 size_max, u32 size_min,
+ u32 align, struct nvkm_mm_node **pnode)
{
- struct nouveau_mm_node *prev, *this, *next;
+ struct nvkm_mm_node *prev, *this, *next;
u32 mask = align - 1;
u32 splitoff;
u32 s, e;
@@ -157,10 +156,10 @@ nouveau_mm_head(struct nouveau_mm *mm, u8 heap, u8 type, u32 size_max,
return -ENOSPC;
}
-static struct nouveau_mm_node *
-region_tail(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
+static struct nvkm_mm_node *
+region_tail(struct nvkm_mm *mm, struct nvkm_mm_node *a, u32 size)
{
- struct nouveau_mm_node *b;
+ struct nvkm_mm_node *b;
if (a->length == size)
return a;
@@ -178,14 +177,15 @@ region_tail(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
list_add(&b->nl_entry, &a->nl_entry);
if (b->type == NVKM_MM_TYPE_NONE)
list_add(&b->fl_entry, &a->fl_entry);
+
return b;
}
int
-nouveau_mm_tail(struct nouveau_mm *mm, u8 heap, u8 type, u32 size_max,
- u32 size_min, u32 align, struct nouveau_mm_node **pnode)
+nvkm_mm_tail(struct nvkm_mm *mm, u8 heap, u8 type, u32 size_max, u32 size_min,
+ u32 align, struct nvkm_mm_node **pnode)
{
- struct nouveau_mm_node *prev, *this, *next;
+ struct nvkm_mm_node *prev, *this, *next;
u32 mask = align - 1;
BUG_ON(type == NVKM_MM_TYPE_NONE || type == NVKM_MM_TYPE_HOLE);
@@ -235,12 +235,12 @@ nouveau_mm_tail(struct nouveau_mm *mm, u8 heap, u8 type, u32 size_max,
}
int
-nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
+nvkm_mm_init(struct nvkm_mm *mm, u32 offset, u32 length, u32 block)
{
- struct nouveau_mm_node *node, *prev;
+ struct nvkm_mm_node *node, *prev;
u32 next;
- if (nouveau_mm_initialised(mm)) {
+ if (nvkm_mm_initialised(mm)) {
prev = list_last_entry(&mm->nodes, typeof(*node), nl_entry);
next = prev->offset + prev->length;
if (next != offset) {
@@ -277,18 +277,18 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
}
int
-nouveau_mm_fini(struct nouveau_mm *mm)
+nvkm_mm_fini(struct nvkm_mm *mm)
{
- struct nouveau_mm_node *node, *temp;
+ struct nvkm_mm_node *node, *temp;
int nodes = 0;
- if (!nouveau_mm_initialised(mm))
+ if (!nvkm_mm_initialised(mm))
return 0;
list_for_each_entry(node, &mm->nodes, nl_entry) {
if (node->type != NVKM_MM_TYPE_HOLE) {
if (++nodes > mm->heap_nodes) {
- nouveau_mm_dump(mm, "mm not clean!");
+ nvkm_mm_dump(mm, "mm not clean!");
return -EBUSY;
}
}
@@ -298,6 +298,7 @@ nouveau_mm_fini(struct nouveau_mm *mm)
list_del(&node->nl_entry);
kfree(node);
}
+
mm->heap_nodes = 0;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/core/namedb.c b/drivers/gpu/drm/nouveau/nvkm/core/namedb.c
index 0594a599f6fb..6400767c5dba 100644
--- a/drivers/gpu/drm/nouveau/core/core/namedb.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/namedb.c
@@ -21,16 +21,14 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
#include <core/namedb.h>
-#include <core/handle.h>
#include <core/gpuobj.h>
+#include <core/handle.h>
-static struct nouveau_handle *
-nouveau_namedb_lookup(struct nouveau_namedb *namedb, u32 name)
+static struct nvkm_handle *
+nvkm_namedb_lookup(struct nvkm_namedb *namedb, u32 name)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (handle->name == name)
@@ -40,10 +38,10 @@ nouveau_namedb_lookup(struct nouveau_namedb *namedb, u32 name)
return NULL;
}
-static struct nouveau_handle *
-nouveau_namedb_lookup_class(struct nouveau_namedb *namedb, u16 oclass)
+static struct nvkm_handle *
+nvkm_namedb_lookup_class(struct nvkm_namedb *namedb, u16 oclass)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (nv_mclass(handle->object) == oclass)
@@ -53,10 +51,10 @@ nouveau_namedb_lookup_class(struct nouveau_namedb *namedb, u16 oclass)
return NULL;
}
-static struct nouveau_handle *
-nouveau_namedb_lookup_vinst(struct nouveau_namedb *namedb, u64 vinst)
+static struct nvkm_handle *
+nvkm_namedb_lookup_vinst(struct nvkm_namedb *namedb, u64 vinst)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
@@ -68,10 +66,10 @@ nouveau_namedb_lookup_vinst(struct nouveau_namedb *namedb, u64 vinst)
return NULL;
}
-static struct nouveau_handle *
-nouveau_namedb_lookup_cinst(struct nouveau_namedb *namedb, u32 cinst)
+static struct nvkm_handle *
+nvkm_namedb_lookup_cinst(struct nvkm_namedb *namedb, u32 cinst)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
@@ -85,14 +83,14 @@ nouveau_namedb_lookup_cinst(struct nouveau_namedb *namedb, u32 cinst)
}
int
-nouveau_namedb_insert(struct nouveau_namedb *namedb, u32 name,
- struct nouveau_object *object,
- struct nouveau_handle *handle)
+nvkm_namedb_insert(struct nvkm_namedb *namedb, u32 name,
+ struct nvkm_object *object,
+ struct nvkm_handle *handle)
{
int ret = -EEXIST;
write_lock_irq(&namedb->lock);
- if (!nouveau_namedb_lookup(namedb, name)) {
- nouveau_object_ref(object, &handle->object);
+ if (!nvkm_namedb_lookup(namedb, name)) {
+ nvkm_object_ref(object, &handle->object);
handle->namedb = namedb;
list_add(&handle->node, &namedb->list);
ret = 0;
@@ -102,80 +100,79 @@ nouveau_namedb_insert(struct nouveau_namedb *namedb, u32 name,
}
void
-nouveau_namedb_remove(struct nouveau_handle *handle)
+nvkm_namedb_remove(struct nvkm_handle *handle)
{
- struct nouveau_namedb *namedb = handle->namedb;
- struct nouveau_object *object = handle->object;
+ struct nvkm_namedb *namedb = handle->namedb;
+ struct nvkm_object *object = handle->object;
write_lock_irq(&namedb->lock);
list_del(&handle->node);
write_unlock_irq(&namedb->lock);
- nouveau_object_ref(NULL, &object);
+ nvkm_object_ref(NULL, &object);
}
-struct nouveau_handle *
-nouveau_namedb_get(struct nouveau_namedb *namedb, u32 name)
+struct nvkm_handle *
+nvkm_namedb_get(struct nvkm_namedb *namedb, u32 name)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
read_lock(&namedb->lock);
- handle = nouveau_namedb_lookup(namedb, name);
+ handle = nvkm_namedb_lookup(namedb, name);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
-struct nouveau_handle *
-nouveau_namedb_get_class(struct nouveau_namedb *namedb, u16 oclass)
+struct nvkm_handle *
+nvkm_namedb_get_class(struct nvkm_namedb *namedb, u16 oclass)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
read_lock(&namedb->lock);
- handle = nouveau_namedb_lookup_class(namedb, oclass);
+ handle = nvkm_namedb_lookup_class(namedb, oclass);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
-struct nouveau_handle *
-nouveau_namedb_get_vinst(struct nouveau_namedb *namedb, u64 vinst)
+struct nvkm_handle *
+nvkm_namedb_get_vinst(struct nvkm_namedb *namedb, u64 vinst)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
read_lock(&namedb->lock);
- handle = nouveau_namedb_lookup_vinst(namedb, vinst);
+ handle = nvkm_namedb_lookup_vinst(namedb, vinst);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
-struct nouveau_handle *
-nouveau_namedb_get_cinst(struct nouveau_namedb *namedb, u32 cinst)
+struct nvkm_handle *
+nvkm_namedb_get_cinst(struct nvkm_namedb *namedb, u32 cinst)
{
- struct nouveau_handle *handle;
+ struct nvkm_handle *handle;
read_lock(&namedb->lock);
- handle = nouveau_namedb_lookup_cinst(namedb, cinst);
+ handle = nvkm_namedb_lookup_cinst(namedb, cinst);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
void
-nouveau_namedb_put(struct nouveau_handle *handle)
+nvkm_namedb_put(struct nvkm_handle *handle)
{
if (handle)
read_unlock(&handle->namedb->lock);
}
int
-nouveau_namedb_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 pclass,
- struct nouveau_oclass *sclass, u64 engcls,
- int length, void **pobject)
+nvkm_namedb_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 pclass,
+ struct nvkm_oclass *sclass, u64 engcls,
+ int length, void **pobject)
{
- struct nouveau_namedb *namedb;
+ struct nvkm_namedb *namedb;
int ret;
- ret = nouveau_parent_create_(parent, engine, oclass, pclass |
- NV_NAMEDB_CLASS, sclass, engcls,
- length, pobject);
+ ret = nvkm_parent_create_(parent, engine, oclass, pclass |
+ NV_NAMEDB_CLASS, sclass, engcls,
+ length, pobject);
namedb = *pobject;
if (ret)
return ret;
@@ -186,15 +183,14 @@ nouveau_namedb_create_(struct nouveau_object *parent,
}
int
-_nouveau_namedb_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+_nvkm_namedb_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_namedb *object;
+ struct nvkm_namedb *object;
int ret;
- ret = nouveau_namedb_create(parent, engine, oclass, 0, NULL, 0, &object);
+ ret = nvkm_namedb_create(parent, engine, oclass, 0, NULL, 0, &object);
*pobject = nv_object(object);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/core/notify.c b/drivers/gpu/drm/nouveau/nvkm/core/notify.c
index 839a32577680..023610d01458 100644
--- a/drivers/gpu/drm/nouveau/core/core/notify.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/notify.c
@@ -21,13 +21,8 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include <core/client.h>
-#include <core/event.h>
#include <core/notify.h>
-
-#include <nvif/unpack.h>
-#include <nvif/event.h>
+#include <core/event.h>
static inline void
nvkm_notify_put_locked(struct nvkm_notify *notify)
@@ -134,7 +129,7 @@ nvkm_notify_fini(struct nvkm_notify *notify)
}
int
-nvkm_notify_init(struct nouveau_object *object, struct nvkm_event *event,
+nvkm_notify_init(struct nvkm_object *object, struct nvkm_event *event,
int (*func)(struct nvkm_notify *), bool work,
void *data, u32 size, u32 reply,
struct nvkm_notify *notify)
diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/nvkm/core/object.c
index b08630577c82..979f3627d395 100644
--- a/drivers/gpu/drm/nouveau/core/core/object.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/object.c
@@ -21,36 +21,34 @@
*
* Authors: Ben Skeggs
*/
-
#include <core/object.h>
#include <core/engine.h>
-#ifdef NOUVEAU_OBJECT_MAGIC
+#ifdef NVKM_OBJECT_MAGIC
static struct list_head _objlist = LIST_HEAD_INIT(_objlist);
static DEFINE_SPINLOCK(_objlist_lock);
#endif
int
-nouveau_object_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 pclass,
- int size, void **pobject)
+nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 pclass,
+ int size, void **pobject)
{
- struct nouveau_object *object;
+ struct nvkm_object *object;
object = *pobject = kzalloc(size, GFP_KERNEL);
if (!object)
return -ENOMEM;
- nouveau_object_ref(parent, &object->parent);
- nouveau_object_ref(engine, &object->engine);
+ nvkm_object_ref(parent, &object->parent);
+ nvkm_object_ref(engine, (struct nvkm_object **)&object->engine);
object->oclass = oclass;
object->oclass->handle |= pclass;
atomic_set(&object->refcount, 1);
atomic_set(&object->usecount, 0);
-#ifdef NOUVEAU_OBJECT_MAGIC
- object->_magic = NOUVEAU_OBJECT_MAGIC;
+#ifdef NVKM_OBJECT_MAGIC
+ object->_magic = NVKM_OBJECT_MAGIC;
spin_lock(&_objlist_lock);
list_add(&object->list, &_objlist);
spin_unlock(&_objlist_lock);
@@ -59,57 +57,55 @@ nouveau_object_create_(struct nouveau_object *parent,
}
int
-_nouveau_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+_nvkm_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
if (size != 0)
return -ENOSYS;
- return nouveau_object_create(parent, engine, oclass, 0, pobject);
+ return nvkm_object_create(parent, engine, oclass, 0, pobject);
}
void
-nouveau_object_destroy(struct nouveau_object *object)
+nvkm_object_destroy(struct nvkm_object *object)
{
-#ifdef NOUVEAU_OBJECT_MAGIC
+#ifdef NVKM_OBJECT_MAGIC
spin_lock(&_objlist_lock);
list_del(&object->list);
spin_unlock(&_objlist_lock);
#endif
- nouveau_object_ref(NULL, &object->engine);
- nouveau_object_ref(NULL, &object->parent);
+ nvkm_object_ref(NULL, (struct nvkm_object **)&object->engine);
+ nvkm_object_ref(NULL, &object->parent);
kfree(object);
}
int
-nouveau_object_init(struct nouveau_object *object)
+nvkm_object_init(struct nvkm_object *object)
{
return 0;
}
int
-nouveau_object_fini(struct nouveau_object *object, bool suspend)
+nvkm_object_fini(struct nvkm_object *object, bool suspend)
{
return 0;
}
-struct nouveau_ofuncs
-nouveau_object_ofuncs = {
- .ctor = _nouveau_object_ctor,
- .dtor = nouveau_object_destroy,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
+struct nvkm_ofuncs
+nvkm_object_ofuncs = {
+ .ctor = _nvkm_object_ctor,
+ .dtor = nvkm_object_destroy,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
};
int
-nouveau_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nvkm_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_ofuncs *ofuncs = oclass->ofuncs;
- struct nouveau_object *object = NULL;
+ struct nvkm_ofuncs *ofuncs = oclass->ofuncs;
+ struct nvkm_object *object = NULL;
int ret;
ret = ofuncs->ctor(parent, engine, oclass, data, size, &object);
@@ -137,14 +133,14 @@ nouveau_object_ctor(struct nouveau_object *parent,
}
static void
-nouveau_object_dtor(struct nouveau_object *object)
+nvkm_object_dtor(struct nvkm_object *object)
{
nv_trace(object, "destroying\n");
nv_ofuncs(object)->dtor(object);
}
void
-nouveau_object_ref(struct nouveau_object *obj, struct nouveau_object **ref)
+nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
{
if (obj) {
atomic_inc(&obj->refcount);
@@ -155,14 +151,14 @@ nouveau_object_ref(struct nouveau_object *obj, struct nouveau_object **ref)
int dead = atomic_dec_and_test(&(*ref)->refcount);
nv_trace(*ref, "dec() == %d\n", atomic_read(&(*ref)->refcount));
if (dead)
- nouveau_object_dtor(*ref);
+ nvkm_object_dtor(*ref);
}
*ref = obj;
}
int
-nouveau_object_inc(struct nouveau_object *object)
+nvkm_object_inc(struct nvkm_object *object)
{
int ref = atomic_add_return(1, &object->usecount);
int ret;
@@ -173,7 +169,7 @@ nouveau_object_inc(struct nouveau_object *object)
nv_trace(object, "initialising...\n");
if (object->parent) {
- ret = nouveau_object_inc(object->parent);
+ ret = nvkm_object_inc(object->parent);
if (ret) {
nv_error(object, "parent failed, %d\n", ret);
goto fail_parent;
@@ -182,7 +178,7 @@ nouveau_object_inc(struct nouveau_object *object)
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
- ret = nouveau_object_inc(object->engine);
+ ret = nvkm_object_inc(&object->engine->subdev.object);
mutex_unlock(&nv_subdev(object->engine)->mutex);
if (ret) {
nv_error(object, "engine failed, %d\n", ret);
@@ -203,19 +199,19 @@ nouveau_object_inc(struct nouveau_object *object)
fail_self:
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
- nouveau_object_dec(object->engine, false);
+ nvkm_object_dec(&object->engine->subdev.object, false);
mutex_unlock(&nv_subdev(object->engine)->mutex);
}
fail_engine:
if (object->parent)
- nouveau_object_dec(object->parent, false);
+ nvkm_object_dec(object->parent, false);
fail_parent:
atomic_dec(&object->usecount);
return ret;
}
static int
-nouveau_object_decf(struct nouveau_object *object)
+nvkm_object_decf(struct nvkm_object *object)
{
int ret;
@@ -228,19 +224,19 @@ nouveau_object_decf(struct nouveau_object *object)
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
- nouveau_object_dec(object->engine, false);
+ nvkm_object_dec(&object->engine->subdev.object, false);
mutex_unlock(&nv_subdev(object->engine)->mutex);
}
if (object->parent)
- nouveau_object_dec(object->parent, false);
+ nvkm_object_dec(object->parent, false);
nv_trace(object, "stopped\n");
return 0;
}
static int
-nouveau_object_decs(struct nouveau_object *object)
+nvkm_object_decs(struct nvkm_object *object)
{
int ret, rret;
@@ -255,7 +251,7 @@ nouveau_object_decs(struct nouveau_object *object)
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
- ret = nouveau_object_dec(object->engine, true);
+ ret = nvkm_object_dec(&object->engine->subdev.object, true);
mutex_unlock(&nv_subdev(object->engine)->mutex);
if (ret) {
nv_warn(object, "engine failed suspend, %d\n", ret);
@@ -264,7 +260,7 @@ nouveau_object_decs(struct nouveau_object *object)
}
if (object->parent) {
- ret = nouveau_object_dec(object->parent, true);
+ ret = nvkm_object_dec(object->parent, true);
if (ret) {
nv_warn(object, "parent failed suspend, %d\n", ret);
goto fail_parent;
@@ -277,7 +273,7 @@ nouveau_object_decs(struct nouveau_object *object)
fail_parent:
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
- rret = nouveau_object_inc(object->engine);
+ rret = nvkm_object_inc(&object->engine->subdev.object);
mutex_unlock(&nv_subdev(object->engine)->mutex);
if (rret)
nv_fatal(object, "engine failed to reinit, %d\n", rret);
@@ -292,7 +288,7 @@ fail_engine:
}
int
-nouveau_object_dec(struct nouveau_object *object, bool suspend)
+nvkm_object_dec(struct nvkm_object *object, bool suspend)
{
int ref = atomic_add_return(-1, &object->usecount);
int ret;
@@ -301,9 +297,9 @@ nouveau_object_dec(struct nouveau_object *object, bool suspend)
if (ref == 0) {
if (suspend)
- ret = nouveau_object_decs(object);
+ ret = nvkm_object_decs(object);
else
- ret = nouveau_object_decf(object);
+ ret = nvkm_object_decf(object);
if (ret) {
atomic_inc(&object->usecount);
@@ -315,10 +311,10 @@ nouveau_object_dec(struct nouveau_object *object, bool suspend)
}
void
-nouveau_object_debug(void)
+nvkm_object_debug(void)
{
-#ifdef NOUVEAU_OBJECT_MAGIC
- struct nouveau_object *object;
+#ifdef NVKM_OBJECT_MAGIC
+ struct nvkm_object *object;
if (!list_empty(&_objlist)) {
nv_fatal(NULL, "*******************************************\n");
nv_fatal(NULL, "* AIIIII! object(s) still exist!!!\n");
diff --git a/drivers/gpu/drm/nouveau/core/core/option.c b/drivers/gpu/drm/nouveau/nvkm/core/option.c
index 9f6fcc5f66c2..19d153f8c8fd 100644
--- a/drivers/gpu/drm/nouveau/core/core/option.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/option.c
@@ -21,12 +21,11 @@
*
* Authors: Ben Skeggs
*/
-
#include <core/option.h>
#include <core/debug.h>
const char *
-nouveau_stropt(const char *optstr, const char *opt, int *arglen)
+nvkm_stropt(const char *optstr, const char *opt, int *arglen)
{
while (optstr && *optstr != '\0') {
int len = strcspn(optstr, ",=");
@@ -52,11 +51,11 @@ nouveau_stropt(const char *optstr, const char *opt, int *arglen)
}
bool
-nouveau_boolopt(const char *optstr, const char *opt, bool value)
+nvkm_boolopt(const char *optstr, const char *opt, bool value)
{
int arglen;
- optstr = nouveau_stropt(optstr, opt, &arglen);
+ optstr = nvkm_stropt(optstr, opt, &arglen);
if (optstr) {
if (!strncasecmpz(optstr, "0", arglen) ||
!strncasecmpz(optstr, "no", arglen) ||
@@ -75,7 +74,7 @@ nouveau_boolopt(const char *optstr, const char *opt, bool value)
}
int
-nouveau_dbgopt(const char *optstr, const char *sub)
+nvkm_dbgopt(const char *optstr, const char *sub)
{
int mode = 1, level = CONFIG_NOUVEAU_DEBUG_DEFAULT;
diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/nvkm/core/parent.c
index 30a2911878f8..dd56cd1eeb38 100644
--- a/drivers/gpu/drm/nouveau/core/core/parent.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/parent.c
@@ -21,25 +21,24 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
#include <core/parent.h>
#include <core/client.h>
+#include <core/engine.h>
int
-nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
- struct nouveau_object **pengine,
- struct nouveau_oclass **poclass)
+nvkm_parent_sclass(struct nvkm_object *parent, u16 handle,
+ struct nvkm_object **pengine,
+ struct nvkm_oclass **poclass)
{
- struct nouveau_sclass *sclass;
- struct nouveau_engine *engine;
- struct nouveau_oclass *oclass;
+ struct nvkm_sclass *sclass;
+ struct nvkm_engine *engine;
+ struct nvkm_oclass *oclass;
u64 mask;
sclass = nv_parent(parent)->sclass;
while (sclass) {
if ((sclass->oclass->handle & 0xffff) == handle) {
- *pengine = parent->engine;
+ *pengine = &parent->engine->subdev.object;
*poclass = sclass->oclass;
return 0;
}
@@ -54,7 +53,7 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
if (nv_iclass(parent, NV_CLIENT_CLASS))
engine = nv_engine(nv_client(parent)->device);
else
- engine = nouveau_engine(parent, i);
+ engine = nvkm_engine(parent, i);
if (engine) {
oclass = engine->sclass;
@@ -75,11 +74,11 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
}
int
-nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size)
+nvkm_parent_lclass(struct nvkm_object *parent, u32 *lclass, int size)
{
- struct nouveau_sclass *sclass;
- struct nouveau_engine *engine;
- struct nouveau_oclass *oclass;
+ struct nvkm_sclass *sclass;
+ struct nvkm_engine *engine;
+ struct nvkm_oclass *oclass;
int nr = -1, i;
u64 mask;
@@ -92,7 +91,7 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size)
mask = nv_parent(parent)->engine;
while (i = __ffs64(mask), mask) {
- engine = nouveau_engine(parent, i);
+ engine = nvkm_engine(parent, i);
if (engine && (oclass = engine->sclass)) {
while (oclass->ofuncs) {
if (++nr < size)
@@ -108,18 +107,17 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size)
}
int
-nouveau_parent_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 pclass,
- struct nouveau_oclass *sclass, u64 engcls,
- int size, void **pobject)
+nvkm_parent_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 pclass,
+ struct nvkm_oclass *sclass, u64 engcls,
+ int size, void **pobject)
{
- struct nouveau_parent *object;
- struct nouveau_sclass *nclass;
+ struct nvkm_parent *object;
+ struct nvkm_sclass *nclass;
int ret;
- ret = nouveau_object_create_(parent, engine, oclass, pclass |
- NV_PARENT_CLASS, size, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, pclass |
+ NV_PARENT_CLASS, size, pobject);
object = *pobject;
if (ret)
return ret;
@@ -141,21 +139,21 @@ nouveau_parent_create_(struct nouveau_object *parent,
}
void
-nouveau_parent_destroy(struct nouveau_parent *parent)
+nvkm_parent_destroy(struct nvkm_parent *parent)
{
- struct nouveau_sclass *sclass;
+ struct nvkm_sclass *sclass;
while ((sclass = parent->sclass)) {
parent->sclass = sclass->sclass;
kfree(sclass);
}
- nouveau_object_destroy(&parent->base);
+ nvkm_object_destroy(&parent->object);
}
void
-_nouveau_parent_dtor(struct nouveau_object *object)
+_nvkm_parent_dtor(struct nvkm_object *object)
{
- nouveau_parent_destroy(nv_parent(object));
+ nvkm_parent_destroy(nv_parent(object));
}
diff --git a/drivers/gpu/drm/nouveau/core/core/printk.c b/drivers/gpu/drm/nouveau/nvkm/core/printk.c
index 03e0060b13da..4a220eb91660 100644
--- a/drivers/gpu/drm/nouveau/core/core/printk.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/printk.c
@@ -21,16 +21,14 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
-#include <core/client.h>
-#include <core/subdev.h>
#include <core/printk.h>
+#include <core/client.h>
+#include <core/device.h>
int nv_info_debug_level = NV_DBG_INFO_NORMAL;
void
-nv_printk_(struct nouveau_object *object, int level, const char *fmt, ...)
+nv_printk_(struct nvkm_object *object, int level, const char *fmt, ...)
{
static const char name[] = { '!', 'E', 'W', ' ', 'D', 'T', 'P', 'S' };
const char *pfx;
@@ -60,20 +58,27 @@ nv_printk_(struct nouveau_object *object, int level, const char *fmt, ...)
}
if (object && !nv_iclass(object, NV_CLIENT_CLASS)) {
- struct nouveau_object *device = object;
- struct nouveau_object *subdev = object;
+ struct nvkm_object *device;
+ struct nvkm_object *subdev;
char obuf[64], *ofmt = "";
- if (object->engine) {
- snprintf(obuf, sizeof(obuf), "[0x%08x][%p]",
- nv_hclass(object), object);
- ofmt = obuf;
- subdev = object->engine;
- device = object->engine;
+ if (object->engine == NULL) {
+ subdev = object;
+ while (subdev && !nv_iclass(subdev, NV_SUBDEV_CLASS))
+ subdev = subdev->parent;
+ } else {
+ subdev = &object->engine->subdev.object;
}
- if (subdev->parent)
- device = subdev->parent;
+ device = subdev;
+ if (device->parent)
+ device = device->parent;
+
+ if (object != subdev) {
+ snprintf(obuf, sizeof(obuf), "[0x%08x]",
+ nv_hclass(object));
+ ofmt = obuf;
+ }
if (level > nv_subdev(subdev)->debug)
return;
diff --git a/drivers/gpu/drm/nouveau/core/core/ramht.c b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
index f3b9bddc3875..ebd4d15479bd 100644
--- a/drivers/gpu/drm/nouveau/core/core/ramht.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
@@ -19,14 +19,13 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
-#include <core/object.h>
#include <core/ramht.h>
+#include <core/engine.h>
#include <subdev/bar.h>
static u32
-nouveau_ramht_hash(struct nouveau_ramht *ramht, int chid, u32 handle)
+nvkm_ramht_hash(struct nvkm_ramht *ramht, int chid, u32 handle)
{
u32 hash = 0;
@@ -41,13 +40,12 @@ nouveau_ramht_hash(struct nouveau_ramht *ramht, int chid, u32 handle)
}
int
-nouveau_ramht_insert(struct nouveau_ramht *ramht, int chid,
- u32 handle, u32 context)
+nvkm_ramht_insert(struct nvkm_ramht *ramht, int chid, u32 handle, u32 context)
{
- struct nouveau_bar *bar = nouveau_bar(ramht);
+ struct nvkm_bar *bar = nvkm_bar(ramht);
u32 co, ho;
- co = ho = nouveau_ramht_hash(ramht, chid, handle);
+ co = ho = nvkm_ramht_hash(ramht, chid, handle);
do {
if (!nv_ro32(ramht, co + 4)) {
nv_wo32(ramht, co + 0, handle);
@@ -66,39 +64,39 @@ nouveau_ramht_insert(struct nouveau_ramht *ramht, int chid,
}
void
-nouveau_ramht_remove(struct nouveau_ramht *ramht, int cookie)
+nvkm_ramht_remove(struct nvkm_ramht *ramht, int cookie)
{
- struct nouveau_bar *bar = nouveau_bar(ramht);
+ struct nvkm_bar *bar = nvkm_bar(ramht);
nv_wo32(ramht, cookie + 0, 0x00000000);
nv_wo32(ramht, cookie + 4, 0x00000000);
if (bar)
bar->flush(bar);
}
-static struct nouveau_oclass
-nouveau_ramht_oclass = {
+static struct nvkm_oclass
+nvkm_ramht_oclass = {
.handle = 0x0000abcd,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = NULL,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
},
};
int
-nouveau_ramht_new(struct nouveau_object *parent, struct nouveau_object *pargpu,
- u32 size, u32 align, struct nouveau_ramht **pramht)
+nvkm_ramht_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
+ u32 size, u32 align, struct nvkm_ramht **pramht)
{
- struct nouveau_ramht *ramht;
+ struct nvkm_ramht *ramht;
int ret;
- ret = nouveau_gpuobj_create(parent, parent->engine ?
- parent->engine : parent, /* <nv50 ramht */
- &nouveau_ramht_oclass, 0, pargpu, size,
- align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
+ ret = nvkm_gpuobj_create(parent, parent->engine ?
+ &parent->engine->subdev.object : parent, /* <nv50 ramht */
+ &nvkm_ramht_oclass, 0, pargpu, size,
+ align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
*pramht = ramht;
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
index 2ea5568b6cf5..c5fb3a793174 100644
--- a/drivers/gpu/drm/nouveau/core/core/subdev.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
@@ -21,14 +21,23 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
#include <core/subdev.h>
#include <core/device.h>
#include <core/option.h>
+struct nvkm_subdev *
+nvkm_subdev(void *obj, int idx)
+{
+ struct nvkm_object *object = nv_object(obj);
+ while (object && !nv_iclass(object, NV_SUBDEV_CLASS))
+ object = object->parent;
+ if (object == NULL || nv_subidx(nv_subdev(object)) != idx)
+ object = nv_device(obj)->subdev[idx];
+ return object ? nv_subdev(object) : NULL;
+}
+
void
-nouveau_subdev_reset(struct nouveau_object *subdev)
+nvkm_subdev_reset(struct nvkm_object *subdev)
{
nv_trace(subdev, "resetting...\n");
nv_ofuncs(subdev)->fini(subdev, false);
@@ -36,65 +45,64 @@ nouveau_subdev_reset(struct nouveau_object *subdev)
}
int
-nouveau_subdev_init(struct nouveau_subdev *subdev)
+nvkm_subdev_init(struct nvkm_subdev *subdev)
{
- int ret = nouveau_object_init(&subdev->base);
+ int ret = nvkm_object_init(&subdev->object);
if (ret)
return ret;
- nouveau_subdev_reset(&subdev->base);
+ nvkm_subdev_reset(&subdev->object);
return 0;
}
int
-_nouveau_subdev_init(struct nouveau_object *object)
+_nvkm_subdev_init(struct nvkm_object *object)
{
- return nouveau_subdev_init(nv_subdev(object));
+ return nvkm_subdev_init(nv_subdev(object));
}
int
-nouveau_subdev_fini(struct nouveau_subdev *subdev, bool suspend)
+nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
{
if (subdev->unit) {
nv_mask(subdev, 0x000200, subdev->unit, 0x00000000);
nv_mask(subdev, 0x000200, subdev->unit, subdev->unit);
}
- return nouveau_object_fini(&subdev->base, suspend);
+ return nvkm_object_fini(&subdev->object, suspend);
}
int
-_nouveau_subdev_fini(struct nouveau_object *object, bool suspend)
+_nvkm_subdev_fini(struct nvkm_object *object, bool suspend)
{
- return nouveau_subdev_fini(nv_subdev(object), suspend);
+ return nvkm_subdev_fini(nv_subdev(object), suspend);
}
void
-nouveau_subdev_destroy(struct nouveau_subdev *subdev)
+nvkm_subdev_destroy(struct nvkm_subdev *subdev)
{
int subidx = nv_hclass(subdev) & 0xff;
nv_device(subdev)->subdev[subidx] = NULL;
- nouveau_object_destroy(&subdev->base);
+ nvkm_object_destroy(&subdev->object);
}
void
-_nouveau_subdev_dtor(struct nouveau_object *object)
+_nvkm_subdev_dtor(struct nvkm_object *object)
{
- nouveau_subdev_destroy(nv_subdev(object));
+ nvkm_subdev_destroy(nv_subdev(object));
}
int
-nouveau_subdev_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 pclass,
- const char *subname, const char *sysname,
- int size, void **pobject)
+nvkm_subdev_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 pclass,
+ const char *subname, const char *sysname,
+ int size, void **pobject)
{
- struct nouveau_subdev *subdev;
+ struct nvkm_subdev *subdev;
int ret;
- ret = nouveau_object_create_(parent, engine, oclass, pclass |
- NV_SUBDEV_CLASS, size, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, pclass |
+ NV_SUBDEV_CLASS, size, pobject);
subdev = *pobject;
if (ret)
return ret;
@@ -103,8 +111,8 @@ nouveau_subdev_create_(struct nouveau_object *parent,
subdev->name = subname;
if (parent) {
- struct nouveau_device *device = nv_device(parent);
- subdev->debug = nouveau_dbgopt(device->dbgopt, subname);
+ struct nvkm_device *device = nv_device(parent);
+ subdev->debug = nvkm_dbgopt(device->dbgopt, subname);
subdev->mmio = nv_subdev(device)->mmio;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild
new file mode 100644
index 000000000000..6bd3d756f32c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/Kbuild
@@ -0,0 +1,19 @@
+nvkm-y += nvkm/engine/falcon.o
+nvkm-y += nvkm/engine/xtensa.o
+
+include $(src)/nvkm/engine/bsp/Kbuild
+include $(src)/nvkm/engine/ce/Kbuild
+include $(src)/nvkm/engine/cipher/Kbuild
+include $(src)/nvkm/engine/device/Kbuild
+include $(src)/nvkm/engine/disp/Kbuild
+include $(src)/nvkm/engine/dmaobj/Kbuild
+include $(src)/nvkm/engine/fifo/Kbuild
+include $(src)/nvkm/engine/gr/Kbuild
+include $(src)/nvkm/engine/mpeg/Kbuild
+include $(src)/nvkm/engine/mspdec/Kbuild
+include $(src)/nvkm/engine/msppp/Kbuild
+include $(src)/nvkm/engine/msvld/Kbuild
+include $(src)/nvkm/engine/pm/Kbuild
+include $(src)/nvkm/engine/sec/Kbuild
+include $(src)/nvkm/engine/sw/Kbuild
+include $(src)/nvkm/engine/vp/Kbuild
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/Kbuild
new file mode 100644
index 000000000000..5ac9f9e1a283
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/Kbuild
@@ -0,0 +1 @@
+nvkm-y += nvkm/engine/bsp/g84.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c
index 1e8e75c0684a..a0b1fd80fa93 100644
--- a/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c
@@ -21,17 +21,18 @@
*
* Authors: Ben Skeggs, Ilia Mirkin
*/
-
-#include <engine/xtensa.h>
#include <engine/bsp.h>
+#include <engine/xtensa.h>
+
+#include <core/engctx.h>
/*******************************************************************************
* BSP object classes
******************************************************************************/
-static struct nouveau_oclass
-nv84_bsp_sclass[] = {
- { 0x74b0, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+g84_bsp_sclass[] = {
+ { 0x74b0, &nvkm_object_ofuncs },
{},
};
@@ -39,16 +40,16 @@ nv84_bsp_sclass[] = {
* BSP context
******************************************************************************/
-static struct nouveau_oclass
-nv84_bsp_cclass = {
+static struct nvkm_oclass
+g84_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_xtensa_engctx_ctor,
- .dtor = _nouveau_engctx_dtor,
- .init = _nouveau_engctx_init,
- .fini = _nouveau_engctx_fini,
- .rd32 = _nouveau_engctx_rd32,
- .wr32 = _nouveau_engctx_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_xtensa_engctx_ctor,
+ .dtor = _nvkm_engctx_dtor,
+ .init = _nvkm_engctx_init,
+ .fini = _nvkm_engctx_fini,
+ .rd32 = _nvkm_engctx_rd32,
+ .wr32 = _nvkm_engctx_wr32,
},
};
@@ -57,36 +58,36 @@ nv84_bsp_cclass = {
******************************************************************************/
static int
-nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_bsp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_xtensa *priv;
+ struct nvkm_xtensa *priv;
int ret;
- ret = nouveau_xtensa_create(parent, engine, oclass, 0x103000, true,
- "PBSP", "bsp", &priv);
+ ret = nvkm_xtensa_create(parent, engine, oclass, 0x103000, true,
+ "PBSP", "bsp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x04008000;
- nv_engine(priv)->cclass = &nv84_bsp_cclass;
- nv_engine(priv)->sclass = nv84_bsp_sclass;
+ nv_engine(priv)->cclass = &g84_bsp_cclass;
+ nv_engine(priv)->sclass = g84_bsp_sclass;
priv->fifo_val = 0x1111;
priv->unkd28 = 0x90044;
return 0;
}
-struct nouveau_oclass
-nv84_bsp_oclass = {
+struct nvkm_oclass
+g84_bsp_oclass = {
.handle = NV_ENGINE(BSP, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_bsp_ctor,
- .dtor = _nouveau_xtensa_dtor,
- .init = _nouveau_xtensa_init,
- .fini = _nouveau_xtensa_fini,
- .rd32 = _nouveau_xtensa_rd32,
- .wr32 = _nouveau_xtensa_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_bsp_ctor,
+ .dtor = _nvkm_xtensa_dtor,
+ .init = _nvkm_xtensa_init,
+ .fini = _nvkm_xtensa_fini,
+ .rd32 = _nvkm_xtensa_rd32,
+ .wr32 = _nvkm_xtensa_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild
new file mode 100644
index 000000000000..858797453e0b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild
@@ -0,0 +1,3 @@
+nvkm-y += nvkm/engine/ce/gt215.o
+nvkm-y += nvkm/engine/ce/gf100.o
+nvkm-y += nvkm/engine/ce/gk104.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/com.fuc
index 219850d53286..a558dfa4d76a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/com.fuc
@@ -1,4 +1,4 @@
-/* fuc microcode for copy engine on nva3- chipsets
+/* fuc microcode for copy engine on gt215- chipsets
*
* Copyright 2011 Red Hat Inc.
*
@@ -23,26 +23,19 @@
* Authors: Ben Skeggs
*/
-/* To build for nva3:nvc0
- * m4 -DNVA3 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nva3_copy.fuc.h
- *
- * To build for nvc0-
- * m4 -DNVC0 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_copy.fuc.h
- */
-
-ifdef(`NVA3',
-.section #nva3_pcopy_data
-,
-.section #nvc0_pcopy_data
-)
+#ifdef GT215
+.section #gt215_pce_data
+#else
+.section #gf100_pce_data
+#endif
ctx_object: .b32 0
-ifdef(`NVA3',
+#ifdef GT215
ctx_dma:
ctx_dma_query: .b32 0
ctx_dma_src: .b32 0
ctx_dma_dst: .b32 0
-,)
+#endif
.equ #ctx_dma_count 3
ctx_query_address_high: .b32 0
ctx_query_address_low: .b32 0
@@ -86,14 +79,14 @@ dispatch_table:
// mthd 0x0140, PM_TRIGGER
.b16 0x050 1
.b32 0x00010000 + #cmd_pm_trigger ~0xffffffff
-ifdef(`NVA3', `
+#ifdef GT215
// mthd 0x0180-0x018c, DMA_
.b16 0x060 #ctx_dma_count
dispatch_dma:
.b32 0x00010000 + #cmd_dma ~0xffffffff
.b32 0x00010000 + #cmd_dma ~0xffffffff
.b32 0x00010000 + #cmd_dma ~0xffffffff
-',)
+#endif
// mthd 0x0200-0x0218, SRC_TILE
.b16 0x80 7
.b32 #ctx_src_tile_mode ~0x00000fff
@@ -134,11 +127,11 @@ dispatch_dma:
.b32 #ctx_query_counter ~0xffffffff
.b16 0x800 0
-ifdef(`NVA3',
-.section #nva3_pcopy_code
-,
-.section #nvc0_pcopy_code
-)
+#ifdef GT215
+.section #gt215_pce_code
+#else
+.section #gf100_pce_code
+#endif
main:
clear b32 $r0
@@ -190,10 +183,10 @@ ih:
swctx:
mov $r4 0x7700
mov $xtargets $r4
-ifdef(`NVA3', `
+#ifdef GT215
// target 7 hardcoded to ctx dma object
mov $xdbase $r0
-', ` // NVC0
+#else
// read SCRATCH3 to decide if we are PCOPY0 or PCOPY1
mov $r4 0x2100
iord $r4 I[$r4 + 0]
@@ -231,7 +224,7 @@ ifdef(`NVA3', `
shl b32 $r6 24
or $r4 $r6
mov $xdbase $r4
-')
+#endif
// 256-byte context, at start of data segment
mov b32 $r4 $r0
sethi $r4 0x60000
@@ -271,7 +264,7 @@ chsw:
bra e #chsw_finish_load
bset $flags $p1
call #swctx
-ifdef(`NVA3',
+#ifdef GT215
// load dma objects back into TARGET regs
mov $r5 #ctx_dma
mov $r6 #ctx_dma_count
@@ -282,8 +275,7 @@ ifdef(`NVA3',
iowr I[$r8] $r7
sub b32 $r6 1
bra nc #chsw_load_ctx_dma
-,)
-
+#endif
chsw_finish_load:
mov $r3 2
iowr I[$r2 + 0x200] $r3
@@ -397,7 +389,7 @@ cmd_pm_trigger:
iowr I[$r2] $r3
ret
-ifdef(`NVA3',
+#ifdef GT215
// SET_DMA_* method handler
//
// Inputs:
@@ -419,7 +411,7 @@ cmd_dma:
shl b32 $r4 6
iowr I[$r4] $r3
ret
-,)
+#endif
// Calculates the hw swizzle mask and adjusts the surface's xcnt to match
//
@@ -548,11 +540,11 @@ cmd_exec_set_surface_tiled:
ld b32 $r7 D[$r5 + #ctx_src_tile_mode]
extr $r9 $r7 8:11
extr $r8 $r7 4:7
-ifdef(`NVA3',
+#ifdef GT215
add b32 $r8 2
-,
+#else
add b32 $r8 3
-)
+#endif
extr $r7 $r7 0:3
cmp b32 $r7 0xe
bra ne #xtile64
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc3 b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc3
new file mode 100644
index 000000000000..36f0a99ac7a2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc3
@@ -0,0 +1,2 @@
+#define GF100
+#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc3.h
index 98cc4216a372..d9af6e4e4585 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvc0_pcopy_data[] = {
+uint32_t gf100_pce_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_query_address_high */
@@ -171,7 +171,7 @@ uint32_t nvc0_pcopy_data[] = {
0x00000800,
};
-uint32_t nvc0_pcopy_code[] = {
+uint32_t gf100_pce_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc3 b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc3
new file mode 100644
index 000000000000..07bda93cfd79
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc3
@@ -0,0 +1,2 @@
+#define GT215
+#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc3.h
index 241b27201206..f42c0d0d6cee 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nva3_pcopy_data[] = {
+uint32_t gt215_pce_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_dma */
@@ -183,7 +183,7 @@ uint32_t nva3_pcopy_data[] = {
0x00000800,
};
-uint32_t nva3_pcopy_code[] = {
+uint32_t gt215_pce_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
new file mode 100644
index 000000000000..2d2e549c2e34
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include <engine/ce.h>
+#include <engine/falcon.h>
+#include "fuc/gf100.fuc3.h"
+
+struct gf100_ce_priv {
+ struct nvkm_falcon base;
+};
+
+/*******************************************************************************
+ * Copy object classes
+ ******************************************************************************/
+
+static struct nvkm_oclass
+gf100_ce0_sclass[] = {
+ { 0x90b5, &nvkm_object_ofuncs },
+ {},
+};
+
+static struct nvkm_oclass
+gf100_ce1_sclass[] = {
+ { 0x90b8, &nvkm_object_ofuncs },
+ {},
+};
+
+/*******************************************************************************
+ * PCE context
+ ******************************************************************************/
+
+static struct nvkm_ofuncs
+gf100_ce_context_ofuncs = {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
+};
+
+static struct nvkm_oclass
+gf100_ce0_cclass = {
+ .handle = NV_ENGCTX(CE0, 0xc0),
+ .ofuncs = &gf100_ce_context_ofuncs,
+};
+
+static struct nvkm_oclass
+gf100_ce1_cclass = {
+ .handle = NV_ENGCTX(CE1, 0xc0),
+ .ofuncs = &gf100_ce_context_ofuncs,
+};
+
+/*******************************************************************************
+ * PCE engine/subdev functions
+ ******************************************************************************/
+
+static int
+gf100_ce_init(struct nvkm_object *object)
+{
+ struct gf100_ce_priv *priv = (void *)object;
+ int ret;
+
+ ret = nvkm_falcon_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_wo32(priv, 0x084, nv_engidx(&priv->base.base) - NVDEV_ENGINE_CE0);
+ return 0;
+}
+
+static int
+gf100_ce0_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gf100_ce_priv *priv;
+ int ret;
+
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x104000, true,
+ "PCE0", "ce0", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000040;
+ nv_subdev(priv)->intr = gt215_ce_intr;
+ nv_engine(priv)->cclass = &gf100_ce0_cclass;
+ nv_engine(priv)->sclass = gf100_ce0_sclass;
+ nv_falcon(priv)->code.data = gf100_pce_code;
+ nv_falcon(priv)->code.size = sizeof(gf100_pce_code);
+ nv_falcon(priv)->data.data = gf100_pce_data;
+ nv_falcon(priv)->data.size = sizeof(gf100_pce_data);
+ return 0;
+}
+
+static int
+gf100_ce1_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gf100_ce_priv *priv;
+ int ret;
+
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x105000, true,
+ "PCE1", "ce1", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000080;
+ nv_subdev(priv)->intr = gt215_ce_intr;
+ nv_engine(priv)->cclass = &gf100_ce1_cclass;
+ nv_engine(priv)->sclass = gf100_ce1_sclass;
+ nv_falcon(priv)->code.data = gf100_pce_code;
+ nv_falcon(priv)->code.size = sizeof(gf100_pce_code);
+ nv_falcon(priv)->data.data = gf100_pce_data;
+ nv_falcon(priv)->data.size = sizeof(gf100_pce_data);
+ return 0;
+}
+
+struct nvkm_oclass
+gf100_ce0_oclass = {
+ .handle = NV_ENGINE(CE0, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_ce0_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = gf100_ce_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
+ },
+};
+
+struct nvkm_oclass
+gf100_ce1_oclass = {
+ .handle = NV_ENGINE(CE1, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_ce1_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = gf100_ce_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c
new file mode 100644
index 000000000000..a998932fae45
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include <engine/ce.h>
+
+#include <core/engctx.h>
+
+struct gk104_ce_priv {
+ struct nvkm_engine base;
+};
+
+/*******************************************************************************
+ * Copy object classes
+ ******************************************************************************/
+
+static struct nvkm_oclass
+gk104_ce_sclass[] = {
+ { 0xa0b5, &nvkm_object_ofuncs },
+ {},
+};
+
+/*******************************************************************************
+ * PCE context
+ ******************************************************************************/
+
+static struct nvkm_ofuncs
+gk104_ce_context_ofuncs = {
+ .ctor = _nvkm_engctx_ctor,
+ .dtor = _nvkm_engctx_dtor,
+ .init = _nvkm_engctx_init,
+ .fini = _nvkm_engctx_fini,
+ .rd32 = _nvkm_engctx_rd32,
+ .wr32 = _nvkm_engctx_wr32,
+};
+
+static struct nvkm_oclass
+gk104_ce_cclass = {
+ .handle = NV_ENGCTX(CE0, 0xc0),
+ .ofuncs = &gk104_ce_context_ofuncs,
+};
+
+/*******************************************************************************
+ * PCE engine/subdev functions
+ ******************************************************************************/
+
+static void
+gk104_ce_intr(struct nvkm_subdev *subdev)
+{
+ const int ce = nv_subidx(subdev) - NVDEV_ENGINE_CE0;
+ struct gk104_ce_priv *priv = (void *)subdev;
+ u32 stat = nv_rd32(priv, 0x104908 + (ce * 0x1000));
+
+ if (stat) {
+ nv_warn(priv, "unhandled intr 0x%08x\n", stat);
+ nv_wr32(priv, 0x104908 + (ce * 0x1000), stat);
+ }
+}
+
+static int
+gk104_ce0_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gk104_ce_priv *priv;
+ int ret;
+
+ ret = nvkm_engine_create(parent, engine, oclass, true,
+ "PCE0", "ce0", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000040;
+ nv_subdev(priv)->intr = gk104_ce_intr;
+ nv_engine(priv)->cclass = &gk104_ce_cclass;
+ nv_engine(priv)->sclass = gk104_ce_sclass;
+ return 0;
+}
+
+static int
+gk104_ce1_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gk104_ce_priv *priv;
+ int ret;
+
+ ret = nvkm_engine_create(parent, engine, oclass, true,
+ "PCE1", "ce1", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00000080;
+ nv_subdev(priv)->intr = gk104_ce_intr;
+ nv_engine(priv)->cclass = &gk104_ce_cclass;
+ nv_engine(priv)->sclass = gk104_ce_sclass;
+ return 0;
+}
+
+static int
+gk104_ce2_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gk104_ce_priv *priv;
+ int ret;
+
+ ret = nvkm_engine_create(parent, engine, oclass, true,
+ "PCE2", "ce2", &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->unit = 0x00200000;
+ nv_subdev(priv)->intr = gk104_ce_intr;
+ nv_engine(priv)->cclass = &gk104_ce_cclass;
+ nv_engine(priv)->sclass = gk104_ce_sclass;
+ return 0;
+}
+
+struct nvkm_oclass
+gk104_ce0_oclass = {
+ .handle = NV_ENGINE(CE0, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_ce0_ctor,
+ .dtor = _nvkm_engine_dtor,
+ .init = _nvkm_engine_init,
+ .fini = _nvkm_engine_fini,
+ },
+};
+
+struct nvkm_oclass
+gk104_ce1_oclass = {
+ .handle = NV_ENGINE(CE1, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_ce1_ctor,
+ .dtor = _nvkm_engine_dtor,
+ .init = _nvkm_engine_init,
+ .fini = _nvkm_engine_fini,
+ },
+};
+
+struct nvkm_oclass
+gk104_ce2_oclass = {
+ .handle = NV_ENGINE(CE2, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_ce2_ctor,
+ .dtor = _nvkm_engine_dtor,
+ .init = _nvkm_engine_init,
+ .fini = _nvkm_engine_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
index abb410ef09ea..d8bb4293bc11 100644
--- a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
@@ -21,57 +21,53 @@
*
* Authors: Ben Skeggs
*/
-
+#include <engine/ce.h>
#include <engine/falcon.h>
#include <engine/fifo.h>
-#include <engine/copy.h>
-
-#include <subdev/fb.h>
-#include <subdev/vm.h>
+#include "fuc/gt215.fuc3.h"
#include <core/client.h>
+#include <core/device.h>
#include <core/enum.h>
-
-#include "fuc/nva3.fuc.h"
-
-struct nva3_copy_priv {
- struct nouveau_falcon base;
+struct gt215_ce_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
* Copy object classes
******************************************************************************/
-static struct nouveau_oclass
-nva3_copy_sclass[] = {
- { 0x85b5, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+gt215_ce_sclass[] = {
+ { 0x85b5, &nvkm_object_ofuncs },
{}
};
/*******************************************************************************
- * PCOPY context
+ * PCE context
******************************************************************************/
-static struct nouveau_oclass
-nva3_copy_cclass = {
- .handle = NV_ENGCTX(COPY0, 0xa3),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+gt215_ce_cclass = {
+ .handle = NV_ENGCTX(CE0, 0xa3),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PCOPY engine/subdev functions
+ * PCE engine/subdev functions
******************************************************************************/
-static const struct nouveau_enum nva3_copy_isr_error_name[] = {
+static const struct nvkm_enum
+gt215_ce_isr_error_name[] = {
{ 0x0001, "ILLEGAL_MTHD" },
{ 0x0002, "INVALID_ENUM" },
{ 0x0003, "INVALID_BITFIELD" },
@@ -79,12 +75,12 @@ static const struct nouveau_enum nva3_copy_isr_error_name[] = {
};
void
-nva3_copy_intr(struct nouveau_subdev *subdev)
+gt215_ce_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_falcon *falcon = (void *)subdev;
- struct nouveau_object *engctx;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_falcon *falcon = (void *)subdev;
+ struct nvkm_object *engctx;
u32 dispatch = nv_ro32(falcon, 0x01c);
u32 stat = nv_ro32(falcon, 0x008) & dispatch & ~(dispatch >> 16);
u64 inst = nv_ro32(falcon, 0x050) & 0x3fffffff;
@@ -95,14 +91,14 @@ nva3_copy_intr(struct nouveau_subdev *subdev)
u32 data = nv_ro32(falcon, 0x044);
int chid;
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & 0x00000040) {
nv_error(falcon, "DISPATCH_ERROR [");
- nouveau_enum_print(nva3_copy_isr_error_name, ssta);
+ nvkm_enum_print(gt215_ce_isr_error_name, ssta);
pr_cont("] ch %d [0x%010llx %s] subc %d mthd 0x%04x data 0x%08x\n",
- chid, inst << 12, nouveau_client_name(engctx), subc,
+ chid, inst << 12, nvkm_client_name(engctx), subc,
mthd, data);
nv_wo32(falcon, 0x004, 0x00000040);
stat &= ~0x00000040;
@@ -113,44 +109,44 @@ nva3_copy_intr(struct nouveau_subdev *subdev)
nv_wo32(falcon, 0x004, stat);
}
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
static int
-nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gt215_ce_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
bool enable = (nv_device(parent)->chipset != 0xaf);
- struct nva3_copy_priv *priv;
+ struct gt215_ce_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x104000, enable,
- "PCE0", "copy0", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x104000, enable,
+ "PCE0", "ce0", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00802000;
- nv_subdev(priv)->intr = nva3_copy_intr;
- nv_engine(priv)->cclass = &nva3_copy_cclass;
- nv_engine(priv)->sclass = nva3_copy_sclass;
- nv_falcon(priv)->code.data = nva3_pcopy_code;
- nv_falcon(priv)->code.size = sizeof(nva3_pcopy_code);
- nv_falcon(priv)->data.data = nva3_pcopy_data;
- nv_falcon(priv)->data.size = sizeof(nva3_pcopy_data);
+ nv_subdev(priv)->intr = gt215_ce_intr;
+ nv_engine(priv)->cclass = &gt215_ce_cclass;
+ nv_engine(priv)->sclass = gt215_ce_sclass;
+ nv_falcon(priv)->code.data = gt215_pce_code;
+ nv_falcon(priv)->code.size = sizeof(gt215_pce_code);
+ nv_falcon(priv)->data.data = gt215_pce_data;
+ nv_falcon(priv)->data.size = sizeof(gt215_pce_data);
return 0;
}
-struct nouveau_oclass
-nva3_copy_oclass = {
- .handle = NV_ENGINE(COPY0, 0xa3),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_copy_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = _nouveau_falcon_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+gt215_ce_oclass = {
+ .handle = NV_ENGINE(CE0, 0xa3),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gt215_ce_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = _nvkm_falcon_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/cipher/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/Kbuild
new file mode 100644
index 000000000000..fa39945327ce
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/Kbuild
@@ -0,0 +1 @@
+nvkm-y += nvkm/engine/cipher/g84.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
index ea5c42f31791..13f30428a305 100644
--- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
@@ -21,20 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include <engine/cipher.h>
+#include <engine/fifo.h>
#include <core/client.h>
-#include <core/os.h>
-#include <core/enum.h>
#include <core/engctx.h>
-#include <core/gpuobj.h>
-
-#include <subdev/fb.h>
-
-#include <engine/fifo.h>
-#include <engine/crypt.h>
+#include <core/enum.h>
-struct nv84_crypt_priv {
- struct nouveau_engine base;
+struct g84_cipher_priv {
+ struct nvkm_engine base;
};
/*******************************************************************************
@@ -42,16 +37,16 @@ struct nv84_crypt_priv {
******************************************************************************/
static int
-nv84_crypt_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_cipher_object_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_gpuobj *obj;
+ struct nvkm_gpuobj *obj;
int ret;
- ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
- 16, 16, 0, &obj);
+ ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
*pobject = nv_object(obj);
if (ret)
return ret;
@@ -63,44 +58,45 @@ nv84_crypt_object_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
-nv84_crypt_ofuncs = {
- .ctor = nv84_crypt_object_ctor,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
+static struct nvkm_ofuncs
+g84_cipher_ofuncs = {
+ .ctor = g84_cipher_object_ctor,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
};
-static struct nouveau_oclass
-nv84_crypt_sclass[] = {
- { 0x74c1, &nv84_crypt_ofuncs },
+static struct nvkm_oclass
+g84_cipher_sclass[] = {
+ { 0x74c1, &g84_cipher_ofuncs },
{}
};
/*******************************************************************************
- * PCRYPT context
+ * PCIPHER context
******************************************************************************/
-static struct nouveau_oclass
-nv84_crypt_cclass = {
- .handle = NV_ENGCTX(CRYPT, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_engctx_ctor,
- .dtor = _nouveau_engctx_dtor,
- .init = _nouveau_engctx_init,
- .fini = _nouveau_engctx_fini,
- .rd32 = _nouveau_engctx_rd32,
- .wr32 = _nouveau_engctx_wr32,
+static struct nvkm_oclass
+g84_cipher_cclass = {
+ .handle = NV_ENGCTX(CIPHER, 0x84),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_engctx_ctor,
+ .dtor = _nvkm_engctx_dtor,
+ .init = _nvkm_engctx_init,
+ .fini = _nvkm_engctx_fini,
+ .rd32 = _nvkm_engctx_rd32,
+ .wr32 = _nvkm_engctx_wr32,
},
};
/*******************************************************************************
- * PCRYPT engine/subdev functions
+ * PCIPHER engine/subdev functions
******************************************************************************/
-static const struct nouveau_bitfield nv84_crypt_intr_mask[] = {
+static const struct nvkm_bitfield
+g84_cipher_intr_mask[] = {
{ 0x00000001, "INVALID_STATE" },
{ 0x00000002, "ILLEGAL_MTHD" },
{ 0x00000004, "ILLEGAL_CLASS" },
@@ -110,63 +106,63 @@ static const struct nouveau_bitfield nv84_crypt_intr_mask[] = {
};
static void
-nv84_crypt_intr(struct nouveau_subdev *subdev)
+g84_cipher_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nv84_crypt_priv *priv = (void *)subdev;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_object *engctx;
+ struct g84_cipher_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, 0x102130);
u32 mthd = nv_rd32(priv, 0x102190);
u32 data = nv_rd32(priv, 0x102194);
u32 inst = nv_rd32(priv, 0x102188) & 0x7fffffff;
int chid;
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat) {
nv_error(priv, "%s", "");
- nouveau_bitfield_print(nv84_crypt_intr_mask, stat);
+ nvkm_bitfield_print(g84_cipher_intr_mask, stat);
pr_cont(" ch %d [0x%010llx %s] mthd 0x%04x data 0x%08x\n",
- chid, (u64)inst << 12, nouveau_client_name(engctx),
+ chid, (u64)inst << 12, nvkm_client_name(engctx),
mthd, data);
}
nv_wr32(priv, 0x102130, stat);
nv_wr32(priv, 0x10200c, 0x10);
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
static int
-nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_cipher_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv84_crypt_priv *priv;
+ struct g84_cipher_priv *priv;
int ret;
- ret = nouveau_engine_create(parent, engine, oclass, true,
- "PCRYPT", "crypt", &priv);
+ ret = nvkm_engine_create(parent, engine, oclass, true,
+ "PCIPHER", "cipher", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00004000;
- nv_subdev(priv)->intr = nv84_crypt_intr;
- nv_engine(priv)->cclass = &nv84_crypt_cclass;
- nv_engine(priv)->sclass = nv84_crypt_sclass;
+ nv_subdev(priv)->intr = g84_cipher_intr;
+ nv_engine(priv)->cclass = &g84_cipher_cclass;
+ nv_engine(priv)->sclass = g84_cipher_sclass;
return 0;
}
static int
-nv84_crypt_init(struct nouveau_object *object)
+g84_cipher_init(struct nvkm_object *object)
{
- struct nv84_crypt_priv *priv = (void *)object;
+ struct g84_cipher_priv *priv = (void *)object;
int ret;
- ret = nouveau_engine_init(&priv->base);
+ ret = nvkm_engine_init(&priv->base);
if (ret)
return ret;
@@ -176,13 +172,13 @@ nv84_crypt_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv84_crypt_oclass = {
- .handle = NV_ENGINE(CRYPT, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_crypt_ctor,
- .dtor = _nouveau_engine_dtor,
- .init = nv84_crypt_init,
- .fini = _nouveau_engine_fini,
+struct nvkm_oclass
+g84_cipher_oclass = {
+ .handle = NV_ENGINE(CIPHER, 0x84),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_cipher_ctor,
+ .dtor = _nvkm_engine_dtor,
+ .init = g84_cipher_init,
+ .fini = _nvkm_engine_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild
new file mode 100644
index 000000000000..de1bf092b2b2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/Kbuild
@@ -0,0 +1,12 @@
+nvkm-y += nvkm/engine/device/acpi.o
+nvkm-y += nvkm/engine/device/base.o
+nvkm-y += nvkm/engine/device/ctrl.o
+nvkm-y += nvkm/engine/device/nv04.o
+nvkm-y += nvkm/engine/device/nv10.o
+nvkm-y += nvkm/engine/device/nv20.o
+nvkm-y += nvkm/engine/device/nv30.o
+nvkm-y += nvkm/engine/device/nv40.o
+nvkm-y += nvkm/engine/device/nv50.o
+nvkm-y += nvkm/engine/device/gf100.o
+nvkm-y += nvkm/engine/device/gk104.o
+nvkm-y += nvkm/engine/device/gm100.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/acpi.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/acpi.c
index 4dbf0ba89e5c..f42706e1d5db 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/acpi.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/acpi.c
@@ -21,14 +21,15 @@
*
* Authors: Ben Skeggs
*/
-
#include "acpi.h"
+#include <core/device.h>
+
#ifdef CONFIG_ACPI
static int
nvkm_acpi_ntfy(struct notifier_block *nb, unsigned long val, void *data)
{
- struct nouveau_device *device =
+ struct nvkm_device *device =
container_of(nb, typeof(*device), acpi.nb);
struct acpi_bus_event *info = data;
@@ -40,7 +41,7 @@ nvkm_acpi_ntfy(struct notifier_block *nb, unsigned long val, void *data)
#endif
int
-nvkm_acpi_fini(struct nouveau_device *device, bool suspend)
+nvkm_acpi_fini(struct nvkm_device *device, bool suspend)
{
#ifdef CONFIG_ACPI
unregister_acpi_notifier(&device->acpi.nb);
@@ -49,7 +50,7 @@ nvkm_acpi_fini(struct nouveau_device *device, bool suspend)
}
int
-nvkm_acpi_init(struct nouveau_device *device)
+nvkm_acpi_init(struct nvkm_device *device)
{
#ifdef CONFIG_ACPI
device->acpi.nb.notifier_call = nvkm_acpi_ntfy;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/acpi.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/acpi.h
new file mode 100644
index 000000000000..82dd359ddfa4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/acpi.h
@@ -0,0 +1,8 @@
+#ifndef __NVKM_DEVICE_ACPI_H__
+#define __NVKM_DEVICE_ACPI_H__
+#include <core/os.h>
+struct nvkm_device;
+
+int nvkm_acpi_init(struct nvkm_device *);
+int nvkm_acpi_fini(struct nvkm_device *, bool);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 137e0b0faeae..29bd539af183 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -21,28 +21,27 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
+#include "acpi.h"
-#include <core/object.h>
-#include <core/device.h>
#include <core/client.h>
#include <core/option.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
+#include <core/notify.h>
+#include <core/parent.h>
#include <subdev/bios.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
-#include "priv.h"
-#include "acpi.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
static DEFINE_MUTEX(nv_devices_mutex);
static LIST_HEAD(nv_devices);
-struct nouveau_device *
-nouveau_device_find(u64 name)
+struct nvkm_device *
+nvkm_device_find(u64 name)
{
- struct nouveau_device *device, *match = NULL;
+ struct nvkm_device *device, *match = NULL;
mutex_lock(&nv_devices_mutex);
list_for_each_entry(device, &nv_devices, head) {
if (device->handle == name) {
@@ -55,9 +54,9 @@ nouveau_device_find(u64 name)
}
int
-nouveau_device_list(u64 *name, int size)
+nvkm_device_list(u64 *name, int size)
{
- struct nouveau_device *device;
+ struct nvkm_device *device;
int nr = 0;
mutex_lock(&nv_devices_mutex);
list_for_each_entry(device, &nv_devices, head) {
@@ -69,20 +68,20 @@ nouveau_device_list(u64 *name, int size)
}
/******************************************************************************
- * nouveau_devobj (0x0080): class implementation
+ * nvkm_devobj (0x0080): class implementation
*****************************************************************************/
-struct nouveau_devobj {
- struct nouveau_parent base;
- struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
+struct nvkm_devobj {
+ struct nvkm_parent base;
+ struct nvkm_object *subdev[NVDEV_SUBDEV_NR];
};
static int
-nouveau_devobj_info(struct nouveau_object *object, void *data, u32 size)
+nvkm_devobj_info(struct nvkm_object *object, void *data, u32 size)
{
- struct nouveau_device *device = nv_device(object);
- struct nouveau_fb *pfb = nouveau_fb(device);
- struct nouveau_instmem *imem = nouveau_instmem(device);
+ struct nvkm_device *device = nv_device(object);
+ struct nvkm_fb *pfb = nvkm_fb(device);
+ struct nvkm_instmem *imem = nvkm_instmem(device);
union {
struct nv_device_info_v0 v0;
} *args = data;
@@ -147,12 +146,11 @@ nouveau_devobj_info(struct nouveau_object *object, void *data, u32 size)
}
static int
-nouveau_devobj_mthd(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
+nvkm_devobj_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
switch (mthd) {
case NV_DEVICE_V0_INFO:
- return nouveau_devobj_info(object, data, size);
+ return nvkm_devobj_info(object, data, size);
default:
break;
}
@@ -160,45 +158,45 @@ nouveau_devobj_mthd(struct nouveau_object *object, u32 mthd,
}
static u8
-nouveau_devobj_rd08(struct nouveau_object *object, u64 addr)
+nvkm_devobj_rd08(struct nvkm_object *object, u64 addr)
{
return nv_rd08(object->engine, addr);
}
static u16
-nouveau_devobj_rd16(struct nouveau_object *object, u64 addr)
+nvkm_devobj_rd16(struct nvkm_object *object, u64 addr)
{
return nv_rd16(object->engine, addr);
}
static u32
-nouveau_devobj_rd32(struct nouveau_object *object, u64 addr)
+nvkm_devobj_rd32(struct nvkm_object *object, u64 addr)
{
return nv_rd32(object->engine, addr);
}
static void
-nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data)
+nvkm_devobj_wr08(struct nvkm_object *object, u64 addr, u8 data)
{
nv_wr08(object->engine, addr, data);
}
static void
-nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data)
+nvkm_devobj_wr16(struct nvkm_object *object, u64 addr, u16 data)
{
nv_wr16(object->engine, addr, data);
}
static void
-nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
+nvkm_devobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
nv_wr32(object->engine, addr, data);
}
static int
-nouveau_devobj_map(struct nouveau_object *object, u64 *addr, u32 *size)
+nvkm_devobj_map(struct nvkm_object *object, u64 *addr, u32 *size)
{
- struct nouveau_device *device = nv_device(object);
+ struct nvkm_device *device = nv_device(object);
*addr = nv_device_resource_start(device, 0);
*size = nv_device_resource_len(device, 0);
return 0;
@@ -209,7 +207,7 @@ static const u64 disable_map[] = {
[NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_GPIO] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_I2C] = NV_DEVICE_V0_DISABLE_CORE,
- [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_V0_DISABLE_CORE,
+ [NVDEV_SUBDEV_CLK ] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_MXM] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_MC] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_BUS] = NV_DEVICE_V0_DISABLE_CORE,
@@ -218,74 +216,75 @@ static const u64 disable_map[] = {
[NVDEV_SUBDEV_LTC] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_IBUS] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_V0_DISABLE_CORE,
- [NVDEV_SUBDEV_VM] = NV_DEVICE_V0_DISABLE_CORE,
+ [NVDEV_SUBDEV_MMU] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_BAR] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_VOLT] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_THERM] = NV_DEVICE_V0_DISABLE_CORE,
- [NVDEV_SUBDEV_PWR] = NV_DEVICE_V0_DISABLE_CORE,
+ [NVDEV_SUBDEV_PMU] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_SUBDEV_FUSE] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_V0_DISABLE_CORE,
- [NVDEV_ENGINE_PERFMON] = NV_DEVICE_V0_DISABLE_CORE,
+ [NVDEV_ENGINE_PM ] = NV_DEVICE_V0_DISABLE_CORE,
[NVDEV_ENGINE_FIFO] = NV_DEVICE_V0_DISABLE_FIFO,
[NVDEV_ENGINE_SW] = NV_DEVICE_V0_DISABLE_FIFO,
- [NVDEV_ENGINE_GR] = NV_DEVICE_V0_DISABLE_GRAPH,
+ [NVDEV_ENGINE_GR] = NV_DEVICE_V0_DISABLE_GR,
[NVDEV_ENGINE_MPEG] = NV_DEVICE_V0_DISABLE_MPEG,
[NVDEV_ENGINE_ME] = NV_DEVICE_V0_DISABLE_ME,
[NVDEV_ENGINE_VP] = NV_DEVICE_V0_DISABLE_VP,
- [NVDEV_ENGINE_CRYPT] = NV_DEVICE_V0_DISABLE_CRYPT,
+ [NVDEV_ENGINE_CIPHER] = NV_DEVICE_V0_DISABLE_CIPHER,
[NVDEV_ENGINE_BSP] = NV_DEVICE_V0_DISABLE_BSP,
- [NVDEV_ENGINE_PPP] = NV_DEVICE_V0_DISABLE_PPP,
- [NVDEV_ENGINE_COPY0] = NV_DEVICE_V0_DISABLE_COPY0,
- [NVDEV_ENGINE_COPY1] = NV_DEVICE_V0_DISABLE_COPY1,
- [NVDEV_ENGINE_COPY2] = NV_DEVICE_V0_DISABLE_COPY1,
+ [NVDEV_ENGINE_MSPPP] = NV_DEVICE_V0_DISABLE_MSPPP,
+ [NVDEV_ENGINE_CE0] = NV_DEVICE_V0_DISABLE_CE0,
+ [NVDEV_ENGINE_CE1] = NV_DEVICE_V0_DISABLE_CE1,
+ [NVDEV_ENGINE_CE2] = NV_DEVICE_V0_DISABLE_CE2,
[NVDEV_ENGINE_VIC] = NV_DEVICE_V0_DISABLE_VIC,
- [NVDEV_ENGINE_VENC] = NV_DEVICE_V0_DISABLE_VENC,
+ [NVDEV_ENGINE_MSENC] = NV_DEVICE_V0_DISABLE_MSENC,
[NVDEV_ENGINE_DISP] = NV_DEVICE_V0_DISABLE_DISP,
+ [NVDEV_ENGINE_MSVLD] = NV_DEVICE_V0_DISABLE_MSVLD,
+ [NVDEV_ENGINE_SEC] = NV_DEVICE_V0_DISABLE_SEC,
[NVDEV_SUBDEV_NR] = 0,
};
static void
-nouveau_devobj_dtor(struct nouveau_object *object)
+nvkm_devobj_dtor(struct nvkm_object *object)
{
- struct nouveau_devobj *devobj = (void *)object;
+ struct nvkm_devobj *devobj = (void *)object;
int i;
for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--)
- nouveau_object_ref(NULL, &devobj->subdev[i]);
+ nvkm_object_ref(NULL, &devobj->subdev[i]);
- nouveau_parent_destroy(&devobj->base);
+ nvkm_parent_destroy(&devobj->base);
}
-static struct nouveau_oclass
-nouveau_devobj_oclass_super = {
+static struct nvkm_oclass
+nvkm_devobj_oclass_super = {
.handle = NV_DEVICE,
- .ofuncs = &(struct nouveau_ofuncs) {
- .dtor = nouveau_devobj_dtor,
- .init = _nouveau_parent_init,
- .fini = _nouveau_parent_fini,
- .mthd = nouveau_devobj_mthd,
- .map = nouveau_devobj_map,
- .rd08 = nouveau_devobj_rd08,
- .rd16 = nouveau_devobj_rd16,
- .rd32 = nouveau_devobj_rd32,
- .wr08 = nouveau_devobj_wr08,
- .wr16 = nouveau_devobj_wr16,
- .wr32 = nouveau_devobj_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .dtor = nvkm_devobj_dtor,
+ .init = _nvkm_parent_init,
+ .fini = _nvkm_parent_fini,
+ .mthd = nvkm_devobj_mthd,
+ .map = nvkm_devobj_map,
+ .rd08 = nvkm_devobj_rd08,
+ .rd16 = nvkm_devobj_rd16,
+ .rd32 = nvkm_devobj_rd32,
+ .wr08 = nvkm_devobj_wr08,
+ .wr16 = nvkm_devobj_wr16,
+ .wr32 = nvkm_devobj_wr32,
}
};
static int
-nouveau_devobj_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nvkm_devobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv_device_v0 v0;
} *args = data;
- struct nouveau_client *client = nv_client(parent);
- struct nouveau_device *device;
- struct nouveau_devobj *devobj;
+ struct nvkm_client *client = nv_client(parent);
+ struct nvkm_device *device;
+ struct nvkm_devobj *devobj;
u32 boot0, strap;
u64 disable, mmio_base, mmio_size;
void __iomem *map;
@@ -302,22 +301,22 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
/* give priviledged clients register access */
if (client->super)
- oclass = &nouveau_devobj_oclass_super;
+ oclass = &nvkm_devobj_oclass_super;
/* find the device subdev that matches what the client requested */
device = nv_device(client->device);
if (args->v0.device != ~0) {
- device = nouveau_device_find(args->v0.device);
+ device = nvkm_device_find(args->v0.device);
if (!device)
return -ENODEV;
}
- ret = nouveau_parent_create(parent, nv_object(device), oclass, 0,
- nouveau_control_oclass,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_FIFO) |
- (1ULL << NVDEV_ENGINE_DISP) |
- (1ULL << NVDEV_ENGINE_PERFMON), &devobj);
+ ret = nvkm_parent_create(parent, nv_object(device), oclass, 0,
+ nvkm_control_oclass,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_FIFO) |
+ (1ULL << NVDEV_ENGINE_DISP) |
+ (1ULL << NVDEV_ENGINE_PM), &devobj);
*pobject = nv_object(devobj);
if (ret)
return ret;
@@ -400,8 +399,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
case NV_30: ret = nv30_identify(device); break;
case NV_40: ret = nv40_identify(device); break;
case NV_50: ret = nv50_identify(device); break;
- case NV_C0: ret = nvc0_identify(device); break;
- case NV_E0: ret = nve0_identify(device); break;
+ case NV_C0: ret = gf100_identify(device); break;
+ case NV_E0: ret = gk104_identify(device); break;
case GM100: ret = gm100_identify(device); break;
default:
ret = -EINVAL;
@@ -436,7 +435,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
} else
if ( (args->v0.disable & NV_DEVICE_V0_DISABLE_IDENTIFY)) {
device->cname = "NULL";
- device->oclass[NVDEV_SUBDEV_VBIOS] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS] = &nvkm_bios_oclass;
}
if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_MMIO) &&
@@ -454,14 +453,12 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
continue;
if (device->subdev[i]) {
- nouveau_object_ref(device->subdev[i],
- &devobj->subdev[i]);
+ nvkm_object_ref(device->subdev[i], &devobj->subdev[i]);
continue;
}
- ret = nouveau_object_ctor(nv_object(device), NULL,
- oclass, NULL, i,
- &devobj->subdev[i]);
+ ret = nvkm_object_ctor(nv_object(device), NULL, oclass,
+ NULL, i, &devobj->subdev[i]);
if (ret == -ENODEV)
continue;
if (ret)
@@ -479,15 +476,15 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
* subdev in turn as they're created.
*/
while (i >= NVDEV_SUBDEV_DEVINIT_LAST && c <= i) {
- struct nouveau_object *subdev = devobj->subdev[c++];
+ struct nvkm_object *subdev = devobj->subdev[c++];
if (subdev && !nv_iclass(subdev, NV_ENGINE_CLASS)) {
- ret = nouveau_object_inc(subdev);
+ ret = nvkm_object_inc(subdev);
if (ret)
return ret;
atomic_dec(&nv_object(device)->usecount);
} else
if (subdev) {
- nouveau_subdev_reset(subdev);
+ nvkm_subdev_reset(subdev);
}
}
}
@@ -495,28 +492,47 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
-nouveau_devobj_ofuncs = {
- .ctor = nouveau_devobj_ctor,
- .dtor = nouveau_devobj_dtor,
- .init = _nouveau_parent_init,
- .fini = _nouveau_parent_fini,
- .mthd = nouveau_devobj_mthd,
+static struct nvkm_ofuncs
+nvkm_devobj_ofuncs = {
+ .ctor = nvkm_devobj_ctor,
+ .dtor = nvkm_devobj_dtor,
+ .init = _nvkm_parent_init,
+ .fini = _nvkm_parent_fini,
+ .mthd = nvkm_devobj_mthd,
};
/******************************************************************************
- * nouveau_device: engine functions
+ * nvkm_device: engine functions
*****************************************************************************/
-static struct nouveau_oclass
-nouveau_device_sclass[] = {
- { 0x0080, &nouveau_devobj_ofuncs },
+struct nvkm_device *
+nv_device(void *obj)
+{
+ struct nvkm_object *device = nv_object(obj);
+ if (device->engine == NULL) {
+ while (device && device->parent)
+ device = device->parent;
+ } else {
+ device = &nv_object(obj)->engine->subdev.object;
+ if (device && device->parent)
+ device = device->parent;
+ }
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!device))
+ nv_assert("BAD CAST -> NvDevice, 0x%08x\n", nv_hclass(obj));
+#endif
+ return (void *)device;
+}
+
+static struct nvkm_oclass
+nvkm_device_sclass[] = {
+ { 0x0080, &nvkm_devobj_ofuncs },
{}
};
static int
-nouveau_device_event_ctor(struct nouveau_object *object, void *data, u32 size,
- struct nvkm_notify *notify)
+nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size,
+ struct nvkm_notify *notify)
{
if (!WARN_ON(size != 0)) {
notify->size = 0;
@@ -528,21 +544,21 @@ nouveau_device_event_ctor(struct nouveau_object *object, void *data, u32 size,
}
static const struct nvkm_event_func
-nouveau_device_event_func = {
- .ctor = nouveau_device_event_ctor,
+nvkm_device_event_func = {
+ .ctor = nvkm_device_event_ctor,
};
static int
-nouveau_device_fini(struct nouveau_object *object, bool suspend)
+nvkm_device_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_device *device = (void *)object;
- struct nouveau_object *subdev;
+ struct nvkm_device *device = (void *)object;
+ struct nvkm_object *subdev;
int ret, i;
for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
- ret = nouveau_object_dec(subdev, suspend);
+ ret = nvkm_object_dec(subdev, suspend);
if (ret && suspend)
goto fail;
}
@@ -554,7 +570,7 @@ fail:
for (; ret && i < NVDEV_SUBDEV_NR; i++) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
- ret = nouveau_object_inc(subdev);
+ ret = nvkm_object_inc(subdev);
if (ret) {
/* XXX */
}
@@ -566,10 +582,10 @@ fail:
}
static int
-nouveau_device_init(struct nouveau_object *object)
+nvkm_device_init(struct nvkm_object *object)
{
- struct nouveau_device *device = (void *)object;
- struct nouveau_object *subdev;
+ struct nvkm_device *device = (void *)object;
+ struct nvkm_object *subdev;
int ret, i = 0;
ret = nvkm_acpi_init(device);
@@ -579,11 +595,11 @@ nouveau_device_init(struct nouveau_object *object)
for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
- ret = nouveau_object_inc(subdev);
+ ret = nvkm_object_inc(subdev);
if (ret)
goto fail;
} else {
- nouveau_subdev_reset(subdev);
+ nvkm_subdev_reset(subdev);
}
}
}
@@ -593,7 +609,7 @@ fail:
for (--i; ret && i >= 0; i--) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS))
- nouveau_object_dec(subdev, false);
+ nvkm_object_dec(subdev, false);
}
}
@@ -603,9 +619,9 @@ fail:
}
static void
-nouveau_device_dtor(struct nouveau_object *object)
+nvkm_device_dtor(struct nvkm_object *object)
{
- struct nouveau_device *device = (void *)object;
+ struct nvkm_device *device = (void *)object;
nvkm_event_fini(&device->event);
@@ -616,11 +632,11 @@ nouveau_device_dtor(struct nouveau_object *object)
if (nv_subdev(device)->mmio)
iounmap(nv_subdev(device)->mmio);
- nouveau_engine_destroy(&device->base);
+ nvkm_engine_destroy(&device->engine);
}
resource_size_t
-nv_device_resource_start(struct nouveau_device *device, unsigned int bar)
+nv_device_resource_start(struct nvkm_device *device, unsigned int bar)
{
if (nv_device_is_pci(device)) {
return pci_resource_start(device->pdev, bar);
@@ -635,7 +651,7 @@ nv_device_resource_start(struct nouveau_device *device, unsigned int bar)
}
resource_size_t
-nv_device_resource_len(struct nouveau_device *device, unsigned int bar)
+nv_device_resource_len(struct nvkm_device *device, unsigned int bar)
{
if (nv_device_is_pci(device)) {
return pci_resource_len(device->pdev, bar);
@@ -650,7 +666,7 @@ nv_device_resource_len(struct nouveau_device *device, unsigned int bar)
}
int
-nv_device_get_irq(struct nouveau_device *device, bool stall)
+nv_device_get_irq(struct nvkm_device *device, bool stall)
{
if (nv_device_is_pci(device)) {
return device->pdev->irq;
@@ -660,22 +676,22 @@ nv_device_get_irq(struct nouveau_device *device, bool stall)
}
}
-static struct nouveau_oclass
-nouveau_device_oclass = {
+static struct nvkm_oclass
+nvkm_device_oclass = {
.handle = NV_ENGINE(DEVICE, 0x00),
- .ofuncs = &(struct nouveau_ofuncs) {
- .dtor = nouveau_device_dtor,
- .init = nouveau_device_init,
- .fini = nouveau_device_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .dtor = nvkm_device_dtor,
+ .init = nvkm_device_init,
+ .fini = nvkm_device_fini,
},
};
int
-nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name,
- const char *sname, const char *cfg, const char *dbg,
- int length, void **pobject)
+nvkm_device_create_(void *dev, enum nv_bus_type type, u64 name,
+ const char *sname, const char *cfg, const char *dbg,
+ int length, void **pobject)
{
- struct nouveau_device *device;
+ struct nvkm_device *device;
int ret = -EEXIST;
mutex_lock(&nv_devices_mutex);
@@ -684,17 +700,17 @@ nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name,
goto done;
}
- ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true,
- "DEVICE", "device", length, pobject);
+ ret = nvkm_engine_create_(NULL, NULL, &nvkm_device_oclass, true,
+ "DEVICE", "device", length, pobject);
device = *pobject;
if (ret)
goto done;
switch (type) {
- case NOUVEAU_BUS_PCI:
+ case NVKM_BUS_PCI:
device->pdev = dev;
break;
- case NOUVEAU_BUS_PLATFORM:
+ case NVKM_BUS_PLATFORM:
device->platformdev = dev;
break;
}
@@ -703,12 +719,11 @@ nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name,
device->dbgopt = dbg;
device->name = sname;
- nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
- nv_engine(device)->sclass = nouveau_device_sclass;
+ nv_subdev(device)->debug = nvkm_dbgopt(device->dbgopt, "DEVICE");
+ nv_engine(device)->sclass = nvkm_device_sclass;
list_add(&device->head, &nv_devices);
- ret = nvkm_event_init(&nouveau_device_event_func, 1, 1,
- &device->event);
+ ret = nvkm_event_init(&nvkm_device_event_func, 1, 1, &device->event);
done:
mutex_unlock(&nv_devices_mutex);
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
index e34101a3490e..0b794b13cec3 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c
@@ -21,25 +21,22 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "priv.h"
#include <core/client.h>
-#include <core/object.h>
-#include <nvif/unpack.h>
+#include <subdev/clk.h>
+
#include <nvif/class.h>
#include <nvif/ioctl.h>
-
-#include <subdev/clock.h>
-
-#include "priv.h"
+#include <nvif/unpack.h>
static int
-nouveau_control_mthd_pstate_info(struct nouveau_object *object,
- void *data, u32 size)
+nvkm_control_mthd_pstate_info(struct nvkm_object *object, void *data, u32 size)
{
union {
struct nvif_control_pstate_info_v0 v0;
} *args = data;
- struct nouveau_clock *clk = nouveau_clock(object);
+ struct nvkm_clk *clk = nvkm_clk(object);
int ret;
nv_ioctl(object, "control pstate info size %d\n", size);
@@ -67,16 +64,15 @@ nouveau_control_mthd_pstate_info(struct nouveau_object *object,
}
static int
-nouveau_control_mthd_pstate_attr(struct nouveau_object *object,
- void *data, u32 size)
+nvkm_control_mthd_pstate_attr(struct nvkm_object *object, void *data, u32 size)
{
union {
struct nvif_control_pstate_attr_v0 v0;
} *args = data;
- struct nouveau_clock *clk = nouveau_clock(object);
- struct nouveau_clocks *domain;
- struct nouveau_pstate *pstate;
- struct nouveau_cstate *cstate;
+ struct nvkm_clk *clk = nvkm_clk(object);
+ struct nvkm_domain *domain;
+ struct nvkm_pstate *pstate;
+ struct nvkm_cstate *cstate;
int i = 0, j = -1;
u32 lo, hi;
int ret;
@@ -141,13 +137,12 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object,
}
static int
-nouveau_control_mthd_pstate_user(struct nouveau_object *object,
- void *data, u32 size)
+nvkm_control_mthd_pstate_user(struct nvkm_object *object, void *data, u32 size)
{
union {
struct nvif_control_pstate_user_v0 v0;
} *args = data;
- struct nouveau_clock *clk = nouveau_clock(object);
+ struct nvkm_clk *clk = nvkm_clk(object);
int ret;
nv_ioctl(object, "control pstate user size %d\n", size);
@@ -161,45 +156,44 @@ nouveau_control_mthd_pstate_user(struct nouveau_object *object,
return ret;
if (args->v0.pwrsrc >= 0) {
- ret |= nouveau_clock_ustate(clk, args->v0.ustate, args->v0.pwrsrc);
+ ret |= nvkm_clk_ustate(clk, args->v0.ustate, args->v0.pwrsrc);
} else {
- ret |= nouveau_clock_ustate(clk, args->v0.ustate, 0);
- ret |= nouveau_clock_ustate(clk, args->v0.ustate, 1);
+ ret |= nvkm_clk_ustate(clk, args->v0.ustate, 0);
+ ret |= nvkm_clk_ustate(clk, args->v0.ustate, 1);
}
return ret;
}
static int
-nouveau_control_mthd(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
+nvkm_control_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
switch (mthd) {
case NVIF_CONTROL_PSTATE_INFO:
- return nouveau_control_mthd_pstate_info(object, data, size);
+ return nvkm_control_mthd_pstate_info(object, data, size);
case NVIF_CONTROL_PSTATE_ATTR:
- return nouveau_control_mthd_pstate_attr(object, data, size);
+ return nvkm_control_mthd_pstate_attr(object, data, size);
case NVIF_CONTROL_PSTATE_USER:
- return nouveau_control_mthd_pstate_user(object, data, size);
+ return nvkm_control_mthd_pstate_user(object, data, size);
default:
break;
}
return -EINVAL;
}
-static struct nouveau_ofuncs
-nouveau_control_ofuncs = {
- .ctor = _nouveau_object_ctor,
- .dtor = nouveau_object_destroy,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
- .mthd = nouveau_control_mthd,
+static struct nvkm_ofuncs
+nvkm_control_ofuncs = {
+ .ctor = _nvkm_object_ctor,
+ .dtor = nvkm_object_destroy,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
+ .mthd = nvkm_control_mthd,
};
-struct nouveau_oclass
-nouveau_control_oclass[] = {
+struct nvkm_oclass
+nvkm_control_oclass[] = {
{ .handle = NVIF_IOCTL_NEW_V0_CONTROL,
- .ofuncs = &nouveau_control_ofuncs
+ .ofuncs = &nvkm_control_ofuncs
},
{}
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c
new file mode 100644
index 000000000000..82b38d7e9730
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+#include <subdev/bios.h>
+#include <subdev/bus.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/fuse.h>
+#include <subdev/clk.h>
+#include <subdev/therm.h>
+#include <subdev/mxm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/ltc.h>
+#include <subdev/ibus.h>
+#include <subdev/instmem.h>
+#include <subdev/mmu.h>
+#include <subdev/bar.h>
+#include <subdev/pmu.h>
+#include <subdev/volt.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
+#include <engine/mspdec.h>
+#include <engine/bsp.h>
+#include <engine/msvld.h>
+#include <engine/msppp.h>
+#include <engine/ce.h>
+#include <engine/disp.h>
+#include <engine/pm.h>
+
+int
+gf100_identify(struct nvkm_device *device)
+{
+ switch (device->chipset) {
+ case 0xc0:
+ device->cname = "GF100";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf100_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf100_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf100_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gf100_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xc4:
+ device->cname = "GF104";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf100_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf100_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gf100_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xc3:
+ device->cname = "GF106";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf100_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xce:
+ device->cname = "GF114";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf100_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf100_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gf100_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xcf:
+ device->cname = "GF116";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf100_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf104_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xc1:
+ device->cname = "GF108";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf100_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf108_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xc8:
+ device->cname = "GF110";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf100_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf100_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf100_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf110_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gf100_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xd9:
+ device->cname = "GF119";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gf110_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gf110_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf110_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf119_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gf110_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ case 0xd7:
+ device->cname = "GF117";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gf110_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gf117_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gf100_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gf100_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gf100_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gf100_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gf117_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gf100_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gf100_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gf100_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gf110_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gf100_pm_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Fermi chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c
new file mode 100644
index 000000000000..bf5893458a47
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+#include <subdev/bios.h>
+#include <subdev/bus.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/fuse.h>
+#include <subdev/clk.h>
+#include <subdev/therm.h>
+#include <subdev/mxm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/ltc.h>
+#include <subdev/ibus.h>
+#include <subdev/instmem.h>
+#include <subdev/mmu.h>
+#include <subdev/bar.h>
+#include <subdev/pmu.h>
+#include <subdev/volt.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
+#include <engine/disp.h>
+#include <engine/ce.h>
+#include <engine/bsp.h>
+#include <engine/msvld.h>
+#include <engine/mspdec.h>
+#include <engine/msppp.h>
+#include <engine/pm.h>
+
+int
+gk104_identify(struct nvkm_device *device)
+{
+ switch (device->chipset) {
+ case 0xe4:
+ device->cname = "GK104";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gk104_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk104_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gk104_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gk104_disp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gk104_pm_oclass;
+ break;
+ case 0xe7:
+ device->cname = "GK107";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gk104_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk104_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf110_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gk104_disp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gk104_pm_oclass;
+ break;
+ case 0xe6:
+ device->cname = "GK106";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gk104_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk104_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gk104_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk104_gr_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gk104_disp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gk104_pm_oclass;
+ break;
+ case 0xea:
+ device->cname = "GK20A";
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk20a_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gk20a_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk20a_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk20a_gr_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gk104_pm_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &gk20a_volt_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gk20a_pmu_oclass;
+ break;
+ case 0xf0:
+ device->cname = "GK110";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gk104_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk104_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf110_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk110_gr_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gk110_disp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
+ break;
+ case 0xf1:
+ device->cname = "GK110B";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gf110_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gf106_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk104_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gf110_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk110b_gr_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gk110_disp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = &gk110_pm_oclass;
+ break;
+ case 0x106:
+ device->cname = "GK208B";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gk104_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk104_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gk208_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk208_gr_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gk110_disp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ break;
+ case 0x108:
+ device->cname = "GK208";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gk104_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gf110_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gf100_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gk104_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gk208_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gk208_gr_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gk110_disp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Kepler chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
index 4e74a3376de8..539561ed3281 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
@@ -21,13 +21,14 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/fuse.h>
-#include <subdev/clock.h>
+#include <subdev/clk.h>
#include <subdev/therm.h>
#include <subdev/mxm.h>
#include <subdev/devinit.h>
@@ -37,108 +38,108 @@
#include <subdev/ltc.h>
#include <subdev/ibus.h>
#include <subdev/instmem.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
#include <subdev/bar.h>
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
#include <subdev/volt.h>
-#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
#include <engine/disp.h>
-#include <engine/copy.h>
+#include <engine/ce.h>
#include <engine/bsp.h>
-#include <engine/vp.h>
-#include <engine/ppp.h>
-#include <engine/perfmon.h>
+#include <engine/msvld.h>
+#include <engine/mspdec.h>
+#include <engine/msppp.h>
+#include <engine/pm.h>
int
-gm100_identify(struct nouveau_device *device)
+gm100_identify(struct nvkm_device *device)
{
switch (device->chipset) {
case 0x117:
device->cname = "GM107";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
- device->oclass[NVDEV_SUBDEV_I2C ] = nvd0_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = gf110_i2c_oclass;
device->oclass[NVDEV_SUBDEV_FUSE ] = &gm107_fuse_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &gm107_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = gm107_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTC ] = gm107_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gk208_pmu_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
#endif
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = gm107_graph_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = gm107_disp_oclass;
- device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gk104_ce0_oclass;
#if 0
- device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gk104_ce1_oclass;
#endif
- device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gk104_ce2_oclass;
#if 0
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
#endif
break;
case 0x124:
device->cname = "GM204";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
- device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = gm204_i2c_oclass;
device->oclass[NVDEV_SUBDEV_FUSE ] = &gm107_fuse_oclass;
#if 0
/* looks to be some non-trivial changes */
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
/* priv ring says no to 0x10eb14 writes */
device->oclass[NVDEV_SUBDEV_THERM ] = &gm107_therm_oclass;
#endif
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = gm204_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
- device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTC ] = gm107_ltc_oclass;
- device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
- device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
- device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gk208_pmu_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
#endif
- device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
#if 0
- device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = gm107_graph_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass;
#endif
device->oclass[NVDEV_ENGINE_DISP ] = gm204_disp_oclass;
#if 0
- device->oclass[NVDEV_ENGINE_COPY0 ] = &gm204_copy0_oclass;
- device->oclass[NVDEV_ENGINE_COPY1 ] = &gm204_copy1_oclass;
- device->oclass[NVDEV_ENGINE_COPY2 ] = &gm204_copy2_oclass;
- device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
- device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
- device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gm204_ce0_oclass;
+ device->oclass[NVDEV_ENGINE_CE1 ] = &gm204_ce1_oclass;
+ device->oclass[NVDEV_ENGINE_CE2 ] = &gm204_ce2_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
#endif
break;
default:
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c
index 573b55f5c2f9..5a2ae043b478 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c
@@ -21,63 +21,63 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/i2c.h>
-#include <subdev/clock.h>
+#include <subdev/clk.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
-#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
#include <engine/disp.h>
int
-nv04_identify(struct nouveau_device *device)
+nv04_identify(struct nvkm_device *device)
{
switch (device->chipset) {
case 0x04:
device->cname = "NV04";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv04_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv04_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x05:
device->cname = "NV05";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv05_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv04_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv04_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
default:
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c
index 183a85a6204e..94a1ca45e94a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c
@@ -21,178 +21,178 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
-#include <subdev/clock.h>
+#include <subdev/clk.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
-#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
#include <engine/disp.h>
int
-nv10_identify(struct nouveau_device *device)
+nv10_identify(struct nvkm_device *device)
{
switch (device->chipset) {
case 0x10:
device->cname = "NV10";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x15:
device->cname = "NV15";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x16:
device->cname = "NV16";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x1a:
device->cname = "nForce";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x11:
device->cname = "NV11";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x17:
device->cname = "NV17";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x1f:
device->cname = "nForce2";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x18:
device->cname = "NV18";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv10_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
default:
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c
index aa564c68a920..d5ec8937df68 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c
@@ -21,105 +21,105 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
-#include <subdev/clock.h>
+#include <subdev/clk.h>
#include <subdev/therm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
-#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
#include <engine/disp.h>
int
-nv20_identify(struct nouveau_device *device)
+nv20_identify(struct nvkm_device *device)
{
switch (device->chipset) {
case 0x20:
device->cname = "NV20";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv20_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv20_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv20_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x25:
device->cname = "NV25";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv25_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x28:
device->cname = "NV28";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv25_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x2a:
device->cname = "NV2A";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv2a_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv2a_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
default:
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c
index 11bd31da82ab..dda09621e898 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c
@@ -21,126 +21,126 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
-#include <subdev/clock.h>
+#include <subdev/clk.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
-#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
#include <engine/mpeg.h>
#include <engine/disp.h>
int
-nv30_identify(struct nouveau_device *device)
+nv30_identify(struct nvkm_device *device)
{
switch (device->chipset) {
case 0x30:
device->cname = "NV30";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv30_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x35:
device->cname = "NV35";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv35_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv35_gr_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x31:
device->cname = "NV31";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv30_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x36:
device->cname = "NV36";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv36_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv35_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x34:
device->cname = "NV34";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv04_clk_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv34_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv34_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c
index e96c223cb797..c6301361d14f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c
@@ -21,41 +21,41 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bus.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
-#include <subdev/clock.h>
+#include <subdev/clk.h>
#include <subdev/therm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
#include <subdev/volt.h>
-#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
-#include <engine/software.h>
-#include <engine/graph.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
#include <engine/mpeg.h>
#include <engine/disp.h>
-#include <engine/perfmon.h>
+#include <engine/pm.h>
int
-nv40_identify(struct nouveau_device *device)
+nv40_identify(struct nvkm_device *device)
{
switch (device->chipset) {
case 0x40:
device->cname = "NV40";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -63,22 +63,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x41:
device->cname = "NV41";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -86,22 +86,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv41_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x42:
device->cname = "NV42";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -109,22 +109,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv41_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x43:
device->cname = "NV43";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -132,22 +132,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv41_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x45:
device->cname = "NV45";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -155,22 +155,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv04_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x47:
device->cname = "G70";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -178,22 +178,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv47_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv41_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x49:
device->cname = "G71";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -201,22 +201,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv41_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4b:
device->cname = "G73";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
@@ -224,22 +224,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv41_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x44:
device->cname = "NV44";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
@@ -247,22 +247,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x46:
device->cname = "G72";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
@@ -270,22 +270,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4a:
device->cname = "NV44A";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
@@ -293,22 +293,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4c:
device->cname = "C61";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
@@ -316,22 +316,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x4e:
device->cname = "C51";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv4e_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
@@ -339,22 +339,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x63:
device->cname = "C73";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
@@ -362,22 +362,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x67:
device->cname = "C67";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
@@ -385,22 +385,22 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
case 0x68:
device->cname = "C68";
- device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass;
- device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &nv40_clk_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
@@ -408,15 +408,15 @@ nv40_identify(struct nouveau_device *device)
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
- device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv44_mmu_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
- device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
- device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv10_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv40_gr_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
- device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv40_pm_oclass;
break;
default:
nv_fatal(device, "unknown Curie chipset\n");
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
new file mode 100644
index 000000000000..249b84454612
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+#include <subdev/bios.h>
+#include <subdev/bus.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/fuse.h>
+#include <subdev/clk.h>
+#include <subdev/therm.h>
+#include <subdev/mxm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/instmem.h>
+#include <subdev/mmu.h>
+#include <subdev/bar.h>
+#include <subdev/pmu.h>
+#include <subdev/volt.h>
+
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/sw.h>
+#include <engine/gr.h>
+#include <engine/mpeg.h>
+#include <engine/vp.h>
+#include <engine/cipher.h>
+#include <engine/sec.h>
+#include <engine/bsp.h>
+#include <engine/msvld.h>
+#include <engine/mspdec.h>
+#include <engine/msppp.h>
+#include <engine/ce.h>
+#include <engine/disp.h>
+#include <engine/pm.h>
+
+int
+nv50_identify(struct nvkm_device *device)
+{
+ switch (device->chipset) {
+ case 0x50:
+ device->cname = "G80";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = nv50_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = nv50_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = nv50_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = nv50_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = nv50_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = nv50_pm_oclass;
+ break;
+ case 0x84:
+ device->cname = "G84";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = g84_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g84_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = g84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &g84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CIPHER ] = &g84_cipher_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &g84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g84_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0x86:
+ device->cname = "G86";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = g84_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g84_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = g84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &g84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CIPHER ] = &g84_cipher_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &g84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g84_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0x92:
+ device->cname = "G92";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = g84_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g84_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = g84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &g84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CIPHER ] = &g84_cipher_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &g84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g84_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0x94:
+ device->cname = "G94";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = g84_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g84_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g94_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = g84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &g84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CIPHER ] = &g84_cipher_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &g84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g94_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0x96:
+ device->cname = "G96";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = g84_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g84_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g94_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = g84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &g84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CIPHER ] = &g84_cipher_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &g84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g94_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0x98:
+ device->cname = "G98";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = g84_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g98_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = g84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &g98_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_SEC ] = &g98_sec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &g98_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &g98_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g94_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0xa0:
+ device->cname = "G200";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = g84_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g84_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = g84_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_VP ] = &g84_vp_oclass;
+ device->oclass[NVDEV_ENGINE_CIPHER ] = &g84_cipher_oclass;
+ device->oclass[NVDEV_ENGINE_BSP ] = &g84_bsp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt200_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0xaa:
+ device->cname = "MCP77/MCP78";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = mcp77_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g98_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = mcp77_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &g98_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_SEC ] = &g98_sec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &g98_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &g98_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g94_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0xac:
+ device->cname = "MCP79/MCP7A";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = mcp77_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &g84_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = g98_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = mcp77_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &g98_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_SEC ] = &g98_sec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &g98_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &g98_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = g94_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = g84_pm_oclass;
+ break;
+ case 0xa3:
+ device->cname = "GT215";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gt215_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gt215_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gt215_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gt215_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MPEG ] = &g84_mpeg_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &g98_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &g98_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &g98_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gt215_ce_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
+ break;
+ case 0xa5:
+ device->cname = "GT216";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gt215_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gt215_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gt215_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gt215_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &g98_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &g98_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &g98_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gt215_ce_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
+ break;
+ case 0xa8:
+ device->cname = "GT218";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gt215_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = gt215_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = gt215_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gt215_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &g98_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &g98_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &g98_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gt215_ce_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
+ break;
+ case 0xaf:
+ device->cname = "MCP89";
+ device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
+ device->oclass[NVDEV_SUBDEV_GPIO ] = g94_gpio_oclass;
+ device->oclass[NVDEV_SUBDEV_I2C ] = g94_i2c_oclass;
+ device->oclass[NVDEV_SUBDEV_FUSE ] = &nv50_fuse_oclass;
+ device->oclass[NVDEV_SUBDEV_CLK ] = &gt215_clk_oclass;
+ device->oclass[NVDEV_SUBDEV_THERM ] = &gt215_therm_oclass;
+ device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
+ device->oclass[NVDEV_SUBDEV_DEVINIT] = mcp89_devinit_oclass;
+ device->oclass[NVDEV_SUBDEV_MC ] = g98_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = g94_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = mcp89_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_MMU ] = &nv50_mmu_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
+ device->oclass[NVDEV_SUBDEV_PMU ] = gt215_pmu_oclass;
+ device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = g84_fifo_oclass;
+ device->oclass[NVDEV_ENGINE_SW ] = nv50_sw_oclass;
+ device->oclass[NVDEV_ENGINE_GR ] = &nv50_gr_oclass;
+ device->oclass[NVDEV_ENGINE_MSPDEC ] = &g98_mspdec_oclass;
+ device->oclass[NVDEV_ENGINE_MSVLD ] = &g98_msvld_oclass;
+ device->oclass[NVDEV_ENGINE_MSPPP ] = &g98_msppp_oclass;
+ device->oclass[NVDEV_ENGINE_CE0 ] = &gt215_ce_oclass;
+ device->oclass[NVDEV_ENGINE_DISP ] = gt215_disp_oclass;
+ device->oclass[NVDEV_ENGINE_PM ] = gt215_pm_oclass;
+ break;
+ default:
+ nv_fatal(device, "unknown Tesla chipset\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
new file mode 100644
index 000000000000..8d3590e7bd87
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
@@ -0,0 +1,16 @@
+#ifndef __NVKM_DEVICE_PRIV_H__
+#define __NVKM_DEVICE_PRIV_H__
+#include <core/device.h>
+
+extern struct nvkm_oclass nvkm_control_oclass[];
+
+int nv04_identify(struct nvkm_device *);
+int nv10_identify(struct nvkm_device *);
+int nv20_identify(struct nvkm_device *);
+int nv30_identify(struct nvkm_device *);
+int nv40_identify(struct nvkm_device *);
+int nv50_identify(struct nvkm_device *);
+int gf100_identify(struct nvkm_device *);
+int gk104_identify(struct nvkm_device *);
+int gm100_identify(struct nvkm_device *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
new file mode 100644
index 000000000000..16a4e2a37008
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
@@ -0,0 +1,29 @@
+nvkm-y += nvkm/engine/disp/base.o
+nvkm-y += nvkm/engine/disp/conn.o
+nvkm-y += nvkm/engine/disp/outp.o
+nvkm-y += nvkm/engine/disp/outpdp.o
+nvkm-y += nvkm/engine/disp/nv04.o
+nvkm-y += nvkm/engine/disp/nv50.o
+nvkm-y += nvkm/engine/disp/g84.o
+nvkm-y += nvkm/engine/disp/g94.o
+nvkm-y += nvkm/engine/disp/gt200.o
+nvkm-y += nvkm/engine/disp/gt215.o
+nvkm-y += nvkm/engine/disp/gf110.o
+nvkm-y += nvkm/engine/disp/gk104.o
+nvkm-y += nvkm/engine/disp/gk110.o
+nvkm-y += nvkm/engine/disp/gm107.o
+nvkm-y += nvkm/engine/disp/gm204.o
+nvkm-y += nvkm/engine/disp/dacnv50.o
+nvkm-y += nvkm/engine/disp/dport.o
+nvkm-y += nvkm/engine/disp/hdagt215.o
+nvkm-y += nvkm/engine/disp/hdagf110.o
+nvkm-y += nvkm/engine/disp/hdmig84.o
+nvkm-y += nvkm/engine/disp/hdmigt215.o
+nvkm-y += nvkm/engine/disp/hdmigf110.o
+nvkm-y += nvkm/engine/disp/hdmigk104.o
+nvkm-y += nvkm/engine/disp/piornv50.o
+nvkm-y += nvkm/engine/disp/sornv50.o
+nvkm-y += nvkm/engine/disp/sorg94.o
+nvkm-y += nvkm/engine/disp/sorgf110.o
+nvkm-y += nvkm/engine/disp/sorgm204.o
+nvkm-y += nvkm/engine/disp/vga.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index 64b84667f3a5..23d1b5c0dc16 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -21,21 +21,23 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
+#include "conn.h"
+#include "outp.h"
+
+#include <core/notify.h>
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
-#include <core/os.h>
-#include <nvif/unpack.h>
#include <nvif/class.h>
#include <nvif/event.h>
-
-#include "priv.h"
-#include "outp.h"
-#include "conn.h"
+#include <nvif/unpack.h>
int
-nouveau_disp_vblank_ctor(struct nouveau_object *object, void *data, u32 size,
- struct nvkm_notify *notify)
+nvkm_disp_vblank_ctor(struct nvkm_object *object, void *data, u32 size,
+ struct nvkm_notify *notify)
{
- struct nouveau_disp *disp =
+ struct nvkm_disp *disp =
container_of(notify->event, typeof(*disp), vblank);
union {
struct nvif_notify_head_req_v0 v0;
@@ -55,17 +57,17 @@ nouveau_disp_vblank_ctor(struct nouveau_object *object, void *data, u32 size,
}
void
-nouveau_disp_vblank(struct nouveau_disp *disp, int head)
+nvkm_disp_vblank(struct nvkm_disp *disp, int head)
{
struct nvif_notify_head_rep_v0 rep = {};
nvkm_event_send(&disp->vblank, 1, head, &rep, sizeof(rep));
}
static int
-nouveau_disp_hpd_ctor(struct nouveau_object *object, void *data, u32 size,
- struct nvkm_notify *notify)
+nvkm_disp_hpd_ctor(struct nvkm_object *object, void *data, u32 size,
+ struct nvkm_notify *notify)
{
- struct nouveau_disp *disp =
+ struct nvkm_disp *disp =
container_of(notify->event, typeof(*disp), hpd);
union {
struct nvif_notify_conn_req_v0 v0;
@@ -91,15 +93,14 @@ nouveau_disp_hpd_ctor(struct nouveau_object *object, void *data, u32 size,
}
static const struct nvkm_event_func
-nouveau_disp_hpd_func = {
- .ctor = nouveau_disp_hpd_ctor
+nvkm_disp_hpd_func = {
+ .ctor = nvkm_disp_hpd_ctor
};
int
-nouveau_disp_ntfy(struct nouveau_object *object, u32 type,
- struct nvkm_event **event)
+nvkm_disp_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **event)
{
- struct nouveau_disp *disp = (void *)object->engine;
+ struct nvkm_disp *disp = (void *)object->engine;
switch (type) {
case NV04_DISP_NTFY_VBLANK:
*event = &disp->vblank;
@@ -114,9 +115,9 @@ nouveau_disp_ntfy(struct nouveau_object *object, u32 type,
}
int
-_nouveau_disp_fini(struct nouveau_object *object, bool suspend)
+_nvkm_disp_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_disp *disp = (void *)object;
+ struct nvkm_disp *disp = (void *)object;
struct nvkm_output *outp;
int ret;
@@ -126,7 +127,7 @@ _nouveau_disp_fini(struct nouveau_object *object, bool suspend)
goto fail_outp;
}
- return nouveau_engine_fini(&disp->base, suspend);
+ return nvkm_engine_fini(&disp->base, suspend);
fail_outp:
list_for_each_entry_continue_reverse(outp, &disp->outp, head) {
@@ -137,13 +138,13 @@ fail_outp:
}
int
-_nouveau_disp_init(struct nouveau_object *object)
+_nvkm_disp_init(struct nvkm_object *object)
{
- struct nouveau_disp *disp = (void *)object;
+ struct nvkm_disp *disp = (void *)object;
struct nvkm_output *outp;
int ret;
- ret = nouveau_engine_init(&disp->base);
+ ret = nvkm_engine_init(&disp->base);
if (ret)
return ret;
@@ -164,9 +165,9 @@ fail_outp:
}
void
-_nouveau_disp_dtor(struct nouveau_object *object)
+_nvkm_disp_dtor(struct nvkm_object *object)
{
- struct nouveau_disp *disp = (void *)object;
+ struct nvkm_disp *disp = (void *)object;
struct nvkm_output *outp, *outt;
nvkm_event_fini(&disp->vblank);
@@ -174,32 +175,30 @@ _nouveau_disp_dtor(struct nouveau_object *object)
if (disp->outp.next) {
list_for_each_entry_safe(outp, outt, &disp->outp, head) {
- nouveau_object_ref(NULL, (struct nouveau_object **)&outp);
+ nvkm_object_ref(NULL, (struct nvkm_object **)&outp);
}
}
- nouveau_engine_destroy(&disp->base);
+ nvkm_engine_destroy(&disp->base);
}
int
-nouveau_disp_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int heads,
- const char *intname, const char *extname,
- int length, void **pobject)
+nvkm_disp_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int heads, const char *intname,
+ const char *extname, int length, void **pobject)
{
- struct nouveau_disp_impl *impl = (void *)oclass;
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nouveau_disp *disp;
- struct nouveau_oclass **sclass;
- struct nouveau_object *object;
+ struct nvkm_disp_impl *impl = (void *)oclass;
+ struct nvkm_bios *bios = nvkm_bios(parent);
+ struct nvkm_disp *disp;
+ struct nvkm_oclass **sclass;
+ struct nvkm_object *object;
struct dcb_output dcbE;
u8 hpd = 0, ver, hdr;
u32 data;
int ret, i;
- ret = nouveau_engine_create_(parent, engine, oclass, true,
- intname, extname, length, pobject);
+ ret = nvkm_engine_create_(parent, engine, oclass, true, intname,
+ extname, length, pobject);
disp = *pobject;
if (ret)
return ret;
@@ -225,12 +224,11 @@ nouveau_disp_create_(struct nouveau_object *parent,
sclass++;
}
- nouveau_object_ctor(*pobject, *pobject, oclass,
- &dcbE, i, &object);
+ nvkm_object_ctor(*pobject, NULL, oclass, &dcbE, i, &object);
hpd = max(hpd, (u8)(dcbE.connector + 1));
}
- ret = nvkm_event_init(&nouveau_disp_hpd_func, 3, hpd, &disp->hpd);
+ ret = nvkm_event_init(&nvkm_disp_hpd_func, 3, hpd, &disp->hpd);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/conn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c
index 1496b567dd4a..cf03e0240ced 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/conn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c
@@ -21,21 +21,20 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/os.h>
-#include <nvif/event.h>
+#include "conn.h"
+#include "outp.h"
+#include "priv.h"
#include <subdev/gpio.h>
-#include "conn.h"
-#include "outp.h"
+#include <nvif/event.h>
static int
nvkm_connector_hpd(struct nvkm_notify *notify)
{
struct nvkm_connector *conn = container_of(notify, typeof(*conn), hpd);
- struct nouveau_disp *disp = nouveau_disp(conn);
- struct nouveau_gpio *gpio = nouveau_gpio(conn);
+ struct nvkm_disp *disp = nvkm_disp(conn);
+ struct nvkm_gpio *gpio = nvkm_gpio(conn);
const struct nvkm_gpio_ntfy_rep *line = notify->data;
struct nvif_notify_conn_rep_v0 rep;
int index = conn->index;
@@ -53,41 +52,41 @@ nvkm_connector_hpd(struct nvkm_notify *notify)
}
int
-_nvkm_connector_fini(struct nouveau_object *object, bool suspend)
+_nvkm_connector_fini(struct nvkm_object *object, bool suspend)
{
struct nvkm_connector *conn = (void *)object;
nvkm_notify_put(&conn->hpd);
- return nouveau_object_fini(&conn->base, suspend);
+ return nvkm_object_fini(&conn->base, suspend);
}
int
-_nvkm_connector_init(struct nouveau_object *object)
+_nvkm_connector_init(struct nvkm_object *object)
{
struct nvkm_connector *conn = (void *)object;
- int ret = nouveau_object_init(&conn->base);
+ int ret = nvkm_object_init(&conn->base);
if (ret == 0)
nvkm_notify_get(&conn->hpd);
return ret;
}
void
-_nvkm_connector_dtor(struct nouveau_object *object)
+_nvkm_connector_dtor(struct nvkm_object *object)
{
struct nvkm_connector *conn = (void *)object;
nvkm_notify_fini(&conn->hpd);
- nouveau_object_destroy(&conn->base);
+ nvkm_object_destroy(&conn->base);
}
int
-nvkm_connector_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
+nvkm_connector_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass,
struct nvbios_connE *info, int index,
int length, void **pobject)
{
static const u8 hpd[] = { 0x07, 0x08, 0x51, 0x52, 0x5e, 0x5f, 0x60 };
- struct nouveau_gpio *gpio = nouveau_gpio(parent);
- struct nouveau_disp *disp = (void *)engine;
+ struct nvkm_disp *disp = nvkm_disp(parent);
+ struct nvkm_gpio *gpio = nvkm_gpio(parent);
struct nvkm_connector *conn;
struct nvkm_output *outp;
struct dcb_gpio_func func;
@@ -101,7 +100,7 @@ nvkm_connector_create_(struct nouveau_object *parent,
}
}
- ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, 0, length, pobject);
conn = *pobject;
if (ret)
return ret;
@@ -145,10 +144,10 @@ nvkm_connector_create_(struct nouveau_object *parent,
}
int
-_nvkm_connector_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *info, u32 index,
- struct nouveau_object **pobject)
+_nvkm_connector_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *info, u32 index,
+ struct nvkm_object **pobject)
{
struct nvkm_connector *conn;
int ret;
@@ -161,11 +160,11 @@ _nvkm_connector_ctor(struct nouveau_object *parent,
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nvkm_connector_oclass = &(struct nvkm_connector_impl) {
.base = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_connector_ctor,
.dtor = _nvkm_connector_dtor,
.init = _nvkm_connector_init,
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/conn.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
index 55e5f5c82c14..c87a061f7f7d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/conn.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
@@ -1,10 +1,13 @@
#ifndef __NVKM_DISP_CONN_H__
#define __NVKM_DISP_CONN_H__
+#include <core/object.h>
+#include <core/notify.h>
-#include "priv.h"
+#include <subdev/bios.h>
+#include <subdev/bios/conn.h>
struct nvkm_connector {
- struct nouveau_object base;
+ struct nvkm_object base;
struct list_head head;
struct nvbios_connE info;
@@ -28,29 +31,28 @@ struct nvkm_connector {
_nvkm_connector_fini(nv_object(disp), (s)); \
})
-int nvkm_connector_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, struct nvbios_connE *,
+int nvkm_connector_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, struct nvbios_connE *,
int, int, void **);
-int _nvkm_connector_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void _nvkm_connector_dtor(struct nouveau_object *);
-int _nvkm_connector_init(struct nouveau_object *);
-int _nvkm_connector_fini(struct nouveau_object *, bool);
+int _nvkm_connector_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void _nvkm_connector_dtor(struct nvkm_object *);
+int _nvkm_connector_init(struct nvkm_object *);
+int _nvkm_connector_fini(struct nvkm_object *, bool);
struct nvkm_connector_impl {
- struct nouveau_oclass base;
+ struct nvkm_oclass base;
};
#ifndef MSG
#define MSG(l,f,a...) do { \
struct nvkm_connector *_conn = (void *)conn; \
- nv_##l(nv_object(conn)->engine, "%02x:%02x%02x: "f, _conn->index, \
+ nv_##l(_conn, "%02x:%02x%02x: "f, _conn->index, \
_conn->info.location, _conn->info.type, ##a); \
} while(0)
#define DBG(f,a...) MSG(debug, f, ##a)
#define ERR(f,a...) MSG(error, f, ##a)
#endif
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c
index b36addff06a9..0f7d1ec4d37e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dacnv50.c
@@ -21,16 +21,14 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outp.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
#include <subdev/timer.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
nv50_dac_power(NV50_DISP_MTHD_V1)
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
index 16db08dfba6e..68347661adca 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
@@ -21,20 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "dport.h"
+#include "outpdp.h"
+#include "nv50.h"
#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
-#include <subdev/bios/dp.h>
#include <subdev/bios/init.h>
#include <subdev/i2c.h>
-#include "nv50.h"
-
#include <nvif/class.h>
-#include "dport.h"
-#include "outpdp.h"
-
/******************************************************************************
* link training
*****************************************************************************/
@@ -54,8 +50,8 @@ dp_set_link_config(struct dp_state *dp)
{
struct nvkm_output_dp_impl *impl = (void *)nv_oclass(dp->outp);
struct nvkm_output_dp *outp = dp->outp;
- struct nouveau_disp *disp = nouveau_disp(outp);
- struct nouveau_bios *bios = nouveau_bios(disp);
+ struct nvkm_disp *disp = nvkm_disp(outp);
+ struct nvkm_bios *bios = nvkm_bios(disp);
struct nvbios_init init = {
.subdev = nv_subdev(disp),
.bios = bios,
@@ -264,8 +260,8 @@ static void
dp_link_train_init(struct dp_state *dp, bool spread)
{
struct nvkm_output_dp *outp = dp->outp;
- struct nouveau_disp *disp = nouveau_disp(outp);
- struct nouveau_bios *bios = nouveau_bios(disp);
+ struct nvkm_disp *disp = nvkm_disp(outp);
+ struct nvkm_bios *bios = nvkm_bios(disp);
struct nvbios_init init = {
.subdev = nv_subdev(disp),
.bios = bios,
@@ -290,8 +286,8 @@ static void
dp_link_train_fini(struct dp_state *dp)
{
struct nvkm_output_dp *outp = dp->outp;
- struct nouveau_disp *disp = nouveau_disp(outp);
- struct nouveau_bios *bios = nouveau_bios(disp);
+ struct nvkm_disp *disp = nvkm_disp(outp);
+ struct nvkm_bios *bios = nvkm_bios(disp);
struct nvbios_init init = {
.subdev = nv_subdev(disp),
.bios = bios,
@@ -309,7 +305,7 @@ static const struct dp_rates {
u32 rate;
u8 bw;
u8 nr;
-} nouveau_dp_rates[] = {
+} nvkm_dp_rates[] = {
{ 2160000, 0x14, 4 },
{ 1080000, 0x0a, 4 },
{ 1080000, 0x14, 2 },
@@ -323,11 +319,11 @@ static const struct dp_rates {
};
void
-nouveau_dp_train(struct work_struct *w)
+nvkm_dp_train(struct work_struct *w)
{
struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work);
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- const struct dp_rates *cfg = nouveau_dp_rates;
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ const struct dp_rates *cfg = nvkm_dp_rates;
struct dp_state _dp = {
.outp = outp,
}, *dp = &_dp;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
index 5628d2d5ec71..9596290329c7 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
@@ -1,5 +1,6 @@
#ifndef __NVKM_DISP_DPORT_H__
#define __NVKM_DISP_DPORT_H__
+#include <core/os.h>
/* DPCD Receiver Capabilities */
#define DPCD_RC00_DPCD_REV 0x00000
@@ -70,6 +71,5 @@
#define DPCD_LS0C_LANE1_POST_CURSOR2 0x0c
#define DPCD_LS0C_LANE0_POST_CURSOR2 0x03
-void nouveau_dp_train(struct work_struct *);
-
+void nvkm_dp_train(struct work_struct *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c
index 13eff5e4ee51..a0dcf534cb20 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c
@@ -21,20 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* EVO master channel object
******************************************************************************/
const struct nv50_disp_mthd_list
-nv84_disp_core_mthd_dac = {
+g84_disp_core_mthd_dac = {
.mthd = 0x0080,
.addr = 0x000008,
.data = {
@@ -46,7 +42,7 @@ nv84_disp_core_mthd_dac = {
};
const struct nv50_disp_mthd_list
-nv84_disp_core_mthd_head = {
+g84_disp_core_mthd_head = {
.mthd = 0x0400,
.addr = 0x000540,
.data = {
@@ -98,15 +94,15 @@ nv84_disp_core_mthd_head = {
};
const struct nv50_disp_mthd_chan
-nv84_disp_core_mthd_chan = {
+g84_disp_core_mthd_chan = {
.name = "Core",
.addr = 0x000000,
.data = {
{ "Global", 1, &nv50_disp_core_mthd_base },
- { "DAC", 3, &nv84_disp_core_mthd_dac },
+ { "DAC", 3, &g84_disp_core_mthd_dac },
{ "SOR", 2, &nv50_disp_core_mthd_sor },
{ "PIOR", 3, &nv50_disp_core_mthd_pior },
- { "HEAD", 2, &nv84_disp_core_mthd_head },
+ { "HEAD", 2, &g84_disp_core_mthd_head },
{}
}
};
@@ -116,7 +112,7 @@ nv84_disp_core_mthd_chan = {
******************************************************************************/
static const struct nv50_disp_mthd_list
-nv84_disp_base_mthd_base = {
+g84_disp_base_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
@@ -146,11 +142,11 @@ nv84_disp_base_mthd_base = {
};
const struct nv50_disp_mthd_chan
-nv84_disp_base_mthd_chan = {
+g84_disp_base_mthd_chan = {
.name = "Base",
.addr = 0x000540,
.data = {
- { "Global", 1, &nv84_disp_base_mthd_base },
+ { "Global", 1, &g84_disp_base_mthd_base },
{ "Image", 2, &nv50_disp_base_mthd_image },
{}
}
@@ -161,7 +157,7 @@ nv84_disp_base_mthd_chan = {
******************************************************************************/
static const struct nv50_disp_mthd_list
-nv84_disp_ovly_mthd_base = {
+g84_disp_ovly_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
@@ -189,11 +185,11 @@ nv84_disp_ovly_mthd_base = {
};
const struct nv50_disp_mthd_chan
-nv84_disp_ovly_mthd_chan = {
+g84_disp_ovly_mthd_chan = {
.name = "Overlay",
.addr = 0x000540,
.data = {
- { "Global", 1, &nv84_disp_ovly_mthd_base },
+ { "Global", 1, &g84_disp_ovly_mthd_base },
{}
}
};
@@ -202,8 +198,8 @@ nv84_disp_ovly_mthd_chan = {
* Base display object
******************************************************************************/
-static struct nouveau_oclass
-nv84_disp_sclass[] = {
+static struct nvkm_oclass
+g84_disp_sclass[] = {
{ G82_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
{ G82_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
{ G82_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
@@ -212,8 +208,8 @@ nv84_disp_sclass[] = {
{}
};
-static struct nouveau_oclass
-nv84_disp_main_oclass[] = {
+static struct nvkm_oclass
+g84_disp_main_oclass[] = {
{ G82_DISP, &nv50_disp_main_ofuncs },
{}
};
@@ -223,15 +219,15 @@ nv84_disp_main_oclass[] = {
******************************************************************************/
static int
-nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
- "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, 2, "PDISP",
+ "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -240,11 +236,11 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_engine(priv)->sclass = nv84_disp_main_oclass;
+ nv_engine(priv)->sclass = g84_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
- priv->sclass = nv84_disp_sclass;
+ priv->sclass = g84_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 2;
@@ -252,25 +248,25 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hdmi = nv84_hdmi_ctrl;
+ priv->sor.hdmi = g84_hdmi_ctrl;
priv->pior.power = nv50_pior_power;
return 0;
}
-struct nouveau_oclass *
-nv84_disp_oclass = &(struct nv50_disp_impl) {
+struct nvkm_oclass *
+g84_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x82),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_disp_ctor,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
.base.outp = nv50_disp_outp_sclass,
- .mthd.core = &nv84_disp_core_mthd_chan,
- .mthd.base = &nv84_disp_base_mthd_chan,
- .mthd.ovly = &nv84_disp_ovly_mthd_chan,
+ .mthd.core = &g84_disp_core_mthd_chan,
+ .mthd.base = &g84_disp_base_mthd_chan,
+ .mthd.ovly = &g84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
.head.scanoutpos = nv50_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c
index 2bb7ac5cd0e6..1ab0d0ae3cc8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c
@@ -21,20 +21,17 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
+#include "outpdp.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* EVO master channel object
******************************************************************************/
const struct nv50_disp_mthd_list
-nv94_disp_core_mthd_sor = {
+g94_disp_core_mthd_sor = {
.mthd = 0x0040,
.addr = 0x000008,
.data = {
@@ -44,15 +41,15 @@ nv94_disp_core_mthd_sor = {
};
const struct nv50_disp_mthd_chan
-nv94_disp_core_mthd_chan = {
+g94_disp_core_mthd_chan = {
.name = "Core",
.addr = 0x000000,
.data = {
{ "Global", 1, &nv50_disp_core_mthd_base },
- { "DAC", 3, &nv84_disp_core_mthd_dac },
- { "SOR", 4, &nv94_disp_core_mthd_sor },
+ { "DAC", 3, &g84_disp_core_mthd_dac },
+ { "SOR", 4, &g94_disp_core_mthd_sor },
{ "PIOR", 3, &nv50_disp_core_mthd_pior },
- { "HEAD", 2, &nv84_disp_core_mthd_head },
+ { "HEAD", 2, &g84_disp_core_mthd_head },
{}
}
};
@@ -61,8 +58,8 @@ nv94_disp_core_mthd_chan = {
* Base display object
******************************************************************************/
-static struct nouveau_oclass
-nv94_disp_sclass[] = {
+static struct nvkm_oclass
+g94_disp_sclass[] = {
{ GT206_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
{ GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
{ GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
@@ -71,8 +68,8 @@ nv94_disp_sclass[] = {
{}
};
-static struct nouveau_oclass
-nv94_disp_main_oclass[] = {
+static struct nvkm_oclass
+g94_disp_main_oclass[] = {
{ GT206_DISP, &nv50_disp_main_ofuncs },
{}
};
@@ -82,15 +79,15 @@ nv94_disp_main_oclass[] = {
******************************************************************************/
static int
-nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g94_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
- "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, 2, "PDISP",
+ "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -99,11 +96,11 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_engine(priv)->sclass = nv94_disp_main_oclass;
+ nv_engine(priv)->sclass = g94_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
- priv->sclass = nv94_disp_sclass;
+ priv->sclass = g94_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 4;
@@ -111,32 +108,32 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hdmi = nv84_hdmi_ctrl;
+ priv->sor.hdmi = g84_hdmi_ctrl;
priv->pior.power = nv50_pior_power;
return 0;
}
-struct nouveau_oclass *
-nv94_disp_outp_sclass[] = {
+struct nvkm_oclass *
+g94_disp_outp_sclass[] = {
&nv50_pior_dp_impl.base.base,
- &nv94_sor_dp_impl.base.base,
+ &g94_sor_dp_impl.base.base,
NULL
};
-struct nouveau_oclass *
-nv94_disp_oclass = &(struct nv50_disp_impl) {
+struct nvkm_oclass *
+g94_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x88),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv94_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g94_disp_ctor,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
- .base.outp = nv94_disp_outp_sclass,
- .mthd.core = &nv94_disp_core_mthd_chan,
- .mthd.base = &nv84_disp_base_mthd_chan,
- .mthd.ovly = &nv84_disp_ovly_mthd_chan,
+ .base.outp = g94_disp_outp_sclass,
+ .mthd.core = &g94_disp_core_mthd_chan,
+ .mthd.base = &g84_disp_base_mthd_chan,
+ .mthd.ovly = &g84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
.head.scanoutpos = nv50_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c
index 181a2d57e356..0ebf466e9ef3 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c
@@ -21,33 +21,30 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outp.h"
+#include "outpdp.h"
-#include <core/object.h>
#include <core/client.h>
-#include <core/parent.h>
-#include <core/handle.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
-#include <engine/disp.h>
-
+#include <core/gpuobj.h>
+#include <core/ramht.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/disp.h>
#include <subdev/bios/init.h>
#include <subdev/bios/pll.h>
#include <subdev/devinit.h>
-#include <subdev/fb.h>
#include <subdev/timer.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
/*******************************************************************************
* EVO channel base class
******************************************************************************/
static void
-nvd0_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
+gf110_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
{
struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
nv_mask(priv, 0x610090, 0x00000001 << index, 0x00000000 << index);
@@ -55,7 +52,7 @@ nvd0_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
}
static void
-nvd0_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
+gf110_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
{
struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
nv_wr32(priv, 0x61008c, 0x00000001 << index);
@@ -63,10 +60,10 @@ nvd0_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
}
const struct nvkm_event_func
-nvd0_disp_chan_uevent = {
+gf110_disp_chan_uevent = {
.ctor = nv50_disp_chan_uevent_ctor,
- .init = nvd0_disp_chan_uevent_init,
- .fini = nvd0_disp_chan_uevent_fini,
+ .init = gf110_disp_chan_uevent_init,
+ .fini = gf110_disp_chan_uevent_fini,
};
/*******************************************************************************
@@ -74,25 +71,25 @@ nvd0_disp_chan_uevent = {
******************************************************************************/
static int
-nvd0_disp_dmac_object_attach(struct nouveau_object *parent,
- struct nouveau_object *object, u32 name)
+gf110_disp_dmac_object_attach(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 name)
{
struct nv50_disp_base *base = (void *)parent->parent;
struct nv50_disp_chan *chan = (void *)parent;
u32 addr = nv_gpuobj(object)->node->offset;
u32 data = (chan->chid << 27) | (addr << 9) | 0x00000001;
- return nouveau_ramht_insert(base->ramht, chan->chid, name, data);
+ return nvkm_ramht_insert(base->ramht, chan->chid, name, data);
}
static void
-nvd0_disp_dmac_object_detach(struct nouveau_object *parent, int cookie)
+gf110_disp_dmac_object_detach(struct nvkm_object *parent, int cookie)
{
struct nv50_disp_base *base = (void *)parent->parent;
- nouveau_ramht_remove(base->ramht, cookie);
+ nvkm_ramht_remove(base->ramht, cookie);
}
static int
-nvd0_disp_dmac_init(struct nouveau_object *object)
+gf110_disp_dmac_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *dmac = (void *)object;
@@ -125,7 +122,7 @@ nvd0_disp_dmac_init(struct nouveau_object *object)
}
static int
-nvd0_disp_dmac_fini(struct nouveau_object *object, bool suspend)
+gf110_disp_dmac_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *dmac = (void *)object;
@@ -153,7 +150,7 @@ nvd0_disp_dmac_fini(struct nouveau_object *object, bool suspend)
******************************************************************************/
const struct nv50_disp_mthd_list
-nvd0_disp_core_mthd_base = {
+gf110_disp_core_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
@@ -166,7 +163,7 @@ nvd0_disp_core_mthd_base = {
};
const struct nv50_disp_mthd_list
-nvd0_disp_core_mthd_dac = {
+gf110_disp_core_mthd_dac = {
.mthd = 0x0020,
.addr = 0x000020,
.data = {
@@ -179,7 +176,7 @@ nvd0_disp_core_mthd_dac = {
};
const struct nv50_disp_mthd_list
-nvd0_disp_core_mthd_sor = {
+gf110_disp_core_mthd_sor = {
.mthd = 0x0020,
.addr = 0x000020,
.data = {
@@ -192,7 +189,7 @@ nvd0_disp_core_mthd_sor = {
};
const struct nv50_disp_mthd_list
-nvd0_disp_core_mthd_pior = {
+gf110_disp_core_mthd_pior = {
.mthd = 0x0020,
.addr = 0x000020,
.data = {
@@ -205,7 +202,7 @@ nvd0_disp_core_mthd_pior = {
};
static const struct nv50_disp_mthd_list
-nvd0_disp_core_mthd_head = {
+gf110_disp_core_mthd_head = {
.mthd = 0x0300,
.addr = 0x000300,
.data = {
@@ -279,21 +276,21 @@ nvd0_disp_core_mthd_head = {
};
static const struct nv50_disp_mthd_chan
-nvd0_disp_core_mthd_chan = {
+gf110_disp_core_mthd_chan = {
.name = "Core",
.addr = 0x000000,
.data = {
- { "Global", 1, &nvd0_disp_core_mthd_base },
- { "DAC", 3, &nvd0_disp_core_mthd_dac },
- { "SOR", 8, &nvd0_disp_core_mthd_sor },
- { "PIOR", 4, &nvd0_disp_core_mthd_pior },
- { "HEAD", 4, &nvd0_disp_core_mthd_head },
+ { "Global", 1, &gf110_disp_core_mthd_base },
+ { "DAC", 3, &gf110_disp_core_mthd_dac },
+ { "SOR", 8, &gf110_disp_core_mthd_sor },
+ { "PIOR", 4, &gf110_disp_core_mthd_pior },
+ { "HEAD", 4, &gf110_disp_core_mthd_head },
{}
}
};
static int
-nvd0_disp_core_init(struct nouveau_object *object)
+gf110_disp_core_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *mast = (void *)object;
@@ -324,7 +321,7 @@ nvd0_disp_core_init(struct nouveau_object *object)
}
static int
-nvd0_disp_core_fini(struct nouveau_object *object, bool suspend)
+gf110_disp_core_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *mast = (void *)object;
@@ -346,18 +343,18 @@ nvd0_disp_core_fini(struct nouveau_object *object, bool suspend)
}
struct nv50_disp_chan_impl
-nvd0_disp_core_ofuncs = {
+gf110_disp_core_ofuncs = {
.base.ctor = nv50_disp_core_ctor,
.base.dtor = nv50_disp_dmac_dtor,
- .base.init = nvd0_disp_core_init,
- .base.fini = nvd0_disp_core_fini,
+ .base.init = gf110_disp_core_init,
+ .base.fini = gf110_disp_core_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32,
.chid = 0,
- .attach = nvd0_disp_dmac_object_attach,
- .detach = nvd0_disp_dmac_object_detach,
+ .attach = gf110_disp_dmac_object_attach,
+ .detach = gf110_disp_dmac_object_detach,
};
/*******************************************************************************
@@ -365,7 +362,7 @@ nvd0_disp_core_ofuncs = {
******************************************************************************/
static const struct nv50_disp_mthd_list
-nvd0_disp_base_mthd_base = {
+gf110_disp_base_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
@@ -415,7 +412,7 @@ nvd0_disp_base_mthd_base = {
};
static const struct nv50_disp_mthd_list
-nvd0_disp_base_mthd_image = {
+gf110_disp_base_mthd_image = {
.mthd = 0x0400,
.addr = 0x000400,
.data = {
@@ -429,29 +426,29 @@ nvd0_disp_base_mthd_image = {
};
const struct nv50_disp_mthd_chan
-nvd0_disp_base_mthd_chan = {
+gf110_disp_base_mthd_chan = {
.name = "Base",
.addr = 0x001000,
.data = {
- { "Global", 1, &nvd0_disp_base_mthd_base },
- { "Image", 2, &nvd0_disp_base_mthd_image },
+ { "Global", 1, &gf110_disp_base_mthd_base },
+ { "Image", 2, &gf110_disp_base_mthd_image },
{}
}
};
struct nv50_disp_chan_impl
-nvd0_disp_base_ofuncs = {
+gf110_disp_base_ofuncs = {
.base.ctor = nv50_disp_base_ctor,
.base.dtor = nv50_disp_dmac_dtor,
- .base.init = nvd0_disp_dmac_init,
- .base.fini = nvd0_disp_dmac_fini,
+ .base.init = gf110_disp_dmac_init,
+ .base.fini = gf110_disp_dmac_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32,
.chid = 1,
- .attach = nvd0_disp_dmac_object_attach,
- .detach = nvd0_disp_dmac_object_detach,
+ .attach = gf110_disp_dmac_object_attach,
+ .detach = gf110_disp_dmac_object_detach,
};
/*******************************************************************************
@@ -459,7 +456,7 @@ nvd0_disp_base_ofuncs = {
******************************************************************************/
static const struct nv50_disp_mthd_list
-nvd0_disp_ovly_mthd_base = {
+gf110_disp_ovly_mthd_base = {
.mthd = 0x0000,
.data = {
{ 0x0080, 0x665080 },
@@ -511,28 +508,28 @@ nvd0_disp_ovly_mthd_base = {
};
static const struct nv50_disp_mthd_chan
-nvd0_disp_ovly_mthd_chan = {
+gf110_disp_ovly_mthd_chan = {
.name = "Overlay",
.addr = 0x001000,
.data = {
- { "Global", 1, &nvd0_disp_ovly_mthd_base },
+ { "Global", 1, &gf110_disp_ovly_mthd_base },
{}
}
};
struct nv50_disp_chan_impl
-nvd0_disp_ovly_ofuncs = {
+gf110_disp_ovly_ofuncs = {
.base.ctor = nv50_disp_ovly_ctor,
.base.dtor = nv50_disp_dmac_dtor,
- .base.init = nvd0_disp_dmac_init,
- .base.fini = nvd0_disp_dmac_fini,
+ .base.init = gf110_disp_dmac_init,
+ .base.fini = gf110_disp_dmac_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32,
.base.wr32 = nv50_disp_chan_wr32,
.chid = 5,
- .attach = nvd0_disp_dmac_object_attach,
- .detach = nvd0_disp_dmac_object_detach,
+ .attach = gf110_disp_dmac_object_attach,
+ .detach = gf110_disp_dmac_object_detach,
};
/*******************************************************************************
@@ -540,7 +537,7 @@ nvd0_disp_ovly_ofuncs = {
******************************************************************************/
static int
-nvd0_disp_pioc_init(struct nouveau_object *object)
+gf110_disp_pioc_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_pioc *pioc = (void *)object;
@@ -566,7 +563,7 @@ nvd0_disp_pioc_init(struct nouveau_object *object)
}
static int
-nvd0_disp_pioc_fini(struct nouveau_object *object, bool suspend)
+gf110_disp_pioc_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_pioc *pioc = (void *)object;
@@ -592,11 +589,11 @@ nvd0_disp_pioc_fini(struct nouveau_object *object, bool suspend)
******************************************************************************/
struct nv50_disp_chan_impl
-nvd0_disp_oimm_ofuncs = {
+gf110_disp_oimm_ofuncs = {
.base.ctor = nv50_disp_oimm_ctor,
.base.dtor = nv50_disp_pioc_dtor,
- .base.init = nvd0_disp_pioc_init,
- .base.fini = nvd0_disp_pioc_fini,
+ .base.init = gf110_disp_pioc_init,
+ .base.fini = gf110_disp_pioc_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32,
@@ -609,11 +606,11 @@ nvd0_disp_oimm_ofuncs = {
******************************************************************************/
struct nv50_disp_chan_impl
-nvd0_disp_curs_ofuncs = {
+gf110_disp_curs_ofuncs = {
.base.ctor = nv50_disp_curs_ctor,
.base.dtor = nv50_disp_pioc_dtor,
- .base.init = nvd0_disp_pioc_init,
- .base.fini = nvd0_disp_pioc_fini,
+ .base.init = gf110_disp_pioc_init,
+ .base.fini = gf110_disp_pioc_fini,
.base.ntfy = nv50_disp_chan_ntfy,
.base.map = nv50_disp_chan_map,
.base.rd32 = nv50_disp_chan_rd32,
@@ -626,7 +623,7 @@ nvd0_disp_curs_ofuncs = {
******************************************************************************/
int
-nvd0_disp_main_scanoutpos(NV50_DISP_MTHD_V0)
+gf110_disp_main_scanoutpos(NV50_DISP_MTHD_V0)
{
const u32 total = nv_rd32(priv, 0x640414 + (head * 0x300));
const u32 blanke = nv_rd32(priv, 0x64041c + (head * 0x300));
@@ -658,14 +655,14 @@ nvd0_disp_main_scanoutpos(NV50_DISP_MTHD_V0)
}
static int
-nvd0_disp_main_init(struct nouveau_object *object)
+gf110_disp_main_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_base *base = (void *)object;
int ret, i;
u32 tmp;
- ret = nouveau_parent_init(&base->base);
+ ret = nvkm_parent_init(&base->base);
if (ret)
return ret;
@@ -715,7 +712,7 @@ nvd0_disp_main_init(struct nouveau_object *object)
nv_wr32(priv, 0x6100b0, 0x00000307);
/* disable underflow reporting, preventing an intermittent issue
- * on some nve4 boards where the production vbios left this
+ * on some gk104 boards where the production vbios left this
* setting enabled by default.
*
* ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt
@@ -727,7 +724,7 @@ nvd0_disp_main_init(struct nouveau_object *object)
}
static int
-nvd0_disp_main_fini(struct nouveau_object *object, bool suspend)
+gf110_disp_main_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_base *base = (void *)object;
@@ -735,32 +732,32 @@ nvd0_disp_main_fini(struct nouveau_object *object, bool suspend)
/* disable all interrupts */
nv_wr32(priv, 0x6100b0, 0x00000000);
- return nouveau_parent_fini(&base->base, suspend);
+ return nvkm_parent_fini(&base->base, suspend);
}
-struct nouveau_ofuncs
-nvd0_disp_main_ofuncs = {
+struct nvkm_ofuncs
+gf110_disp_main_ofuncs = {
.ctor = nv50_disp_main_ctor,
.dtor = nv50_disp_main_dtor,
- .init = nvd0_disp_main_init,
- .fini = nvd0_disp_main_fini,
+ .init = gf110_disp_main_init,
+ .fini = gf110_disp_main_fini,
.mthd = nv50_disp_main_mthd,
- .ntfy = nouveau_disp_ntfy,
+ .ntfy = nvkm_disp_ntfy,
};
-static struct nouveau_oclass
-nvd0_disp_main_oclass[] = {
- { GF110_DISP, &nvd0_disp_main_ofuncs },
+static struct nvkm_oclass
+gf110_disp_main_oclass[] = {
+ { GF110_DISP, &gf110_disp_main_ofuncs },
{}
};
-static struct nouveau_oclass
-nvd0_disp_sclass[] = {
- { GF110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
- { GF110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
- { GF110_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
- { GF110_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
- { GF110_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
+static struct nvkm_oclass
+gf110_disp_sclass[] = {
+ { GF110_DISP_CORE_CHANNEL_DMA, &gf110_disp_core_ofuncs.base },
+ { GF110_DISP_BASE_CHANNEL_DMA, &gf110_disp_base_ofuncs.base },
+ { GF110_DISP_OVERLAY_CONTROL_DMA, &gf110_disp_ovly_ofuncs.base },
+ { GF110_DISP_OVERLAY, &gf110_disp_oimm_ofuncs.base },
+ { GF110_DISP_CURSOR, &gf110_disp_curs_ofuncs.base },
{}
};
@@ -769,24 +766,24 @@ nvd0_disp_sclass[] = {
******************************************************************************/
static void
-nvd0_disp_vblank_init(struct nvkm_event *event, int type, int head)
+gf110_disp_vblank_init(struct nvkm_event *event, int type, int head)
{
- struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
+ struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
nv_mask(disp, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000001);
}
static void
-nvd0_disp_vblank_fini(struct nvkm_event *event, int type, int head)
+gf110_disp_vblank_fini(struct nvkm_event *event, int type, int head)
{
- struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
+ struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
nv_mask(disp, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000000);
}
const struct nvkm_event_func
-nvd0_disp_vblank_func = {
- .ctor = nouveau_disp_vblank_ctor,
- .init = nvd0_disp_vblank_init,
- .fini = nvd0_disp_vblank_fini,
+gf110_disp_vblank_func = {
+ .ctor = nvkm_disp_vblank_ctor,
+ .init = gf110_disp_vblank_init,
+ .fini = gf110_disp_vblank_fini,
};
static struct nvkm_output *
@@ -794,7 +791,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl,
u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_outp *info)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvkm_output *outp;
u16 mask, type;
@@ -838,7 +835,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl,
static struct nvkm_output *
exec_script(struct nv50_disp_priv *priv, int head, int id)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvkm_output *outp;
struct nvbios_outp info;
u8 ver, hdr, cnt, len;
@@ -874,7 +871,7 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
static struct nvkm_output *
exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvkm_output *outp;
struct nvbios_outp info1;
struct nvbios_ocfg info2;
@@ -934,13 +931,13 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf)
}
static void
-nvd0_disp_intr_unk1_0(struct nv50_disp_priv *priv, int head)
+gf110_disp_intr_unk1_0(struct nv50_disp_priv *priv, int head)
{
exec_script(priv, head, 1);
}
static void
-nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head)
+gf110_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head)
{
struct nvkm_output *outp = exec_script(priv, head, 2);
@@ -949,7 +946,7 @@ nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head)
struct nvkm_output_dp *outpdp = (void *)outp;
struct nvbios_init init = {
.subdev = nv_subdev(priv),
- .bios = nouveau_bios(priv),
+ .bios = nvkm_bios(priv),
.outp = &outp->info,
.crtc = head,
.offset = outpdp->info.script[4],
@@ -962,9 +959,9 @@ nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head)
}
static void
-nvd0_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head)
+gf110_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head)
{
- struct nouveau_devinit *devinit = nouveau_devinit(priv);
+ struct nvkm_devinit *devinit = nvkm_devinit(priv);
u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
if (pclk)
devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
@@ -972,8 +969,8 @@ nvd0_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head)
}
static void
-nvd0_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head,
- struct dcb_output *outp)
+gf110_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head,
+ struct dcb_output *outp)
{
const int or = ffs(outp->or) - 1;
const u32 ctrl = nv_rd32(priv, 0x660200 + (or * 0x020));
@@ -1033,7 +1030,7 @@ nvd0_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head,
}
static void
-nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
+gf110_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
{
struct nvkm_output *outp;
u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
@@ -1075,7 +1072,7 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
nv_mask(priv, addr, 0x007c0000, 0x00280000);
break;
case DCB_OUTPUT_DP:
- nvd0_disp_intr_unk2_2_tu(priv, head, &outp->info);
+ gf110_disp_intr_unk2_2_tu(priv, head, &outp->info);
break;
default:
break;
@@ -1086,7 +1083,7 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
}
static void
-nvd0_disp_intr_unk4_0(struct nv50_disp_priv *priv, int head)
+gf110_disp_intr_unk4_0(struct nv50_disp_priv *priv, int head)
{
u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
u32 conf;
@@ -1095,7 +1092,7 @@ nvd0_disp_intr_unk4_0(struct nv50_disp_priv *priv, int head)
}
void
-nvd0_disp_intr_supervisor(struct work_struct *work)
+gf110_disp_intr_supervisor(struct work_struct *work)
{
struct nv50_disp_priv *priv =
container_of(work, struct nv50_disp_priv, supervisor);
@@ -1115,7 +1112,7 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
if (!(mask[head] & 0x00001000))
continue;
nv_debug(priv, "supervisor 1.0 - head %d\n", head);
- nvd0_disp_intr_unk1_0(priv, head);
+ gf110_disp_intr_unk1_0(priv, head);
}
} else
if (priv->super & 0x00000002) {
@@ -1123,19 +1120,19 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
if (!(mask[head] & 0x00001000))
continue;
nv_debug(priv, "supervisor 2.0 - head %d\n", head);
- nvd0_disp_intr_unk2_0(priv, head);
+ gf110_disp_intr_unk2_0(priv, head);
}
for (head = 0; head < priv->head.nr; head++) {
if (!(mask[head] & 0x00010000))
continue;
nv_debug(priv, "supervisor 2.1 - head %d\n", head);
- nvd0_disp_intr_unk2_1(priv, head);
+ gf110_disp_intr_unk2_1(priv, head);
}
for (head = 0; head < priv->head.nr; head++) {
if (!(mask[head] & 0x00001000))
continue;
nv_debug(priv, "supervisor 2.2 - head %d\n", head);
- nvd0_disp_intr_unk2_2(priv, head);
+ gf110_disp_intr_unk2_2(priv, head);
}
} else
if (priv->super & 0x00000004) {
@@ -1143,7 +1140,7 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
if (!(mask[head] & 0x00001000))
continue;
nv_debug(priv, "supervisor 3.0 - head %d\n", head);
- nvd0_disp_intr_unk4_0(priv, head);
+ gf110_disp_intr_unk4_0(priv, head);
}
}
@@ -1153,7 +1150,7 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
}
static void
-nvd0_disp_intr_error(struct nv50_disp_priv *priv, int chid)
+gf110_disp_intr_error(struct nv50_disp_priv *priv, int chid)
{
const struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
u32 mthd = nv_rd32(priv, 0x6101f0 + (chid * 12));
@@ -1200,7 +1197,7 @@ nvd0_disp_intr_error(struct nv50_disp_priv *priv, int chid)
}
void
-nvd0_disp_intr(struct nouveau_subdev *subdev)
+gf110_disp_intr(struct nvkm_subdev *subdev)
{
struct nv50_disp_priv *priv = (void *)subdev;
u32 intr = nv_rd32(priv, 0x610088);
@@ -1220,7 +1217,7 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
u32 stat = nv_rd32(priv, 0x61009c);
int chid = ffs(stat) - 1;
if (chid >= 0)
- nvd0_disp_intr_error(priv, chid);
+ gf110_disp_intr_error(priv, chid);
intr &= ~0x00000002;
}
@@ -1246,7 +1243,7 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
if (mask & intr) {
u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800));
if (stat & 0x00000001)
- nouveau_disp_vblank(&priv->base, i);
+ nvkm_disp_vblank(&priv->base, i);
nv_mask(priv, 0x6100bc + (i * 0x800), 0, 0);
nv_rd32(priv, 0x6100c0 + (i * 0x800));
}
@@ -1254,60 +1251,60 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
}
static int
-nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf110_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, heads,
- "PDISP", "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, heads,
+ "PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
+ ret = nvkm_event_init(&gf110_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
- nv_engine(priv)->sclass = nvd0_disp_main_oclass;
+ nv_engine(priv)->sclass = gf110_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
- nv_subdev(priv)->intr = nvd0_disp_intr;
- INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
- priv->sclass = nvd0_disp_sclass;
+ nv_subdev(priv)->intr = gf110_disp_intr;
+ INIT_WORK(&priv->supervisor, gf110_disp_intr_supervisor);
+ priv->sclass = gf110_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hda_eld = nvd0_hda_eld;
- priv->sor.hdmi = nvd0_hdmi_ctrl;
+ priv->sor.hda_eld = gf110_hda_eld;
+ priv->sor.hdmi = gf110_hdmi_ctrl;
return 0;
}
-struct nouveau_oclass *
-nvd0_disp_outp_sclass[] = {
- &nvd0_sor_dp_impl.base.base,
+struct nvkm_oclass *
+gf110_disp_outp_sclass[] = {
+ &gf110_sor_dp_impl.base.base,
NULL
};
-struct nouveau_oclass *
-nvd0_disp_oclass = &(struct nv50_disp_impl) {
+struct nvkm_oclass *
+gf110_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x90),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvd0_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf110_disp_ctor,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
- .base.vblank = &nvd0_disp_vblank_func,
- .base.outp = nvd0_disp_outp_sclass,
- .mthd.core = &nvd0_disp_core_mthd_chan,
- .mthd.base = &nvd0_disp_base_mthd_chan,
- .mthd.ovly = &nvd0_disp_ovly_mthd_chan,
+ .base.vblank = &gf110_disp_vblank_func,
+ .base.outp = gf110_disp_outp_sclass,
+ .mthd.core = &gf110_disp_core_mthd_chan,
+ .mthd.base = &gf110_disp_base_mthd_chan,
+ .mthd.ovly = &gf110_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
- .head.scanoutpos = nvd0_disp_main_scanoutpos,
+ .head.scanoutpos = gf110_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c
index 55debec7e68f..6f4019ab4e65 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c
@@ -21,20 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* EVO master channel object
******************************************************************************/
static const struct nv50_disp_mthd_list
-nve0_disp_core_mthd_head = {
+gk104_disp_core_mthd_head = {
.mthd = 0x0300,
.addr = 0x000300,
.data = {
@@ -113,15 +109,15 @@ nve0_disp_core_mthd_head = {
};
const struct nv50_disp_mthd_chan
-nve0_disp_core_mthd_chan = {
+gk104_disp_core_mthd_chan = {
.name = "Core",
.addr = 0x000000,
.data = {
- { "Global", 1, &nvd0_disp_core_mthd_base },
- { "DAC", 3, &nvd0_disp_core_mthd_dac },
- { "SOR", 8, &nvd0_disp_core_mthd_sor },
- { "PIOR", 4, &nvd0_disp_core_mthd_pior },
- { "HEAD", 4, &nve0_disp_core_mthd_head },
+ { "Global", 1, &gf110_disp_core_mthd_base },
+ { "DAC", 3, &gf110_disp_core_mthd_dac },
+ { "SOR", 8, &gf110_disp_core_mthd_sor },
+ { "PIOR", 4, &gf110_disp_core_mthd_pior },
+ { "HEAD", 4, &gk104_disp_core_mthd_head },
{}
}
};
@@ -131,7 +127,7 @@ nve0_disp_core_mthd_chan = {
******************************************************************************/
static const struct nv50_disp_mthd_list
-nve0_disp_ovly_mthd_base = {
+gk104_disp_ovly_mthd_base = {
.mthd = 0x0000,
.data = {
{ 0x0080, 0x665080 },
@@ -185,11 +181,11 @@ nve0_disp_ovly_mthd_base = {
};
const struct nv50_disp_mthd_chan
-nve0_disp_ovly_mthd_chan = {
+gk104_disp_ovly_mthd_chan = {
.name = "Overlay",
.addr = 0x001000,
.data = {
- { "Global", 1, &nve0_disp_ovly_mthd_base },
+ { "Global", 1, &gk104_disp_ovly_mthd_base },
{}
}
};
@@ -198,19 +194,19 @@ nve0_disp_ovly_mthd_chan = {
* Base display object
******************************************************************************/
-static struct nouveau_oclass
-nve0_disp_sclass[] = {
- { GK104_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
- { GK104_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
- { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
- { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
- { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
+static struct nvkm_oclass
+gk104_disp_sclass[] = {
+ { GK104_DISP_CORE_CHANNEL_DMA, &gf110_disp_core_ofuncs.base },
+ { GK104_DISP_BASE_CHANNEL_DMA, &gf110_disp_base_ofuncs.base },
+ { GK104_DISP_OVERLAY_CONTROL_DMA, &gf110_disp_ovly_ofuncs.base },
+ { GK104_DISP_OVERLAY, &gf110_disp_oimm_ofuncs.base },
+ { GK104_DISP_CURSOR, &gf110_disp_curs_ofuncs.base },
{}
};
-static struct nouveau_oclass
-nve0_disp_main_oclass[] = {
- { GK104_DISP, &nvd0_disp_main_ofuncs },
+static struct nvkm_oclass
+gk104_disp_main_oclass[] = {
+ { GK104_DISP, &gf110_disp_main_ofuncs },
{}
};
@@ -219,54 +215,54 @@ nve0_disp_main_oclass[] = {
******************************************************************************/
static int
-nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, heads,
- "PDISP", "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, heads,
+ "PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
+ ret = nvkm_event_init(&gf110_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
- nv_engine(priv)->sclass = nve0_disp_main_oclass;
+ nv_engine(priv)->sclass = gk104_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
- nv_subdev(priv)->intr = nvd0_disp_intr;
- INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
- priv->sclass = nve0_disp_sclass;
+ nv_subdev(priv)->intr = gf110_disp_intr;
+ INIT_WORK(&priv->supervisor, gf110_disp_intr_supervisor);
+ priv->sclass = gk104_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hda_eld = nvd0_hda_eld;
- priv->sor.hdmi = nve0_hdmi_ctrl;
+ priv->sor.hda_eld = gf110_hda_eld;
+ priv->sor.hdmi = gk104_hdmi_ctrl;
return 0;
}
-struct nouveau_oclass *
-nve0_disp_oclass = &(struct nv50_disp_impl) {
+struct nvkm_oclass *
+gk104_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x91),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_disp_ctor,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
- .base.vblank = &nvd0_disp_vblank_func,
- .base.outp = nvd0_disp_outp_sclass,
- .mthd.core = &nve0_disp_core_mthd_chan,
- .mthd.base = &nvd0_disp_base_mthd_chan,
- .mthd.ovly = &nve0_disp_ovly_mthd_chan,
+ .base.vblank = &gf110_disp_vblank_func,
+ .base.outp = gf110_disp_outp_sclass,
+ .mthd.core = &gk104_disp_core_mthd_chan,
+ .mthd.base = &gf110_disp_base_mthd_chan,
+ .mthd.ovly = &gk104_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
- .head.scanoutpos = nvd0_disp_main_scanoutpos,
+ .head.scanoutpos = gf110_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c
index 3e7e2d28744c..daa4b460a6ba 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gk110.c
@@ -21,31 +21,27 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* Base display object
******************************************************************************/
-static struct nouveau_oclass
-nvf0_disp_sclass[] = {
- { GK110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
- { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
- { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
- { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
- { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
+static struct nvkm_oclass
+gk110_disp_sclass[] = {
+ { GK110_DISP_CORE_CHANNEL_DMA, &gf110_disp_core_ofuncs.base },
+ { GK110_DISP_BASE_CHANNEL_DMA, &gf110_disp_base_ofuncs.base },
+ { GK104_DISP_OVERLAY_CONTROL_DMA, &gf110_disp_ovly_ofuncs.base },
+ { GK104_DISP_OVERLAY, &gf110_disp_oimm_ofuncs.base },
+ { GK104_DISP_CURSOR, &gf110_disp_curs_ofuncs.base },
{}
};
-static struct nouveau_oclass
-nvf0_disp_main_oclass[] = {
- { GK110_DISP, &nvd0_disp_main_ofuncs },
+static struct nvkm_oclass
+gk110_disp_main_oclass[] = {
+ { GK110_DISP, &gf110_disp_main_ofuncs },
{}
};
@@ -54,54 +50,54 @@ nvf0_disp_main_oclass[] = {
******************************************************************************/
static int
-nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk110_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, heads,
- "PDISP", "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, heads,
+ "PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
+ ret = nvkm_event_init(&gf110_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
- nv_engine(priv)->sclass = nvf0_disp_main_oclass;
+ nv_engine(priv)->sclass = gk110_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
- nv_subdev(priv)->intr = nvd0_disp_intr;
- INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
- priv->sclass = nvf0_disp_sclass;
+ nv_subdev(priv)->intr = gf110_disp_intr;
+ INIT_WORK(&priv->supervisor, gf110_disp_intr_supervisor);
+ priv->sclass = gk110_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hda_eld = nvd0_hda_eld;
- priv->sor.hdmi = nve0_hdmi_ctrl;
+ priv->sor.hda_eld = gf110_hda_eld;
+ priv->sor.hdmi = gk104_hdmi_ctrl;
return 0;
}
-struct nouveau_oclass *
-nvf0_disp_oclass = &(struct nv50_disp_impl) {
+struct nvkm_oclass *
+gk110_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x92),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvf0_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk110_disp_ctor,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
- .base.vblank = &nvd0_disp_vblank_func,
- .base.outp = nvd0_disp_outp_sclass,
- .mthd.core = &nve0_disp_core_mthd_chan,
- .mthd.base = &nvd0_disp_base_mthd_chan,
- .mthd.ovly = &nve0_disp_ovly_mthd_chan,
+ .base.vblank = &gf110_disp_vblank_func,
+ .base.outp = gf110_disp_outp_sclass,
+ .mthd.core = &gk104_disp_core_mthd_chan,
+ .mthd.base = &gf110_disp_base_mthd_chan,
+ .mthd.ovly = &gk104_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
- .head.scanoutpos = nvd0_disp_main_scanoutpos,
+ .head.scanoutpos = gf110_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
index e2ad0543fb31..881cc94385a1 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
@@ -21,31 +21,27 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* Base display object
******************************************************************************/
-static struct nouveau_oclass
+static struct nvkm_oclass
gm107_disp_sclass[] = {
- { GM107_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
- { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
- { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
- { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
- { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
+ { GM107_DISP_CORE_CHANNEL_DMA, &gf110_disp_core_ofuncs.base },
+ { GK110_DISP_BASE_CHANNEL_DMA, &gf110_disp_base_ofuncs.base },
+ { GK104_DISP_OVERLAY_CONTROL_DMA, &gf110_disp_ovly_ofuncs.base },
+ { GK104_DISP_OVERLAY, &gf110_disp_oimm_ofuncs.base },
+ { GK104_DISP_CURSOR, &gf110_disp_curs_ofuncs.base },
{}
};
-static struct nouveau_oclass
+static struct nvkm_oclass
gm107_disp_main_oclass[] = {
- { GM107_DISP, &nvd0_disp_main_ofuncs },
+ { GM107_DISP, &gf110_disp_main_ofuncs },
{}
};
@@ -54,28 +50,28 @@ gm107_disp_main_oclass[] = {
******************************************************************************/
static int
-gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gm107_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, heads,
- "PDISP", "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, heads,
+ "PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
+ ret = nvkm_event_init(&gf110_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = gm107_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
- nv_subdev(priv)->intr = nvd0_disp_intr;
- INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
+ nv_subdev(priv)->intr = gf110_disp_intr;
+ INIT_WORK(&priv->supervisor, gf110_disp_intr_supervisor);
priv->sclass = gm107_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
@@ -83,25 +79,25 @@ gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hda_eld = nvd0_hda_eld;
- priv->sor.hdmi = nve0_hdmi_ctrl;
+ priv->sor.hda_eld = gf110_hda_eld;
+ priv->sor.hdmi = gk104_hdmi_ctrl;
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
gm107_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x07),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm107_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
- .base.vblank = &nvd0_disp_vblank_func,
- .base.outp = nvd0_disp_outp_sclass,
- .mthd.core = &nve0_disp_core_mthd_chan,
- .mthd.base = &nvd0_disp_base_mthd_chan,
- .mthd.ovly = &nve0_disp_ovly_mthd_chan,
+ .base.vblank = &gf110_disp_vblank_func,
+ .base.outp = gf110_disp_outp_sclass,
+ .mthd.core = &gk104_disp_core_mthd_chan,
+ .mthd.base = &gf110_disp_base_mthd_chan,
+ .mthd.ovly = &gk104_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
- .head.scanoutpos = nvd0_disp_main_scanoutpos,
+ .head.scanoutpos = gf110_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/gm204.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm204.c
index 672ded79b2a9..67004f8302b3 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/gm204.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm204.c
@@ -21,31 +21,28 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
+#include "outpdp.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* Base display object
******************************************************************************/
-static struct nouveau_oclass
+static struct nvkm_oclass
gm204_disp_sclass[] = {
- { GM204_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
- { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
- { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
- { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
- { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
+ { GM204_DISP_CORE_CHANNEL_DMA, &gf110_disp_core_ofuncs.base },
+ { GK110_DISP_BASE_CHANNEL_DMA, &gf110_disp_base_ofuncs.base },
+ { GK104_DISP_OVERLAY_CONTROL_DMA, &gf110_disp_ovly_ofuncs.base },
+ { GK104_DISP_OVERLAY, &gf110_disp_oimm_ofuncs.base },
+ { GK104_DISP_CURSOR, &gf110_disp_curs_ofuncs.base },
{}
};
-static struct nouveau_oclass
+static struct nvkm_oclass
gm204_disp_main_oclass[] = {
- { GM204_DISP, &nvd0_disp_main_ofuncs },
+ { GM204_DISP, &gf110_disp_main_ofuncs },
{}
};
@@ -54,28 +51,28 @@ gm204_disp_main_oclass[] = {
******************************************************************************/
static int
-gm204_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gm204_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, heads,
- "PDISP", "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, heads,
+ "PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
+ ret = nvkm_event_init(&gf110_disp_chan_uevent, 1, 17, &priv->uevent);
if (ret)
return ret;
nv_engine(priv)->sclass = gm204_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
- nv_subdev(priv)->intr = nvd0_disp_intr;
- INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
+ nv_subdev(priv)->intr = gf110_disp_intr;
+ INIT_WORK(&priv->supervisor, gf110_disp_intr_supervisor);
priv->sclass = gm204_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
@@ -83,32 +80,32 @@ gm204_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hda_eld = nvd0_hda_eld;
- priv->sor.hdmi = nvd0_hdmi_ctrl;
+ priv->sor.hda_eld = gf110_hda_eld;
+ priv->sor.hdmi = gf110_hdmi_ctrl;
priv->sor.magic = gm204_sor_magic;
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
gm204_disp_outp_sclass[] = {
&gm204_sor_dp_impl.base.base,
NULL
};
-struct nouveau_oclass *
+struct nvkm_oclass *
gm204_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x07),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm204_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
- .base.vblank = &nvd0_disp_vblank_func,
+ .base.vblank = &gf110_disp_vblank_func,
.base.outp = gm204_disp_outp_sclass,
- .mthd.core = &nve0_disp_core_mthd_chan,
- .mthd.base = &nvd0_disp_base_mthd_chan,
- .mthd.ovly = &nve0_disp_ovly_mthd_chan,
+ .mthd.core = &gk104_disp_core_mthd_chan,
+ .mthd.base = &gf110_disp_base_mthd_chan,
+ .mthd.ovly = &gk104_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
- .head.scanoutpos = nvd0_disp_main_scanoutpos,
+ .head.scanoutpos = gf110_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c
index b32456c9494f..a45307213f4b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt200.c
@@ -21,20 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* EVO overlay channel objects
******************************************************************************/
static const struct nv50_disp_mthd_list
-nva0_disp_ovly_mthd_base = {
+gt200_disp_ovly_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
@@ -65,11 +61,11 @@ nva0_disp_ovly_mthd_base = {
};
static const struct nv50_disp_mthd_chan
-nva0_disp_ovly_mthd_chan = {
+gt200_disp_ovly_mthd_chan = {
.name = "Overlay",
.addr = 0x000540,
.data = {
- { "Global", 1, &nva0_disp_ovly_mthd_base },
+ { "Global", 1, &gt200_disp_ovly_mthd_base },
{}
}
};
@@ -78,8 +74,8 @@ nva0_disp_ovly_mthd_chan = {
* Base display object
******************************************************************************/
-static struct nouveau_oclass
-nva0_disp_sclass[] = {
+static struct nvkm_oclass
+gt200_disp_sclass[] = {
{ GT200_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
{ GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
{ GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
@@ -88,8 +84,8 @@ nva0_disp_sclass[] = {
{}
};
-static struct nouveau_oclass
-nva0_disp_main_oclass[] = {
+static struct nvkm_oclass
+gt200_disp_main_oclass[] = {
{ GT200_DISP, &nv50_disp_main_ofuncs },
{}
};
@@ -99,15 +95,15 @@ nva0_disp_main_oclass[] = {
******************************************************************************/
static int
-nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gt200_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
- "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, 2, "PDISP",
+ "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -116,11 +112,11 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_engine(priv)->sclass = nva0_disp_main_oclass;
+ nv_engine(priv)->sclass = gt200_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
- priv->sclass = nva0_disp_sclass;
+ priv->sclass = gt200_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 2;
@@ -128,25 +124,25 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hdmi = nv84_hdmi_ctrl;
+ priv->sor.hdmi = g84_hdmi_ctrl;
priv->pior.power = nv50_pior_power;
return 0;
}
-struct nouveau_oclass *
-nva0_disp_oclass = &(struct nv50_disp_impl) {
+struct nvkm_oclass *
+gt200_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x83),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva0_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gt200_disp_ctor,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
.base.outp = nv50_disp_outp_sclass,
- .mthd.core = &nv84_disp_core_mthd_chan,
- .mthd.base = &nv84_disp_base_mthd_chan,
- .mthd.ovly = &nva0_disp_ovly_mthd_chan,
+ .mthd.core = &g84_disp_core_mthd_chan,
+ .mthd.base = &g84_disp_base_mthd_chan,
+ .mthd.ovly = &gt200_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
.head.scanoutpos = nv50_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c
index 951d79f9b781..55f0d3ac591e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c
@@ -21,20 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/software.h>
-#include <engine/disp.h>
+#include "nv50.h"
#include <nvif/class.h>
-#include "nv50.h"
-
/*******************************************************************************
* Base display object
******************************************************************************/
-static struct nouveau_oclass
-nva3_disp_sclass[] = {
+static struct nvkm_oclass
+gt215_disp_sclass[] = {
{ GT214_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
{ GT214_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
{ GT214_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
@@ -43,8 +39,8 @@ nva3_disp_sclass[] = {
{}
};
-static struct nouveau_oclass
-nva3_disp_main_oclass[] = {
+static struct nvkm_oclass
+gt215_disp_main_oclass[] = {
{ GT214_DISP, &nv50_disp_main_ofuncs },
{}
};
@@ -54,15 +50,15 @@ nva3_disp_main_oclass[] = {
******************************************************************************/
static int
-nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gt215_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
- "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, 2, "PDISP",
+ "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -71,11 +67,11 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_engine(priv)->sclass = nva3_disp_main_oclass;
+ nv_engine(priv)->sclass = gt215_disp_main_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
- priv->sclass = nva3_disp_sclass;
+ priv->sclass = gt215_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 4;
@@ -83,26 +79,26 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
- priv->sor.hda_eld = nva3_hda_eld;
- priv->sor.hdmi = nva3_hdmi_ctrl;
+ priv->sor.hda_eld = gt215_hda_eld;
+ priv->sor.hdmi = gt215_hdmi_ctrl;
priv->pior.power = nv50_pior_power;
return 0;
}
-struct nouveau_oclass *
-nva3_disp_oclass = &(struct nv50_disp_impl) {
+struct nvkm_oclass *
+gt215_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x85),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gt215_disp_ctor,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
- .base.outp = nv94_disp_outp_sclass,
- .mthd.core = &nv94_disp_core_mthd_chan,
- .mthd.base = &nv84_disp_base_mthd_chan,
- .mthd.ovly = &nv84_disp_ovly_mthd_chan,
+ .base.outp = g94_disp_outp_sclass,
+ .mthd.core = &g94_disp_core_mthd_chan,
+ .mthd.base = &g84_disp_base_mthd_chan,
+ .mthd.ovly = &g84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
.head.scanoutpos = nv50_disp_main_scanoutpos,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf110.c
index 1d4e8432d857..b9813d246ba5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagf110.c
@@ -21,17 +21,19 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outp.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
#include <subdev/timer.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
-nvd0_hda_eld(NV50_DISP_MTHD_V1)
+gf110_hda_eld(NV50_DISP_MTHD_V1)
{
union {
struct nv50_disp_sor_hda_eld_v0 v0;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c
index fe9ef5894dd4..891d1e7bf7d2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdagt215.c
@@ -21,17 +21,17 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outp.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
#include <subdev/timer.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
-nva3_hda_eld(NV50_DISP_MTHD_V1)
+gt215_hda_eld(NV50_DISP_MTHD_V1)
{
union {
struct nv50_disp_sor_hda_eld_v0 v0;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c
index fa276dede9cd..621cb0b7ff19 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmig84.c
@@ -21,15 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
-nv84_hdmi_ctrl(NV50_DISP_MTHD_V1)
+g84_hdmi_ctrl(NV50_DISP_MTHD_V1)
{
const u32 hoff = (head * 0x800);
union {
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf110.c
index bac4fc4570f0..c28449061bbd 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigf110.c
@@ -21,15 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
-nvd0_hdmi_ctrl(NV50_DISP_MTHD_V1)
+gf110_hdmi_ctrl(NV50_DISP_MTHD_V1)
{
const u32 hoff = (head * 0x800);
union {
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminve0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c
index 528d14ec2f7f..ca34ff81ad7f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigk104.c
@@ -21,15 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
-nve0_hdmi_ctrl(NV50_DISP_MTHD_V1)
+gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
{
const u32 hoff = (head * 0x800);
const u32 hdmi = (head * 0x400);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c
index 57eeed1d1942..b641c167dcfa 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigt215.c
@@ -21,15 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outp.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
-nva3_hdmi_ctrl(NV50_DISP_MTHD_V1)
+gt215_hdmi_ctrl(NV50_DISP_MTHD_V1)
{
const u32 soff = outp->or * 0x800;
union {
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv04.c
index 366f315fc9a5..ff09b2659c17 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv04.c
@@ -21,20 +21,20 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
#include <core/client.h>
-#include <core/event.h>
-#include <nvif/unpack.h>
+#include <core/device.h>
+
#include <nvif/class.h>
+#include <nvif/unpack.h>
struct nv04_disp_priv {
- struct nouveau_disp base;
+ struct nvkm_disp base;
};
static int
-nv04_disp_scanoutpos(struct nouveau_object *object, struct nv04_disp_priv *priv,
+nv04_disp_scanoutpos(struct nvkm_object *object, struct nv04_disp_priv *priv,
void *data, u32 size, int head)
{
const u32 hoff = head * 0x2000;
@@ -75,7 +75,7 @@ nv04_disp_scanoutpos(struct nouveau_object *object, struct nv04_disp_priv *priv,
}
static int
-nv04_disp_mthd(struct nouveau_object *object, u32 mthd, void *data, u32 size)
+nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
union {
struct nv04_disp_mthd_v0 v0;
@@ -105,17 +105,17 @@ nv04_disp_mthd(struct nouveau_object *object, u32 mthd, void *data, u32 size)
return -EINVAL;
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv04_disp_ofuncs = {
- .ctor = _nouveau_object_ctor,
- .dtor = nouveau_object_destroy,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
+ .ctor = _nvkm_object_ctor,
+ .dtor = nvkm_object_destroy,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
.mthd = nv04_disp_mthd,
- .ntfy = nouveau_disp_ntfy,
+ .ntfy = nvkm_disp_ntfy,
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv04_disp_sclass[] = {
{ NV04_DISP, &nv04_disp_ofuncs },
{},
@@ -128,26 +128,26 @@ nv04_disp_sclass[] = {
static void
nv04_disp_vblank_init(struct nvkm_event *event, int type, int head)
{
- struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
+ struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
nv_wr32(disp, 0x600140 + (head * 0x2000) , 0x00000001);
}
static void
nv04_disp_vblank_fini(struct nvkm_event *event, int type, int head)
{
- struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
+ struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
nv_wr32(disp, 0x600140 + (head * 0x2000) , 0x00000000);
}
static const struct nvkm_event_func
nv04_disp_vblank_func = {
- .ctor = nouveau_disp_vblank_ctor,
+ .ctor = nvkm_disp_vblank_ctor,
.init = nv04_disp_vblank_init,
.fini = nv04_disp_vblank_fini,
};
static void
-nv04_disp_intr(struct nouveau_subdev *subdev)
+nv04_disp_intr(struct nvkm_subdev *subdev)
{
struct nv04_disp_priv *priv = (void *)subdev;
u32 crtc0 = nv_rd32(priv, 0x600100);
@@ -155,12 +155,12 @@ nv04_disp_intr(struct nouveau_subdev *subdev)
u32 pvideo;
if (crtc0 & 0x00000001) {
- nouveau_disp_vblank(&priv->base, 0);
+ nvkm_disp_vblank(&priv->base, 0);
nv_wr32(priv, 0x600100, 0x00000001);
}
if (crtc1 & 0x00000001) {
- nouveau_disp_vblank(&priv->base, 1);
+ nvkm_disp_vblank(&priv->base, 1);
nv_wr32(priv, 0x602100, 0x00000001);
}
@@ -174,15 +174,15 @@ nv04_disp_intr(struct nouveau_subdev *subdev)
}
static int
-nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_disp_priv *priv;
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, 2, "DISPLAY",
- "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, 2, "DISPLAY",
+ "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -192,14 +192,14 @@ nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv04_disp_oclass = &(struct nouveau_disp_impl) {
+struct nvkm_oclass *
+nv04_disp_oclass = &(struct nvkm_disp_impl) {
.base.handle = NV_ENGINE(DISP, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
.vblank = &nv04_disp_vblank_func,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
index 44a8290aaea5..84ade810e27c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
@@ -21,35 +21,38 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outp.h"
+#include "outpdp.h"
-#include <core/object.h>
#include <core/client.h>
-#include <core/parent.h>
-#include <core/handle.h>
+#include <core/device.h>
+#include <core/engctx.h>
#include <core/enum.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-#include <nvif/event.h>
-
+#include <core/handle.h>
+#include <core/ramht.h>
+#include <engine/dmaobj.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/disp.h>
#include <subdev/bios/init.h>
#include <subdev/bios/pll.h>
#include <subdev/devinit.h>
-#include <subdev/timer.h>
#include <subdev/fb.h>
+#include <subdev/timer.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/event.h>
+#include <nvif/unpack.h>
/*******************************************************************************
* EVO channel base class
******************************************************************************/
static int
-nv50_disp_chan_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int head,
+nv50_disp_chan_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int head,
int length, void **pobject)
{
const struct nv50_disp_chan_impl *impl = (void *)oclass->ofuncs;
@@ -62,9 +65,9 @@ nv50_disp_chan_create_(struct nouveau_object *parent,
return -EBUSY;
base->chan |= (1 << chid);
- ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
- (1ULL << NVDEV_ENGINE_DMAOBJ),
- length, pobject);
+ ret = nvkm_namedb_create_(parent, engine, oclass, 0, NULL,
+ (1ULL << NVDEV_ENGINE_DMAOBJ),
+ length, pobject);
chan = *pobject;
if (ret)
return ret;
@@ -80,7 +83,7 @@ nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
{
struct nv50_disp_base *base = (void *)nv_object(chan)->parent;
base->chan &= ~(1 << chan->chid);
- nouveau_namedb_destroy(&chan->base);
+ nvkm_namedb_destroy(&chan->base);
}
static void
@@ -109,7 +112,7 @@ nv50_disp_chan_uevent_send(struct nv50_disp_priv *priv, int chid)
}
int
-nv50_disp_chan_uevent_ctor(struct nouveau_object *object, void *data, u32 size,
+nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
struct nv50_disp_dmac *dmac = (void *)object;
@@ -136,7 +139,7 @@ nv50_disp_chan_uevent = {
};
int
-nv50_disp_chan_ntfy(struct nouveau_object *object, u32 type,
+nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type,
struct nvkm_event **pevent)
{
struct nv50_disp_priv *priv = (void *)object->engine;
@@ -151,7 +154,7 @@ nv50_disp_chan_ntfy(struct nouveau_object *object, u32 type,
}
int
-nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size)
+nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size)
{
struct nv50_disp_chan *chan = (void *)object;
*addr = nv_device_resource_start(nv_device(object), 0) +
@@ -161,7 +164,7 @@ nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size)
}
u32
-nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr)
+nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_chan *chan = (void *)object;
@@ -169,7 +172,7 @@ nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr)
}
void
-nv50_disp_chan_wr32(struct nouveau_object *object, u64 addr, u32 data)
+nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_chan *chan = (void *)object;
@@ -181,28 +184,28 @@ nv50_disp_chan_wr32(struct nouveau_object *object, u64 addr, u32 data)
******************************************************************************/
static int
-nv50_disp_dmac_object_attach(struct nouveau_object *parent,
- struct nouveau_object *object, u32 name)
+nv50_disp_dmac_object_attach(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 name)
{
struct nv50_disp_base *base = (void *)parent->parent;
struct nv50_disp_chan *chan = (void *)parent;
u32 addr = nv_gpuobj(object)->node->offset;
u32 chid = chan->chid;
u32 data = (chid << 28) | (addr << 10) | chid;
- return nouveau_ramht_insert(base->ramht, chid, name, data);
+ return nvkm_ramht_insert(base->ramht, chid, name, data);
}
static void
-nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie)
+nv50_disp_dmac_object_detach(struct nvkm_object *parent, int cookie)
{
struct nv50_disp_base *base = (void *)parent->parent;
- nouveau_ramht_remove(base->ramht, cookie);
+ nvkm_ramht_remove(base->ramht, cookie);
}
static int
-nv50_disp_dmac_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 pushbuf, int head,
+nv50_disp_dmac_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 pushbuf, int head,
int length, void **pobject)
{
struct nv50_disp_dmac *dmac;
@@ -214,7 +217,7 @@ nv50_disp_dmac_create_(struct nouveau_object *parent,
if (ret)
return ret;
- dmac->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
+ dmac->pushdma = (void *)nvkm_handle_ref(parent, pushbuf);
if (!dmac->pushdma)
return -ENOENT;
@@ -243,15 +246,15 @@ nv50_disp_dmac_create_(struct nouveau_object *parent,
}
void
-nv50_disp_dmac_dtor(struct nouveau_object *object)
+nv50_disp_dmac_dtor(struct nvkm_object *object)
{
struct nv50_disp_dmac *dmac = (void *)object;
- nouveau_object_ref(NULL, (struct nouveau_object **)&dmac->pushdma);
+ nvkm_object_ref(NULL, (struct nvkm_object **)&dmac->pushdma);
nv50_disp_chan_destroy(&dmac->base);
}
static int
-nv50_disp_dmac_init(struct nouveau_object *object)
+nv50_disp_dmac_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *dmac = (void *)object;
@@ -284,7 +287,7 @@ nv50_disp_dmac_init(struct nouveau_object *object)
}
static int
-nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend)
+nv50_disp_dmac_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *dmac = (void *)object;
@@ -314,7 +317,7 @@ static void
nv50_disp_mthd_list(struct nv50_disp_priv *priv, int debug, u32 base, int c,
const struct nv50_disp_mthd_list *list, int inst)
{
- struct nouveau_object *disp = nv_object(priv);
+ struct nvkm_object *disp = nv_object(priv);
int i;
for (i = 0; list->data[i].mthd; i++) {
@@ -341,7 +344,7 @@ void
nv50_disp_mthd_chan(struct nv50_disp_priv *priv, int debug, int head,
const struct nv50_disp_mthd_chan *chan)
{
- struct nouveau_object *disp = nv_object(priv);
+ struct nvkm_object *disp = nv_object(priv);
const struct nv50_disp_impl *impl = (void *)disp->oclass;
const struct nv50_disp_mthd_list *list;
int i, j;
@@ -482,10 +485,10 @@ nv50_disp_core_mthd_chan = {
};
int
-nv50_disp_core_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_core_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_disp_core_channel_dma_v0 v0;
@@ -511,7 +514,7 @@ nv50_disp_core_ctor(struct nouveau_object *parent,
}
static int
-nv50_disp_core_init(struct nouveau_object *object)
+nv50_disp_core_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *mast = (void *)object;
@@ -548,7 +551,7 @@ nv50_disp_core_init(struct nouveau_object *object)
}
static int
-nv50_disp_core_fini(struct nouveau_object *object, bool suspend)
+nv50_disp_core_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_dmac *mast = (void *)object;
@@ -638,10 +641,10 @@ nv50_disp_base_mthd_chan = {
};
int
-nv50_disp_base_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_base_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_disp_base_channel_dma_v0 v0;
@@ -728,10 +731,10 @@ nv50_disp_ovly_mthd_chan = {
};
int
-nv50_disp_ovly_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_ovly_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_disp_overlay_channel_dma_v0 v0;
@@ -780,9 +783,9 @@ nv50_disp_ovly_ofuncs = {
******************************************************************************/
static int
-nv50_disp_pioc_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int head,
+nv50_disp_pioc_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int head,
int length, void **pobject)
{
return nv50_disp_chan_create_(parent, engine, oclass, head,
@@ -790,14 +793,14 @@ nv50_disp_pioc_create_(struct nouveau_object *parent,
}
void
-nv50_disp_pioc_dtor(struct nouveau_object *object)
+nv50_disp_pioc_dtor(struct nvkm_object *object)
{
struct nv50_disp_pioc *pioc = (void *)object;
nv50_disp_chan_destroy(&pioc->base);
}
static int
-nv50_disp_pioc_init(struct nouveau_object *object)
+nv50_disp_pioc_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_pioc *pioc = (void *)object;
@@ -826,7 +829,7 @@ nv50_disp_pioc_init(struct nouveau_object *object)
}
static int
-nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend)
+nv50_disp_pioc_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_pioc *pioc = (void *)object;
@@ -848,10 +851,10 @@ nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend)
******************************************************************************/
int
-nv50_disp_oimm_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_oimm_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_disp_overlay_v0 v0;
@@ -896,10 +899,10 @@ nv50_disp_oimm_ofuncs = {
******************************************************************************/
int
-nv50_disp_curs_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_curs_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_disp_cursor_v0 v0;
@@ -976,8 +979,7 @@ nv50_disp_main_scanoutpos(NV50_DISP_MTHD_V0)
}
int
-nv50_disp_main_mthd(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
+nv50_disp_main_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
const struct nv50_disp_impl *impl = (void *)nv_oclass(object->engine);
union {
@@ -1100,42 +1102,42 @@ nv50_disp_main_mthd(struct nouveau_object *object, u32 mthd,
}
int
-nv50_disp_main_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_main_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv = (void *)engine;
struct nv50_disp_base *base;
int ret;
- ret = nouveau_parent_create(parent, engine, oclass, 0,
- priv->sclass, 0, &base);
+ ret = nvkm_parent_create(parent, engine, oclass, 0,
+ priv->sclass, 0, &base);
*pobject = nv_object(base);
if (ret)
return ret;
- return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
- &base->ramht);
+ return nvkm_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
+ &base->ramht);
}
void
-nv50_disp_main_dtor(struct nouveau_object *object)
+nv50_disp_main_dtor(struct nvkm_object *object)
{
struct nv50_disp_base *base = (void *)object;
- nouveau_ramht_ref(NULL, &base->ramht);
- nouveau_parent_destroy(&base->base);
+ nvkm_ramht_ref(NULL, &base->ramht);
+ nvkm_parent_destroy(&base->base);
}
static int
-nv50_disp_main_init(struct nouveau_object *object)
+nv50_disp_main_init(struct nvkm_object *object)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_base *base = (void *)object;
int ret, i;
u32 tmp;
- ret = nouveau_parent_init(&base->base);
+ ret = nvkm_parent_init(&base->base);
if (ret)
return ret;
@@ -1196,7 +1198,7 @@ nv50_disp_main_init(struct nouveau_object *object)
}
static int
-nv50_disp_main_fini(struct nouveau_object *object, bool suspend)
+nv50_disp_main_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_disp_priv *priv = (void *)object->engine;
struct nv50_disp_base *base = (void *)object;
@@ -1205,26 +1207,26 @@ nv50_disp_main_fini(struct nouveau_object *object, bool suspend)
nv_wr32(priv, 0x610024, 0x00000000);
nv_wr32(priv, 0x610020, 0x00000000);
- return nouveau_parent_fini(&base->base, suspend);
+ return nvkm_parent_fini(&base->base, suspend);
}
-struct nouveau_ofuncs
+struct nvkm_ofuncs
nv50_disp_main_ofuncs = {
.ctor = nv50_disp_main_ctor,
.dtor = nv50_disp_main_dtor,
.init = nv50_disp_main_init,
.fini = nv50_disp_main_fini,
.mthd = nv50_disp_main_mthd,
- .ntfy = nouveau_disp_ntfy,
+ .ntfy = nvkm_disp_ntfy,
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_disp_main_oclass[] = {
{ NV50_DISP, &nv50_disp_main_ofuncs },
{}
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_disp_sclass[] = {
{ NV50_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
{ NV50_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
@@ -1240,13 +1242,13 @@ nv50_disp_sclass[] = {
******************************************************************************/
static int
-nv50_disp_data_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_data_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv = (void *)engine;
- struct nouveau_engctx *ectx;
+ struct nvkm_engctx *ectx;
int ret = -EBUSY;
/* no context needed for channel objects... */
@@ -1259,25 +1261,24 @@ nv50_disp_data_ctor(struct nouveau_object *parent,
/* allocate display hardware to client */
mutex_lock(&nv_subdev(priv)->mutex);
if (list_empty(&nv_engine(priv)->contexts)) {
- ret = nouveau_engctx_create(parent, engine, oclass, NULL,
- 0x10000, 0x10000,
- NVOBJ_FLAG_HEAP, &ectx);
+ ret = nvkm_engctx_create(parent, engine, oclass, NULL, 0x10000,
+ 0x10000, NVOBJ_FLAG_HEAP, &ectx);
*pobject = nv_object(ectx);
}
mutex_unlock(&nv_subdev(priv)->mutex);
return ret;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv50_disp_cclass = {
.handle = NV_ENGCTX(DISP, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_disp_data_ctor,
- .dtor = _nouveau_engctx_dtor,
- .init = _nouveau_engctx_init,
- .fini = _nouveau_engctx_fini,
- .rd32 = _nouveau_engctx_rd32,
- .wr32 = _nouveau_engctx_wr32,
+ .dtor = _nvkm_engctx_dtor,
+ .init = _nvkm_engctx_init,
+ .fini = _nvkm_engctx_fini,
+ .rd32 = _nvkm_engctx_rd32,
+ .wr32 = _nvkm_engctx_wr32,
},
};
@@ -1288,25 +1289,25 @@ nv50_disp_cclass = {
static void
nv50_disp_vblank_fini(struct nvkm_event *event, int type, int head)
{
- struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
+ struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
nv_mask(disp, 0x61002c, (4 << head), 0);
}
static void
nv50_disp_vblank_init(struct nvkm_event *event, int type, int head)
{
- struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
+ struct nvkm_disp *disp = container_of(event, typeof(*disp), vblank);
nv_mask(disp, 0x61002c, (4 << head), (4 << head));
}
const struct nvkm_event_func
nv50_disp_vblank_func = {
- .ctor = nouveau_disp_vblank_ctor,
+ .ctor = nvkm_disp_vblank_ctor,
.init = nv50_disp_vblank_init,
.fini = nv50_disp_vblank_fini,
};
-static const struct nouveau_enum
+static const struct nvkm_enum
nv50_disp_intr_error_type[] = {
{ 3, "ILLEGAL_MTHD" },
{ 4, "INVALID_VALUE" },
@@ -1315,7 +1316,7 @@ nv50_disp_intr_error_type[] = {
{}
};
-static const struct nouveau_enum
+static const struct nvkm_enum
nv50_disp_intr_error_code[] = {
{ 0x00, "" },
{}
@@ -1330,14 +1331,14 @@ nv50_disp_intr_error(struct nv50_disp_priv *priv, int chid)
u32 code = (addr & 0x00ff0000) >> 16;
u32 type = (addr & 0x00007000) >> 12;
u32 mthd = (addr & 0x00000ffc);
- const struct nouveau_enum *ec, *et;
+ const struct nvkm_enum *ec, *et;
char ecunk[6], etunk[6];
- et = nouveau_enum_find(nv50_disp_intr_error_type, type);
+ et = nvkm_enum_find(nv50_disp_intr_error_type, type);
if (!et)
snprintf(etunk, sizeof(etunk), "UNK%02X", type);
- ec = nouveau_enum_find(nv50_disp_intr_error_code, code);
+ ec = nvkm_enum_find(nv50_disp_intr_error_code, code);
if (!ec)
snprintf(ecunk, sizeof(ecunk), "UNK%02X", code);
@@ -1385,7 +1386,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl,
u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_outp *info)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvkm_output *outp;
u16 mask, type;
@@ -1440,7 +1441,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl,
static struct nvkm_output *
exec_script(struct nv50_disp_priv *priv, int head, int id)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvkm_output *outp;
struct nvbios_outp info;
u8 ver, hdr, cnt, len;
@@ -1497,7 +1498,7 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
static struct nvkm_output *
exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvkm_output *outp;
struct nvbios_outp info1;
struct nvbios_ocfg info2;
@@ -1610,7 +1611,7 @@ nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head)
struct nvkm_output_dp *outpdp = (void *)outp;
struct nvbios_init init = {
.subdev = nv_subdev(priv),
- .bios = nouveau_bios(priv),
+ .bios = nvkm_bios(priv),
.outp = &outp->info,
.crtc = head,
.offset = outpdp->info.script[4],
@@ -1625,7 +1626,7 @@ nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head)
static void
nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head)
{
- struct nouveau_devinit *devinit = nouveau_devinit(priv);
+ struct nvkm_devinit *devinit = nvkm_devinit(priv);
u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
if (pclk)
devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
@@ -1841,9 +1842,10 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head)
* programmed for DisplayPort.
*/
static void
-nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp)
+nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv,
+ struct dcb_output *outp)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
const int link = !(outp->sorconf.link & 1);
const int or = ffs(outp->or) - 1;
const u32 loff = (or * 0x800) + (link * 0x80);
@@ -1920,7 +1922,7 @@ nv50_disp_intr_supervisor(struct work_struct *work)
}
void
-nv50_disp_intr(struct nouveau_subdev *subdev)
+nv50_disp_intr(struct nvkm_subdev *subdev)
{
struct nv50_disp_priv *priv = (void *)subdev;
u32 intr0 = nv_rd32(priv, 0x610020);
@@ -1939,13 +1941,13 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
}
if (intr1 & 0x00000004) {
- nouveau_disp_vblank(&priv->base, 0);
+ nvkm_disp_vblank(&priv->base, 0);
nv_wr32(priv, 0x610024, 0x00000004);
intr1 &= ~0x00000004;
}
if (intr1 & 0x00000008) {
- nouveau_disp_vblank(&priv->base, 1);
+ nvkm_disp_vblank(&priv->base, 1);
nv_wr32(priv, 0x610024, 0x00000008);
intr1 &= ~0x00000008;
}
@@ -1959,15 +1961,15 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
}
static int
-nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_disp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
- ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
- "display", &priv);
+ ret = nvkm_disp_create(parent, engine, oclass, 2, "PDISP",
+ "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -1992,20 +1994,20 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv50_disp_outp_sclass[] = {
&nv50_pior_dp_impl.base.base,
NULL
};
-struct nouveau_oclass *
+struct nvkm_oclass *
nv50_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x50),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_disp_ctor,
- .dtor = _nouveau_disp_dtor,
- .init = _nouveau_disp_init,
- .fini = _nouveau_disp_fini,
+ .dtor = _nvkm_disp_dtor,
+ .init = _nvkm_disp_init,
+ .fini = _nvkm_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
.base.outp = nv50_disp_outp_sclass,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
new file mode 100644
index 000000000000..b4ed620070fa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
@@ -0,0 +1,226 @@
+#ifndef __NV50_DISP_H__
+#define __NV50_DISP_H__
+#include "priv.h"
+struct nvkm_output;
+struct nvkm_output_dp;
+
+#define NV50_DISP_MTHD_ struct nvkm_object *object, \
+ struct nv50_disp_priv *priv, void *data, u32 size
+#define NV50_DISP_MTHD_V0 NV50_DISP_MTHD_, int head
+#define NV50_DISP_MTHD_V1 NV50_DISP_MTHD_, int head, struct nvkm_output *outp
+
+struct nv50_disp_priv {
+ struct nvkm_disp base;
+ struct nvkm_oclass *sclass;
+
+ struct work_struct supervisor;
+ u32 super;
+
+ struct nvkm_event uevent;
+
+ struct {
+ int nr;
+ } head;
+ struct {
+ int nr;
+ int (*power)(NV50_DISP_MTHD_V1);
+ int (*sense)(NV50_DISP_MTHD_V1);
+ } dac;
+ struct {
+ int nr;
+ int (*power)(NV50_DISP_MTHD_V1);
+ int (*hda_eld)(NV50_DISP_MTHD_V1);
+ int (*hdmi)(NV50_DISP_MTHD_V1);
+ u32 lvdsconf;
+ void (*magic)(struct nvkm_output *);
+ } sor;
+ struct {
+ int nr;
+ int (*power)(NV50_DISP_MTHD_V1);
+ u8 type[3];
+ } pior;
+};
+
+struct nv50_disp_impl {
+ struct nvkm_disp_impl base;
+ struct {
+ const struct nv50_disp_mthd_chan *core;
+ const struct nv50_disp_mthd_chan *base;
+ const struct nv50_disp_mthd_chan *ovly;
+ int prev;
+ } mthd;
+ struct {
+ int (*scanoutpos)(NV50_DISP_MTHD_V0);
+ } head;
+};
+
+int nv50_disp_main_scanoutpos(NV50_DISP_MTHD_V0);
+int nv50_disp_main_mthd(struct nvkm_object *, u32, void *, u32);
+
+int gf110_disp_main_scanoutpos(NV50_DISP_MTHD_V0);
+
+int nv50_dac_power(NV50_DISP_MTHD_V1);
+int nv50_dac_sense(NV50_DISP_MTHD_V1);
+
+int gt215_hda_eld(NV50_DISP_MTHD_V1);
+int gf110_hda_eld(NV50_DISP_MTHD_V1);
+
+int g84_hdmi_ctrl(NV50_DISP_MTHD_V1);
+int gt215_hdmi_ctrl(NV50_DISP_MTHD_V1);
+int gf110_hdmi_ctrl(NV50_DISP_MTHD_V1);
+int gk104_hdmi_ctrl(NV50_DISP_MTHD_V1);
+
+int nv50_sor_power(NV50_DISP_MTHD_V1);
+int nv50_pior_power(NV50_DISP_MTHD_V1);
+
+#include <core/parent.h>
+
+struct nv50_disp_base {
+ struct nvkm_parent base;
+ struct nvkm_ramht *ramht;
+ u32 chan;
+};
+
+struct nv50_disp_chan_impl {
+ struct nvkm_ofuncs base;
+ int chid;
+ int (*attach)(struct nvkm_object *, struct nvkm_object *, u32);
+ void (*detach)(struct nvkm_object *, int);
+};
+
+#include <core/namedb.h>
+
+struct nv50_disp_chan {
+ struct nvkm_namedb base;
+ int chid;
+};
+
+int nv50_disp_chan_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
+int nv50_disp_chan_map(struct nvkm_object *, u64 *, u32 *);
+u32 nv50_disp_chan_rd32(struct nvkm_object *, u64);
+void nv50_disp_chan_wr32(struct nvkm_object *, u64, u32);
+extern const struct nvkm_event_func nv50_disp_chan_uevent;
+int nv50_disp_chan_uevent_ctor(struct nvkm_object *, void *, u32,
+ struct nvkm_notify *);
+void nv50_disp_chan_uevent_send(struct nv50_disp_priv *, int);
+
+extern const struct nvkm_event_func gf110_disp_chan_uevent;
+
+#define nv50_disp_chan_init(a) \
+ nvkm_namedb_init(&(a)->base)
+#define nv50_disp_chan_fini(a,b) \
+ nvkm_namedb_fini(&(a)->base, (b))
+
+struct nv50_disp_dmac {
+ struct nv50_disp_chan base;
+ struct nvkm_dmaobj *pushdma;
+ u32 push;
+};
+
+void nv50_disp_dmac_dtor(struct nvkm_object *);
+
+struct nv50_disp_pioc {
+ struct nv50_disp_chan base;
+};
+
+void nv50_disp_pioc_dtor(struct nvkm_object *);
+
+struct nv50_disp_mthd_list {
+ u32 mthd;
+ u32 addr;
+ struct {
+ u32 mthd;
+ u32 addr;
+ const char *name;
+ } data[];
+};
+
+struct nv50_disp_mthd_chan {
+ const char *name;
+ u32 addr;
+ struct {
+ const char *name;
+ int nr;
+ const struct nv50_disp_mthd_list *mthd;
+ } data[];
+};
+
+extern struct nv50_disp_chan_impl nv50_disp_core_ofuncs;
+int nv50_disp_core_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_base;
+extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_sor;
+extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_pior;
+extern struct nv50_disp_chan_impl nv50_disp_base_ofuncs;
+int nv50_disp_base_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+extern const struct nv50_disp_mthd_list nv50_disp_base_mthd_image;
+extern struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs;
+int nv50_disp_ovly_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+extern const struct nv50_disp_mthd_list nv50_disp_ovly_mthd_base;
+extern struct nv50_disp_chan_impl nv50_disp_oimm_ofuncs;
+int nv50_disp_oimm_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+extern struct nv50_disp_chan_impl nv50_disp_curs_ofuncs;
+int nv50_disp_curs_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+extern struct nvkm_ofuncs nv50_disp_main_ofuncs;
+int nv50_disp_main_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv50_disp_main_dtor(struct nvkm_object *);
+extern struct nvkm_omthds nv50_disp_main_omthds[];
+extern struct nvkm_oclass nv50_disp_cclass;
+void nv50_disp_mthd_chan(struct nv50_disp_priv *, int debug, int head,
+ const struct nv50_disp_mthd_chan *);
+void nv50_disp_intr_supervisor(struct work_struct *);
+void nv50_disp_intr(struct nvkm_subdev *);
+extern const struct nvkm_event_func nv50_disp_vblank_func;
+
+extern const struct nv50_disp_mthd_chan g84_disp_core_mthd_chan;
+extern const struct nv50_disp_mthd_list g84_disp_core_mthd_dac;
+extern const struct nv50_disp_mthd_list g84_disp_core_mthd_head;
+extern const struct nv50_disp_mthd_chan g84_disp_base_mthd_chan;
+extern const struct nv50_disp_mthd_chan g84_disp_ovly_mthd_chan;
+
+extern const struct nv50_disp_mthd_chan g94_disp_core_mthd_chan;
+
+extern struct nv50_disp_chan_impl gf110_disp_core_ofuncs;
+extern const struct nv50_disp_mthd_list gf110_disp_core_mthd_base;
+extern const struct nv50_disp_mthd_list gf110_disp_core_mthd_dac;
+extern const struct nv50_disp_mthd_list gf110_disp_core_mthd_sor;
+extern const struct nv50_disp_mthd_list gf110_disp_core_mthd_pior;
+extern struct nv50_disp_chan_impl gf110_disp_base_ofuncs;
+extern struct nv50_disp_chan_impl gf110_disp_ovly_ofuncs;
+extern const struct nv50_disp_mthd_chan gf110_disp_base_mthd_chan;
+extern struct nv50_disp_chan_impl gf110_disp_oimm_ofuncs;
+extern struct nv50_disp_chan_impl gf110_disp_curs_ofuncs;
+extern struct nvkm_ofuncs gf110_disp_main_ofuncs;
+extern struct nvkm_oclass gf110_disp_cclass;
+void gf110_disp_intr_supervisor(struct work_struct *);
+void gf110_disp_intr(struct nvkm_subdev *);
+extern const struct nvkm_event_func gf110_disp_vblank_func;
+
+extern const struct nv50_disp_mthd_chan gk104_disp_core_mthd_chan;
+extern const struct nv50_disp_mthd_chan gk104_disp_ovly_mthd_chan;
+
+extern struct nvkm_output_dp_impl nv50_pior_dp_impl;
+extern struct nvkm_oclass *nv50_disp_outp_sclass[];
+
+extern struct nvkm_output_dp_impl g94_sor_dp_impl;
+int g94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int);
+extern struct nvkm_oclass *g94_disp_outp_sclass[];
+
+extern struct nvkm_output_dp_impl gf110_sor_dp_impl;
+int gf110_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
+extern struct nvkm_oclass *gf110_disp_outp_sclass[];
+
+void gm204_sor_magic(struct nvkm_output *outp);
+extern struct nvkm_output_dp_impl gm204_sor_dp_impl;
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
index bbd9b6fdc90f..9224bcbf0159 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
@@ -21,57 +21,58 @@
*
* Authors: Ben Skeggs
*/
+#include "outp.h"
+#include "priv.h"
-#include <subdev/i2c.h>
#include <subdev/bios.h>
#include <subdev/bios/conn.h>
-
-#include "outp.h"
+#include <subdev/bios/dcb.h>
+#include <subdev/i2c.h>
int
-_nvkm_output_fini(struct nouveau_object *object, bool suspend)
+_nvkm_output_fini(struct nvkm_object *object, bool suspend)
{
struct nvkm_output *outp = (void *)object;
nv_ofuncs(outp->conn)->fini(nv_object(outp->conn), suspend);
- return nouveau_object_fini(&outp->base, suspend);
+ return nvkm_object_fini(&outp->base, suspend);
}
int
-_nvkm_output_init(struct nouveau_object *object)
+_nvkm_output_init(struct nvkm_object *object)
{
struct nvkm_output *outp = (void *)object;
- int ret = nouveau_object_init(&outp->base);
+ int ret = nvkm_object_init(&outp->base);
if (ret == 0)
nv_ofuncs(outp->conn)->init(nv_object(outp->conn));
return 0;
}
void
-_nvkm_output_dtor(struct nouveau_object *object)
+_nvkm_output_dtor(struct nvkm_object *object)
{
struct nvkm_output *outp = (void *)object;
list_del(&outp->head);
- nouveau_object_ref(NULL, (void *)&outp->conn);
- nouveau_object_destroy(&outp->base);
+ nvkm_object_ref(NULL, (void *)&outp->conn);
+ nvkm_object_destroy(&outp->base);
}
int
-nvkm_output_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
+nvkm_output_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass,
struct dcb_output *dcbE, int index,
int length, void **pobject)
{
- struct nouveau_bios *bios = nouveau_bios(engine);
- struct nouveau_i2c *i2c = nouveau_i2c(parent);
- struct nouveau_disp *disp = (void *)engine;
+ struct nvkm_disp *disp = nvkm_disp(parent);
+ struct nvkm_bios *bios = nvkm_bios(parent);
+ struct nvkm_i2c *i2c = nvkm_i2c(parent);
struct nvbios_connE connE;
struct nvkm_output *outp;
u8 ver, hdr;
u32 data;
int ret;
- ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, 0, length, pobject);
outp = *pobject;
if (ret)
return ret;
@@ -98,9 +99,9 @@ nvkm_output_create_(struct nouveau_object *parent,
connE.type = DCB_CONNECTOR_NONE;
}
- ret = nouveau_object_ctor(parent, engine, nvkm_connector_oclass,
- &connE, outp->info.connector,
- (struct nouveau_object **)&outp->conn);
+ ret = nvkm_object_ctor(parent, NULL, nvkm_connector_oclass,
+ &connE, outp->info.connector,
+ (struct nvkm_object **)&outp->conn);
if (ret < 0) {
ERR("error %d creating connector, disabling\n", ret);
return ret;
@@ -111,10 +112,10 @@ nvkm_output_create_(struct nouveau_object *parent,
}
int
-_nvkm_output_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *dcbE, u32 index,
- struct nouveau_object **pobject)
+_nvkm_output_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *dcbE, u32 index,
+ struct nvkm_object **pobject)
{
struct nvkm_output *outp;
int ret;
@@ -127,11 +128,11 @@ _nvkm_output_ctor(struct nouveau_object *parent,
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nvkm_output_oclass = &(struct nvkm_output_impl) {
.base = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_output_ctor,
.dtor = _nvkm_output_dtor,
.init = _nvkm_output_init,
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
index 187f435ad0e2..d9253d26c31b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/outp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
@@ -1,18 +1,20 @@
#ifndef __NVKM_DISP_OUTP_H__
#define __NVKM_DISP_OUTP_H__
+#include <core/object.h>
-#include "priv.h"
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
struct nvkm_output {
- struct nouveau_object base;
+ struct nvkm_object base;
struct list_head head;
struct dcb_output info;
int index;
int or;
- struct nouveau_i2c_port *port;
- struct nouveau_i2c_port *edid;
+ struct nvkm_i2c_port *port;
+ struct nvkm_i2c_port *edid;
struct nvkm_connector *conn;
};
@@ -32,29 +34,28 @@ struct nvkm_output {
_nvkm_output_fini(nv_object(_outp), (s)); \
})
-int nvkm_output_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, struct dcb_output *,
+int nvkm_output_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, struct dcb_output *,
int, int, void **);
-int _nvkm_output_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void _nvkm_output_dtor(struct nouveau_object *);
-int _nvkm_output_init(struct nouveau_object *);
-int _nvkm_output_fini(struct nouveau_object *, bool);
+int _nvkm_output_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void _nvkm_output_dtor(struct nvkm_object *);
+int _nvkm_output_init(struct nvkm_object *);
+int _nvkm_output_fini(struct nvkm_object *, bool);
struct nvkm_output_impl {
- struct nouveau_oclass base;
+ struct nvkm_oclass base;
};
#ifndef MSG
#define MSG(l,f,a...) do { \
struct nvkm_output *_outp = (void *)outp; \
- nv_##l(nv_object(outp)->engine, "%02x:%04x:%04x: "f, _outp->index, \
+ nv_##l(_outp, "%02x:%04x:%04x: "f, _outp->index, \
_outp->info.hasht, _outp->info.hashm, ##a); \
} while(0)
#define DBG(f,a...) MSG(debug, f, ##a)
#define ERR(f,a...) MSG(error, f, ##a)
#endif
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.c
index 667a9070e006..0bde0fa5b59d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/os.h>
-#include <nvif/event.h>
-
-#include <subdev/i2c.h>
-
#include "outpdp.h"
#include "conn.h"
#include "dport.h"
+#include "priv.h"
+
+#include <subdev/i2c.h>
+
+#include <nvif/event.h>
int
nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
@@ -105,17 +104,17 @@ done:
static void
nvkm_output_dp_enable(struct nvkm_output_dp *outp, bool present)
{
- struct nouveau_i2c_port *port = outp->base.edid;
+ struct nvkm_i2c_port *port = outp->base.edid;
if (present) {
if (!outp->present) {
- nouveau_i2c(port)->acquire_pad(port, 0);
+ nvkm_i2c(port)->acquire_pad(port, 0);
DBG("aux power -> always\n");
outp->present = true;
}
nvkm_output_dp_train(&outp->base, 0, true);
} else {
if (outp->present) {
- nouveau_i2c(port)->release_pad(port);
+ nvkm_i2c(port)->release_pad(port);
DBG("aux power -> demand\n");
outp->present = false;
}
@@ -126,13 +125,13 @@ nvkm_output_dp_enable(struct nvkm_output_dp *outp, bool present)
static void
nvkm_output_dp_detect(struct nvkm_output_dp *outp)
{
- struct nouveau_i2c_port *port = outp->base.edid;
- int ret = nouveau_i2c(port)->acquire_pad(port, 0);
+ struct nvkm_i2c_port *port = outp->base.edid;
+ int ret = nvkm_i2c(port)->acquire_pad(port, 0);
if (ret == 0) {
ret = nv_rdaux(outp->base.edid, DPCD_RC00_DPCD_REV,
outp->dpcd, sizeof(outp->dpcd));
nvkm_output_dp_enable(outp, ret == 0);
- nouveau_i2c(port)->release_pad(port);
+ nvkm_i2c(port)->release_pad(port);
}
}
@@ -141,7 +140,7 @@ nvkm_output_dp_hpd(struct nvkm_notify *notify)
{
struct nvkm_connector *conn = container_of(notify, typeof(*conn), hpd);
struct nvkm_output_dp *outp;
- struct nouveau_disp *disp = nouveau_disp(conn);
+ struct nvkm_disp *disp = nvkm_disp(conn);
const struct nvkm_i2c_ntfy_rep *line = notify->data;
struct nvif_notify_conn_rep_v0 rep = {};
@@ -170,7 +169,7 @@ static int
nvkm_output_dp_irq(struct nvkm_notify *notify)
{
struct nvkm_output_dp *outp = container_of(notify, typeof(*outp), irq);
- struct nouveau_disp *disp = nouveau_disp(outp);
+ struct nvkm_disp *disp = nvkm_disp(outp);
const struct nvkm_i2c_ntfy_rep *line = notify->data;
struct nvif_notify_conn_rep_v0 rep = {
.mask = NVIF_NOTIFY_CONN_V0_IRQ,
@@ -185,7 +184,7 @@ nvkm_output_dp_irq(struct nvkm_notify *notify)
}
int
-_nvkm_output_dp_fini(struct nouveau_object *object, bool suspend)
+_nvkm_output_dp_fini(struct nvkm_object *object, bool suspend)
{
struct nvkm_output_dp *outp = (void *)object;
nvkm_notify_put(&outp->irq);
@@ -194,7 +193,7 @@ _nvkm_output_dp_fini(struct nouveau_object *object, bool suspend)
}
int
-_nvkm_output_dp_init(struct nouveau_object *object)
+_nvkm_output_dp_init(struct nvkm_object *object)
{
struct nvkm_output_dp *outp = (void *)object;
nvkm_output_dp_detect(outp);
@@ -202,7 +201,7 @@ _nvkm_output_dp_init(struct nouveau_object *object)
}
void
-_nvkm_output_dp_dtor(struct nouveau_object *object)
+_nvkm_output_dp_dtor(struct nvkm_object *object)
{
struct nvkm_output_dp *outp = (void *)object;
nvkm_notify_fini(&outp->irq);
@@ -210,14 +209,14 @@ _nvkm_output_dp_dtor(struct nouveau_object *object)
}
int
-nvkm_output_dp_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
+nvkm_output_dp_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass,
struct dcb_output *info, int index,
int length, void **pobject)
{
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nouveau_i2c *i2c = nouveau_i2c(parent);
+ struct nvkm_bios *bios = nvkm_bios(parent);
+ struct nvkm_i2c *i2c = nvkm_i2c(parent);
struct nvkm_output_dp *outp;
u8 hdr, cnt, len;
u32 data;
@@ -249,7 +248,7 @@ nvkm_output_dp_create_(struct nouveau_object *parent,
DBG("bios dp %02x %02x %02x %02x\n", outp->version, hdr, cnt, len);
/* link training */
- INIT_WORK(&outp->lt.work, nouveau_dp_train);
+ INIT_WORK(&outp->lt.work, nvkm_dp_train);
init_waitqueue_head(&outp->lt.wait);
atomic_set(&outp->lt.done, 0);
@@ -285,10 +284,10 @@ nvkm_output_dp_create_(struct nouveau_object *parent,
}
int
-_nvkm_output_dp_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *info, u32 index,
- struct nouveau_object **pobject)
+_nvkm_output_dp_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *info, u32 index,
+ struct nvkm_object **pobject)
{
struct nvkm_output_dp *outp;
int ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
index 1fac367cc867..70c77aec4850 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
@@ -1,11 +1,11 @@
#ifndef __NVKM_DISP_OUTP_DP_H__
#define __NVKM_DISP_OUTP_DP_H__
+#include "outp.h"
+#include <core/notify.h>
#include <subdev/bios.h>
#include <subdev/bios/dp.h>
-#include "outp.h"
-
struct nvkm_output_dp {
struct nvkm_output base;
@@ -38,16 +38,16 @@ struct nvkm_output_dp {
_nvkm_output_dp_fini(nv_object(_outp), (s)); \
})
-int nvkm_output_dp_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, struct dcb_output *,
+int nvkm_output_dp_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, struct dcb_output *,
int, int, void **);
-int _nvkm_output_dp_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void _nvkm_output_dp_dtor(struct nouveau_object *);
-int _nvkm_output_dp_init(struct nouveau_object *);
-int _nvkm_output_dp_fini(struct nouveau_object *, bool);
+int _nvkm_output_dp_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void _nvkm_output_dp_dtor(struct nvkm_object *);
+int _nvkm_output_dp_init(struct nvkm_object *);
+int _nvkm_output_dp_fini(struct nvkm_object *, bool);
struct nvkm_output_dp_impl {
struct nvkm_output_impl base;
@@ -58,5 +58,4 @@ struct nvkm_output_dp_impl {
};
int nvkm_output_dp_train(struct nvkm_output *, u32 rate, bool wait);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
index d00f89a468a7..2a1d8871bf82 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
@@ -21,29 +21,27 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outpdp.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
-#include <subdev/timer.h>
#include <subdev/i2c.h>
+#include <subdev/timer.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
/******************************************************************************
* TMDS
*****************************************************************************/
static int
-nv50_pior_tmds_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *info, u32 index,
- struct nouveau_object **pobject)
+nv50_pior_tmds_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *info, u32 index,
+ struct nvkm_object **pobject)
{
- struct nouveau_i2c *i2c = nouveau_i2c(parent);
+ struct nvkm_i2c *i2c = nvkm_i2c(parent);
struct nvkm_output *outp;
int ret;
@@ -59,7 +57,7 @@ nv50_pior_tmds_ctor(struct nouveau_object *parent,
struct nvkm_output_impl
nv50_pior_tmds_impl = {
.base.handle = DCB_OUTPUT_TMDS | 0x0100,
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_pior_tmds_ctor,
.dtor = _nvkm_output_dtor,
.init = _nvkm_output_init,
@@ -74,7 +72,7 @@ nv50_pior_tmds_impl = {
static int
nv50_pior_dp_pattern(struct nvkm_output_dp *outp, int pattern)
{
- struct nouveau_i2c_port *port = outp->base.edid;
+ struct nvkm_i2c_port *port = outp->base.edid;
if (port && port->func->pattern)
return port->func->pattern(port, pattern);
return port ? 0 : -ENODEV;
@@ -89,7 +87,7 @@ nv50_pior_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
static int
nv50_pior_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
{
- struct nouveau_i2c_port *port = outp->base.edid;
+ struct nvkm_i2c_port *port = outp->base.edid;
if (port && port->func->lnk_ctl)
return port->func->lnk_ctl(port, nr, bw, ef);
return port ? 0 : -ENODEV;
@@ -98,19 +96,19 @@ nv50_pior_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
static int
nv50_pior_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
{
- struct nouveau_i2c_port *port = outp->base.edid;
+ struct nvkm_i2c_port *port = outp->base.edid;
if (port && port->func->drv_ctl)
return port->func->drv_ctl(port, ln, vs, pe);
return port ? 0 : -ENODEV;
}
static int
-nv50_pior_dp_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *info, u32 index,
- struct nouveau_object **pobject)
+nv50_pior_dp_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *info, u32 index,
+ struct nvkm_object **pobject)
{
- struct nouveau_i2c *i2c = nouveau_i2c(parent);
+ struct nvkm_i2c *i2c = nvkm_i2c(parent);
struct nvkm_output_dp *outp;
int ret;
@@ -127,7 +125,7 @@ nv50_pior_dp_ctor(struct nouveau_object *parent,
struct nvkm_output_dp_impl
nv50_pior_dp_impl = {
.base.base.handle = DCB_OUTPUT_DP | 0x0010,
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_pior_dp_ctor,
.dtor = _nvkm_output_dp_dtor,
.init = _nvkm_output_dp_init,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
new file mode 100644
index 000000000000..961ce8bb2135
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
@@ -0,0 +1,42 @@
+#ifndef __NVKM_DISP_PRIV_H__
+#define __NVKM_DISP_PRIV_H__
+#include <engine/disp.h>
+
+struct nvkm_disp_impl {
+ struct nvkm_oclass base;
+ struct nvkm_oclass **outp;
+ struct nvkm_oclass **conn;
+ const struct nvkm_event_func *vblank;
+};
+
+#define nvkm_disp_create(p,e,c,h,i,x,d) \
+ nvkm_disp_create_((p), (e), (c), (h), (i), (x), \
+ sizeof(**d), (void **)d)
+#define nvkm_disp_destroy(d) ({ \
+ struct nvkm_disp *disp = (d); \
+ _nvkm_disp_dtor(nv_object(disp)); \
+})
+#define nvkm_disp_init(d) ({ \
+ struct nvkm_disp *disp = (d); \
+ _nvkm_disp_init(nv_object(disp)); \
+})
+#define nvkm_disp_fini(d,s) ({ \
+ struct nvkm_disp *disp = (d); \
+ _nvkm_disp_fini(nv_object(disp), (s)); \
+})
+
+int nvkm_disp_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int heads,
+ const char *, const char *, int, void **);
+void _nvkm_disp_dtor(struct nvkm_object *);
+int _nvkm_disp_init(struct nvkm_object *);
+int _nvkm_disp_fini(struct nvkm_object *, bool);
+
+extern struct nvkm_oclass *nvkm_output_oclass;
+extern struct nvkm_oclass *nvkm_connector_oclass;
+
+int nvkm_disp_vblank_ctor(struct nvkm_object *, void *data, u32 size,
+ struct nvkm_notify *);
+void nvkm_disp_vblank(struct nvkm_disp *, int head);
+int nvkm_disp_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
index 39f85d627336..8918da7ffdf2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
@@ -21,59 +21,53 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/os.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
-#include <subdev/bios/dp.h>
-#include <subdev/bios/init.h>
-#include <subdev/timer.h>
-
#include "nv50.h"
#include "outpdp.h"
+#include <core/device.h>
+#include <subdev/timer.h>
+
static inline u32
-nv94_sor_soff(struct nvkm_output_dp *outp)
+g94_sor_soff(struct nvkm_output_dp *outp)
{
return (ffs(outp->base.info.or) - 1) * 0x800;
}
static inline u32
-nv94_sor_loff(struct nvkm_output_dp *outp)
+g94_sor_loff(struct nvkm_output_dp *outp)
{
- return nv94_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
+ return g94_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
}
static inline u32
-nv94_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
+g94_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
{
- static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
- static const u8 nv94[] = { 16, 8, 0, 24 };
+ static const u8 mcp89[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
+ static const u8 g94[] = { 16, 8, 0, 24 };
if (nv_device(priv)->chipset == 0xaf)
- return nvaf[lane];
- return nv94[lane];
+ return mcp89[lane];
+ return g94[lane];
}
static int
-nv94_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+g94_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- const u32 loff = nv94_sor_loff(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ const u32 loff = g94_sor_loff(outp);
nv_mask(priv, 0x61c10c + loff, 0x0f000000, pattern << 24);
return 0;
}
int
-nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
+g94_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- const u32 soff = nv94_sor_soff(outp);
- const u32 loff = nv94_sor_loff(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ const u32 soff = g94_sor_soff(outp);
+ const u32 loff = g94_sor_loff(outp);
u32 mask = 0, i;
for (i = 0; i < nr; i++)
- mask |= 1 << (nv94_sor_dp_lane_map(priv, i) >> 3);
+ mask |= 1 << (g94_sor_dp_lane_map(priv, i) >> 3);
nv_mask(priv, 0x61c130 + loff, 0x0000000f, mask);
nv_mask(priv, 0x61c034 + soff, 0x80000000, 0x80000000);
@@ -82,11 +76,11 @@ nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
}
static int
-nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
+g94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- const u32 soff = nv94_sor_soff(outp);
- const u32 loff = nv94_sor_loff(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ const u32 soff = g94_sor_soff(outp);
+ const u32 loff = g94_sor_loff(outp);
u32 dpctrl = 0x00000000;
u32 clksor = 0x00000000;
@@ -102,12 +96,12 @@ nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
}
static int
-nv94_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
+g94_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- struct nouveau_bios *bios = nouveau_bios(priv);
- const u32 shift = nv94_sor_dp_lane_map(priv, ln);
- const u32 loff = nv94_sor_loff(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ struct nvkm_bios *bios = nvkm_bios(priv);
+ const u32 shift = g94_sor_dp_lane_map(priv, ln);
+ const u32 loff = g94_sor_loff(outp);
u32 addr, data[3];
u8 ver, hdr, cnt, len;
struct nvbios_dpout info;
@@ -136,16 +130,16 @@ nv94_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
}
struct nvkm_output_dp_impl
-nv94_sor_dp_impl = {
+g94_sor_dp_impl = {
.base.base.handle = DCB_OUTPUT_DP,
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_output_dp_ctor,
.dtor = _nvkm_output_dp_dtor,
.init = _nvkm_output_dp_init,
.fini = _nvkm_output_dp_fini,
},
- .pattern = nv94_sor_dp_pattern,
- .lnk_pwr = nv94_sor_dp_lnk_pwr,
- .lnk_ctl = nv94_sor_dp_lnk_ctl,
- .drv_ctl = nv94_sor_dp_drv_ctl,
+ .pattern = g94_sor_dp_pattern,
+ .lnk_pwr = g94_sor_dp_lnk_pwr,
+ .lnk_ctl = g94_sor_dp_lnk_ctl,
+ .drv_ctl = g94_sor_dp_drv_ctl,
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf110.c
index fdab2939070c..52fbe4880e13 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf110.c
@@ -21,51 +21,43 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/os.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
-#include <subdev/bios/dp.h>
-#include <subdev/bios/init.h>
-#include <subdev/timer.h>
-
#include "nv50.h"
+#include "outpdp.h"
static inline u32
-nvd0_sor_soff(struct nvkm_output_dp *outp)
+gf110_sor_soff(struct nvkm_output_dp *outp)
{
return (ffs(outp->base.info.or) - 1) * 0x800;
}
static inline u32
-nvd0_sor_loff(struct nvkm_output_dp *outp)
+gf110_sor_loff(struct nvkm_output_dp *outp)
{
- return nvd0_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
+ return gf110_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
}
static inline u32
-nvd0_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
+gf110_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
{
- static const u8 nvd0[] = { 16, 8, 0, 24 };
- return nvd0[lane];
+ static const u8 gf110[] = { 16, 8, 0, 24 };
+ return gf110[lane];
}
static int
-nvd0_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+gf110_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- const u32 loff = nvd0_sor_loff(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ const u32 loff = gf110_sor_loff(outp);
nv_mask(priv, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
return 0;
}
int
-nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
+gf110_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- const u32 soff = nvd0_sor_soff(outp);
- const u32 loff = nvd0_sor_loff(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ const u32 soff = gf110_sor_soff(outp);
+ const u32 loff = gf110_sor_loff(outp);
u32 dpctrl = 0x00000000;
u32 clksor = 0x00000000;
@@ -80,12 +72,13 @@ nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
}
static int
-nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
+gf110_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
+ int ln, int vs, int pe, int pc)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- struct nouveau_bios *bios = nouveau_bios(priv);
- const u32 shift = nvd0_sor_dp_lane_map(priv, ln);
- const u32 loff = nvd0_sor_loff(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ struct nvkm_bios *bios = nvkm_bios(priv);
+ const u32 shift = gf110_sor_dp_lane_map(priv, ln);
+ const u32 loff = gf110_sor_loff(outp);
u32 addr, data[4];
u8 ver, hdr, cnt, len;
struct nvbios_dpout info;
@@ -93,12 +86,12 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
addr = nvbios_dpout_match(bios, outp->base.info.hasht,
outp->base.info.hashm,
- &ver, &hdr, &cnt, &len, &info);
+ &ver, &hdr, &cnt, &len, &info);
if (!addr)
return -ENODEV;
addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe,
- &ver, &hdr, &cnt, &len, &ocfg);
+ &ver, &hdr, &cnt, &len, &ocfg);
if (!addr)
return -EINVAL;
@@ -116,16 +109,16 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
}
struct nvkm_output_dp_impl
-nvd0_sor_dp_impl = {
+gf110_sor_dp_impl = {
.base.base.handle = DCB_OUTPUT_DP,
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_output_dp_ctor,
.dtor = _nvkm_output_dp_dtor,
.init = _nvkm_output_dp_init,
.fini = _nvkm_output_dp_fini,
},
- .pattern = nvd0_sor_dp_pattern,
- .lnk_pwr = nv94_sor_dp_lnk_pwr,
- .lnk_ctl = nvd0_sor_dp_lnk_ctl,
- .drv_ctl = nvd0_sor_dp_drv_ctl,
+ .pattern = gf110_sor_dp_pattern,
+ .lnk_pwr = g94_sor_dp_lnk_pwr,
+ .lnk_ctl = gf110_sor_dp_lnk_ctl,
+ .drv_ctl = gf110_sor_dp_drv_ctl,
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm204.c
index 0b4fad39e9a6..1e40dfe11319 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm204.c
@@ -21,17 +21,11 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outpdp.h"
-#include <core/os.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
-#include <subdev/bios/dp.h>
-#include <subdev/bios/init.h>
#include <subdev/timer.h>
-#include "nv50.h"
-
static inline u32
gm204_sor_soff(struct nvkm_output_dp *outp)
{
@@ -47,7 +41,7 @@ gm204_sor_loff(struct nvkm_output_dp *outp)
void
gm204_sor_magic(struct nvkm_output *outp)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
const u32 soff = outp->or * 0x100;
const u32 data = outp->or + 1;
if (outp->info.sorconf.link & 1)
@@ -65,7 +59,7 @@ gm204_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
static int
gm204_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
const u32 soff = gm204_sor_soff(outp);
const u32 data = 0x01010101 * pattern;
if (outp->base.info.sorconf.link & 1)
@@ -78,7 +72,7 @@ gm204_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
static int
gm204_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
const u32 soff = gm204_sor_soff(outp);
const u32 loff = gm204_sor_loff(outp);
u32 mask = 0, i;
@@ -93,10 +87,11 @@ gm204_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
}
static int
-gm204_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
+gm204_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
+ int ln, int vs, int pe, int pc)
{
- struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nv50_disp_priv *priv = (void *)nvkm_disp(outp);
+ struct nvkm_bios *bios = nvkm_bios(priv);
const u32 shift = gm204_sor_dp_lane_map(priv, ln);
const u32 loff = gm204_sor_loff(outp);
u32 addr, data[4];
@@ -106,12 +101,12 @@ gm204_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc
addr = nvbios_dpout_match(bios, outp->base.info.hasht,
outp->base.info.hashm,
- &ver, &hdr, &cnt, &len, &info);
+ &ver, &hdr, &cnt, &len, &info);
if (!addr)
return -ENODEV;
addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe,
- &ver, &hdr, &cnt, &len, &ocfg);
+ &ver, &hdr, &cnt, &len, &ocfg);
if (!addr)
return -EINVAL;
@@ -131,7 +126,7 @@ gm204_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc
struct nvkm_output_dp_impl
gm204_sor_dp_impl = {
.base.base.handle = DCB_OUTPUT_DP,
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_output_dp_ctor,
.dtor = _nvkm_output_dp_dtor,
.init = _nvkm_output_dp_init,
@@ -139,6 +134,6 @@ gm204_sor_dp_impl = {
},
.pattern = gm204_sor_dp_pattern,
.lnk_pwr = gm204_sor_dp_lnk_pwr,
- .lnk_ctl = nvd0_sor_dp_lnk_ctl,
+ .lnk_ctl = gf110_sor_dp_lnk_ctl,
.drv_ctl = gm204_sor_dp_drv_ctl,
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c
index ddf1760c4400..b229a311c78c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sornv50.c
@@ -21,16 +21,14 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "outp.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
-#include <subdev/bios.h>
-#include <subdev/bios/dcb.h>
#include <subdev/timer.h>
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
int
nv50_sor_power(NV50_DISP_MTHD_V1)
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/vga.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/vga.c
index 8836c3cb99c3..c4622c7388d0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/vga.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/vga.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs
*/
+#include <subdev/vga.h>
-#include <core/subdev.h>
#include <core/device.h>
-#include <subdev/vga.h>
u8
nv_rdport(void *obj, int head, u16 port)
{
- struct nouveau_device *device = nv_device(obj);
+ struct nvkm_device *device = nv_device(obj);
if (device->card_type >= NV_50)
return nv_rd08(obj, 0x601000 + port);
@@ -54,7 +53,7 @@ nv_rdport(void *obj, int head, u16 port)
void
nv_wrport(void *obj, int head, u16 port, u8 data)
{
- struct nouveau_device *device = nv_device(obj);
+ struct nvkm_device *device = nv_device(obj);
if (device->card_type >= NV_50)
nv_wr08(obj, 0x601000 + port, data);
@@ -138,7 +137,7 @@ nv_wrvgai(void *obj, int head, u16 port, u8 index, u8 value)
bool
nv_lockvgac(void *obj, bool lock)
{
- struct nouveau_device *dev = nv_device(obj);
+ struct nvkm_device *dev = nv_device(obj);
bool locked = !nv_rdvgac(obj, 0, 0x1f);
u8 data = lock ? 0x99 : 0x57;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/Kbuild
new file mode 100644
index 000000000000..7529632dbedb
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/Kbuild
@@ -0,0 +1,5 @@
+nvkm-y += nvkm/engine/dmaobj/base.o
+nvkm-y += nvkm/engine/dmaobj/nv04.o
+nvkm-y += nvkm/engine/dmaobj/nv50.o
+nvkm-y += nvkm/engine/dmaobj/gf100.o
+nvkm-y += nvkm/engine/dmaobj/gf110.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/base.c
index e1500f77a56a..a2b60d86baba 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/base.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
-#include <core/object.h>
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
+#include <core/device.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
-#include "priv.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
static int
-nvkm_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent,
- struct nouveau_gpuobj **pgpuobj)
+nvkm_dmaobj_bind(struct nvkm_dmaobj *dmaobj, struct nvkm_object *parent,
+ struct nvkm_gpuobj **pgpuobj)
{
const struct nvkm_dmaeng_impl *impl = (void *)
nv_oclass(nv_object(dmaobj)->engine);
@@ -47,7 +46,7 @@ nvkm_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent,
}
ret = impl->bind(dmaobj, parent, pgpuobj);
if (ret == 0)
- nouveau_object_ref(NULL, &parent);
+ nvkm_object_ref(NULL, &parent);
return ret;
}
@@ -55,24 +54,24 @@ nvkm_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent,
}
int
-nvkm_dmaobj_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void **pdata, u32 *psize,
+nvkm_dmaobj_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void **pdata, u32 *psize,
int length, void **pobject)
{
union {
struct nv_dma_v0 v0;
} *args = *pdata;
- struct nouveau_instmem *instmem = nouveau_instmem(parent);
- struct nouveau_client *client = nouveau_client(parent);
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_dmaobj *dmaobj;
+ struct nvkm_instmem *instmem = nvkm_instmem(parent);
+ struct nvkm_client *client = nvkm_client(parent);
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_dmaobj *dmaobj;
void *data = *pdata;
u32 size = *psize;
int ret;
- ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, 0, length, pobject);
dmaobj = *pobject;
if (ret)
return ret;
@@ -145,16 +144,16 @@ nvkm_dmaobj_create_(struct nouveau_object *parent,
}
int
-_nvkm_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+_nvkm_dmaeng_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
const struct nvkm_dmaeng_impl *impl = (void *)oclass;
- struct nouveau_dmaeng *dmaeng;
+ struct nvkm_dmaeng *dmaeng;
int ret;
- ret = nouveau_engine_create(parent, engine, oclass, true, "DMAOBJ",
- "dmaobj", &dmaeng);
+ ret = nvkm_engine_create(parent, engine, oclass, true, "DMAOBJ",
+ "dmaobj", &dmaeng);
*pobject = nv_object(dmaeng);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/gf100.c
index 88ec33b20048..f880e5167e45 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/gf100.c
@@ -21,29 +21,26 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <core/client.h>
-#include <core/device.h>
#include <core/gpuobj.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
#include <subdev/fb.h>
-#include "priv.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
-struct nvc0_dmaobj_priv {
- struct nouveau_dmaobj base;
+struct gf100_dmaobj_priv {
+ struct nvkm_dmaobj base;
u32 flags0;
u32 flags5;
};
static int
-nvc0_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
- struct nouveau_object *parent,
- struct nouveau_gpuobj **pgpuobj)
+gf100_dmaobj_bind(struct nvkm_dmaobj *dmaobj, struct nvkm_object *parent,
+ struct nvkm_gpuobj **pgpuobj)
{
- struct nvc0_dmaobj_priv *priv = (void *)dmaobj;
+ struct gf100_dmaobj_priv *priv = (void *)dmaobj;
int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
@@ -58,7 +55,7 @@ nvc0_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
} else
return 0;
- ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
+ ret = nvkm_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, priv->flags0 | nv_mclass(dmaobj));
nv_wo32(*pgpuobj, 0x04, lower_32_bits(priv->base.limit));
@@ -73,15 +70,15 @@ nvc0_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
}
static int
-nvc0_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_dmaobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_dmaeng *dmaeng = (void *)engine;
+ struct nvkm_dmaeng *dmaeng = (void *)engine;
union {
struct gf100_dma_v0 v0;
} *args;
- struct nvc0_dmaobj_priv *priv;
+ struct gf100_dmaobj_priv *priv;
u32 kind, user, unkn;
int ret;
@@ -149,31 +146,31 @@ nvc0_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject);
}
-static struct nouveau_ofuncs
-nvc0_dmaobj_ofuncs = {
- .ctor = nvc0_dmaobj_ctor,
+static struct nvkm_ofuncs
+gf100_dmaobj_ofuncs = {
+ .ctor = gf100_dmaobj_ctor,
.dtor = _nvkm_dmaobj_dtor,
.init = _nvkm_dmaobj_init,
.fini = _nvkm_dmaobj_fini,
};
-static struct nouveau_oclass
-nvc0_dmaeng_sclass[] = {
- { NV_DMA_FROM_MEMORY, &nvc0_dmaobj_ofuncs },
- { NV_DMA_TO_MEMORY, &nvc0_dmaobj_ofuncs },
- { NV_DMA_IN_MEMORY, &nvc0_dmaobj_ofuncs },
+static struct nvkm_oclass
+gf100_dmaeng_sclass[] = {
+ { NV_DMA_FROM_MEMORY, &gf100_dmaobj_ofuncs },
+ { NV_DMA_TO_MEMORY, &gf100_dmaobj_ofuncs },
+ { NV_DMA_IN_MEMORY, &gf100_dmaobj_ofuncs },
{}
};
-struct nouveau_oclass *
-nvc0_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
+struct nvkm_oclass *
+gf100_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.base.handle = NV_ENGINE(DMAOBJ, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_dmaeng_ctor,
.dtor = _nvkm_dmaeng_dtor,
.init = _nvkm_dmaeng_init,
.fini = _nvkm_dmaeng_fini,
},
- .sclass = nvc0_dmaeng_sclass,
- .bind = nvc0_dmaobj_bind,
+ .sclass = gf100_dmaeng_sclass,
+ .bind = gf100_dmaobj_bind,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/gf110.c
index 19f5f6522962..bf8f0f20976c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/gf110.c
@@ -21,28 +21,25 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <core/client.h>
-#include <core/device.h>
#include <core/gpuobj.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
#include <subdev/fb.h>
-#include "priv.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
-struct nvd0_dmaobj_priv {
- struct nouveau_dmaobj base;
+struct gf110_dmaobj_priv {
+ struct nvkm_dmaobj base;
u32 flags0;
};
static int
-nvd0_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
- struct nouveau_object *parent,
- struct nouveau_gpuobj **pgpuobj)
+gf110_dmaobj_bind(struct nvkm_dmaobj *dmaobj, struct nvkm_object *parent,
+ struct nvkm_gpuobj **pgpuobj)
{
- struct nvd0_dmaobj_priv *priv = (void *)dmaobj;
+ struct gf110_dmaobj_priv *priv = (void *)dmaobj;
int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
@@ -64,7 +61,7 @@ nvd0_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
} else
return 0;
- ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
+ ret = nvkm_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, priv->flags0);
nv_wo32(*pgpuobj, 0x04, priv->base.start >> 8);
@@ -78,15 +75,15 @@ nvd0_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
}
static int
-nvd0_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf110_dmaobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_dmaeng *dmaeng = (void *)engine;
+ struct nvkm_dmaeng *dmaeng = (void *)engine;
union {
struct gf110_dma_v0 v0;
} *args;
- struct nvd0_dmaobj_priv *priv;
+ struct gf110_dmaobj_priv *priv;
u32 kind, page;
int ret;
@@ -138,31 +135,31 @@ nvd0_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject);
}
-static struct nouveau_ofuncs
-nvd0_dmaobj_ofuncs = {
- .ctor = nvd0_dmaobj_ctor,
+static struct nvkm_ofuncs
+gf110_dmaobj_ofuncs = {
+ .ctor = gf110_dmaobj_ctor,
.dtor = _nvkm_dmaobj_dtor,
.init = _nvkm_dmaobj_init,
.fini = _nvkm_dmaobj_fini,
};
-static struct nouveau_oclass
-nvd0_dmaeng_sclass[] = {
- { NV_DMA_FROM_MEMORY, &nvd0_dmaobj_ofuncs },
- { NV_DMA_TO_MEMORY, &nvd0_dmaobj_ofuncs },
- { NV_DMA_IN_MEMORY, &nvd0_dmaobj_ofuncs },
+static struct nvkm_oclass
+gf110_dmaeng_sclass[] = {
+ { NV_DMA_FROM_MEMORY, &gf110_dmaobj_ofuncs },
+ { NV_DMA_TO_MEMORY, &gf110_dmaobj_ofuncs },
+ { NV_DMA_IN_MEMORY, &gf110_dmaobj_ofuncs },
{}
};
-struct nouveau_oclass *
-nvd0_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
+struct nvkm_oclass *
+gf110_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.base.handle = NV_ENGINE(DMAOBJ, 0xd0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_dmaeng_ctor,
.dtor = _nvkm_dmaeng_dtor,
.init = _nvkm_dmaeng_init,
.fini = _nvkm_dmaeng_fini,
},
- .sclass = nvd0_dmaeng_sclass,
- .bind = nvd0_dmaobj_bind,
+ .sclass = gf110_dmaeng_sclass,
+ .bind = gf110_dmaobj_bind,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/nv04.c
index 20c9dbfe3b2e..b4379c2a2fb5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/nv04.c
@@ -21,29 +21,27 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <core/gpuobj.h>
-#include <nvif/class.h>
-
#include <subdev/fb.h>
-#include <subdev/vm/nv04.h>
+#include <subdev/mmu/nv04.h>
-#include "priv.h"
+#include <nvif/class.h>
struct nv04_dmaobj_priv {
- struct nouveau_dmaobj base;
+ struct nvkm_dmaobj base;
bool clone;
u32 flags0;
u32 flags2;
};
static int
-nv04_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
- struct nouveau_object *parent,
- struct nouveau_gpuobj **pgpuobj)
+nv04_dmaobj_bind(struct nvkm_dmaobj *dmaobj, struct nvkm_object *parent,
+ struct nvkm_gpuobj **pgpuobj)
{
struct nv04_dmaobj_priv *priv = (void *)dmaobj;
- struct nouveau_gpuobj *gpuobj;
+ struct nvkm_gpuobj *gpuobj;
u64 offset = priv->base.start & 0xfffff000;
u64 adjust = priv->base.start & 0x00000fff;
u32 length = priv->base.limit - priv->base.start;
@@ -62,15 +60,15 @@ nv04_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
}
if (priv->clone) {
- struct nv04_vmmgr_priv *vmm = nv04_vmmgr(dmaobj);
- struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0];
+ struct nv04_mmu_priv *mmu = nv04_mmu(dmaobj);
+ struct nvkm_gpuobj *pgt = mmu->vm->pgt[0].obj[0];
if (!dmaobj->start)
- return nouveau_gpuobj_dup(parent, pgt, pgpuobj);
+ return nvkm_gpuobj_dup(parent, pgt, pgpuobj);
offset = nv_ro32(pgt, 8 + (offset >> 10));
offset &= 0xfffff000;
}
- ret = nouveau_gpuobj_new(parent, parent, 16, 16, 0, &gpuobj);
+ ret = nvkm_gpuobj_new(parent, parent, 16, 16, 0, &gpuobj);
*pgpuobj = gpuobj;
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, priv->flags0 | (adjust << 20));
@@ -83,12 +81,12 @@ nv04_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
}
static int
-nv04_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_dmaobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_dmaeng *dmaeng = (void *)engine;
- struct nv04_vmmgr_priv *vmm = nv04_vmmgr(engine);
+ struct nvkm_dmaeng *dmaeng = (void *)engine;
+ struct nv04_mmu_priv *mmu = nv04_mmu(engine);
struct nv04_dmaobj_priv *priv;
int ret;
@@ -98,7 +96,7 @@ nv04_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
if (priv->base.target == NV_MEM_TARGET_VM) {
- if (nv_object(vmm)->oclass == &nv04_vmmgr_oclass)
+ if (nv_object(mmu)->oclass == &nv04_mmu_oclass)
priv->clone = true;
priv->base.target = NV_MEM_TARGET_PCI;
priv->base.access = NV_MEM_ACCESS_RW;
@@ -135,7 +133,7 @@ nv04_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject);
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv04_dmaobj_ofuncs = {
.ctor = nv04_dmaobj_ctor,
.dtor = _nvkm_dmaobj_dtor,
@@ -143,7 +141,7 @@ nv04_dmaobj_ofuncs = {
.fini = _nvkm_dmaobj_fini,
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv04_dmaeng_sclass[] = {
{ NV_DMA_FROM_MEMORY, &nv04_dmaobj_ofuncs },
{ NV_DMA_TO_MEMORY, &nv04_dmaobj_ofuncs },
@@ -151,10 +149,10 @@ nv04_dmaeng_sclass[] = {
{}
};
-struct nouveau_oclass *
+struct nvkm_oclass *
nv04_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.base.handle = NV_ENGINE(DMAOBJ, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_dmaeng_ctor,
.dtor = _nvkm_dmaeng_dtor,
.init = _nvkm_dmaeng_init,
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/nv50.c
index a740ddba2ee2..4d3c828fe0e6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/nv50.c
@@ -21,26 +21,24 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <core/client.h>
#include <core/gpuobj.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
#include <subdev/fb.h>
-#include "priv.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
struct nv50_dmaobj_priv {
- struct nouveau_dmaobj base;
+ struct nvkm_dmaobj base;
u32 flags0;
u32 flags5;
};
static int
-nv50_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
- struct nouveau_object *parent,
- struct nouveau_gpuobj **pgpuobj)
+nv50_dmaobj_bind(struct nvkm_dmaobj *dmaobj, struct nvkm_object *parent,
+ struct nvkm_gpuobj **pgpuobj)
{
struct nv50_dmaobj_priv *priv = (void *)dmaobj;
int ret;
@@ -69,7 +67,7 @@ nv50_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
}
}
- ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
+ ret = nvkm_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, priv->flags0 | nv_mclass(dmaobj));
nv_wo32(*pgpuobj, 0x04, lower_32_bits(priv->base.limit));
@@ -84,11 +82,11 @@ nv50_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
}
static int
-nv50_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_dmaobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_dmaeng *dmaeng = (void *)engine;
+ struct nvkm_dmaeng *dmaeng = (void *)engine;
union {
struct nv50_dma_v0 v0;
} *args;
@@ -167,7 +165,7 @@ nv50_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject);
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv50_dmaobj_ofuncs = {
.ctor = nv50_dmaobj_ctor,
.dtor = _nvkm_dmaobj_dtor,
@@ -175,7 +173,7 @@ nv50_dmaobj_ofuncs = {
.fini = _nvkm_dmaobj_fini,
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_dmaeng_sclass[] = {
{ NV_DMA_FROM_MEMORY, &nv50_dmaobj_ofuncs },
{ NV_DMA_TO_MEMORY, &nv50_dmaobj_ofuncs },
@@ -183,10 +181,10 @@ nv50_dmaeng_sclass[] = {
{}
};
-struct nouveau_oclass *
+struct nvkm_oclass *
nv50_dmaeng_oclass = &(struct nvkm_dmaeng_impl) {
.base.handle = NV_ENGINE(DMAOBJ, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_dmaeng_ctor,
.dtor = _nvkm_dmaeng_dtor,
.init = _nvkm_dmaeng_init,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/priv.h
new file mode 100644
index 000000000000..44ae8a0ca65c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dmaobj/priv.h
@@ -0,0 +1,28 @@
+#ifndef __NVKM_DMAOBJ_PRIV_H__
+#define __NVKM_DMAOBJ_PRIV_H__
+#include <engine/dmaobj.h>
+
+#define nvkm_dmaobj_create(p,e,c,pa,sa,d) \
+ nvkm_dmaobj_create_((p), (e), (c), (pa), (sa), sizeof(**d), (void **)d)
+
+int nvkm_dmaobj_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void **, u32 *,
+ int, void **);
+#define _nvkm_dmaobj_dtor nvkm_object_destroy
+#define _nvkm_dmaobj_init nvkm_object_init
+#define _nvkm_dmaobj_fini nvkm_object_fini
+
+int _nvkm_dmaeng_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+#define _nvkm_dmaeng_dtor _nvkm_engine_dtor
+#define _nvkm_dmaeng_init _nvkm_engine_init
+#define _nvkm_dmaeng_fini _nvkm_engine_fini
+
+struct nvkm_dmaeng_impl {
+ struct nvkm_oclass base;
+ struct nvkm_oclass *sclass;
+ int (*bind)(struct nvkm_dmaobj *, struct nvkm_object *,
+ struct nvkm_gpuobj **);
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/falcon.c b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
index 2914646c8709..30958c19e61d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/falcon.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
@@ -19,14 +19,15 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
#include <engine/falcon.h>
+
+#include <core/device.h>
#include <subdev/timer.h>
void
-nouveau_falcon_intr(struct nouveau_subdev *subdev)
+nvkm_falcon_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_falcon *falcon = (void *)subdev;
+ struct nvkm_falcon *falcon = (void *)subdev;
u32 dispatch = nv_ro32(falcon, 0x01c);
u32 intr = nv_ro32(falcon, 0x008) & dispatch & ~(dispatch >> 16);
@@ -43,16 +44,16 @@ nouveau_falcon_intr(struct nouveau_subdev *subdev)
}
u32
-_nouveau_falcon_rd32(struct nouveau_object *object, u64 addr)
+_nvkm_falcon_rd32(struct nvkm_object *object, u64 addr)
{
- struct nouveau_falcon *falcon = (void *)object;
+ struct nvkm_falcon *falcon = (void *)object;
return nv_rd32(falcon, falcon->addr + addr);
}
void
-_nouveau_falcon_wr32(struct nouveau_object *object, u64 addr, u32 data)
+_nvkm_falcon_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
- struct nouveau_falcon *falcon = (void *)object;
+ struct nvkm_falcon *falcon = (void *)object;
nv_wr32(falcon, falcon->addr + addr, data);
}
@@ -67,17 +68,17 @@ vmemdup(const void *src, size_t len)
}
int
-_nouveau_falcon_init(struct nouveau_object *object)
+_nvkm_falcon_init(struct nvkm_object *object)
{
- struct nouveau_device *device = nv_device(object);
- struct nouveau_falcon *falcon = (void *)object;
+ struct nvkm_device *device = nv_device(object);
+ struct nvkm_falcon *falcon = (void *)object;
const struct firmware *fw;
char name[32] = "internal";
int ret, i;
u32 caps;
/* enable engine, and determine its capabilities */
- ret = nouveau_engine_init(&falcon->base);
+ ret = nvkm_engine_init(&falcon->base);
if (ret)
return ret;
@@ -171,9 +172,8 @@ _nouveau_falcon_init(struct nouveau_object *object)
/* ensure any "self-bootstrapping" firmware image is in vram */
if (!falcon->data.data && !falcon->core) {
- ret = nouveau_gpuobj_new(object->parent, NULL,
- falcon->code.size, 256, 0,
- &falcon->core);
+ ret = nvkm_gpuobj_new(object->parent, NULL, falcon->code.size,
+ 256, 0, &falcon->core);
if (ret) {
nv_error(falcon, "core allocation failed, %d\n", ret);
return ret;
@@ -238,12 +238,12 @@ _nouveau_falcon_init(struct nouveau_object *object)
}
int
-_nouveau_falcon_fini(struct nouveau_object *object, bool suspend)
+_nvkm_falcon_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_falcon *falcon = (void *)object;
+ struct nvkm_falcon *falcon = (void *)object;
if (!suspend) {
- nouveau_gpuobj_ref(NULL, &falcon->core);
+ nvkm_gpuobj_ref(NULL, &falcon->core);
if (falcon->external) {
vfree(falcon->data.data);
vfree(falcon->code.data);
@@ -254,21 +254,20 @@ _nouveau_falcon_fini(struct nouveau_object *object, bool suspend)
nv_mo32(falcon, 0x048, 0x00000003, 0x00000000);
nv_wo32(falcon, 0x014, 0xffffffff);
- return nouveau_engine_fini(&falcon->base, suspend);
+ return nvkm_engine_fini(&falcon->base, suspend);
}
int
-nouveau_falcon_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 addr, bool enable,
- const char *iname, const char *fname,
- int length, void **pobject)
+nvkm_falcon_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 addr, bool enable,
+ const char *iname, const char *fname,
+ int length, void **pobject)
{
- struct nouveau_falcon *falcon;
+ struct nvkm_falcon *falcon;
int ret;
- ret = nouveau_engine_create_(parent, engine, oclass, enable, iname,
- fname, length, pobject);
+ ret = nvkm_engine_create_(parent, engine, oclass, enable, iname,
+ fname, length, pobject);
falcon = *pobject;
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
new file mode 100644
index 000000000000..c5a2d8718c5b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
@@ -0,0 +1,11 @@
+nvkm-y += nvkm/engine/fifo/base.o
+nvkm-y += nvkm/engine/fifo/nv04.o
+nvkm-y += nvkm/engine/fifo/nv10.o
+nvkm-y += nvkm/engine/fifo/nv17.o
+nvkm-y += nvkm/engine/fifo/nv40.o
+nvkm-y += nvkm/engine/fifo/nv50.o
+nvkm-y += nvkm/engine/fifo/g84.o
+nvkm-y += nvkm/engine/fifo/gf100.o
+nvkm-y += nvkm/engine/fifo/gk104.o
+nvkm-y += nvkm/engine/fifo/gk20a.o
+nvkm-y += nvkm/engine/fifo/gk208.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
index ac8375cf4eef..fa223f88d25e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
@@ -21,21 +21,21 @@
*
* Authors: Ben Skeggs
*/
+#include <engine/fifo.h>
#include <core/client.h>
-#include <core/object.h>
+#include <core/device.h>
#include <core/handle.h>
-#include <core/event.h>
-#include <nvif/unpack.h>
+#include <core/notify.h>
+#include <engine/dmaobj.h>
+
#include <nvif/class.h>
#include <nvif/event.h>
-
-#include <engine/dmaobj.h>
-#include <engine/fifo.h>
+#include <nvif/unpack.h>
static int
-nouveau_fifo_event_ctor(struct nouveau_object *object, void *data, u32 size,
- struct nvkm_notify *notify)
+nvkm_fifo_event_ctor(struct nvkm_object *object, void *data, u32 size,
+ struct nvkm_notify *notify)
{
if (size == 0) {
notify->size = 0;
@@ -47,33 +47,33 @@ nouveau_fifo_event_ctor(struct nouveau_object *object, void *data, u32 size,
}
static const struct nvkm_event_func
-nouveau_fifo_event_func = {
- .ctor = nouveau_fifo_event_ctor,
+nvkm_fifo_event_func = {
+ .ctor = nvkm_fifo_event_ctor,
};
int
-nouveau_fifo_channel_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int bar, u32 addr, u32 size, u32 pushbuf,
- u64 engmask, int len, void **ptr)
+nvkm_fifo_channel_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass,
+ int bar, u32 addr, u32 size, u32 pushbuf,
+ u64 engmask, int len, void **ptr)
{
- struct nouveau_device *device = nv_device(engine);
- struct nouveau_fifo *priv = (void *)engine;
- struct nouveau_fifo_chan *chan;
- struct nouveau_dmaeng *dmaeng;
+ struct nvkm_device *device = nv_device(engine);
+ struct nvkm_fifo *priv = (void *)engine;
+ struct nvkm_fifo_chan *chan;
+ struct nvkm_dmaeng *dmaeng;
unsigned long flags;
int ret;
/* create base object class */
- ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
- engmask, len, ptr);
+ ret = nvkm_namedb_create_(parent, engine, oclass, 0, NULL,
+ engmask, len, ptr);
chan = *ptr;
if (ret)
return ret;
/* validate dma object representing push buffer */
- chan->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
+ chan->pushdma = (void *)nvkm_handle_ref(parent, pushbuf);
if (!chan->pushdma)
return -ENOENT;
@@ -113,9 +113,9 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
}
void
-nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *chan)
+nvkm_fifo_channel_destroy(struct nvkm_fifo_chan *chan)
{
- struct nouveau_fifo *priv = (void *)nv_object(chan)->engine;
+ struct nvkm_fifo *priv = (void *)nv_object(chan)->engine;
unsigned long flags;
if (chan->user)
@@ -125,31 +125,31 @@ nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *chan)
priv->channel[chan->chid] = NULL;
spin_unlock_irqrestore(&priv->lock, flags);
- nouveau_gpuobj_ref(NULL, &chan->pushgpu);
- nouveau_object_ref(NULL, (struct nouveau_object **)&chan->pushdma);
- nouveau_namedb_destroy(&chan->base);
+ nvkm_gpuobj_ref(NULL, &chan->pushgpu);
+ nvkm_object_ref(NULL, (struct nvkm_object **)&chan->pushdma);
+ nvkm_namedb_destroy(&chan->namedb);
}
void
-_nouveau_fifo_channel_dtor(struct nouveau_object *object)
+_nvkm_fifo_channel_dtor(struct nvkm_object *object)
{
- struct nouveau_fifo_chan *chan = (void *)object;
- nouveau_fifo_channel_destroy(chan);
+ struct nvkm_fifo_chan *chan = (void *)object;
+ nvkm_fifo_channel_destroy(chan);
}
int
-_nouveau_fifo_channel_map(struct nouveau_object *object, u64 *addr, u32 *size)
+_nvkm_fifo_channel_map(struct nvkm_object *object, u64 *addr, u32 *size)
{
- struct nouveau_fifo_chan *chan = (void *)object;
+ struct nvkm_fifo_chan *chan = (void *)object;
*addr = chan->addr;
*size = chan->size;
return 0;
}
u32
-_nouveau_fifo_channel_rd32(struct nouveau_object *object, u64 addr)
+_nvkm_fifo_channel_rd32(struct nvkm_object *object, u64 addr)
{
- struct nouveau_fifo_chan *chan = (void *)object;
+ struct nvkm_fifo_chan *chan = (void *)object;
if (unlikely(!chan->user)) {
chan->user = ioremap(chan->addr, chan->size);
if (WARN_ON_ONCE(chan->user == NULL))
@@ -159,9 +159,9 @@ _nouveau_fifo_channel_rd32(struct nouveau_object *object, u64 addr)
}
void
-_nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data)
+_nvkm_fifo_channel_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
- struct nouveau_fifo_chan *chan = (void *)object;
+ struct nvkm_fifo_chan *chan = (void *)object;
if (unlikely(!chan->user)) {
chan->user = ioremap(chan->addr, chan->size);
if (WARN_ON_ONCE(chan->user == NULL))
@@ -171,8 +171,8 @@ _nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data)
}
int
-nouveau_fifo_uevent_ctor(struct nouveau_object *object, void *data, u32 size,
- struct nvkm_notify *notify)
+nvkm_fifo_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
+ struct nvkm_notify *notify)
{
union {
struct nvif_notify_uevent_req none;
@@ -189,7 +189,7 @@ nouveau_fifo_uevent_ctor(struct nouveau_object *object, void *data, u32 size,
}
void
-nouveau_fifo_uevent(struct nouveau_fifo *fifo)
+nvkm_fifo_uevent(struct nvkm_fifo *fifo)
{
struct nvif_notify_uevent_rep rep = {
};
@@ -197,10 +197,10 @@ nouveau_fifo_uevent(struct nouveau_fifo *fifo)
}
int
-_nouveau_fifo_channel_ntfy(struct nouveau_object *object, u32 type,
- struct nvkm_event **event)
+_nvkm_fifo_channel_ntfy(struct nvkm_object *object, u32 type,
+ struct nvkm_event **event)
{
- struct nouveau_fifo *fifo = (void *)object->engine;
+ struct nvkm_fifo *fifo = (void *)object->engine;
switch (type) {
case G82_CHANNEL_DMA_V0_NTFY_UEVENT:
if (nv_mclass(object) >= G82_CHANNEL_DMA) {
@@ -215,14 +215,14 @@ _nouveau_fifo_channel_ntfy(struct nouveau_object *object, u32 type,
}
static int
-nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object)
+nvkm_fifo_chid(struct nvkm_fifo *priv, struct nvkm_object *object)
{
int engidx = nv_hclass(priv) & 0xff;
while (object && object->parent) {
if ( nv_iclass(object->parent, NV_ENGCTX_CLASS) &&
(nv_hclass(object->parent) & 0xff) == engidx)
- return nouveau_fifo_chan(object)->chid;
+ return nvkm_fifo_chan(object)->chid;
object = object->parent;
}
@@ -230,9 +230,9 @@ nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object)
}
const char *
-nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid)
+nvkm_client_name_for_fifo_chid(struct nvkm_fifo *fifo, u32 chid)
{
- struct nouveau_fifo_chan *chan = NULL;
+ struct nvkm_fifo_chan *chan = NULL;
unsigned long flags;
spin_lock_irqsave(&fifo->lock, flags);
@@ -240,29 +240,28 @@ nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid)
chan = (void *)fifo->channel[chid];
spin_unlock_irqrestore(&fifo->lock, flags);
- return nouveau_client_name(chan);
+ return nvkm_client_name(chan);
}
void
-nouveau_fifo_destroy(struct nouveau_fifo *priv)
+nvkm_fifo_destroy(struct nvkm_fifo *priv)
{
kfree(priv->channel);
nvkm_event_fini(&priv->uevent);
nvkm_event_fini(&priv->cevent);
- nouveau_engine_destroy(&priv->base);
+ nvkm_engine_destroy(&priv->base);
}
int
-nouveau_fifo_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int min, int max, int length, void **pobject)
+nvkm_fifo_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass,
+ int min, int max, int length, void **pobject)
{
- struct nouveau_fifo *priv;
+ struct nvkm_fifo *priv;
int ret;
- ret = nouveau_engine_create_(parent, engine, oclass, true, "PFIFO",
- "fifo", length, pobject);
+ ret = nvkm_engine_create_(parent, engine, oclass, true, "PFIFO",
+ "fifo", length, pobject);
priv = *pobject;
if (ret)
return ret;
@@ -273,11 +272,11 @@ nouveau_fifo_create_(struct nouveau_object *parent,
if (!priv->channel)
return -ENOMEM;
- ret = nvkm_event_init(&nouveau_fifo_event_func, 1, 1, &priv->cevent);
+ ret = nvkm_event_init(&nvkm_fifo_event_func, 1, 1, &priv->cevent);
if (ret)
return ret;
- priv->chid = nouveau_fifo_chid;
+ priv->chid = nvkm_fifo_chid;
spin_lock_init(&priv->lock);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
index 1f42996b354a..a04920b3cf84 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
@@ -21,48 +21,45 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "nv04.h"
-#include <core/os.h>
#include <core/client.h>
#include <core/engctx.h>
#include <core/ramht.h>
-#include <core/event.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
-#include <subdev/timer.h>
#include <subdev/bar.h>
+#include <subdev/mmu.h>
+#include <subdev/timer.h>
-#include <engine/dmaobj.h>
-#include <engine/fifo.h>
-
-#include "nv04.h"
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static int
-nv84_fifo_context_attach(struct nouveau_object *parent,
- struct nouveau_object *object)
+g84_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent->parent;
- struct nouveau_gpuobj *ectx = (void *)object;
+ struct nvkm_gpuobj *ectx = (void *)object;
u64 limit = ectx->addr + ectx->size - 1;
u64 start = ectx->addr;
u32 addr;
switch (nv_engidx(object->engine)) {
- case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR : addr = 0x0020; break;
- case NVDEV_ENGINE_VP : addr = 0x0040; break;
- case NVDEV_ENGINE_PPP :
- case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
- case NVDEV_ENGINE_BSP : addr = 0x0080; break;
- case NVDEV_ENGINE_CRYPT: addr = 0x00a0; break;
- case NVDEV_ENGINE_COPY0: addr = 0x00c0; break;
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0020; break;
+ case NVDEV_ENGINE_VP :
+ case NVDEV_ENGINE_MSPDEC: addr = 0x0040; break;
+ case NVDEV_ENGINE_MSPPP :
+ case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
+ case NVDEV_ENGINE_BSP :
+ case NVDEV_ENGINE_MSVLD : addr = 0x0080; break;
+ case NVDEV_ENGINE_CIPHER:
+ case NVDEV_ENGINE_SEC : addr = 0x00a0; break;
+ case NVDEV_ENGINE_CE0 : addr = 0x00c0; break;
default:
return -EINVAL;
}
@@ -80,10 +77,10 @@ nv84_fifo_context_attach(struct nouveau_object *parent,
}
static int
-nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
- struct nouveau_object *object)
+g84_fifo_context_detach(struct nvkm_object *parent, bool suspend,
+ struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_priv *priv = (void *)parent->engine;
struct nv50_fifo_base *base = (void *)parent->parent;
struct nv50_fifo_chan *chan = (void *)parent;
@@ -91,14 +88,17 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
bool done;
switch (nv_engidx(object->engine)) {
- case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR : engn = 0; addr = 0x0020; break;
- case NVDEV_ENGINE_VP : engn = 3; addr = 0x0040; break;
- case NVDEV_ENGINE_PPP :
- case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break;
- case NVDEV_ENGINE_BSP : engn = 5; addr = 0x0080; break;
- case NVDEV_ENGINE_CRYPT: engn = 4; addr = 0x00a0; break;
- case NVDEV_ENGINE_COPY0: engn = 2; addr = 0x00c0; break;
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : engn = 0; addr = 0x0020; break;
+ case NVDEV_ENGINE_VP :
+ case NVDEV_ENGINE_MSPDEC: engn = 3; addr = 0x0040; break;
+ case NVDEV_ENGINE_MSPPP :
+ case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break;
+ case NVDEV_ENGINE_BSP :
+ case NVDEV_ENGINE_MSVLD : engn = 5; addr = 0x0080; break;
+ case NVDEV_ENGINE_CIPHER:
+ case NVDEV_ENGINE_SEC : engn = 4; addr = 0x00a0; break;
+ case NVDEV_ENGINE_CE0 : engn = 2; addr = 0x00c0; break;
default:
return -EINVAL;
}
@@ -109,7 +109,7 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
nv_wr32(priv, 0x002520, save);
if (!done) {
nv_error(priv, "channel %d [%s] unload timeout\n",
- chan->base.chid, nouveau_client_name(chan));
+ chan->base.chid, nvkm_client_name(chan));
if (suspend)
return -EBUSY;
}
@@ -125,8 +125,8 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
}
static int
-nv84_fifo_object_attach(struct nouveau_object *parent,
- struct nouveau_object *object, u32 handle)
+g84_fifo_object_attach(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 handle)
{
struct nv50_fifo_chan *chan = (void *)parent;
u32 context;
@@ -141,30 +141,32 @@ nv84_fifo_object_attach(struct nouveau_object *parent,
case NVDEV_ENGINE_SW : context |= 0x00000000; break;
case NVDEV_ENGINE_GR : context |= 0x00100000; break;
case NVDEV_ENGINE_MPEG :
- case NVDEV_ENGINE_PPP : context |= 0x00200000; break;
+ case NVDEV_ENGINE_MSPPP : context |= 0x00200000; break;
case NVDEV_ENGINE_ME :
- case NVDEV_ENGINE_COPY0 : context |= 0x00300000; break;
- case NVDEV_ENGINE_VP : context |= 0x00400000; break;
- case NVDEV_ENGINE_CRYPT :
+ case NVDEV_ENGINE_CE0 : context |= 0x00300000; break;
+ case NVDEV_ENGINE_VP :
+ case NVDEV_ENGINE_MSPDEC: context |= 0x00400000; break;
+ case NVDEV_ENGINE_CIPHER:
+ case NVDEV_ENGINE_SEC :
case NVDEV_ENGINE_VIC : context |= 0x00500000; break;
- case NVDEV_ENGINE_BSP : context |= 0x00600000; break;
+ case NVDEV_ENGINE_BSP :
+ case NVDEV_ENGINE_MSVLD : context |= 0x00600000; break;
default:
return -EINVAL;
}
- return nouveau_ramht_insert(chan->ramht, 0, handle, context);
+ return nvkm_ramht_insert(chan->ramht, 0, handle, context);
}
static int
-nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
int ret;
@@ -177,33 +179,36 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
- 0x2000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR) |
- (1ULL << NVDEV_ENGINE_MPEG) |
- (1ULL << NVDEV_ENGINE_ME) |
- (1ULL << NVDEV_ENGINE_VP) |
- (1ULL << NVDEV_ENGINE_CRYPT) |
- (1ULL << NVDEV_ENGINE_BSP) |
- (1ULL << NVDEV_ENGINE_PPP) |
- (1ULL << NVDEV_ENGINE_COPY0) |
- (1ULL << NVDEV_ENGINE_VIC), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR) |
+ (1ULL << NVDEV_ENGINE_MPEG) |
+ (1ULL << NVDEV_ENGINE_ME) |
+ (1ULL << NVDEV_ENGINE_VP) |
+ (1ULL << NVDEV_ENGINE_CIPHER) |
+ (1ULL << NVDEV_ENGINE_SEC) |
+ (1ULL << NVDEV_ENGINE_BSP) |
+ (1ULL << NVDEV_ENGINE_MSVLD) |
+ (1ULL << NVDEV_ENGINE_MSPDEC) |
+ (1ULL << NVDEV_ENGINE_MSPPP) |
+ (1ULL << NVDEV_ENGINE_CE0) |
+ (1ULL << NVDEV_ENGINE_VIC), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
args->v0.chid = chan->base.chid;
- ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
- &chan->ramht);
+ ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
+ &chan->ramht);
if (ret)
return ret;
- nv_parent(chan)->context_attach = nv84_fifo_context_attach;
- nv_parent(chan)->context_detach = nv84_fifo_context_detach;
- nv_parent(chan)->object_attach = nv84_fifo_object_attach;
+ nv_parent(chan)->context_attach = g84_fifo_context_attach;
+ nv_parent(chan)->context_detach = g84_fifo_context_detach;
+ nv_parent(chan)->object_attach = g84_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
nv_wo32(base->ramfc, 0x08, lower_32_bits(args->v0.offset));
@@ -219,7 +224,7 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
- (chan->ramht->base.node->offset >> 4));
+ (chan->ramht->gpuobj.node->offset >> 4));
nv_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
nv_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
bar->flush(bar);
@@ -227,15 +232,14 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
}
static int
-nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_channel_gpfifo_v0 v0;
} *args = data;
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
u64 ioffset, ilength;
@@ -250,33 +254,36 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
- 0x2000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR) |
- (1ULL << NVDEV_ENGINE_MPEG) |
- (1ULL << NVDEV_ENGINE_ME) |
- (1ULL << NVDEV_ENGINE_VP) |
- (1ULL << NVDEV_ENGINE_CRYPT) |
- (1ULL << NVDEV_ENGINE_BSP) |
- (1ULL << NVDEV_ENGINE_PPP) |
- (1ULL << NVDEV_ENGINE_COPY0) |
- (1ULL << NVDEV_ENGINE_VIC), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR) |
+ (1ULL << NVDEV_ENGINE_MPEG) |
+ (1ULL << NVDEV_ENGINE_ME) |
+ (1ULL << NVDEV_ENGINE_VP) |
+ (1ULL << NVDEV_ENGINE_CIPHER) |
+ (1ULL << NVDEV_ENGINE_SEC) |
+ (1ULL << NVDEV_ENGINE_BSP) |
+ (1ULL << NVDEV_ENGINE_MSVLD) |
+ (1ULL << NVDEV_ENGINE_MSPDEC) |
+ (1ULL << NVDEV_ENGINE_MSPPP) |
+ (1ULL << NVDEV_ENGINE_CE0) |
+ (1ULL << NVDEV_ENGINE_VIC), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
args->v0.chid = chan->base.chid;
- ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
- &chan->ramht);
+ ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
+ &chan->ramht);
if (ret)
return ret;
- nv_parent(chan)->context_attach = nv84_fifo_context_attach;
- nv_parent(chan)->context_detach = nv84_fifo_context_detach;
- nv_parent(chan)->object_attach = nv84_fifo_object_attach;
+ nv_parent(chan)->context_attach = g84_fifo_context_attach;
+ nv_parent(chan)->context_detach = g84_fifo_context_detach;
+ nv_parent(chan)->object_attach = g84_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
ioffset = args->v0.ioffset;
@@ -292,7 +299,7 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
- (chan->ramht->base.node->offset >> 4));
+ (chan->ramht->gpuobj.node->offset >> 4));
nv_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
nv_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
bar->flush(bar);
@@ -300,16 +307,16 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
}
static int
-nv84_fifo_chan_init(struct nouveau_object *object)
+g84_fifo_chan_init(struct nvkm_object *object)
{
struct nv50_fifo_priv *priv = (void *)object->engine;
struct nv50_fifo_base *base = (void *)object->parent;
struct nv50_fifo_chan *chan = (void *)object;
- struct nouveau_gpuobj *ramfc = base->ramfc;
+ struct nvkm_gpuobj *ramfc = base->ramfc;
u32 chid = chan->base.chid;
int ret;
- ret = nouveau_fifo_channel_init(&chan->base);
+ ret = nvkm_fifo_channel_init(&chan->base);
if (ret)
return ret;
@@ -318,34 +325,34 @@ nv84_fifo_chan_init(struct nouveau_object *object)
return 0;
}
-static struct nouveau_ofuncs
-nv84_fifo_ofuncs_dma = {
- .ctor = nv84_fifo_chan_ctor_dma,
+static struct nvkm_ofuncs
+g84_fifo_ofuncs_dma = {
+ .ctor = g84_fifo_chan_ctor_dma,
.dtor = nv50_fifo_chan_dtor,
- .init = nv84_fifo_chan_init,
+ .init = g84_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_ofuncs
-nv84_fifo_ofuncs_ind = {
- .ctor = nv84_fifo_chan_ctor_ind,
+static struct nvkm_ofuncs
+g84_fifo_ofuncs_ind = {
+ .ctor = g84_fifo_chan_ctor_ind,
.dtor = nv50_fifo_chan_dtor,
- .init = nv84_fifo_chan_init,
+ .init = g84_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
-nv84_fifo_sclass[] = {
- { G82_CHANNEL_DMA, &nv84_fifo_ofuncs_dma },
- { G82_CHANNEL_GPFIFO, &nv84_fifo_ofuncs_ind },
+static struct nvkm_oclass
+g84_fifo_sclass[] = {
+ { G82_CHANNEL_DMA, &g84_fifo_ofuncs_dma },
+ { G82_CHANNEL_GPFIFO, &g84_fifo_ofuncs_ind },
{}
};
@@ -354,57 +361,56 @@ nv84_fifo_sclass[] = {
******************************************************************************/
static int
-nv84_fifo_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_fifo_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_fifo_base *base;
int ret;
- ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
- 0x1000, NVOBJ_FLAG_HEAP, &base);
+ ret = nvkm_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
+ 0x1000, NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200, 0,
- NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
+ ret = nvkm_gpuobj_new(nv_object(base), nv_object(base), 0x0200, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0,
- 0, &base->pgd);
+ ret = nvkm_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0,
+ 0, &base->pgd);
if (ret)
return ret;
- ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ ret = nvkm_vm_ref(nvkm_client(parent)->vm, &base->vm, base->pgd);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1000,
- 0x400, NVOBJ_FLAG_ZERO_ALLOC, &base->cache);
+ ret = nvkm_gpuobj_new(nv_object(base), nv_object(base), 0x1000,
+ 0x400, NVOBJ_FLAG_ZERO_ALLOC, &base->cache);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0100,
- 0x100, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
+ ret = nvkm_gpuobj_new(nv_object(base), nv_object(base), 0x0100,
+ 0x100, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
if (ret)
return ret;
return 0;
}
-static struct nouveau_oclass
-nv84_fifo_cclass = {
+static struct nvkm_oclass
+g84_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_fifo_context_ctor,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_fifo_context_ctor,
.dtor = nv50_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -413,69 +419,69 @@ nv84_fifo_cclass = {
******************************************************************************/
static void
-nv84_fifo_uevent_init(struct nvkm_event *event, int type, int index)
+g84_fifo_uevent_init(struct nvkm_event *event, int type, int index)
{
- struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
nv_mask(fifo, 0x002140, 0x40000000, 0x40000000);
}
static void
-nv84_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
+g84_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
{
- struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
nv_mask(fifo, 0x002140, 0x40000000, 0x00000000);
}
static const struct nvkm_event_func
-nv84_fifo_uevent_func = {
- .ctor = nouveau_fifo_uevent_ctor,
- .init = nv84_fifo_uevent_init,
- .fini = nv84_fifo_uevent_fini,
+g84_fifo_uevent_func = {
+ .ctor = nvkm_fifo_uevent_ctor,
+ .init = g84_fifo_uevent_init,
+ .fini = g84_fifo_uevent_fini,
};
static int
-nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_fifo_priv *priv;
int ret;
- ret = nouveau_fifo_create(parent, engine, oclass, 1, 127, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 1, 127, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
- &priv->playlist[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[0]);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
- &priv->playlist[1]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[1]);
if (ret)
return ret;
- ret = nvkm_event_init(&nv84_fifo_uevent_func, 1, 1, &priv->base.uevent);
+ ret = nvkm_event_init(&g84_fifo_uevent_func, 1, 1, &priv->base.uevent);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
- nv_engine(priv)->cclass = &nv84_fifo_cclass;
- nv_engine(priv)->sclass = nv84_fifo_sclass;
+ nv_engine(priv)->cclass = &g84_fifo_cclass;
+ nv_engine(priv)->sclass = g84_fifo_sclass;
priv->base.pause = nv04_fifo_pause;
priv->base.start = nv04_fifo_start;
return 0;
}
-struct nouveau_oclass *
-nv84_fifo_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+g84_fifo_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(FIFO, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_fifo_ctor,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_fifo_ctor,
.dtor = nv50_fifo_dtor,
.init = nv50_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .fini = _nvkm_fifo_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
index 074d434c3077..b745252f2261 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
@@ -21,52 +21,47 @@
*
* Authors: Ben Skeggs
*/
+#include <engine/fifo.h>
#include <core/client.h>
-#include <core/handle.h>
-#include <core/namedb.h>
-#include <core/gpuobj.h>
#include <core/engctx.h>
-#include <core/event.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
#include <core/enum.h>
-
-#include <subdev/timer.h>
+#include <core/handle.h>
#include <subdev/bar.h>
#include <subdev/fb.h>
-#include <subdev/vm.h>
+#include <subdev/mmu.h>
+#include <subdev/timer.h>
-#include <engine/dmaobj.h>
-#include <engine/fifo.h>
+#include <nvif/class.h>
+#include <nvif/unpack.h>
-struct nvc0_fifo_priv {
- struct nouveau_fifo base;
+struct gf100_fifo_priv {
+ struct nvkm_fifo base;
struct work_struct fault;
u64 mask;
struct {
- struct nouveau_gpuobj *mem[2];
+ struct nvkm_gpuobj *mem[2];
int active;
wait_queue_head_t wait;
} runlist;
struct {
- struct nouveau_gpuobj *mem;
- struct nouveau_vma bar;
+ struct nvkm_gpuobj *mem;
+ struct nvkm_vma bar;
} user;
int spoon_nr;
};
-struct nvc0_fifo_base {
- struct nouveau_fifo_base base;
- struct nouveau_gpuobj *pgd;
- struct nouveau_vm *vm;
+struct gf100_fifo_base {
+ struct nvkm_fifo_base base;
+ struct nvkm_gpuobj *pgd;
+ struct nvkm_vm *vm;
};
-struct nvc0_fifo_chan {
- struct nouveau_fifo_chan base;
+struct gf100_fifo_chan {
+ struct nvkm_fifo_chan base;
enum {
STOPPED,
RUNNING,
@@ -79,10 +74,10 @@ struct nvc0_fifo_chan {
******************************************************************************/
static void
-nvc0_fifo_runlist_update(struct nvc0_fifo_priv *priv)
+gf100_fifo_runlist_update(struct gf100_fifo_priv *priv)
{
- struct nouveau_bar *bar = nouveau_bar(priv);
- struct nouveau_gpuobj *cur;
+ struct nvkm_bar *bar = nvkm_bar(priv);
+ struct nvkm_gpuobj *cur;
int i, p;
mutex_lock(&nv_subdev(priv)->mutex);
@@ -90,7 +85,7 @@ nvc0_fifo_runlist_update(struct nvc0_fifo_priv *priv)
priv->runlist.active = !priv->runlist.active;
for (i = 0, p = 0; i < 128; i++) {
- struct nvc0_fifo_chan *chan = (void *)priv->base.channel[i];
+ struct gf100_fifo_chan *chan = (void *)priv->base.channel[i];
if (chan && chan->state == RUNNING) {
nv_wo32(cur, p + 0, i);
nv_wo32(cur, p + 4, 0x00000004);
@@ -110,30 +105,30 @@ nvc0_fifo_runlist_update(struct nvc0_fifo_priv *priv)
}
static int
-nvc0_fifo_context_attach(struct nouveau_object *parent,
- struct nouveau_object *object)
+gf100_fifo_context_attach(struct nvkm_object *parent,
+ struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
- struct nvc0_fifo_base *base = (void *)parent->parent;
- struct nouveau_engctx *ectx = (void *)object;
+ struct nvkm_bar *bar = nvkm_bar(parent);
+ struct gf100_fifo_base *base = (void *)parent->parent;
+ struct nvkm_engctx *ectx = (void *)object;
u32 addr;
int ret;
switch (nv_engidx(object->engine)) {
- case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR : addr = 0x0210; break;
- case NVDEV_ENGINE_COPY0: addr = 0x0230; break;
- case NVDEV_ENGINE_COPY1: addr = 0x0240; break;
- case NVDEV_ENGINE_BSP : addr = 0x0270; break;
- case NVDEV_ENGINE_VP : addr = 0x0250; break;
- case NVDEV_ENGINE_PPP : addr = 0x0260; break;
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_CE0 : addr = 0x0230; break;
+ case NVDEV_ENGINE_CE1 : addr = 0x0240; break;
+ case NVDEV_ENGINE_MSVLD : addr = 0x0270; break;
+ case NVDEV_ENGINE_MSPDEC: addr = 0x0250; break;
+ case NVDEV_ENGINE_MSPPP : addr = 0x0260; break;
default:
return -EINVAL;
}
if (!ectx->vma.node) {
- ret = nouveau_gpuobj_map_vm(nv_gpuobj(ectx), base->vm,
- NV_MEM_ACCESS_RW, &ectx->vma);
+ ret = nvkm_gpuobj_map_vm(nv_gpuobj(ectx), base->vm,
+ NV_MEM_ACCESS_RW, &ectx->vma);
if (ret)
return ret;
@@ -147,23 +142,23 @@ nvc0_fifo_context_attach(struct nouveau_object *parent,
}
static int
-nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
- struct nouveau_object *object)
+gf100_fifo_context_detach(struct nvkm_object *parent, bool suspend,
+ struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
- struct nvc0_fifo_priv *priv = (void *)parent->engine;
- struct nvc0_fifo_base *base = (void *)parent->parent;
- struct nvc0_fifo_chan *chan = (void *)parent;
+ struct nvkm_bar *bar = nvkm_bar(parent);
+ struct gf100_fifo_priv *priv = (void *)parent->engine;
+ struct gf100_fifo_base *base = (void *)parent->parent;
+ struct gf100_fifo_chan *chan = (void *)parent;
u32 addr;
switch (nv_engidx(object->engine)) {
- case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR : addr = 0x0210; break;
- case NVDEV_ENGINE_COPY0: addr = 0x0230; break;
- case NVDEV_ENGINE_COPY1: addr = 0x0240; break;
- case NVDEV_ENGINE_BSP : addr = 0x0270; break;
- case NVDEV_ENGINE_VP : addr = 0x0250; break;
- case NVDEV_ENGINE_PPP : addr = 0x0260; break;
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_CE0 : addr = 0x0230; break;
+ case NVDEV_ENGINE_CE1 : addr = 0x0240; break;
+ case NVDEV_ENGINE_MSVLD : addr = 0x0270; break;
+ case NVDEV_ENGINE_MSPDEC: addr = 0x0250; break;
+ case NVDEV_ENGINE_MSPPP : addr = 0x0260; break;
default:
return -EINVAL;
}
@@ -171,7 +166,7 @@ nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
nv_wr32(priv, 0x002634, chan->base.chid);
if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
nv_error(priv, "channel %d [%s] kick timeout\n",
- chan->base.chid, nouveau_client_name(chan));
+ chan->base.chid, nvkm_client_name(chan));
if (suspend)
return -EBUSY;
}
@@ -183,18 +178,17 @@ nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
}
static int
-nvc0_fifo_chan_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_channel_gpfifo_v0 v0;
} *args = data;
- struct nouveau_bar *bar = nouveau_bar(parent);
- struct nvc0_fifo_priv *priv = (void *)engine;
- struct nvc0_fifo_base *base = (void *)parent;
- struct nvc0_fifo_chan *chan;
+ struct nvkm_bar *bar = nvkm_bar(parent);
+ struct gf100_fifo_priv *priv = (void *)engine;
+ struct gf100_fifo_base *base = (void *)parent;
+ struct gf100_fifo_chan *chan;
u64 usermem, ioffset, ilength;
int ret, i;
@@ -207,24 +201,24 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
- priv->user.bar.offset, 0x1000,
- args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR) |
- (1ULL << NVDEV_ENGINE_COPY0) |
- (1ULL << NVDEV_ENGINE_COPY1) |
- (1ULL << NVDEV_ENGINE_BSP) |
- (1ULL << NVDEV_ENGINE_VP) |
- (1ULL << NVDEV_ENGINE_PPP), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 1,
+ priv->user.bar.offset, 0x1000,
+ args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR) |
+ (1ULL << NVDEV_ENGINE_CE0) |
+ (1ULL << NVDEV_ENGINE_CE1) |
+ (1ULL << NVDEV_ENGINE_MSVLD) |
+ (1ULL << NVDEV_ENGINE_MSPDEC) |
+ (1ULL << NVDEV_ENGINE_MSPPP), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
args->v0.chid = chan->base.chid;
- nv_parent(chan)->context_attach = nvc0_fifo_context_attach;
- nv_parent(chan)->context_detach = nvc0_fifo_context_detach;
+ nv_parent(chan)->context_attach = gf100_fifo_context_attach;
+ nv_parent(chan)->context_detach = gf100_fifo_context_detach;
usermem = chan->base.chid * 0x1000;
ioffset = args->v0.ioffset;
@@ -254,15 +248,15 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent,
}
static int
-nvc0_fifo_chan_init(struct nouveau_object *object)
+gf100_fifo_chan_init(struct nvkm_object *object)
{
- struct nouveau_gpuobj *base = nv_gpuobj(object->parent);
- struct nvc0_fifo_priv *priv = (void *)object->engine;
- struct nvc0_fifo_chan *chan = (void *)object;
+ struct nvkm_gpuobj *base = nv_gpuobj(object->parent);
+ struct gf100_fifo_priv *priv = (void *)object->engine;
+ struct gf100_fifo_chan *chan = (void *)object;
u32 chid = chan->base.chid;
int ret;
- ret = nouveau_fifo_channel_init(&chan->base);
+ ret = nvkm_fifo_channel_init(&chan->base);
if (ret)
return ret;
@@ -270,47 +264,47 @@ nvc0_fifo_chan_init(struct nouveau_object *object)
if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) {
nv_wr32(priv, 0x003004 + (chid * 8), 0x001f0001);
- nvc0_fifo_runlist_update(priv);
+ gf100_fifo_runlist_update(priv);
}
return 0;
}
-static void nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv);
+static void gf100_fifo_intr_engine(struct gf100_fifo_priv *priv);
static int
-nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+gf100_fifo_chan_fini(struct nvkm_object *object, bool suspend)
{
- struct nvc0_fifo_priv *priv = (void *)object->engine;
- struct nvc0_fifo_chan *chan = (void *)object;
+ struct gf100_fifo_priv *priv = (void *)object->engine;
+ struct gf100_fifo_chan *chan = (void *)object;
u32 chid = chan->base.chid;
if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) {
nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000);
- nvc0_fifo_runlist_update(priv);
+ gf100_fifo_runlist_update(priv);
}
- nvc0_fifo_intr_engine(priv);
+ gf100_fifo_intr_engine(priv);
nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000);
- return nouveau_fifo_channel_fini(&chan->base, suspend);
+ return nvkm_fifo_channel_fini(&chan->base, suspend);
}
-static struct nouveau_ofuncs
-nvc0_fifo_ofuncs = {
- .ctor = nvc0_fifo_chan_ctor,
- .dtor = _nouveau_fifo_channel_dtor,
- .init = nvc0_fifo_chan_init,
- .fini = nvc0_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+static struct nvkm_ofuncs
+gf100_fifo_ofuncs = {
+ .ctor = gf100_fifo_chan_ctor,
+ .dtor = _nvkm_fifo_channel_dtor,
+ .init = gf100_fifo_chan_init,
+ .fini = gf100_fifo_chan_fini,
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
-nvc0_fifo_sclass[] = {
- { FERMI_CHANNEL_GPFIFO, &nvc0_fifo_ofuncs },
+static struct nvkm_oclass
+gf100_fifo_sclass[] = {
+ { FERMI_CHANNEL_GPFIFO, &gf100_fifo_ofuncs },
{}
};
@@ -319,23 +313,22 @@ nvc0_fifo_sclass[] = {
******************************************************************************/
static int
-nvc0_fifo_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_fifo_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_fifo_base *base;
+ struct gf100_fifo_base *base;
int ret;
- ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
- 0x1000, NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_HEAP, &base);
+ ret = nvkm_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
- &base->pgd);
+ ret = nvkm_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
+ &base->pgd);
if (ret)
return ret;
@@ -344,7 +337,7 @@ nvc0_fifo_context_ctor(struct nouveau_object *parent,
nv_wo32(base, 0x0208, 0xffffffff);
nv_wo32(base, 0x020c, 0x000000ff);
- ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ ret = nvkm_vm_ref(nvkm_client(parent)->vm, &base->vm, base->pgd);
if (ret)
return ret;
@@ -352,24 +345,24 @@ nvc0_fifo_context_ctor(struct nouveau_object *parent,
}
static void
-nvc0_fifo_context_dtor(struct nouveau_object *object)
+gf100_fifo_context_dtor(struct nvkm_object *object)
{
- struct nvc0_fifo_base *base = (void *)object;
- nouveau_vm_ref(NULL, &base->vm, base->pgd);
- nouveau_gpuobj_ref(NULL, &base->pgd);
- nouveau_fifo_context_destroy(&base->base);
+ struct gf100_fifo_base *base = (void *)object;
+ nvkm_vm_ref(NULL, &base->vm, base->pgd);
+ nvkm_gpuobj_ref(NULL, &base->pgd);
+ nvkm_fifo_context_destroy(&base->base);
}
-static struct nouveau_oclass
-nvc0_fifo_cclass = {
+static struct nvkm_oclass
+gf100_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_fifo_context_ctor,
- .dtor = nvc0_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_fifo_context_ctor,
+ .dtor = gf100_fifo_context_dtor,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -378,15 +371,15 @@ nvc0_fifo_cclass = {
******************************************************************************/
static inline int
-nvc0_fifo_engidx(struct nvc0_fifo_priv *priv, u32 engn)
+gf100_fifo_engidx(struct gf100_fifo_priv *priv, u32 engn)
{
switch (engn) {
- case NVDEV_ENGINE_GR : engn = 0; break;
- case NVDEV_ENGINE_BSP : engn = 1; break;
- case NVDEV_ENGINE_PPP : engn = 2; break;
- case NVDEV_ENGINE_VP : engn = 3; break;
- case NVDEV_ENGINE_COPY0: engn = 4; break;
- case NVDEV_ENGINE_COPY1: engn = 5; break;
+ case NVDEV_ENGINE_GR : engn = 0; break;
+ case NVDEV_ENGINE_MSVLD : engn = 1; break;
+ case NVDEV_ENGINE_MSPPP : engn = 2; break;
+ case NVDEV_ENGINE_MSPDEC: engn = 3; break;
+ case NVDEV_ENGINE_CE0 : engn = 4; break;
+ case NVDEV_ENGINE_CE1 : engn = 5; break;
default:
return -1;
}
@@ -394,28 +387,28 @@ nvc0_fifo_engidx(struct nvc0_fifo_priv *priv, u32 engn)
return engn;
}
-static inline struct nouveau_engine *
-nvc0_fifo_engine(struct nvc0_fifo_priv *priv, u32 engn)
+static inline struct nvkm_engine *
+gf100_fifo_engine(struct gf100_fifo_priv *priv, u32 engn)
{
switch (engn) {
case 0: engn = NVDEV_ENGINE_GR; break;
- case 1: engn = NVDEV_ENGINE_BSP; break;
- case 2: engn = NVDEV_ENGINE_PPP; break;
- case 3: engn = NVDEV_ENGINE_VP; break;
- case 4: engn = NVDEV_ENGINE_COPY0; break;
- case 5: engn = NVDEV_ENGINE_COPY1; break;
+ case 1: engn = NVDEV_ENGINE_MSVLD; break;
+ case 2: engn = NVDEV_ENGINE_MSPPP; break;
+ case 3: engn = NVDEV_ENGINE_MSPDEC; break;
+ case 4: engn = NVDEV_ENGINE_CE0; break;
+ case 5: engn = NVDEV_ENGINE_CE1; break;
default:
return NULL;
}
- return nouveau_engine(priv, engn);
+ return nvkm_engine(priv, engn);
}
static void
-nvc0_fifo_recover_work(struct work_struct *work)
+gf100_fifo_recover_work(struct work_struct *work)
{
- struct nvc0_fifo_priv *priv = container_of(work, typeof(*priv), fault);
- struct nouveau_object *engine;
+ struct gf100_fifo_priv *priv = container_of(work, typeof(*priv), fault);
+ struct nvkm_object *engine;
unsigned long flags;
u32 engn, engm = 0;
u64 mask, todo;
@@ -426,26 +419,25 @@ nvc0_fifo_recover_work(struct work_struct *work)
spin_unlock_irqrestore(&priv->base.lock, flags);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
- engm |= 1 << nvc0_fifo_engidx(priv, engn);
+ engm |= 1 << gf100_fifo_engidx(priv, engn);
nv_mask(priv, 0x002630, engm, engm);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
- if ((engine = (void *)nouveau_engine(priv, engn))) {
+ if ((engine = (void *)nvkm_engine(priv, engn))) {
nv_ofuncs(engine)->fini(engine, false);
WARN_ON(nv_ofuncs(engine)->init(engine));
}
}
- nvc0_fifo_runlist_update(priv);
+ gf100_fifo_runlist_update(priv);
nv_wr32(priv, 0x00262c, engm);
nv_mask(priv, 0x002630, engm, 0x00000000);
}
static void
-nvc0_fifo_recover(struct nvc0_fifo_priv *priv, struct nouveau_engine *engine,
- struct nvc0_fifo_chan *chan)
+gf100_fifo_recover(struct gf100_fifo_priv *priv, struct nvkm_engine *engine,
+ struct gf100_fifo_chan *chan)
{
- struct nouveau_object *engobj = nv_object(engine);
u32 chid = chan->base.chid;
unsigned long flags;
@@ -456,16 +448,16 @@ nvc0_fifo_recover(struct nvc0_fifo_priv *priv, struct nouveau_engine *engine,
chan->state = KILLED;
spin_lock_irqsave(&priv->base.lock, flags);
- priv->mask |= 1ULL << nv_engidx(engobj);
+ priv->mask |= 1ULL << nv_engidx(engine);
spin_unlock_irqrestore(&priv->base.lock, flags);
schedule_work(&priv->fault);
}
static int
-nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
+gf100_fifo_swmthd(struct gf100_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
{
- struct nvc0_fifo_chan *chan = NULL;
- struct nouveau_handle *bind;
+ struct gf100_fifo_chan *chan = NULL;
+ struct nvkm_handle *bind;
unsigned long flags;
int ret = -EINVAL;
@@ -475,11 +467,11 @@ nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
if (unlikely(!chan))
goto out;
- bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
+ bind = nvkm_namedb_get_class(nv_namedb(chan), 0x906e);
if (likely(bind)) {
if (!mthd || !nv_call(bind->object, mthd, data))
ret = 0;
- nouveau_namedb_put(bind);
+ nvkm_namedb_put(bind);
}
out:
@@ -487,17 +479,17 @@ out:
return ret;
}
-static const struct nouveau_enum
-nvc0_fifo_sched_reason[] = {
+static const struct nvkm_enum
+gf100_fifo_sched_reason[] = {
{ 0x0a, "CTXSW_TIMEOUT" },
{}
};
static void
-nvc0_fifo_intr_sched_ctxsw(struct nvc0_fifo_priv *priv)
+gf100_fifo_intr_sched_ctxsw(struct gf100_fifo_priv *priv)
{
- struct nouveau_engine *engine;
- struct nvc0_fifo_chan *chan;
+ struct nvkm_engine *engine;
+ struct gf100_fifo_chan *chan;
u32 engn;
for (engn = 0; engn < 6; engn++) {
@@ -512,22 +504,22 @@ nvc0_fifo_intr_sched_ctxsw(struct nvc0_fifo_priv *priv)
if (busy && unk0 && unk1) {
if (!(chan = (void *)priv->base.channel[chid]))
continue;
- if (!(engine = nvc0_fifo_engine(priv, engn)))
+ if (!(engine = gf100_fifo_engine(priv, engn)))
continue;
- nvc0_fifo_recover(priv, engine, chan);
+ gf100_fifo_recover(priv, engine, chan);
}
}
}
static void
-nvc0_fifo_intr_sched(struct nvc0_fifo_priv *priv)
+gf100_fifo_intr_sched(struct gf100_fifo_priv *priv)
{
u32 intr = nv_rd32(priv, 0x00254c);
u32 code = intr & 0x000000ff;
- const struct nouveau_enum *en;
+ const struct nvkm_enum *en;
char enunk[6] = "";
- en = nouveau_enum_find(nvc0_fifo_sched_reason, code);
+ en = nvkm_enum_find(gf100_fifo_sched_reason, code);
if (!en)
snprintf(enunk, sizeof(enunk), "UNK%02x", code);
@@ -535,32 +527,32 @@ nvc0_fifo_intr_sched(struct nvc0_fifo_priv *priv)
switch (code) {
case 0x0a:
- nvc0_fifo_intr_sched_ctxsw(priv);
+ gf100_fifo_intr_sched_ctxsw(priv);
break;
default:
break;
}
}
-static const struct nouveau_enum
-nvc0_fifo_fault_engine[] = {
+static const struct nvkm_enum
+gf100_fifo_fault_engine[] = {
{ 0x00, "PGRAPH", NULL, NVDEV_ENGINE_GR },
{ 0x03, "PEEPHOLE", NULL, NVDEV_ENGINE_IFB },
{ 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR },
{ 0x05, "BAR3", NULL, NVDEV_SUBDEV_INSTMEM },
{ 0x07, "PFIFO", NULL, NVDEV_ENGINE_FIFO },
- { 0x10, "PBSP", NULL, NVDEV_ENGINE_BSP },
- { 0x11, "PPPP", NULL, NVDEV_ENGINE_PPP },
+ { 0x10, "PMSVLD", NULL, NVDEV_ENGINE_MSVLD },
+ { 0x11, "PMSPPP", NULL, NVDEV_ENGINE_MSPPP },
{ 0x13, "PCOUNTER" },
- { 0x14, "PVP", NULL, NVDEV_ENGINE_VP },
- { 0x15, "PCOPY0", NULL, NVDEV_ENGINE_COPY0 },
- { 0x16, "PCOPY1", NULL, NVDEV_ENGINE_COPY1 },
+ { 0x14, "PMSPDEC", NULL, NVDEV_ENGINE_MSPDEC },
+ { 0x15, "PCE0", NULL, NVDEV_ENGINE_CE0 },
+ { 0x16, "PCE1", NULL, NVDEV_ENGINE_CE1 },
{ 0x17, "PDAEMON" },
{}
};
-static const struct nouveau_enum
-nvc0_fifo_fault_reason[] = {
+static const struct nvkm_enum
+gf100_fifo_fault_reason[] = {
{ 0x00, "PT_NOT_PRESENT" },
{ 0x01, "PT_TOO_SHORT" },
{ 0x02, "PAGE_NOT_PRESENT" },
@@ -573,8 +565,8 @@ nvc0_fifo_fault_reason[] = {
{}
};
-static const struct nouveau_enum
-nvc0_fifo_fault_hubclient[] = {
+static const struct nvkm_enum
+gf100_fifo_fault_hubclient[] = {
{ 0x01, "PCOPY0" },
{ 0x02, "PCOPY1" },
{ 0x04, "DISPATCH" },
@@ -583,8 +575,8 @@ nvc0_fifo_fault_hubclient[] = {
{ 0x07, "BAR_READ" },
{ 0x08, "BAR_WRITE" },
{ 0x0b, "PVP" },
- { 0x0c, "PPPP" },
- { 0x0d, "PBSP" },
+ { 0x0c, "PMSPPP" },
+ { 0x0d, "PMSVLD" },
{ 0x11, "PCOUNTER" },
{ 0x12, "PDAEMON" },
{ 0x14, "CCACHE" },
@@ -592,8 +584,8 @@ nvc0_fifo_fault_hubclient[] = {
{}
};
-static const struct nouveau_enum
-nvc0_fifo_fault_gpcclient[] = {
+static const struct nvkm_enum
+gf100_fifo_fault_gpcclient[] = {
{ 0x01, "TEX" },
{ 0x0c, "ESETUP" },
{ 0x0e, "CTXCTL" },
@@ -602,7 +594,7 @@ nvc0_fifo_fault_gpcclient[] = {
};
static void
-nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit)
+gf100_fifo_intr_fault(struct gf100_fifo_priv *priv, int unit)
{
u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10));
u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10));
@@ -613,19 +605,19 @@ nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit)
u32 write = (stat & 0x00000080);
u32 hub = (stat & 0x00000040);
u32 reason = (stat & 0x0000000f);
- struct nouveau_object *engctx = NULL, *object;
- struct nouveau_engine *engine = NULL;
- const struct nouveau_enum *er, *eu, *ec;
+ struct nvkm_object *engctx = NULL, *object;
+ struct nvkm_engine *engine = NULL;
+ const struct nvkm_enum *er, *eu, *ec;
char erunk[6] = "";
char euunk[6] = "";
char ecunk[6] = "";
char gpcid[3] = "";
- er = nouveau_enum_find(nvc0_fifo_fault_reason, reason);
+ er = nvkm_enum_find(gf100_fifo_fault_reason, reason);
if (!er)
snprintf(erunk, sizeof(erunk), "UNK%02X", reason);
- eu = nouveau_enum_find(nvc0_fifo_fault_engine, unit);
+ eu = nvkm_enum_find(gf100_fifo_fault_engine, unit);
if (eu) {
switch (eu->data2) {
case NVDEV_SUBDEV_BAR:
@@ -638,9 +630,9 @@ nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit)
nv_mask(priv, 0x001718, 0x00000000, 0x00000000);
break;
default:
- engine = nouveau_engine(priv, eu->data2);
+ engine = nvkm_engine(priv, eu->data2);
if (engine)
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
break;
}
} else {
@@ -648,9 +640,9 @@ nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit)
}
if (hub) {
- ec = nouveau_enum_find(nvc0_fifo_fault_hubclient, client);
+ ec = nvkm_enum_find(gf100_fifo_fault_hubclient, client);
} else {
- ec = nouveau_enum_find(nvc0_fifo_fault_gpcclient, client);
+ ec = nvkm_enum_find(gf100_fifo_fault_gpcclient, client);
snprintf(gpcid, sizeof(gpcid), "%d", gpc);
}
@@ -662,23 +654,23 @@ nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit)
(u64)vahi << 32 | valo, er ? er->name : erunk,
eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/",
ec ? ec->name : ecunk, (u64)inst << 12,
- nouveau_client_name(engctx));
+ nvkm_client_name(engctx));
object = engctx;
while (object) {
switch (nv_mclass(object)) {
case FERMI_CHANNEL_GPFIFO:
- nvc0_fifo_recover(priv, engine, (void *)object);
+ gf100_fifo_recover(priv, engine, (void *)object);
break;
}
object = object->parent;
}
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
-static const struct nouveau_bitfield
-nvc0_fifo_pbdma_intr[] = {
+static const struct nvkm_bitfield
+gf100_fifo_pbdma_intr[] = {
/* { 0x00008000, "" } seen with null ib push */
{ 0x00200000, "ILLEGAL_MTHD" },
{ 0x00800000, "EMPTY_SUBC" },
@@ -686,7 +678,7 @@ nvc0_fifo_pbdma_intr[] = {
};
static void
-nvc0_fifo_intr_pbdma(struct nvc0_fifo_priv *priv, int unit)
+gf100_fifo_intr_pbdma(struct gf100_fifo_priv *priv, int unit)
{
u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000));
u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000));
@@ -697,18 +689,18 @@ nvc0_fifo_intr_pbdma(struct nvc0_fifo_priv *priv, int unit)
u32 show = stat;
if (stat & 0x00800000) {
- if (!nvc0_fifo_swmthd(priv, chid, mthd, data))
+ if (!gf100_fifo_swmthd(priv, chid, mthd, data))
show &= ~0x00800000;
}
if (show) {
nv_error(priv, "PBDMA%d:", unit);
- nouveau_bitfield_print(nvc0_fifo_pbdma_intr, show);
+ nvkm_bitfield_print(gf100_fifo_pbdma_intr, show);
pr_cont("\n");
nv_error(priv,
"PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
unit, chid,
- nouveau_client_name_for_fifo_chid(&priv->base, chid),
+ nvkm_client_name_for_fifo_chid(&priv->base, chid),
subc, mthd, data);
}
@@ -717,7 +709,7 @@ nvc0_fifo_intr_pbdma(struct nvc0_fifo_priv *priv, int unit)
}
static void
-nvc0_fifo_intr_runlist(struct nvc0_fifo_priv *priv)
+gf100_fifo_intr_runlist(struct gf100_fifo_priv *priv)
{
u32 intr = nv_rd32(priv, 0x002a00);
@@ -734,7 +726,7 @@ nvc0_fifo_intr_runlist(struct nvc0_fifo_priv *priv)
}
static void
-nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
+gf100_fifo_intr_engine_unit(struct gf100_fifo_priv *priv, int engn)
{
u32 intr = nv_rd32(priv, 0x0025a8 + (engn * 0x04));
u32 inte = nv_rd32(priv, 0x002628);
@@ -745,7 +737,7 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
for (unkn = 0; unkn < 8; unkn++) {
u32 ints = (intr >> (unkn * 0x04)) & inte;
if (ints & 0x1) {
- nouveau_fifo_uevent(&priv->base);
+ nvkm_fifo_uevent(&priv->base);
ints &= ~1;
}
if (ints) {
@@ -756,20 +748,20 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
}
static void
-nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv)
+gf100_fifo_intr_engine(struct gf100_fifo_priv *priv)
{
u32 mask = nv_rd32(priv, 0x0025a4);
while (mask) {
u32 unit = __ffs(mask);
- nvc0_fifo_intr_engine_unit(priv, unit);
+ gf100_fifo_intr_engine_unit(priv, unit);
mask &= ~(1 << unit);
}
}
static void
-nvc0_fifo_intr(struct nouveau_subdev *subdev)
+gf100_fifo_intr(struct nvkm_subdev *subdev)
{
- struct nvc0_fifo_priv *priv = (void *)subdev;
+ struct gf100_fifo_priv *priv = (void *)subdev;
u32 mask = nv_rd32(priv, 0x002140);
u32 stat = nv_rd32(priv, 0x002100) & mask;
@@ -781,7 +773,7 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x00000100) {
- nvc0_fifo_intr_sched(priv);
+ gf100_fifo_intr_sched(priv);
nv_wr32(priv, 0x002100, 0x00000100);
stat &= ~0x00000100;
}
@@ -804,7 +796,7 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
u32 mask = nv_rd32(priv, 0x00259c);
while (mask) {
u32 unit = __ffs(mask);
- nvc0_fifo_intr_fault(priv, unit);
+ gf100_fifo_intr_fault(priv, unit);
nv_wr32(priv, 0x00259c, (1 << unit));
mask &= ~(1 << unit);
}
@@ -815,7 +807,7 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
u32 mask = nv_rd32(priv, 0x0025a0);
while (mask) {
u32 unit = __ffs(mask);
- nvc0_fifo_intr_pbdma(priv, unit);
+ gf100_fifo_intr_pbdma(priv, unit);
nv_wr32(priv, 0x0025a0, (1 << unit));
mask &= ~(1 << unit);
}
@@ -823,12 +815,12 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x40000000) {
- nvc0_fifo_intr_runlist(priv);
+ gf100_fifo_intr_runlist(priv);
stat &= ~0x40000000;
}
if (stat & 0x80000000) {
- nvc0_fifo_intr_engine(priv);
+ gf100_fifo_intr_engine(priv);
stat &= ~0x80000000;
}
@@ -840,94 +832,94 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
}
static void
-nvc0_fifo_uevent_init(struct nvkm_event *event, int type, int index)
+gf100_fifo_uevent_init(struct nvkm_event *event, int type, int index)
{
- struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
nv_mask(fifo, 0x002140, 0x80000000, 0x80000000);
}
static void
-nvc0_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
+gf100_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
{
- struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
nv_mask(fifo, 0x002140, 0x80000000, 0x00000000);
}
static const struct nvkm_event_func
-nvc0_fifo_uevent_func = {
- .ctor = nouveau_fifo_uevent_ctor,
- .init = nvc0_fifo_uevent_init,
- .fini = nvc0_fifo_uevent_fini,
+gf100_fifo_uevent_func = {
+ .ctor = nvkm_fifo_uevent_ctor,
+ .init = gf100_fifo_uevent_init,
+ .fini = gf100_fifo_uevent_fini,
};
static int
-nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_fifo_priv *priv;
+ struct gf100_fifo_priv *priv;
int ret;
- ret = nouveau_fifo_create(parent, engine, oclass, 0, 127, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 0, 127, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- INIT_WORK(&priv->fault, nvc0_fifo_recover_work);
+ INIT_WORK(&priv->fault, gf100_fifo_recover_work);
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
- &priv->runlist.mem[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
+ &priv->runlist.mem[0]);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
- &priv->runlist.mem[1]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
+ &priv->runlist.mem[1]);
if (ret)
return ret;
init_waitqueue_head(&priv->runlist.wait);
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 0x1000, 0x1000, 0,
- &priv->user.mem);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 128 * 0x1000, 0x1000, 0,
+ &priv->user.mem);
if (ret)
return ret;
- ret = nouveau_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW,
- &priv->user.bar);
+ ret = nvkm_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW,
+ &priv->user.bar);
if (ret)
return ret;
- ret = nvkm_event_init(&nvc0_fifo_uevent_func, 1, 1, &priv->base.uevent);
+ ret = nvkm_event_init(&gf100_fifo_uevent_func, 1, 1, &priv->base.uevent);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000100;
- nv_subdev(priv)->intr = nvc0_fifo_intr;
- nv_engine(priv)->cclass = &nvc0_fifo_cclass;
- nv_engine(priv)->sclass = nvc0_fifo_sclass;
+ nv_subdev(priv)->intr = gf100_fifo_intr;
+ nv_engine(priv)->cclass = &gf100_fifo_cclass;
+ nv_engine(priv)->sclass = gf100_fifo_sclass;
return 0;
}
static void
-nvc0_fifo_dtor(struct nouveau_object *object)
+gf100_fifo_dtor(struct nvkm_object *object)
{
- struct nvc0_fifo_priv *priv = (void *)object;
+ struct gf100_fifo_priv *priv = (void *)object;
- nouveau_gpuobj_unmap(&priv->user.bar);
- nouveau_gpuobj_ref(NULL, &priv->user.mem);
- nouveau_gpuobj_ref(NULL, &priv->runlist.mem[0]);
- nouveau_gpuobj_ref(NULL, &priv->runlist.mem[1]);
+ nvkm_gpuobj_unmap(&priv->user.bar);
+ nvkm_gpuobj_ref(NULL, &priv->user.mem);
+ nvkm_gpuobj_ref(NULL, &priv->runlist.mem[0]);
+ nvkm_gpuobj_ref(NULL, &priv->runlist.mem[1]);
- nouveau_fifo_destroy(&priv->base);
+ nvkm_fifo_destroy(&priv->base);
}
static int
-nvc0_fifo_init(struct nouveau_object *object)
+gf100_fifo_init(struct nvkm_object *object)
{
- struct nvc0_fifo_priv *priv = (void *)object;
+ struct gf100_fifo_priv *priv = (void *)object;
int ret, i;
- ret = nouveau_fifo_init(&priv->base);
+ ret = nvkm_fifo_init(&priv->base);
if (ret)
return ret;
@@ -941,8 +933,8 @@ nvc0_fifo_init(struct nouveau_object *object)
if (priv->spoon_nr >= 3) {
nv_wr32(priv, 0x002208, ~(1 << 0)); /* PGRAPH */
nv_wr32(priv, 0x00220c, ~(1 << 1)); /* PVP */
- nv_wr32(priv, 0x002210, ~(1 << 1)); /* PPP */
- nv_wr32(priv, 0x002214, ~(1 << 1)); /* PBSP */
+ nv_wr32(priv, 0x002210, ~(1 << 1)); /* PMSPP */
+ nv_wr32(priv, 0x002214, ~(1 << 1)); /* PMSVLD */
nv_wr32(priv, 0x002218, ~(1 << 2)); /* PCE0 */
nv_wr32(priv, 0x00221c, ~(1 << 1)); /* PCE1 */
}
@@ -963,13 +955,13 @@ nvc0_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nvc0_fifo_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+gf100_fifo_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(FIFO, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_fifo_ctor,
- .dtor = nvc0_fifo_dtor,
- .init = nvc0_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_fifo_ctor,
+ .dtor = gf100_fifo_dtor,
+ .init = gf100_fifo_init,
+ .fini = _nvkm_fifo_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
index 6a8db7c80bd1..9585539e59f2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
@@ -21,25 +21,19 @@
*
* Authors: Ben Skeggs
*/
+#include "gk104.h"
#include <core/client.h>
-#include <core/handle.h>
-#include <core/namedb.h>
-#include <core/gpuobj.h>
#include <core/engctx.h>
-#include <core/event.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
#include <core/enum.h>
-
-#include <subdev/timer.h>
+#include <core/handle.h>
#include <subdev/bar.h>
#include <subdev/fb.h>
-#include <subdev/vm.h>
-
-#include <engine/dmaobj.h>
+#include <subdev/mmu.h>
+#include <subdev/timer.h>
-#include "nve0.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
#define _(a,b) { (a), ((1ULL << (a)) | (b)) }
static const struct {
@@ -47,45 +41,45 @@ static const struct {
u64 mask;
} fifo_engine[] = {
_(NVDEV_ENGINE_GR , (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_COPY2)),
- _(NVDEV_ENGINE_VP , 0),
- _(NVDEV_ENGINE_PPP , 0),
- _(NVDEV_ENGINE_BSP , 0),
- _(NVDEV_ENGINE_COPY0 , 0),
- _(NVDEV_ENGINE_COPY1 , 0),
- _(NVDEV_ENGINE_VENC , 0),
+ (1ULL << NVDEV_ENGINE_CE2)),
+ _(NVDEV_ENGINE_MSPDEC , 0),
+ _(NVDEV_ENGINE_MSPPP , 0),
+ _(NVDEV_ENGINE_MSVLD , 0),
+ _(NVDEV_ENGINE_CE0 , 0),
+ _(NVDEV_ENGINE_CE1 , 0),
+ _(NVDEV_ENGINE_MSENC , 0),
};
#undef _
#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
-struct nve0_fifo_engn {
- struct nouveau_gpuobj *runlist[2];
+struct gk104_fifo_engn {
+ struct nvkm_gpuobj *runlist[2];
int cur_runlist;
wait_queue_head_t wait;
};
-struct nve0_fifo_priv {
- struct nouveau_fifo base;
+struct gk104_fifo_priv {
+ struct nvkm_fifo base;
struct work_struct fault;
u64 mask;
- struct nve0_fifo_engn engine[FIFO_ENGINE_NR];
+ struct gk104_fifo_engn engine[FIFO_ENGINE_NR];
struct {
- struct nouveau_gpuobj *mem;
- struct nouveau_vma bar;
+ struct nvkm_gpuobj *mem;
+ struct nvkm_vma bar;
} user;
int spoon_nr;
};
-struct nve0_fifo_base {
- struct nouveau_fifo_base base;
- struct nouveau_gpuobj *pgd;
- struct nouveau_vm *vm;
+struct gk104_fifo_base {
+ struct nvkm_fifo_base base;
+ struct nvkm_gpuobj *pgd;
+ struct nvkm_vm *vm;
};
-struct nve0_fifo_chan {
- struct nouveau_fifo_chan base;
+struct gk104_fifo_chan {
+ struct nvkm_fifo_chan base;
u32 engine;
enum {
STOPPED,
@@ -99,11 +93,11 @@ struct nve0_fifo_chan {
******************************************************************************/
static void
-nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine)
+gk104_fifo_runlist_update(struct gk104_fifo_priv *priv, u32 engine)
{
- struct nouveau_bar *bar = nouveau_bar(priv);
- struct nve0_fifo_engn *engn = &priv->engine[engine];
- struct nouveau_gpuobj *cur;
+ struct nvkm_bar *bar = nvkm_bar(priv);
+ struct gk104_fifo_engn *engn = &priv->engine[engine];
+ struct nvkm_gpuobj *cur;
int i, p;
mutex_lock(&nv_subdev(priv)->mutex);
@@ -111,7 +105,7 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine)
engn->cur_runlist = !engn->cur_runlist;
for (i = 0, p = 0; i < priv->base.max; i++) {
- struct nve0_fifo_chan *chan = (void *)priv->base.channel[i];
+ struct gk104_fifo_chan *chan = (void *)priv->base.channel[i];
if (chan && chan->state == RUNNING && chan->engine == engine) {
nv_wo32(cur, p + 0, i);
nv_wo32(cur, p + 4, 0x00000000);
@@ -131,34 +125,34 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine)
}
static int
-nve0_fifo_context_attach(struct nouveau_object *parent,
- struct nouveau_object *object)
+gk104_fifo_context_attach(struct nvkm_object *parent,
+ struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
- struct nve0_fifo_base *base = (void *)parent->parent;
- struct nouveau_engctx *ectx = (void *)object;
+ struct nvkm_bar *bar = nvkm_bar(parent);
+ struct gk104_fifo_base *base = (void *)parent->parent;
+ struct nvkm_engctx *ectx = (void *)object;
u32 addr;
int ret;
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW :
return 0;
- case NVDEV_ENGINE_COPY0:
- case NVDEV_ENGINE_COPY1:
- case NVDEV_ENGINE_COPY2:
+ case NVDEV_ENGINE_CE0:
+ case NVDEV_ENGINE_CE1:
+ case NVDEV_ENGINE_CE2:
nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
return 0;
- case NVDEV_ENGINE_GR : addr = 0x0210; break;
- case NVDEV_ENGINE_BSP : addr = 0x0270; break;
- case NVDEV_ENGINE_VP : addr = 0x0250; break;
- case NVDEV_ENGINE_PPP : addr = 0x0260; break;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_MSVLD : addr = 0x0270; break;
+ case NVDEV_ENGINE_MSPDEC: addr = 0x0250; break;
+ case NVDEV_ENGINE_MSPPP : addr = 0x0260; break;
default:
return -EINVAL;
}
if (!ectx->vma.node) {
- ret = nouveau_gpuobj_map_vm(nv_gpuobj(ectx), base->vm,
- NV_MEM_ACCESS_RW, &ectx->vma);
+ ret = nvkm_gpuobj_map_vm(nv_gpuobj(ectx), base->vm,
+ NV_MEM_ACCESS_RW, &ectx->vma);
if (ret)
return ret;
@@ -172,24 +166,24 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
}
static int
-nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
- struct nouveau_object *object)
+gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend,
+ struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
- struct nve0_fifo_priv *priv = (void *)parent->engine;
- struct nve0_fifo_base *base = (void *)parent->parent;
- struct nve0_fifo_chan *chan = (void *)parent;
+ struct nvkm_bar *bar = nvkm_bar(parent);
+ struct gk104_fifo_priv *priv = (void *)parent->engine;
+ struct gk104_fifo_base *base = (void *)parent->parent;
+ struct gk104_fifo_chan *chan = (void *)parent;
u32 addr;
switch (nv_engidx(object->engine)) {
- case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_COPY0:
- case NVDEV_ENGINE_COPY1:
- case NVDEV_ENGINE_COPY2: addr = 0x0000; break;
- case NVDEV_ENGINE_GR : addr = 0x0210; break;
- case NVDEV_ENGINE_BSP : addr = 0x0270; break;
- case NVDEV_ENGINE_VP : addr = 0x0250; break;
- case NVDEV_ENGINE_PPP : addr = 0x0260; break;
+ case NVDEV_ENGINE_SW : return 0;
+ case NVDEV_ENGINE_CE0 :
+ case NVDEV_ENGINE_CE1 :
+ case NVDEV_ENGINE_CE2 : addr = 0x0000; break;
+ case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_MSVLD : addr = 0x0270; break;
+ case NVDEV_ENGINE_MSPDEC: addr = 0x0250; break;
+ case NVDEV_ENGINE_MSPPP : addr = 0x0260; break;
default:
return -EINVAL;
}
@@ -197,7 +191,7 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
nv_wr32(priv, 0x002634, chan->base.chid);
if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
nv_error(priv, "channel %d [%s] kick timeout\n",
- chan->base.chid, nouveau_client_name(chan));
+ chan->base.chid, nvkm_client_name(chan));
if (suspend)
return -EBUSY;
}
@@ -212,18 +206,17 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
}
static int
-nve0_fifo_chan_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct kepler_channel_gpfifo_a_v0 v0;
} *args = data;
- struct nouveau_bar *bar = nouveau_bar(parent);
- struct nve0_fifo_priv *priv = (void *)engine;
- struct nve0_fifo_base *base = (void *)parent;
- struct nve0_fifo_chan *chan;
+ struct nvkm_bar *bar = nvkm_bar(parent);
+ struct gk104_fifo_priv *priv = (void *)engine;
+ struct gk104_fifo_base *base = (void *)parent;
+ struct gk104_fifo_chan *chan;
u64 usermem, ioffset, ilength;
int ret, i;
@@ -238,7 +231,7 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent,
for (i = 0; i < FIFO_ENGINE_NR; i++) {
if (args->v0.engine & (1 << i)) {
- if (nouveau_engine(parent, fifo_engine[i].subdev)) {
+ if (nvkm_engine(parent, fifo_engine[i].subdev)) {
args->v0.engine = (1 << i);
break;
}
@@ -250,18 +243,18 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent,
return -ENODEV;
}
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
- priv->user.bar.offset, 0x200,
- args->v0.pushbuf,
- fifo_engine[i].mask, &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 1,
+ priv->user.bar.offset, 0x200,
+ args->v0.pushbuf,
+ fifo_engine[i].mask, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
args->v0.chid = chan->base.chid;
- nv_parent(chan)->context_attach = nve0_fifo_context_attach;
- nv_parent(chan)->context_detach = nve0_fifo_context_detach;
+ nv_parent(chan)->context_attach = gk104_fifo_context_attach;
+ nv_parent(chan)->context_detach = gk104_fifo_context_detach;
chan->engine = i;
usermem = chan->base.chid * 0x200;
@@ -290,15 +283,15 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent,
}
static int
-nve0_fifo_chan_init(struct nouveau_object *object)
+gk104_fifo_chan_init(struct nvkm_object *object)
{
- struct nouveau_gpuobj *base = nv_gpuobj(object->parent);
- struct nve0_fifo_priv *priv = (void *)object->engine;
- struct nve0_fifo_chan *chan = (void *)object;
+ struct nvkm_gpuobj *base = nv_gpuobj(object->parent);
+ struct gk104_fifo_priv *priv = (void *)object->engine;
+ struct gk104_fifo_chan *chan = (void *)object;
u32 chid = chan->base.chid;
int ret;
- ret = nouveau_fifo_channel_init(&chan->base);
+ ret = nvkm_fifo_channel_init(&chan->base);
if (ret)
return ret;
@@ -307,7 +300,7 @@ nve0_fifo_chan_init(struct nouveau_object *object)
if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) {
nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
- nve0_fifo_runlist_update(priv, chan->engine);
+ gk104_fifo_runlist_update(priv, chan->engine);
nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
}
@@ -315,36 +308,36 @@ nve0_fifo_chan_init(struct nouveau_object *object)
}
static int
-nve0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+gk104_fifo_chan_fini(struct nvkm_object *object, bool suspend)
{
- struct nve0_fifo_priv *priv = (void *)object->engine;
- struct nve0_fifo_chan *chan = (void *)object;
+ struct gk104_fifo_priv *priv = (void *)object->engine;
+ struct gk104_fifo_chan *chan = (void *)object;
u32 chid = chan->base.chid;
if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) {
nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800);
- nve0_fifo_runlist_update(priv, chan->engine);
+ gk104_fifo_runlist_update(priv, chan->engine);
}
nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000);
- return nouveau_fifo_channel_fini(&chan->base, suspend);
+ return nvkm_fifo_channel_fini(&chan->base, suspend);
}
-static struct nouveau_ofuncs
-nve0_fifo_ofuncs = {
- .ctor = nve0_fifo_chan_ctor,
- .dtor = _nouveau_fifo_channel_dtor,
- .init = nve0_fifo_chan_init,
- .fini = nve0_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+static struct nvkm_ofuncs
+gk104_fifo_ofuncs = {
+ .ctor = gk104_fifo_chan_ctor,
+ .dtor = _nvkm_fifo_channel_dtor,
+ .init = gk104_fifo_chan_init,
+ .fini = gk104_fifo_chan_fini,
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
-nve0_fifo_sclass[] = {
- { KEPLER_CHANNEL_GPFIFO_A, &nve0_fifo_ofuncs },
+static struct nvkm_oclass
+gk104_fifo_sclass[] = {
+ { KEPLER_CHANNEL_GPFIFO_A, &gk104_fifo_ofuncs },
{}
};
@@ -353,22 +346,21 @@ nve0_fifo_sclass[] = {
******************************************************************************/
static int
-nve0_fifo_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_fifo_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nve0_fifo_base *base;
+ struct gk104_fifo_base *base;
int ret;
- ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
- 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base);
+ ret = nvkm_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base);
*pobject = nv_object(base);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
- &base->pgd);
+ ret = nvkm_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
+ &base->pgd);
if (ret)
return ret;
@@ -377,7 +369,7 @@ nve0_fifo_context_ctor(struct nouveau_object *parent,
nv_wo32(base, 0x0208, 0xffffffff);
nv_wo32(base, 0x020c, 0x000000ff);
- ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ ret = nvkm_vm_ref(nvkm_client(parent)->vm, &base->vm, base->pgd);
if (ret)
return ret;
@@ -385,24 +377,24 @@ nve0_fifo_context_ctor(struct nouveau_object *parent,
}
static void
-nve0_fifo_context_dtor(struct nouveau_object *object)
+gk104_fifo_context_dtor(struct nvkm_object *object)
{
- struct nve0_fifo_base *base = (void *)object;
- nouveau_vm_ref(NULL, &base->vm, base->pgd);
- nouveau_gpuobj_ref(NULL, &base->pgd);
- nouveau_fifo_context_destroy(&base->base);
+ struct gk104_fifo_base *base = (void *)object;
+ nvkm_vm_ref(NULL, &base->vm, base->pgd);
+ nvkm_gpuobj_ref(NULL, &base->pgd);
+ nvkm_fifo_context_destroy(&base->base);
}
-static struct nouveau_oclass
-nve0_fifo_cclass = {
+static struct nvkm_oclass
+gk104_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_fifo_context_ctor,
- .dtor = nve0_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_fifo_context_ctor,
+ .dtor = gk104_fifo_context_dtor,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -411,17 +403,17 @@ nve0_fifo_cclass = {
******************************************************************************/
static inline int
-nve0_fifo_engidx(struct nve0_fifo_priv *priv, u32 engn)
+gk104_fifo_engidx(struct gk104_fifo_priv *priv, u32 engn)
{
switch (engn) {
- case NVDEV_ENGINE_GR :
- case NVDEV_ENGINE_COPY2: engn = 0; break;
- case NVDEV_ENGINE_BSP : engn = 1; break;
- case NVDEV_ENGINE_PPP : engn = 2; break;
- case NVDEV_ENGINE_VP : engn = 3; break;
- case NVDEV_ENGINE_COPY0: engn = 4; break;
- case NVDEV_ENGINE_COPY1: engn = 5; break;
- case NVDEV_ENGINE_VENC : engn = 6; break;
+ case NVDEV_ENGINE_GR :
+ case NVDEV_ENGINE_CE2 : engn = 0; break;
+ case NVDEV_ENGINE_MSVLD : engn = 1; break;
+ case NVDEV_ENGINE_MSPPP : engn = 2; break;
+ case NVDEV_ENGINE_MSPDEC: engn = 3; break;
+ case NVDEV_ENGINE_CE0 : engn = 4; break;
+ case NVDEV_ENGINE_CE1 : engn = 5; break;
+ case NVDEV_ENGINE_MSENC : engn = 6; break;
default:
return -1;
}
@@ -429,19 +421,19 @@ nve0_fifo_engidx(struct nve0_fifo_priv *priv, u32 engn)
return engn;
}
-static inline struct nouveau_engine *
-nve0_fifo_engine(struct nve0_fifo_priv *priv, u32 engn)
+static inline struct nvkm_engine *
+gk104_fifo_engine(struct gk104_fifo_priv *priv, u32 engn)
{
if (engn >= ARRAY_SIZE(fifo_engine))
return NULL;
- return nouveau_engine(priv, fifo_engine[engn].subdev);
+ return nvkm_engine(priv, fifo_engine[engn].subdev);
}
static void
-nve0_fifo_recover_work(struct work_struct *work)
+gk104_fifo_recover_work(struct work_struct *work)
{
- struct nve0_fifo_priv *priv = container_of(work, typeof(*priv), fault);
- struct nouveau_object *engine;
+ struct gk104_fifo_priv *priv = container_of(work, typeof(*priv), fault);
+ struct nvkm_object *engine;
unsigned long flags;
u32 engn, engm = 0;
u64 mask, todo;
@@ -452,15 +444,15 @@ nve0_fifo_recover_work(struct work_struct *work)
spin_unlock_irqrestore(&priv->base.lock, flags);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
- engm |= 1 << nve0_fifo_engidx(priv, engn);
+ engm |= 1 << gk104_fifo_engidx(priv, engn);
nv_mask(priv, 0x002630, engm, engm);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
- if ((engine = (void *)nouveau_engine(priv, engn))) {
+ if ((engine = (void *)nvkm_engine(priv, engn))) {
nv_ofuncs(engine)->fini(engine, false);
WARN_ON(nv_ofuncs(engine)->init(engine));
}
- nve0_fifo_runlist_update(priv, nve0_fifo_engidx(priv, engn));
+ gk104_fifo_runlist_update(priv, gk104_fifo_engidx(priv, engn));
}
nv_wr32(priv, 0x00262c, engm);
@@ -468,10 +460,9 @@ nve0_fifo_recover_work(struct work_struct *work)
}
static void
-nve0_fifo_recover(struct nve0_fifo_priv *priv, struct nouveau_engine *engine,
- struct nve0_fifo_chan *chan)
+gk104_fifo_recover(struct gk104_fifo_priv *priv, struct nvkm_engine *engine,
+ struct gk104_fifo_chan *chan)
{
- struct nouveau_object *engobj = nv_object(engine);
u32 chid = chan->base.chid;
unsigned long flags;
@@ -482,16 +473,16 @@ nve0_fifo_recover(struct nve0_fifo_priv *priv, struct nouveau_engine *engine,
chan->state = KILLED;
spin_lock_irqsave(&priv->base.lock, flags);
- priv->mask |= 1ULL << nv_engidx(engobj);
+ priv->mask |= 1ULL << nv_engidx(engine);
spin_unlock_irqrestore(&priv->base.lock, flags);
schedule_work(&priv->fault);
}
static int
-nve0_fifo_swmthd(struct nve0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
+gk104_fifo_swmthd(struct gk104_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
{
- struct nve0_fifo_chan *chan = NULL;
- struct nouveau_handle *bind;
+ struct gk104_fifo_chan *chan = NULL;
+ struct nvkm_handle *bind;
unsigned long flags;
int ret = -EINVAL;
@@ -501,11 +492,11 @@ nve0_fifo_swmthd(struct nve0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
if (unlikely(!chan))
goto out;
- bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
+ bind = nvkm_namedb_get_class(nv_namedb(chan), 0x906e);
if (likely(bind)) {
if (!mthd || !nv_call(bind->object, mthd, data))
ret = 0;
- nouveau_namedb_put(bind);
+ nvkm_namedb_put(bind);
}
out:
@@ -513,8 +504,8 @@ out:
return ret;
}
-static const struct nouveau_enum
-nve0_fifo_bind_reason[] = {
+static const struct nvkm_enum
+gk104_fifo_bind_reason[] = {
{ 0x01, "BIND_NOT_UNBOUND" },
{ 0x02, "SNOOP_WITHOUT_BAR1" },
{ 0x03, "UNBIND_WHILE_RUNNING" },
@@ -525,31 +516,31 @@ nve0_fifo_bind_reason[] = {
};
static void
-nve0_fifo_intr_bind(struct nve0_fifo_priv *priv)
+gk104_fifo_intr_bind(struct gk104_fifo_priv *priv)
{
u32 intr = nv_rd32(priv, 0x00252c);
u32 code = intr & 0x000000ff;
- const struct nouveau_enum *en;
+ const struct nvkm_enum *en;
char enunk[6] = "";
- en = nouveau_enum_find(nve0_fifo_bind_reason, code);
+ en = nvkm_enum_find(gk104_fifo_bind_reason, code);
if (!en)
snprintf(enunk, sizeof(enunk), "UNK%02x", code);
nv_error(priv, "BIND_ERROR [ %s ]\n", en ? en->name : enunk);
}
-static const struct nouveau_enum
-nve0_fifo_sched_reason[] = {
+static const struct nvkm_enum
+gk104_fifo_sched_reason[] = {
{ 0x0a, "CTXSW_TIMEOUT" },
{}
};
static void
-nve0_fifo_intr_sched_ctxsw(struct nve0_fifo_priv *priv)
+gk104_fifo_intr_sched_ctxsw(struct gk104_fifo_priv *priv)
{
- struct nouveau_engine *engine;
- struct nve0_fifo_chan *chan;
+ struct nvkm_engine *engine;
+ struct gk104_fifo_chan *chan;
u32 engn;
for (engn = 0; engn < ARRAY_SIZE(fifo_engine); engn++) {
@@ -566,22 +557,22 @@ nve0_fifo_intr_sched_ctxsw(struct nve0_fifo_priv *priv)
if (busy && chsw) {
if (!(chan = (void *)priv->base.channel[chid]))
continue;
- if (!(engine = nve0_fifo_engine(priv, engn)))
+ if (!(engine = gk104_fifo_engine(priv, engn)))
continue;
- nve0_fifo_recover(priv, engine, chan);
+ gk104_fifo_recover(priv, engine, chan);
}
}
}
static void
-nve0_fifo_intr_sched(struct nve0_fifo_priv *priv)
+gk104_fifo_intr_sched(struct gk104_fifo_priv *priv)
{
u32 intr = nv_rd32(priv, 0x00254c);
u32 code = intr & 0x000000ff;
- const struct nouveau_enum *en;
+ const struct nvkm_enum *en;
char enunk[6] = "";
- en = nouveau_enum_find(nve0_fifo_sched_reason, code);
+ en = nvkm_enum_find(gk104_fifo_sched_reason, code);
if (!en)
snprintf(enunk, sizeof(enunk), "UNK%02x", code);
@@ -589,7 +580,7 @@ nve0_fifo_intr_sched(struct nve0_fifo_priv *priv)
switch (code) {
case 0x0a:
- nve0_fifo_intr_sched_ctxsw(priv);
+ gk104_fifo_intr_sched_ctxsw(priv);
break;
default:
break;
@@ -597,7 +588,7 @@ nve0_fifo_intr_sched(struct nve0_fifo_priv *priv)
}
static void
-nve0_fifo_intr_chsw(struct nve0_fifo_priv *priv)
+gk104_fifo_intr_chsw(struct gk104_fifo_priv *priv)
{
u32 stat = nv_rd32(priv, 0x00256c);
nv_error(priv, "CHSW_ERROR 0x%08x\n", stat);
@@ -605,14 +596,14 @@ nve0_fifo_intr_chsw(struct nve0_fifo_priv *priv)
}
static void
-nve0_fifo_intr_dropped_fault(struct nve0_fifo_priv *priv)
+gk104_fifo_intr_dropped_fault(struct gk104_fifo_priv *priv)
{
u32 stat = nv_rd32(priv, 0x00259c);
nv_error(priv, "DROPPED_MMU_FAULT 0x%08x\n", stat);
}
-static const struct nouveau_enum
-nve0_fifo_fault_engine[] = {
+static const struct nvkm_enum
+gk104_fifo_fault_engine[] = {
{ 0x00, "GR", NULL, NVDEV_ENGINE_GR },
{ 0x03, "IFB", NULL, NVDEV_ENGINE_IFB },
{ 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR },
@@ -620,20 +611,20 @@ nve0_fifo_fault_engine[] = {
{ 0x07, "PBDMA0", NULL, NVDEV_ENGINE_FIFO },
{ 0x08, "PBDMA1", NULL, NVDEV_ENGINE_FIFO },
{ 0x09, "PBDMA2", NULL, NVDEV_ENGINE_FIFO },
- { 0x10, "MSVLD", NULL, NVDEV_ENGINE_BSP },
- { 0x11, "MSPPP", NULL, NVDEV_ENGINE_PPP },
+ { 0x10, "MSVLD", NULL, NVDEV_ENGINE_MSVLD },
+ { 0x11, "MSPPP", NULL, NVDEV_ENGINE_MSPPP },
{ 0x13, "PERF" },
- { 0x14, "MSPDEC", NULL, NVDEV_ENGINE_VP },
- { 0x15, "CE0", NULL, NVDEV_ENGINE_COPY0 },
- { 0x16, "CE1", NULL, NVDEV_ENGINE_COPY1 },
+ { 0x14, "MSPDEC", NULL, NVDEV_ENGINE_MSPDEC },
+ { 0x15, "CE0", NULL, NVDEV_ENGINE_CE0 },
+ { 0x16, "CE1", NULL, NVDEV_ENGINE_CE1 },
{ 0x17, "PMU" },
- { 0x19, "MSENC", NULL, NVDEV_ENGINE_VENC },
- { 0x1b, "CE2", NULL, NVDEV_ENGINE_COPY2 },
+ { 0x19, "MSENC", NULL, NVDEV_ENGINE_MSENC },
+ { 0x1b, "CE2", NULL, NVDEV_ENGINE_CE2 },
{}
};
-static const struct nouveau_enum
-nve0_fifo_fault_reason[] = {
+static const struct nvkm_enum
+gk104_fifo_fault_reason[] = {
{ 0x00, "PDE" },
{ 0x01, "PDE_SIZE" },
{ 0x02, "PTE" },
@@ -653,8 +644,8 @@ nve0_fifo_fault_reason[] = {
{}
};
-static const struct nouveau_enum
-nve0_fifo_fault_hubclient[] = {
+static const struct nvkm_enum
+gk104_fifo_fault_hubclient[] = {
{ 0x00, "VIP" },
{ 0x01, "CE0" },
{ 0x02, "CE1" },
@@ -679,7 +670,7 @@ nve0_fifo_fault_hubclient[] = {
{ 0x15, "SCC_NB" },
{ 0x16, "SEC" },
{ 0x17, "SSYNC" },
- { 0x18, "GR_COPY" },
+ { 0x18, "GR_CE" },
{ 0x19, "CE2" },
{ 0x1a, "XV" },
{ 0x1b, "MMU_NB" },
@@ -690,8 +681,8 @@ nve0_fifo_fault_hubclient[] = {
{}
};
-static const struct nouveau_enum
-nve0_fifo_fault_gpcclient[] = {
+static const struct nvkm_enum
+gk104_fifo_fault_gpcclient[] = {
{ 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" },
{ 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" },
{ 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" },
@@ -717,7 +708,7 @@ nve0_fifo_fault_gpcclient[] = {
};
static void
-nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
+gk104_fifo_intr_fault(struct gk104_fifo_priv *priv, int unit)
{
u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10));
u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10));
@@ -728,19 +719,19 @@ nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
u32 write = (stat & 0x00000080);
u32 hub = (stat & 0x00000040);
u32 reason = (stat & 0x0000000f);
- struct nouveau_object *engctx = NULL, *object;
- struct nouveau_engine *engine = NULL;
- const struct nouveau_enum *er, *eu, *ec;
+ struct nvkm_object *engctx = NULL, *object;
+ struct nvkm_engine *engine = NULL;
+ const struct nvkm_enum *er, *eu, *ec;
char erunk[6] = "";
char euunk[6] = "";
char ecunk[6] = "";
char gpcid[3] = "";
- er = nouveau_enum_find(nve0_fifo_fault_reason, reason);
+ er = nvkm_enum_find(gk104_fifo_fault_reason, reason);
if (!er)
snprintf(erunk, sizeof(erunk), "UNK%02X", reason);
- eu = nouveau_enum_find(nve0_fifo_fault_engine, unit);
+ eu = nvkm_enum_find(gk104_fifo_fault_engine, unit);
if (eu) {
switch (eu->data2) {
case NVDEV_SUBDEV_BAR:
@@ -753,9 +744,9 @@ nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
nv_mask(priv, 0x001718, 0x00000000, 0x00000000);
break;
default:
- engine = nouveau_engine(priv, eu->data2);
+ engine = nvkm_engine(priv, eu->data2);
if (engine)
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
break;
}
} else {
@@ -763,9 +754,9 @@ nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
}
if (hub) {
- ec = nouveau_enum_find(nve0_fifo_fault_hubclient, client);
+ ec = nvkm_enum_find(gk104_fifo_fault_hubclient, client);
} else {
- ec = nouveau_enum_find(nve0_fifo_fault_gpcclient, client);
+ ec = nvkm_enum_find(gk104_fifo_fault_gpcclient, client);
snprintf(gpcid, sizeof(gpcid), "%d", gpc);
}
@@ -777,22 +768,22 @@ nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
(u64)vahi << 32 | valo, er ? er->name : erunk,
eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/",
ec ? ec->name : ecunk, (u64)inst << 12,
- nouveau_client_name(engctx));
+ nvkm_client_name(engctx));
object = engctx;
while (object) {
switch (nv_mclass(object)) {
case KEPLER_CHANNEL_GPFIFO_A:
- nve0_fifo_recover(priv, engine, (void *)object);
+ gk104_fifo_recover(priv, engine, (void *)object);
break;
}
object = object->parent;
}
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
-static const struct nouveau_bitfield nve0_fifo_pbdma_intr_0[] = {
+static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = {
{ 0x00000001, "MEMREQ" },
{ 0x00000002, "MEMACK_TIMEOUT" },
{ 0x00000004, "MEMACK_EXTRA" },
@@ -827,7 +818,7 @@ static const struct nouveau_bitfield nve0_fifo_pbdma_intr_0[] = {
};
static void
-nve0_fifo_intr_pbdma_0(struct nve0_fifo_priv *priv, int unit)
+gk104_fifo_intr_pbdma_0(struct gk104_fifo_priv *priv, int unit)
{
u32 mask = nv_rd32(priv, 0x04010c + (unit * 0x2000));
u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000)) & mask;
@@ -839,26 +830,26 @@ nve0_fifo_intr_pbdma_0(struct nve0_fifo_priv *priv, int unit)
u32 show = stat;
if (stat & 0x00800000) {
- if (!nve0_fifo_swmthd(priv, chid, mthd, data))
+ if (!gk104_fifo_swmthd(priv, chid, mthd, data))
show &= ~0x00800000;
nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008);
}
if (show) {
nv_error(priv, "PBDMA%d:", unit);
- nouveau_bitfield_print(nve0_fifo_pbdma_intr_0, show);
+ nvkm_bitfield_print(gk104_fifo_pbdma_intr_0, show);
pr_cont("\n");
nv_error(priv,
"PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
unit, chid,
- nouveau_client_name_for_fifo_chid(&priv->base, chid),
+ nvkm_client_name_for_fifo_chid(&priv->base, chid),
subc, mthd, data);
}
nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
}
-static const struct nouveau_bitfield nve0_fifo_pbdma_intr_1[] = {
+static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = {
{ 0x00000001, "HCE_RE_ILLEGAL_OP" },
{ 0x00000002, "HCE_RE_ALIGNB" },
{ 0x00000004, "HCE_PRIV" },
@@ -868,7 +859,7 @@ static const struct nouveau_bitfield nve0_fifo_pbdma_intr_1[] = {
};
static void
-nve0_fifo_intr_pbdma_1(struct nve0_fifo_priv *priv, int unit)
+gk104_fifo_intr_pbdma_1(struct gk104_fifo_priv *priv, int unit)
{
u32 mask = nv_rd32(priv, 0x04014c + (unit * 0x2000));
u32 stat = nv_rd32(priv, 0x040148 + (unit * 0x2000)) & mask;
@@ -876,7 +867,7 @@ nve0_fifo_intr_pbdma_1(struct nve0_fifo_priv *priv, int unit)
if (stat) {
nv_error(priv, "PBDMA%d:", unit);
- nouveau_bitfield_print(nve0_fifo_pbdma_intr_1, stat);
+ nvkm_bitfield_print(gk104_fifo_pbdma_intr_1, stat);
pr_cont("\n");
nv_error(priv, "PBDMA%d: ch %d %08x %08x\n", unit, chid,
nv_rd32(priv, 0x040150 + (unit * 0x2000)),
@@ -887,7 +878,7 @@ nve0_fifo_intr_pbdma_1(struct nve0_fifo_priv *priv, int unit)
}
static void
-nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv)
+gk104_fifo_intr_runlist(struct gk104_fifo_priv *priv)
{
u32 mask = nv_rd32(priv, 0x002a00);
while (mask) {
@@ -899,20 +890,20 @@ nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv)
}
static void
-nve0_fifo_intr_engine(struct nve0_fifo_priv *priv)
+gk104_fifo_intr_engine(struct gk104_fifo_priv *priv)
{
- nouveau_fifo_uevent(&priv->base);
+ nvkm_fifo_uevent(&priv->base);
}
static void
-nve0_fifo_intr(struct nouveau_subdev *subdev)
+gk104_fifo_intr(struct nvkm_subdev *subdev)
{
- struct nve0_fifo_priv *priv = (void *)subdev;
+ struct gk104_fifo_priv *priv = (void *)subdev;
u32 mask = nv_rd32(priv, 0x002140);
u32 stat = nv_rd32(priv, 0x002100) & mask;
if (stat & 0x00000001) {
- nve0_fifo_intr_bind(priv);
+ gk104_fifo_intr_bind(priv);
nv_wr32(priv, 0x002100, 0x00000001);
stat &= ~0x00000001;
}
@@ -924,13 +915,13 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x00000100) {
- nve0_fifo_intr_sched(priv);
+ gk104_fifo_intr_sched(priv);
nv_wr32(priv, 0x002100, 0x00000100);
stat &= ~0x00000100;
}
if (stat & 0x00010000) {
- nve0_fifo_intr_chsw(priv);
+ gk104_fifo_intr_chsw(priv);
nv_wr32(priv, 0x002100, 0x00010000);
stat &= ~0x00010000;
}
@@ -948,7 +939,7 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x08000000) {
- nve0_fifo_intr_dropped_fault(priv);
+ gk104_fifo_intr_dropped_fault(priv);
nv_wr32(priv, 0x002100, 0x08000000);
stat &= ~0x08000000;
}
@@ -957,7 +948,7 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
u32 mask = nv_rd32(priv, 0x00259c);
while (mask) {
u32 unit = __ffs(mask);
- nve0_fifo_intr_fault(priv, unit);
+ gk104_fifo_intr_fault(priv, unit);
nv_wr32(priv, 0x00259c, (1 << unit));
mask &= ~(1 << unit);
}
@@ -968,8 +959,8 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
u32 mask = nv_rd32(priv, 0x0025a0);
while (mask) {
u32 unit = __ffs(mask);
- nve0_fifo_intr_pbdma_0(priv, unit);
- nve0_fifo_intr_pbdma_1(priv, unit);
+ gk104_fifo_intr_pbdma_0(priv, unit);
+ gk104_fifo_intr_pbdma_1(priv, unit);
nv_wr32(priv, 0x0025a0, (1 << unit));
mask &= ~(1 << unit);
}
@@ -977,13 +968,13 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x40000000) {
- nve0_fifo_intr_runlist(priv);
+ gk104_fifo_intr_runlist(priv);
stat &= ~0x40000000;
}
if (stat & 0x80000000) {
nv_wr32(priv, 0x002100, 0x80000000);
- nve0_fifo_intr_engine(priv);
+ gk104_fifo_intr_engine(priv);
stat &= ~0x80000000;
}
@@ -995,33 +986,33 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
}
static void
-nve0_fifo_uevent_init(struct nvkm_event *event, int type, int index)
+gk104_fifo_uevent_init(struct nvkm_event *event, int type, int index)
{
- struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
nv_mask(fifo, 0x002140, 0x80000000, 0x80000000);
}
static void
-nve0_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
+gk104_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
{
- struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
nv_mask(fifo, 0x002140, 0x80000000, 0x00000000);
}
static const struct nvkm_event_func
-nve0_fifo_uevent_func = {
- .ctor = nouveau_fifo_uevent_ctor,
- .init = nve0_fifo_uevent_init,
- .fini = nve0_fifo_uevent_fini,
+gk104_fifo_uevent_func = {
+ .ctor = nvkm_fifo_uevent_ctor,
+ .init = gk104_fifo_uevent_init,
+ .fini = gk104_fifo_uevent_fini,
};
int
-nve0_fifo_fini(struct nouveau_object *object, bool suspend)
+gk104_fifo_fini(struct nvkm_object *object, bool suspend)
{
- struct nve0_fifo_priv *priv = (void *)object;
+ struct gk104_fifo_priv *priv = (void *)object;
int ret;
- ret = nouveau_fifo_fini(&priv->base, suspend);
+ ret = nvkm_fifo_fini(&priv->base, suspend);
if (ret)
return ret;
@@ -1031,12 +1022,12 @@ nve0_fifo_fini(struct nouveau_object *object, bool suspend)
}
int
-nve0_fifo_init(struct nouveau_object *object)
+gk104_fifo_init(struct nvkm_object *object)
{
- struct nve0_fifo_priv *priv = (void *)object;
+ struct gk104_fifo_priv *priv = (void *)object;
int ret, i;
- ret = nouveau_fifo_init(&priv->base);
+ ret = nvkm_fifo_init(&priv->base);
if (ret)
return ret;
@@ -1066,82 +1057,82 @@ nve0_fifo_init(struct nouveau_object *object)
}
void
-nve0_fifo_dtor(struct nouveau_object *object)
+gk104_fifo_dtor(struct nvkm_object *object)
{
- struct nve0_fifo_priv *priv = (void *)object;
+ struct gk104_fifo_priv *priv = (void *)object;
int i;
- nouveau_gpuobj_unmap(&priv->user.bar);
- nouveau_gpuobj_ref(NULL, &priv->user.mem);
+ nvkm_gpuobj_unmap(&priv->user.bar);
+ nvkm_gpuobj_ref(NULL, &priv->user.mem);
for (i = 0; i < FIFO_ENGINE_NR; i++) {
- nouveau_gpuobj_ref(NULL, &priv->engine[i].runlist[1]);
- nouveau_gpuobj_ref(NULL, &priv->engine[i].runlist[0]);
+ nvkm_gpuobj_ref(NULL, &priv->engine[i].runlist[1]);
+ nvkm_gpuobj_ref(NULL, &priv->engine[i].runlist[0]);
}
- nouveau_fifo_destroy(&priv->base);
+ nvkm_fifo_destroy(&priv->base);
}
int
-nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nve0_fifo_impl *impl = (void *)oclass;
- struct nve0_fifo_priv *priv;
+ struct gk104_fifo_impl *impl = (void *)oclass;
+ struct gk104_fifo_priv *priv;
int ret, i;
- ret = nouveau_fifo_create(parent, engine, oclass, 0,
- impl->channels - 1, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 0,
+ impl->channels - 1, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- INIT_WORK(&priv->fault, nve0_fifo_recover_work);
+ INIT_WORK(&priv->fault, gk104_fifo_recover_work);
for (i = 0; i < FIFO_ENGINE_NR; i++) {
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
- 0, &priv->engine[i].runlist[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
+ 0, &priv->engine[i].runlist[0]);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
- 0, &priv->engine[i].runlist[1]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
+ 0, &priv->engine[i].runlist[1]);
if (ret)
return ret;
init_waitqueue_head(&priv->engine[i].wait);
}
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, impl->channels * 0x200,
- 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, impl->channels * 0x200,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
if (ret)
return ret;
- ret = nouveau_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW,
- &priv->user.bar);
+ ret = nvkm_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW,
+ &priv->user.bar);
if (ret)
return ret;
- ret = nvkm_event_init(&nve0_fifo_uevent_func, 1, 1, &priv->base.uevent);
+ ret = nvkm_event_init(&gk104_fifo_uevent_func, 1, 1, &priv->base.uevent);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000100;
- nv_subdev(priv)->intr = nve0_fifo_intr;
- nv_engine(priv)->cclass = &nve0_fifo_cclass;
- nv_engine(priv)->sclass = nve0_fifo_sclass;
+ nv_subdev(priv)->intr = gk104_fifo_intr;
+ nv_engine(priv)->cclass = &gk104_fifo_cclass;
+ nv_engine(priv)->sclass = gk104_fifo_sclass;
return 0;
}
-struct nouveau_oclass *
-nve0_fifo_oclass = &(struct nve0_fifo_impl) {
+struct nvkm_oclass *
+gk104_fifo_oclass = &(struct gk104_fifo_impl) {
.base.handle = NV_ENGINE(FIFO, 0xe0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_fifo_ctor,
- .dtor = nve0_fifo_dtor,
- .init = nve0_fifo_init,
- .fini = nve0_fifo_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_fifo_ctor,
+ .dtor = gk104_fifo_dtor,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
},
.channels = 4096,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
new file mode 100644
index 000000000000..3046e00ed6ba
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
@@ -0,0 +1,16 @@
+#ifndef __NVKM_FIFO_NVE0_H__
+#define __NVKM_FIFO_NVE0_H__
+#include <engine/fifo.h>
+
+int gk104_fifo_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void gk104_fifo_dtor(struct nvkm_object *);
+int gk104_fifo_init(struct nvkm_object *);
+int gk104_fifo_fini(struct nvkm_object *, bool);
+
+struct gk104_fifo_impl {
+ struct nvkm_oclass base;
+ u32 channels;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv108.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
index 09362a51ba57..927092217a06 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
@@ -21,17 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "gk104.h"
-#include "nve0.h"
-
-struct nouveau_oclass *
-nv108_fifo_oclass = &(struct nve0_fifo_impl) {
+struct nvkm_oclass *
+gk208_fifo_oclass = &(struct gk104_fifo_impl) {
.base.handle = NV_ENGINE(FIFO, 0x08),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_fifo_ctor,
- .dtor = nve0_fifo_dtor,
- .init = nve0_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_fifo_ctor,
+ .dtor = gk104_fifo_dtor,
+ .init = gk104_fifo_init,
+ .fini = _nvkm_fifo_fini,
},
.channels = 1024,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c
index 327456eae963..b30dc87a1357 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c
@@ -19,17 +19,16 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+#include "gk104.h"
-#include "nve0.h"
-
-struct nouveau_oclass *
-gk20a_fifo_oclass = &(struct nve0_fifo_impl) {
+struct nvkm_oclass *
+gk20a_fifo_oclass = &(struct gk104_fifo_impl) {
.base.handle = NV_ENGINE(FIFO, 0xea),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_fifo_ctor,
- .dtor = nve0_fifo_dtor,
- .init = nve0_fifo_init,
- .fini = nve0_fifo_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_fifo_ctor,
+ .dtor = gk104_fifo_dtor,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
},
.channels = 128,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
index 1931057f9962..b038b6eb51db 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
@@ -21,24 +21,18 @@
*
* Authors: Ben Skeggs
*/
+#include "nv04.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
+#include <core/device.h>
#include <core/engctx.h>
-#include <core/namedb.h>
#include <core/handle.h>
#include <core/ramht.h>
-#include <core/event.h>
-
-#include <subdev/instmem.h>
#include <subdev/instmem/nv04.h>
#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <engine/fifo.h>
-
-#include "nv04.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
static struct ramfc_desc
nv04_ramfc[] = {
@@ -58,8 +52,8 @@ nv04_ramfc[] = {
******************************************************************************/
int
-nv04_fifo_object_attach(struct nouveau_object *parent,
- struct nouveau_object *object, u32 handle)
+nv04_fifo_object_attach(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 handle)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
@@ -90,33 +84,33 @@ nv04_fifo_object_attach(struct nouveau_object *parent,
context |= chid << 24;
mutex_lock(&nv_subdev(priv)->mutex);
- ret = nouveau_ramht_insert(priv->ramht, chid, handle, context);
+ ret = nvkm_ramht_insert(priv->ramht, chid, handle, context);
mutex_unlock(&nv_subdev(priv)->mutex);
return ret;
}
void
-nv04_fifo_object_detach(struct nouveau_object *parent, int cookie)
+nv04_fifo_object_detach(struct nvkm_object *parent, int cookie)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
mutex_lock(&nv_subdev(priv)->mutex);
- nouveau_ramht_remove(priv->ramht, cookie);
+ nvkm_ramht_remove(priv->ramht, cookie);
mutex_unlock(&nv_subdev(priv)->mutex);
}
int
-nv04_fifo_context_attach(struct nouveau_object *parent,
- struct nouveau_object *object)
+nv04_fifo_context_attach(struct nvkm_object *parent,
+ struct nvkm_object *object)
{
- nv_engctx(object)->addr = nouveau_fifo_chan(parent)->chid;
+ nv_engctx(object)->addr = nvkm_fifo_chan(parent)->chid;
return 0;
}
static int
-nv04_fifo_chan_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_fifo_chan_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
@@ -133,11 +127,11 @@ nv04_fifo_chan_ctor(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
- 0x10000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
+ 0x10000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -163,7 +157,7 @@ nv04_fifo_chan_ctor(struct nouveau_object *parent,
}
void
-nv04_fifo_chan_dtor(struct nouveau_object *object)
+nv04_fifo_chan_dtor(struct nvkm_object *object)
{
struct nv04_fifo_priv *priv = (void *)object->engine;
struct nv04_fifo_chan *chan = (void *)object;
@@ -173,11 +167,11 @@ nv04_fifo_chan_dtor(struct nouveau_object *object)
nv_wo32(priv->ramfc, chan->ramfc + c->ctxp, 0x00000000);
} while ((++c)->bits);
- nouveau_fifo_channel_destroy(&chan->base);
+ nvkm_fifo_channel_destroy(&chan->base);
}
int
-nv04_fifo_chan_init(struct nouveau_object *object)
+nv04_fifo_chan_init(struct nvkm_object *object)
{
struct nv04_fifo_priv *priv = (void *)object->engine;
struct nv04_fifo_chan *chan = (void *)object;
@@ -185,7 +179,7 @@ nv04_fifo_chan_init(struct nouveau_object *object)
unsigned long flags;
int ret;
- ret = nouveau_fifo_channel_init(&chan->base);
+ ret = nvkm_fifo_channel_init(&chan->base);
if (ret)
return ret;
@@ -196,11 +190,11 @@ nv04_fifo_chan_init(struct nouveau_object *object)
}
int
-nv04_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+nv04_fifo_chan_fini(struct nvkm_object *object, bool suspend)
{
struct nv04_fifo_priv *priv = (void *)object->engine;
struct nv04_fifo_chan *chan = (void *)object;
- struct nouveau_gpuobj *fctx = priv->ramfc;
+ struct nvkm_gpuobj *fctx = priv->ramfc;
struct ramfc_desc *c;
unsigned long flags;
u32 data = chan->ramfc;
@@ -243,22 +237,22 @@ nv04_fifo_chan_fini(struct nouveau_object *object, bool suspend)
nv_wr32(priv, NV03_PFIFO_CACHES, 1);
spin_unlock_irqrestore(&priv->base.lock, flags);
- return nouveau_fifo_channel_fini(&chan->base, suspend);
+ return nvkm_fifo_channel_fini(&chan->base, suspend);
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv04_fifo_ofuncs = {
.ctor = nv04_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv04_fifo_sclass[] = {
{ NV03_CHANNEL_DMA, &nv04_fifo_ofuncs },
{}
@@ -269,16 +263,16 @@ nv04_fifo_sclass[] = {
******************************************************************************/
int
-nv04_fifo_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_fifo_context_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_fifo_base *base;
int ret;
- ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
- 0x1000, NVOBJ_FLAG_HEAP, &base);
+ ret = nvkm_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
+ 0x1000, NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
@@ -286,16 +280,16 @@ nv04_fifo_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
+static struct nvkm_oclass
nv04_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fifo_context_ctor,
- .dtor = _nouveau_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .dtor = _nvkm_fifo_context_dtor,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -304,7 +298,7 @@ nv04_fifo_cclass = {
******************************************************************************/
void
-nv04_fifo_pause(struct nouveau_fifo *pfifo, unsigned long *pflags)
+nv04_fifo_pause(struct nvkm_fifo *pfifo, unsigned long *pflags)
__acquires(priv->base.lock)
{
struct nv04_fifo_priv *priv = (void *)pfifo;
@@ -337,7 +331,7 @@ __acquires(priv->base.lock)
}
void
-nv04_fifo_start(struct nouveau_fifo *pfifo, unsigned long *pflags)
+nv04_fifo_start(struct nvkm_fifo *pfifo, unsigned long *pflags)
__releases(priv->base.lock)
{
struct nv04_fifo_priv *priv = (void *)pfifo;
@@ -363,7 +357,7 @@ static bool
nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data)
{
struct nv04_fifo_chan *chan = NULL;
- struct nouveau_handle *bind;
+ struct nvkm_handle *bind;
const int subc = (addr >> 13) & 0x7;
const int mthd = addr & 0x1ffc;
bool handled = false;
@@ -378,7 +372,7 @@ nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data)
switch (mthd) {
case 0x0000:
- bind = nouveau_namedb_get(nv_namedb(chan), data);
+ bind = nvkm_namedb_get(nv_namedb(chan), data);
if (unlikely(!bind))
break;
@@ -390,18 +384,18 @@ nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data)
nv_mask(priv, NV04_PFIFO_CACHE1_ENGINE, engine, 0);
}
- nouveau_namedb_put(bind);
+ nvkm_namedb_put(bind);
break;
default:
engine = nv_rd32(priv, NV04_PFIFO_CACHE1_ENGINE);
if (unlikely(((engine >> (subc * 4)) & 0xf) != 0))
break;
- bind = nouveau_namedb_get(nv_namedb(chan), chan->subc[subc]);
+ bind = nvkm_namedb_get(nv_namedb(chan), chan->subc[subc]);
if (likely(bind)) {
if (!nv_call(bind->object, mthd, data))
handled = true;
- nouveau_namedb_put(bind);
+ nvkm_namedb_put(bind);
}
break;
}
@@ -412,8 +406,8 @@ out:
}
static void
-nv04_fifo_cache_error(struct nouveau_device *device,
- struct nv04_fifo_priv *priv, u32 chid, u32 get)
+nv04_fifo_cache_error(struct nvkm_device *device,
+ struct nv04_fifo_priv *priv, u32 chid, u32 get)
{
u32 mthd, data;
int ptr;
@@ -435,7 +429,7 @@ nv04_fifo_cache_error(struct nouveau_device *device,
if (!nv04_fifo_swmthd(priv, chid, mthd, data)) {
const char *client_name =
- nouveau_client_name_for_fifo_chid(&priv->base, chid);
+ nvkm_client_name_for_fifo_chid(&priv->base, chid);
nv_error(priv,
"CACHE_ERROR - ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
chid, client_name, (mthd >> 13) & 7, mthd & 0x1ffc,
@@ -458,8 +452,8 @@ nv04_fifo_cache_error(struct nouveau_device *device,
}
static void
-nv04_fifo_dma_pusher(struct nouveau_device *device, struct nv04_fifo_priv *priv,
- u32 chid)
+nv04_fifo_dma_pusher(struct nvkm_device *device,
+ struct nv04_fifo_priv *priv, u32 chid)
{
const char *client_name;
u32 dma_get = nv_rd32(priv, 0x003244);
@@ -467,7 +461,7 @@ nv04_fifo_dma_pusher(struct nouveau_device *device, struct nv04_fifo_priv *priv,
u32 push = nv_rd32(priv, 0x003220);
u32 state = nv_rd32(priv, 0x003228);
- client_name = nouveau_client_name_for_fifo_chid(&priv->base, chid);
+ client_name = nvkm_client_name_for_fifo_chid(&priv->base, chid);
if (device->card_type == NV_50) {
u32 ho_get = nv_rd32(priv, 0x003328);
@@ -504,9 +498,9 @@ nv04_fifo_dma_pusher(struct nouveau_device *device, struct nv04_fifo_priv *priv,
}
void
-nv04_fifo_intr(struct nouveau_subdev *subdev)
+nv04_fifo_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_device *device = nv_device(subdev);
+ struct nvkm_device *device = nv_device(subdev);
struct nv04_fifo_priv *priv = (void *)subdev;
uint32_t status, reassign;
int cnt = 0;
@@ -552,7 +546,7 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
if (status & 0x40000000) {
nv_wr32(priv, 0x002100, 0x40000000);
- nouveau_fifo_uevent(&priv->base);
+ nvkm_fifo_uevent(&priv->base);
status &= ~0x40000000;
}
}
@@ -577,22 +571,22 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
}
static int
-nv04_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
- ret = nouveau_fifo_create(parent, engine, oclass, 0, 15, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 0, 15, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nouveau_ramht_ref(imem->ramht, &priv->ramht);
- nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
- nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+ nvkm_ramht_ref(imem->ramht, &priv->ramht);
+ nvkm_gpuobj_ref(imem->ramro, &priv->ramro);
+ nvkm_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
@@ -605,22 +599,22 @@ nv04_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
void
-nv04_fifo_dtor(struct nouveau_object *object)
+nv04_fifo_dtor(struct nvkm_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
- nouveau_gpuobj_ref(NULL, &priv->ramfc);
- nouveau_gpuobj_ref(NULL, &priv->ramro);
- nouveau_ramht_ref(NULL, &priv->ramht);
- nouveau_fifo_destroy(&priv->base);
+ nvkm_gpuobj_ref(NULL, &priv->ramfc);
+ nvkm_gpuobj_ref(NULL, &priv->ramro);
+ nvkm_ramht_ref(NULL, &priv->ramht);
+ nvkm_fifo_destroy(&priv->base);
}
int
-nv04_fifo_init(struct nouveau_object *object)
+nv04_fifo_init(struct nvkm_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
int ret;
- ret = nouveau_fifo_init(&priv->base);
+ ret = nvkm_fifo_init(&priv->base);
if (ret)
return ret;
@@ -629,7 +623,7 @@ nv04_fifo_init(struct nouveau_object *object)
nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
((priv->ramht->bits - 9) << 16) |
- (priv->ramht->base.addr >> 8));
+ (priv->ramht->gpuobj.addr >> 8));
nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
nv_wr32(priv, NV03_PFIFO_RAMFC, priv->ramfc->addr >> 8);
@@ -644,13 +638,13 @@ nv04_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv04_fifo_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+nv04_fifo_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(FIFO, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv04_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .fini = _nvkm_fifo_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
index 496a4b4fdfaf..e0e0c47cb4ca 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
@@ -1,6 +1,5 @@
#ifndef __NV04_FIFO_H__
#define __NV04_FIFO_H__
-
#include <engine/fifo.h>
#define NV04_PFIFO_DELAY_0 0x00002040
@@ -141,38 +140,36 @@ struct ramfc_desc {
};
struct nv04_fifo_priv {
- struct nouveau_fifo base;
+ struct nvkm_fifo base;
struct ramfc_desc *ramfc_desc;
- struct nouveau_ramht *ramht;
- struct nouveau_gpuobj *ramro;
- struct nouveau_gpuobj *ramfc;
+ struct nvkm_ramht *ramht;
+ struct nvkm_gpuobj *ramro;
+ struct nvkm_gpuobj *ramfc;
};
struct nv04_fifo_base {
- struct nouveau_fifo_base base;
+ struct nvkm_fifo_base base;
};
struct nv04_fifo_chan {
- struct nouveau_fifo_chan base;
+ struct nvkm_fifo_chan base;
u32 subc[8];
u32 ramfc;
};
-int nv04_fifo_object_attach(struct nouveau_object *,
- struct nouveau_object *, u32);
-void nv04_fifo_object_detach(struct nouveau_object *, int);
-
-void nv04_fifo_chan_dtor(struct nouveau_object *);
-int nv04_fifo_chan_init(struct nouveau_object *);
-int nv04_fifo_chan_fini(struct nouveau_object *, bool suspend);
+int nv04_fifo_object_attach(struct nvkm_object *, struct nvkm_object *, u32);
+void nv04_fifo_object_detach(struct nvkm_object *, int);
-int nv04_fifo_context_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
+void nv04_fifo_chan_dtor(struct nvkm_object *);
+int nv04_fifo_chan_init(struct nvkm_object *);
+int nv04_fifo_chan_fini(struct nvkm_object *, bool suspend);
-void nv04_fifo_dtor(struct nouveau_object *);
-int nv04_fifo_init(struct nouveau_object *);
-void nv04_fifo_pause(struct nouveau_fifo *, unsigned long *);
-void nv04_fifo_start(struct nouveau_fifo *, unsigned long *);
+int nv04_fifo_context_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv04_fifo_dtor(struct nvkm_object *);
+int nv04_fifo_init(struct nvkm_object *);
+void nv04_fifo_pause(struct nvkm_fifo *, unsigned long *);
+void nv04_fifo_start(struct nvkm_fifo *, unsigned long *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
index 2a32add51c81..48ce4af6f543 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
@@ -21,20 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include "nv04.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
-
-#include <subdev/instmem.h>
#include <subdev/instmem/nv04.h>
-#include <subdev/fb.h>
-#include <engine/fifo.h>
-
-#include "nv04.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
static struct ramfc_desc
nv10_ramfc[] = {
@@ -55,10 +50,10 @@ nv10_ramfc[] = {
******************************************************************************/
static int
-nv10_fifo_chan_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv10_fifo_chan_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
@@ -75,11 +70,11 @@ nv10_fifo_chan_ctor(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
- 0x10000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
+ 0x10000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -104,19 +99,19 @@ nv10_fifo_chan_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv10_fifo_ofuncs = {
.ctor = nv10_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv10_fifo_sclass[] = {
{ NV10_CHANNEL_DMA, &nv10_fifo_ofuncs },
{}
@@ -126,16 +121,16 @@ nv10_fifo_sclass[] = {
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
-static struct nouveau_oclass
+static struct nvkm_oclass
nv10_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x10),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fifo_context_ctor,
- .dtor = _nouveau_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .dtor = _nvkm_fifo_context_dtor,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -144,22 +139,22 @@ nv10_fifo_cclass = {
******************************************************************************/
static int
-nv10_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv10_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
- ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 0, 31, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nouveau_ramht_ref(imem->ramht, &priv->ramht);
- nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
- nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+ nvkm_ramht_ref(imem->ramht, &priv->ramht);
+ nvkm_gpuobj_ref(imem->ramro, &priv->ramro);
+ nvkm_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
@@ -171,13 +166,13 @@ nv10_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv10_fifo_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+nv10_fifo_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(FIFO, 0x10),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv10_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv04_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .fini = _nvkm_fifo_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
index 12d76c8adb23..4a20a6fd3887 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
@@ -21,20 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include "nv04.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
-
-#include <subdev/instmem.h>
#include <subdev/instmem/nv04.h>
-#include <subdev/fb.h>
-#include <engine/fifo.h>
-
-#include "nv04.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
static struct ramfc_desc
nv17_ramfc[] = {
@@ -60,10 +55,10 @@ nv17_ramfc[] = {
******************************************************************************/
static int
-nv17_fifo_chan_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv17_fifo_chan_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
@@ -80,13 +75,13 @@ nv17_fifo_chan_ctor(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
- 0x10000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR) |
- (1ULL << NVDEV_ENGINE_MPEG), /* NV31- */
- &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
+ 0x10000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR) |
+ (1ULL << NVDEV_ENGINE_MPEG), /* NV31- */
+ &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -111,19 +106,19 @@ nv17_fifo_chan_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv17_fifo_ofuncs = {
.ctor = nv17_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv17_fifo_sclass[] = {
{ NV17_CHANNEL_DMA, &nv17_fifo_ofuncs },
{}
@@ -133,16 +128,16 @@ nv17_fifo_sclass[] = {
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
-static struct nouveau_oclass
+static struct nvkm_oclass
nv17_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x17),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fifo_context_ctor,
- .dtor = _nouveau_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .dtor = _nvkm_fifo_context_dtor,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -151,22 +146,22 @@ nv17_fifo_cclass = {
******************************************************************************/
static int
-nv17_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv17_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
- ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 0, 31, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nouveau_ramht_ref(imem->ramht, &priv->ramht);
- nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
- nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+ nvkm_ramht_ref(imem->ramht, &priv->ramht);
+ nvkm_gpuobj_ref(imem->ramro, &priv->ramro);
+ nvkm_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
@@ -179,12 +174,12 @@ nv17_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
static int
-nv17_fifo_init(struct nouveau_object *object)
+nv17_fifo_init(struct nvkm_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
int ret;
- ret = nouveau_fifo_init(&priv->base);
+ ret = nvkm_fifo_init(&priv->base);
if (ret)
return ret;
@@ -193,7 +188,7 @@ nv17_fifo_init(struct nouveau_object *object)
nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
((priv->ramht->bits - 9) << 16) |
- (priv->ramht->base.addr >> 8));
+ (priv->ramht->gpuobj.addr >> 8));
nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
nv_wr32(priv, NV03_PFIFO_RAMFC, priv->ramfc->addr >> 8 | 0x00010000);
@@ -208,13 +203,13 @@ nv17_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv17_fifo_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+nv17_fifo_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(FIFO, 0x17),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv17_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv17_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .fini = _nvkm_fifo_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
index 9f49c3a24dc6..5bfc96265f3b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
@@ -21,20 +21,17 @@
*
* Authors: Ben Skeggs
*/
+#include "nv04.h"
#include <core/client.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
+#include <core/device.h>
#include <core/engctx.h>
#include <core/ramht.h>
-
-#include <subdev/instmem.h>
-#include <subdev/instmem/nv04.h>
#include <subdev/fb.h>
+#include <subdev/instmem/nv04.h>
-#include <engine/fifo.h>
-
-#include "nv04.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
static struct ramfc_desc
nv40_ramfc[] = {
@@ -68,8 +65,8 @@ nv40_ramfc[] = {
******************************************************************************/
static int
-nv40_fifo_object_attach(struct nouveau_object *parent,
- struct nouveau_object *object, u32 handle)
+nv40_fifo_object_attach(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 handle)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
@@ -99,14 +96,13 @@ nv40_fifo_object_attach(struct nouveau_object *parent,
context |= chid << 23;
mutex_lock(&nv_subdev(priv)->mutex);
- ret = nouveau_ramht_insert(priv->ramht, chid, handle, context);
+ ret = nvkm_ramht_insert(priv->ramht, chid, handle, context);
mutex_unlock(&nv_subdev(priv)->mutex);
return ret;
}
static int
-nv40_fifo_context_attach(struct nouveau_object *parent,
- struct nouveau_object *engctx)
+nv40_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *engctx)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
@@ -142,8 +138,8 @@ nv40_fifo_context_attach(struct nouveau_object *parent,
}
static int
-nv40_fifo_context_detach(struct nouveau_object *parent, bool suspend,
- struct nouveau_object *engctx)
+nv40_fifo_context_detach(struct nvkm_object *parent, bool suspend,
+ struct nvkm_object *engctx)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
@@ -178,10 +174,9 @@ nv40_fifo_context_detach(struct nouveau_object *parent, bool suspend,
}
static int
-nv40_fifo_chan_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
@@ -198,12 +193,12 @@ nv40_fifo_chan_ctor(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
- 0x1000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR) |
- (1ULL << NVDEV_ENGINE_MPEG), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x1000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR) |
+ (1ULL << NVDEV_ENGINE_MPEG), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -230,19 +225,19 @@ nv40_fifo_chan_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv40_fifo_ofuncs = {
.ctor = nv40_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv40_fifo_sclass[] = {
{ NV40_CHANNEL_DMA, &nv40_fifo_ofuncs },
{}
@@ -252,16 +247,16 @@ nv40_fifo_sclass[] = {
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
-static struct nouveau_oclass
+static struct nvkm_oclass
nv40_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fifo_context_ctor,
- .dtor = _nouveau_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .dtor = _nvkm_fifo_context_dtor,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -270,22 +265,22 @@ nv40_fifo_cclass = {
******************************************************************************/
static int
-nv40_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
- ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 0, 31, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nouveau_ramht_ref(imem->ramht, &priv->ramht);
- nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
- nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
+ nvkm_ramht_ref(imem->ramht, &priv->ramht);
+ nvkm_gpuobj_ref(imem->ramro, &priv->ramro);
+ nvkm_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
@@ -298,13 +293,13 @@ nv40_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
static int
-nv40_fifo_init(struct nouveau_object *object)
+nv40_fifo_init(struct nvkm_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
- struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nvkm_fb *pfb = nvkm_fb(object);
int ret;
- ret = nouveau_fifo_init(&priv->base);
+ ret = nvkm_fifo_init(&priv->base);
if (ret)
return ret;
@@ -314,7 +309,7 @@ nv40_fifo_init(struct nouveau_object *object)
nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
((priv->ramht->bits - 9) << 16) |
- (priv->ramht->base.addr >> 8));
+ (priv->ramht->gpuobj.addr >> 8));
nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
switch (nv_device(priv)->chipset) {
@@ -349,13 +344,13 @@ nv40_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv40_fifo_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+nv40_fifo_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(FIFO, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv40_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv40_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .fini = _nvkm_fifo_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
index 5d1e86bc244c..f25f0fd0655d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
@@ -21,21 +21,18 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "nv04.h"
#include <core/client.h>
#include <core/engctx.h>
#include <core/ramht.h>
-#include <nvif/unpack.h>
-#include <nvif/class.h>
-
-#include <subdev/timer.h>
#include <subdev/bar.h>
+#include <subdev/mmu.h>
+#include <subdev/timer.h>
-#include <engine/dmaobj.h>
-#include <engine/fifo.h>
-
-#include "nv04.h"
-#include "nv50.h"
+#include <nvif/class.h>
+#include <nvif/unpack.h>
/*******************************************************************************
* FIFO channel objects
@@ -44,8 +41,8 @@
static void
nv50_fifo_playlist_update_locked(struct nv50_fifo_priv *priv)
{
- struct nouveau_bar *bar = nouveau_bar(priv);
- struct nouveau_gpuobj *cur;
+ struct nvkm_bar *bar = nvkm_bar(priv);
+ struct nvkm_gpuobj *cur;
int i, p;
cur = priv->playlist[priv->cur_playlist];
@@ -72,12 +69,11 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
}
static int
-nv50_fifo_context_attach(struct nouveau_object *parent,
- struct nouveau_object *object)
+nv50_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent->parent;
- struct nouveau_gpuobj *ectx = (void *)object;
+ struct nvkm_gpuobj *ectx = (void *)object;
u64 limit = ectx->addr + ectx->size - 1;
u64 start = ectx->addr;
u32 addr;
@@ -103,10 +99,10 @@ nv50_fifo_context_attach(struct nouveau_object *parent,
}
static int
-nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
- struct nouveau_object *object)
+nv50_fifo_context_detach(struct nvkm_object *parent, bool suspend,
+ struct nvkm_object *object)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_priv *priv = (void *)parent->engine;
struct nv50_fifo_base *base = (void *)parent->parent;
struct nv50_fifo_chan *chan = (void *)parent;
@@ -139,7 +135,7 @@ nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12);
if (!nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff)) {
nv_error(priv, "channel %d [%s] unload timeout\n",
- chan->base.chid, nouveau_client_name(chan));
+ chan->base.chid, nvkm_client_name(chan));
if (suspend)
ret = -EBUSY;
}
@@ -159,8 +155,8 @@ nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
}
static int
-nv50_fifo_object_attach(struct nouveau_object *parent,
- struct nouveau_object *object, u32 handle)
+nv50_fifo_object_attach(struct nvkm_object *parent,
+ struct nvkm_object *object, u32 handle)
{
struct nv50_fifo_chan *chan = (void *)parent;
u32 context;
@@ -179,26 +175,25 @@ nv50_fifo_object_attach(struct nouveau_object *parent,
return -EINVAL;
}
- return nouveau_ramht_insert(chan->ramht, 0, handle, context);
+ return nvkm_ramht_insert(chan->ramht, 0, handle, context);
}
void
-nv50_fifo_object_detach(struct nouveau_object *parent, int cookie)
+nv50_fifo_object_detach(struct nvkm_object *parent, int cookie)
{
struct nv50_fifo_chan *chan = (void *)parent;
- nouveau_ramht_remove(chan->ramht, cookie);
+ nvkm_ramht_remove(chan->ramht, cookie);
}
static int
-nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv03_channel_dma_v0 v0;
} *args = data;
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
int ret;
@@ -211,12 +206,12 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
- 0x2000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR) |
- (1ULL << NVDEV_ENGINE_MPEG), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR) |
+ (1ULL << NVDEV_ENGINE_MPEG), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -228,8 +223,8 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
- ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
- &chan->ramht);
+ ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
+ &chan->ramht);
if (ret)
return ret;
@@ -246,21 +241,20 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
- (chan->ramht->base.node->offset >> 4));
+ (chan->ramht->gpuobj.node->offset >> 4));
bar->flush(bar);
return 0;
}
static int
-nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nv50_channel_gpfifo_v0 v0;
} *args = data;
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
u64 ioffset, ilength;
@@ -275,12 +269,12 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
} else
return ret;
- ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
- 0x2000, args->v0.pushbuf,
- (1ULL << NVDEV_ENGINE_DMAOBJ) |
- (1ULL << NVDEV_ENGINE_SW) |
- (1ULL << NVDEV_ENGINE_GR) |
- (1ULL << NVDEV_ENGINE_MPEG), &chan);
+ ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
+ 0x2000, args->v0.pushbuf,
+ (1ULL << NVDEV_ENGINE_DMAOBJ) |
+ (1ULL << NVDEV_ENGINE_SW) |
+ (1ULL << NVDEV_ENGINE_GR) |
+ (1ULL << NVDEV_ENGINE_MPEG), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -292,8 +286,8 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
- ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
- &chan->ramht);
+ ret = nvkm_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
+ &chan->ramht);
if (ret)
return ret;
@@ -310,30 +304,30 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
- (chan->ramht->base.node->offset >> 4));
+ (chan->ramht->gpuobj.node->offset >> 4));
bar->flush(bar);
return 0;
}
void
-nv50_fifo_chan_dtor(struct nouveau_object *object)
+nv50_fifo_chan_dtor(struct nvkm_object *object)
{
struct nv50_fifo_chan *chan = (void *)object;
- nouveau_ramht_ref(NULL, &chan->ramht);
- nouveau_fifo_channel_destroy(&chan->base);
+ nvkm_ramht_ref(NULL, &chan->ramht);
+ nvkm_fifo_channel_destroy(&chan->base);
}
static int
-nv50_fifo_chan_init(struct nouveau_object *object)
+nv50_fifo_chan_init(struct nvkm_object *object)
{
struct nv50_fifo_priv *priv = (void *)object->engine;
struct nv50_fifo_base *base = (void *)object->parent;
struct nv50_fifo_chan *chan = (void *)object;
- struct nouveau_gpuobj *ramfc = base->ramfc;
+ struct nvkm_gpuobj *ramfc = base->ramfc;
u32 chid = chan->base.chid;
int ret;
- ret = nouveau_fifo_channel_init(&chan->base);
+ ret = nvkm_fifo_channel_init(&chan->base);
if (ret)
return ret;
@@ -343,7 +337,7 @@ nv50_fifo_chan_init(struct nouveau_object *object)
}
int
-nv50_fifo_chan_fini(struct nouveau_object *object, bool suspend)
+nv50_fifo_chan_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_fifo_priv *priv = (void *)object->engine;
struct nv50_fifo_chan *chan = (void *)object;
@@ -354,34 +348,34 @@ nv50_fifo_chan_fini(struct nouveau_object *object, bool suspend)
nv50_fifo_playlist_update(priv);
nv_wr32(priv, 0x002600 + (chid * 4), 0x00000000);
- return nouveau_fifo_channel_fini(&chan->base, suspend);
+ return nvkm_fifo_channel_fini(&chan->base, suspend);
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv50_fifo_ofuncs_dma = {
.ctor = nv50_fifo_chan_ctor_dma,
.dtor = nv50_fifo_chan_dtor,
.init = nv50_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
nv50_fifo_ofuncs_ind = {
.ctor = nv50_fifo_chan_ctor_ind,
.dtor = nv50_fifo_chan_dtor,
.init = nv50_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
- .map = _nouveau_fifo_channel_map,
- .rd32 = _nouveau_fifo_channel_rd32,
- .wr32 = _nouveau_fifo_channel_wr32,
- .ntfy = _nouveau_fifo_channel_ntfy
+ .map = _nvkm_fifo_channel_map,
+ .rd32 = _nvkm_fifo_channel_rd32,
+ .wr32 = _nvkm_fifo_channel_wr32,
+ .ntfy = _nvkm_fifo_channel_ntfy
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_fifo_sclass[] = {
{ NV50_CHANNEL_DMA, &nv50_fifo_ofuncs_dma },
{ NV50_CHANNEL_GPFIFO, &nv50_fifo_ofuncs_ind },
@@ -393,36 +387,35 @@ nv50_fifo_sclass[] = {
******************************************************************************/
static int
-nv50_fifo_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_fifo_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_fifo_base *base;
int ret;
- ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
- 0x1000, NVOBJ_FLAG_HEAP, &base);
+ ret = nvkm_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
+ 0x1000, NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200,
- 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
+ ret = nvkm_gpuobj_new(nv_object(base), nv_object(base), 0x0200,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1200, 0,
- NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
+ ret = nvkm_gpuobj_new(nv_object(base), nv_object(base), 0x1200, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0, 0,
- &base->pgd);
+ ret = nvkm_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0, 0,
+ &base->pgd);
if (ret)
return ret;
- ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
+ ret = nvkm_vm_ref(nvkm_client(parent)->vm, &base->vm, base->pgd);
if (ret)
return ret;
@@ -430,27 +423,27 @@ nv50_fifo_context_ctor(struct nouveau_object *parent,
}
void
-nv50_fifo_context_dtor(struct nouveau_object *object)
+nv50_fifo_context_dtor(struct nvkm_object *object)
{
struct nv50_fifo_base *base = (void *)object;
- nouveau_vm_ref(NULL, &base->vm, base->pgd);
- nouveau_gpuobj_ref(NULL, &base->pgd);
- nouveau_gpuobj_ref(NULL, &base->eng);
- nouveau_gpuobj_ref(NULL, &base->ramfc);
- nouveau_gpuobj_ref(NULL, &base->cache);
- nouveau_fifo_context_destroy(&base->base);
+ nvkm_vm_ref(NULL, &base->vm, base->pgd);
+ nvkm_gpuobj_ref(NULL, &base->pgd);
+ nvkm_gpuobj_ref(NULL, &base->eng);
+ nvkm_gpuobj_ref(NULL, &base->ramfc);
+ nvkm_gpuobj_ref(NULL, &base->cache);
+ nvkm_fifo_context_destroy(&base->base);
}
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_fifo_context_ctor,
.dtor = nv50_fifo_context_dtor,
- .init = _nouveau_fifo_context_init,
- .fini = _nouveau_fifo_context_fini,
- .rd32 = _nouveau_fifo_context_rd32,
- .wr32 = _nouveau_fifo_context_wr32,
+ .init = _nvkm_fifo_context_init,
+ .fini = _nvkm_fifo_context_fini,
+ .rd32 = _nvkm_fifo_context_rd32,
+ .wr32 = _nvkm_fifo_context_wr32,
},
};
@@ -459,25 +452,25 @@ nv50_fifo_cclass = {
******************************************************************************/
static int
-nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_fifo_priv *priv;
int ret;
- ret = nouveau_fifo_create(parent, engine, oclass, 1, 127, &priv);
+ ret = nvkm_fifo_create(parent, engine, oclass, 1, 127, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
- &priv->playlist[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[0]);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
- &priv->playlist[1]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
+ &priv->playlist[1]);
if (ret)
return ret;
@@ -491,23 +484,23 @@ nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
void
-nv50_fifo_dtor(struct nouveau_object *object)
+nv50_fifo_dtor(struct nvkm_object *object)
{
struct nv50_fifo_priv *priv = (void *)object;
- nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
- nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
+ nvkm_gpuobj_ref(NULL, &priv->playlist[1]);
+ nvkm_gpuobj_ref(NULL, &priv->playlist[0]);
- nouveau_fifo_destroy(&priv->base);
+ nvkm_fifo_destroy(&priv->base);
}
int
-nv50_fifo_init(struct nouveau_object *object)
+nv50_fifo_init(struct nvkm_object *object)
{
struct nv50_fifo_priv *priv = (void *)object;
int ret, i;
- ret = nouveau_fifo_init(&priv->base);
+ ret = nvkm_fifo_init(&priv->base);
if (ret)
return ret;
@@ -529,13 +522,13 @@ nv50_fifo_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nv50_fifo_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+nv50_fifo_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(FIFO, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_fifo_ctor,
.dtor = nv50_fifo_dtor,
.init = nv50_fifo_init,
- .fini = _nouveau_fifo_fini,
+ .fini = _nvkm_fifo_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
new file mode 100644
index 000000000000..09ed93c66567
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.h
@@ -0,0 +1,36 @@
+#ifndef __NV50_FIFO_H__
+#define __NV50_FIFO_H__
+#include <engine/fifo.h>
+
+struct nv50_fifo_priv {
+ struct nvkm_fifo base;
+ struct nvkm_gpuobj *playlist[2];
+ int cur_playlist;
+};
+
+struct nv50_fifo_base {
+ struct nvkm_fifo_base base;
+ struct nvkm_gpuobj *ramfc;
+ struct nvkm_gpuobj *cache;
+ struct nvkm_gpuobj *eng;
+ struct nvkm_gpuobj *pgd;
+ struct nvkm_vm *vm;
+};
+
+struct nv50_fifo_chan {
+ struct nvkm_fifo_chan base;
+ u32 subc[8];
+ struct nvkm_ramht *ramht;
+};
+
+void nv50_fifo_playlist_update(struct nv50_fifo_priv *);
+
+void nv50_fifo_object_detach(struct nvkm_object *, int);
+void nv50_fifo_chan_dtor(struct nvkm_object *);
+int nv50_fifo_chan_fini(struct nvkm_object *, bool);
+
+void nv50_fifo_context_dtor(struct nvkm_object *);
+
+void nv50_fifo_dtor(struct nvkm_object *);
+int nv50_fifo_init(struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild
new file mode 100644
index 000000000000..1771d944591b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/Kbuild
@@ -0,0 +1,36 @@
+nvkm-y += nvkm/engine/gr/ctxnv40.o
+nvkm-y += nvkm/engine/gr/ctxnv50.o
+nvkm-y += nvkm/engine/gr/ctxgf100.o
+nvkm-y += nvkm/engine/gr/ctxgf108.o
+nvkm-y += nvkm/engine/gr/ctxgf104.o
+nvkm-y += nvkm/engine/gr/ctxgf110.o
+nvkm-y += nvkm/engine/gr/ctxgf117.o
+nvkm-y += nvkm/engine/gr/ctxgf119.o
+nvkm-y += nvkm/engine/gr/ctxgk104.o
+nvkm-y += nvkm/engine/gr/ctxgk20a.o
+nvkm-y += nvkm/engine/gr/ctxgk110.o
+nvkm-y += nvkm/engine/gr/ctxgk110b.o
+nvkm-y += nvkm/engine/gr/ctxgk208.o
+nvkm-y += nvkm/engine/gr/ctxgm107.o
+nvkm-y += nvkm/engine/gr/nv04.o
+nvkm-y += nvkm/engine/gr/nv10.o
+nvkm-y += nvkm/engine/gr/nv20.o
+nvkm-y += nvkm/engine/gr/nv25.o
+nvkm-y += nvkm/engine/gr/nv2a.o
+nvkm-y += nvkm/engine/gr/nv30.o
+nvkm-y += nvkm/engine/gr/nv34.o
+nvkm-y += nvkm/engine/gr/nv35.o
+nvkm-y += nvkm/engine/gr/nv40.o
+nvkm-y += nvkm/engine/gr/nv50.o
+nvkm-y += nvkm/engine/gr/gf100.o
+nvkm-y += nvkm/engine/gr/gf108.o
+nvkm-y += nvkm/engine/gr/gf104.o
+nvkm-y += nvkm/engine/gr/gf110.o
+nvkm-y += nvkm/engine/gr/gf117.o
+nvkm-y += nvkm/engine/gr/gf119.o
+nvkm-y += nvkm/engine/gr/gk104.o
+nvkm-y += nvkm/engine/gr/gk20a.o
+nvkm-y += nvkm/engine/gr/gk110.o
+nvkm-y += nvkm/engine/gr/gk110b.o
+nvkm-y += nvkm/engine/gr/gk208.o
+nvkm-y += nvkm/engine/gr/gm107.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
index b8e5fe60a1eb..2e7ec389eea7 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
@@ -21,15 +21,19 @@
*
* Authors: Ben Skeggs
*/
+#include "ctxgf100.h"
-#include "ctxnvc0.h"
+#include <subdev/bar.h>
+#include <subdev/fb.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvc0_grctx_init_icmd_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
@@ -266,14 +270,14 @@ nvc0_grctx_init_icmd_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvc0_grctx_pack_icmd[] = {
- { nvc0_grctx_init_icmd_0 },
+const struct gf100_gr_pack
+gf100_grctx_pack_icmd[] = {
+ { gf100_grctx_init_icmd_0 },
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_9097_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_9097_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
{ 0x000808, 8, 0x40, 0x00000400 },
@@ -575,8 +579,8 @@ nvc0_grctx_init_9097_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_902d_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_902d_0[] = {
{ 0x000200, 1, 0x04, 0x000000cf },
{ 0x000204, 1, 0x04, 0x00000001 },
{ 0x000208, 1, 0x04, 0x00000020 },
@@ -594,8 +598,8 @@ nvc0_grctx_init_902d_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_9039_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_9039_0[] = {
{ 0x00030c, 3, 0x04, 0x00000000 },
{ 0x000320, 1, 0x04, 0x00000000 },
{ 0x000238, 2, 0x04, 0x00000000 },
@@ -603,8 +607,8 @@ nvc0_grctx_init_9039_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_90c0_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_90c0_0[] = {
{ 0x00270c, 8, 0x20, 0x00000000 },
{ 0x00030c, 1, 0x04, 0x00000001 },
{ 0x001944, 1, 0x04, 0x00000000 },
@@ -621,23 +625,23 @@ nvc0_grctx_init_90c0_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvc0_grctx_pack_mthd[] = {
- { nvc0_grctx_init_9097_0, 0x9097 },
- { nvc0_grctx_init_902d_0, 0x902d },
- { nvc0_grctx_init_9039_0, 0x9039 },
- { nvc0_grctx_init_90c0_0, 0x90c0 },
+const struct gf100_gr_pack
+gf100_grctx_pack_mthd[] = {
+ { gf100_grctx_init_9097_0, 0x9097 },
+ { gf100_grctx_init_902d_0, 0x902d },
+ { gf100_grctx_init_9039_0, 0x9039 },
+ { gf100_grctx_init_90c0_0, 0x90c0 },
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_main_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_main_0[] = {
{ 0x400204, 2, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_fe_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_fe_0[] = {
{ 0x404004, 11, 0x04, 0x00000000 },
{ 0x404044, 1, 0x04, 0x00000000 },
{ 0x404094, 13, 0x04, 0x00000000 },
@@ -657,8 +661,8 @@ nvc0_grctx_init_fe_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_pri_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_pri_0[] = {
{ 0x404404, 14, 0x04, 0x00000000 },
{ 0x404460, 2, 0x04, 0x00000000 },
{ 0x404468, 1, 0x04, 0x00ffffff },
@@ -668,8 +672,8 @@ nvc0_grctx_init_pri_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_memfmt_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_memfmt_0[] = {
{ 0x404604, 1, 0x04, 0x00000015 },
{ 0x404608, 1, 0x04, 0x00000000 },
{ 0x40460c, 1, 0x04, 0x00002e00 },
@@ -690,8 +694,8 @@ nvc0_grctx_init_memfmt_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_ds_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x078000bf },
{ 0x405830, 1, 0x04, 0x02180000 },
{ 0x405834, 2, 0x04, 0x00000000 },
@@ -702,8 +706,8 @@ nvc0_grctx_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_pd_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x000103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
@@ -712,8 +716,8 @@ nvc0_grctx_init_pd_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_rstr2d_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_rstr2d_0[] = {
{ 0x407804, 1, 0x04, 0x00000023 },
{ 0x40780c, 1, 0x04, 0x0a418820 },
{ 0x407810, 1, 0x04, 0x062080e6 },
@@ -725,8 +729,8 @@ nvc0_grctx_init_rstr2d_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_scc_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_scc_0[] = {
{ 0x408000, 2, 0x04, 0x00000000 },
{ 0x408008, 1, 0x04, 0x00000018 },
{ 0x40800c, 2, 0x04, 0x00000000 },
@@ -736,8 +740,8 @@ nvc0_grctx_init_scc_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_be_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x02802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x0003e00d },
@@ -748,28 +752,28 @@ nvc0_grctx_init_be_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvc0_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
- { nvc0_grctx_init_fe_0 },
- { nvc0_grctx_init_pri_0 },
- { nvc0_grctx_init_memfmt_0 },
- { nvc0_grctx_init_ds_0 },
- { nvc0_grctx_init_pd_0 },
- { nvc0_grctx_init_rstr2d_0 },
- { nvc0_grctx_init_scc_0 },
- { nvc0_grctx_init_be_0 },
+const struct gf100_gr_pack
+gf100_grctx_pack_hub[] = {
+ { gf100_grctx_init_main_0 },
+ { gf100_grctx_init_fe_0 },
+ { gf100_grctx_init_pri_0 },
+ { gf100_grctx_init_memfmt_0 },
+ { gf100_grctx_init_ds_0 },
+ { gf100_grctx_init_pd_0 },
+ { gf100_grctx_init_rstr2d_0 },
+ { gf100_grctx_init_scc_0 },
+ { gf100_grctx_init_be_0 },
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_gpc_unk_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_gpc_unk_0[] = {
{ 0x418380, 1, 0x04, 0x00000016 },
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_prop_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_prop_0[] = {
{ 0x418400, 1, 0x04, 0x38004e00 },
{ 0x418404, 1, 0x04, 0x71e0ffff },
{ 0x418408, 1, 0x04, 0x00000000 },
@@ -782,8 +786,8 @@ nvc0_grctx_init_prop_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_gpc_unk_1[] = {
+const struct gf100_gr_init
+gf100_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000001f },
{ 0x418684, 1, 0x04, 0x0000000f },
{ 0x418700, 1, 0x04, 0x00000002 },
@@ -794,8 +798,8 @@ nvc0_grctx_init_gpc_unk_1[] = {
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x0006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
@@ -807,8 +811,8 @@ nvc0_grctx_init_setup_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_zcull_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_zcull_0[] = {
{ 0x41891c, 1, 0x04, 0x00ff00ff },
{ 0x418924, 1, 0x04, 0x00000000 },
{ 0x418928, 1, 0x04, 0x00ffff00 },
@@ -816,8 +820,8 @@ nvc0_grctx_init_zcull_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_crstr_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_crstr_0[] = {
{ 0x418b00, 1, 0x04, 0x00000000 },
{ 0x418b08, 1, 0x04, 0x0a418820 },
{ 0x418b0c, 1, 0x04, 0x062080e6 },
@@ -829,8 +833,8 @@ nvc0_grctx_init_crstr_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_gpm_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_gpm_0[] = {
{ 0x418c08, 1, 0x04, 0x00000001 },
{ 0x418c10, 8, 0x04, 0x00000000 },
{ 0x418c80, 1, 0x04, 0x20200004 },
@@ -838,29 +842,29 @@ nvc0_grctx_init_gpm_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_gcc_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_gcc_0[] = {
{ 0x419000, 1, 0x04, 0x00000780 },
{ 0x419004, 2, 0x04, 0x00000000 },
{ 0x419014, 1, 0x04, 0x00000004 },
{}
};
-const struct nvc0_graph_pack
-nvc0_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nvc0_grctx_init_prop_0 },
- { nvc0_grctx_init_gpc_unk_1 },
- { nvc0_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nvc0_grctx_init_crstr_0 },
- { nvc0_grctx_init_gpm_0 },
- { nvc0_grctx_init_gcc_0 },
+const struct gf100_gr_pack
+gf100_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gf100_grctx_init_prop_0 },
+ { gf100_grctx_init_gpc_unk_1 },
+ { gf100_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gf100_grctx_init_crstr_0 },
+ { gf100_grctx_init_gpm_0 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_zcullr_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_zcullr_0[] = {
{ 0x418a00, 3, 0x04, 0x00000000 },
{ 0x418a0c, 1, 0x04, 0x00010000 },
{ 0x418a10, 3, 0x04, 0x00000000 },
@@ -888,14 +892,14 @@ nvc0_grctx_init_zcullr_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvc0_grctx_pack_zcull[] = {
- { nvc0_grctx_init_zcullr_0 },
+const struct gf100_gr_pack
+gf100_grctx_pack_zcull[] = {
+ { gf100_grctx_init_zcullr_0 },
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_pe_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_pe_0[] = {
{ 0x419818, 1, 0x04, 0x00000000 },
{ 0x41983c, 1, 0x04, 0x00038bc7 },
{ 0x419848, 1, 0x04, 0x00000000 },
@@ -904,8 +908,8 @@ nvc0_grctx_init_pe_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_tex_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000001f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000023 },
@@ -915,8 +919,8 @@ nvc0_grctx_init_tex_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_wwdx_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_wwdx_0[] = {
{ 0x419b00, 1, 0x04, 0x0a418820 },
{ 0x419b04, 1, 0x04, 0x062080e6 },
{ 0x419b08, 1, 0x04, 0x020398a4 },
@@ -929,8 +933,8 @@ nvc0_grctx_init_wwdx_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_mpc_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x00000002 },
{ 0x419c04, 1, 0x04, 0x00000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
@@ -938,23 +942,23 @@ nvc0_grctx_init_mpc_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_l1c_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_l1c_0[] = {
{ 0x419cb0, 1, 0x04, 0x00060048 },
{ 0x419ce8, 1, 0x04, 0x00000000 },
{ 0x419cf4, 1, 0x04, 0x00000183 },
{}
};
-const struct nvc0_graph_init
-nvc0_grctx_init_tpccs_0[] = {
+const struct gf100_gr_init
+gf100_grctx_init_tpccs_0[] = {
{ 0x419d20, 1, 0x04, 0x02180000 },
{ 0x419d24, 1, 0x04, 0x00001fff },
{}
};
-static const struct nvc0_graph_init
-nvc0_grctx_init_sm_0[] = {
+static const struct gf100_gr_init
+gf100_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00000002 },
{ 0x419e44, 1, 0x04, 0x001beff2 },
@@ -966,15 +970,15 @@ nvc0_grctx_init_sm_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvc0_grctx_pack_tpc[] = {
- { nvc0_grctx_init_pe_0 },
- { nvc0_grctx_init_tex_0 },
- { nvc0_grctx_init_wwdx_0 },
- { nvc0_grctx_init_mpc_0 },
- { nvc0_grctx_init_l1c_0 },
- { nvc0_grctx_init_tpccs_0 },
- { nvc0_grctx_init_sm_0 },
+const struct gf100_gr_pack
+gf100_grctx_pack_tpc[] = {
+ { gf100_grctx_init_pe_0 },
+ { gf100_grctx_init_tex_0 },
+ { gf100_grctx_init_wwdx_0 },
+ { gf100_grctx_init_mpc_0 },
+ { gf100_grctx_init_l1c_0 },
+ { gf100_grctx_init_tpccs_0 },
+ { gf100_grctx_init_sm_0 },
{}
};
@@ -983,7 +987,7 @@ nvc0_grctx_pack_tpc[] = {
******************************************************************************/
int
-nvc0_grctx_mmio_data(struct nvc0_grctx *info, u32 size, u32 align, u32 access)
+gf100_grctx_mmio_data(struct gf100_grctx *info, u32 size, u32 align, u32 access)
{
if (info->data) {
info->buffer[info->buffer_nr] = round_up(info->addr, align);
@@ -998,8 +1002,8 @@ nvc0_grctx_mmio_data(struct nvc0_grctx *info, u32 size, u32 align, u32 access)
}
void
-nvc0_grctx_mmio_item(struct nvc0_grctx *info, u32 addr, u32 data,
- int shift, int buffer)
+gf100_grctx_mmio_item(struct gf100_grctx *info, u32 addr, u32 data,
+ int shift, int buffer)
{
if (info->data) {
if (shift >= 0) {
@@ -1021,9 +1025,9 @@ nvc0_grctx_mmio_item(struct nvc0_grctx *info, u32 addr, u32 data,
}
void
-nvc0_grctx_generate_bundle(struct nvc0_grctx *info)
+gf100_grctx_generate_bundle(struct gf100_grctx *info)
{
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv);
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(info->priv);
const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS;
const int s = 8;
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
@@ -1034,9 +1038,9 @@ nvc0_grctx_generate_bundle(struct nvc0_grctx *info)
}
void
-nvc0_grctx_generate_pagepool(struct nvc0_grctx *info)
+gf100_grctx_generate_pagepool(struct gf100_grctx *info)
{
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv);
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(info->priv);
const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS;
const int s = 8;
const int b = mmio_vram(info, impl->pagepool_size, (1 << s), access);
@@ -1047,10 +1051,10 @@ nvc0_grctx_generate_pagepool(struct nvc0_grctx *info)
}
void
-nvc0_grctx_generate_attrib(struct nvc0_grctx *info)
+gf100_grctx_generate_attrib(struct gf100_grctx *info)
{
- struct nvc0_graph_priv *priv = info->priv;
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(priv);
+ struct gf100_gr_priv *priv = info->priv;
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(priv);
const u32 attrib = impl->attrib_nr;
const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max);
const u32 access = NV_MEM_ACCESS_RW;
@@ -1074,12 +1078,12 @@ nvc0_grctx_generate_attrib(struct nvc0_grctx *info)
}
void
-nvc0_grctx_generate_unkn(struct nvc0_graph_priv *priv)
+gf100_grctx_generate_unkn(struct gf100_gr_priv *priv)
{
}
void
-nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *priv)
+gf100_grctx_generate_tpcid(struct gf100_gr_priv *priv)
{
int gpc, tpc, id;
@@ -1100,7 +1104,7 @@ nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *priv)
}
void
-nvc0_grctx_generate_r406028(struct nvc0_graph_priv *priv)
+gf100_grctx_generate_r406028(struct gf100_gr_priv *priv)
{
u32 tmp[GPC_MAX / 8] = {}, i = 0;
for (i = 0; i < priv->gpc_nr; i++)
@@ -1112,7 +1116,7 @@ nvc0_grctx_generate_r406028(struct nvc0_graph_priv *priv)
}
void
-nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *priv)
+gf100_grctx_generate_r4060a8(struct gf100_gr_priv *priv)
{
u8 tpcnr[GPC_MAX], data[TPC_MAX];
int gpc, tpc, i;
@@ -1134,7 +1138,7 @@ nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *priv)
}
void
-nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *priv)
+gf100_grctx_generate_r418bb8(struct gf100_gr_priv *priv)
{
u32 data[6] = {}, data2[2] = {};
u8 tpcnr[GPC_MAX];
@@ -1192,7 +1196,7 @@ nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *priv)
}
void
-nvc0_grctx_generate_r406800(struct nvc0_graph_priv *priv)
+gf100_grctx_generate_r406800(struct gf100_gr_priv *priv)
{
u64 tpc_mask = 0, tpc_set = 0;
u8 tpcnr[GPC_MAX];
@@ -1225,17 +1229,17 @@ nvc0_grctx_generate_r406800(struct nvc0_graph_priv *priv)
}
void
-nvc0_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+gf100_grctx_generate_main(struct gf100_gr_priv *priv, struct gf100_grctx *info)
{
- struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+ struct gf100_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 0);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 0);
- nvc0_graph_mmio(priv, oclass->hub);
- nvc0_graph_mmio(priv, oclass->gpc);
- nvc0_graph_mmio(priv, oclass->zcull);
- nvc0_graph_mmio(priv, oclass->tpc);
- nvc0_graph_mmio(priv, oclass->ppc);
+ gf100_gr_mmio(priv, oclass->hub);
+ gf100_gr_mmio(priv, oclass->gpc);
+ gf100_gr_mmio(priv, oclass->zcull);
+ gf100_gr_mmio(priv, oclass->tpc);
+ gf100_gr_mmio(priv, oclass->ppc);
nv_wr32(priv, 0x404154, 0x00000000);
@@ -1244,32 +1248,32 @@ nvc0_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
oclass->attrib(info);
oclass->unkn(priv);
- nvc0_grctx_generate_tpcid(priv);
- nvc0_grctx_generate_r406028(priv);
- nvc0_grctx_generate_r4060a8(priv);
- nvc0_grctx_generate_r418bb8(priv);
- nvc0_grctx_generate_r406800(priv);
+ gf100_grctx_generate_tpcid(priv);
+ gf100_grctx_generate_r406028(priv);
+ gf100_grctx_generate_r4060a8(priv);
+ gf100_grctx_generate_r418bb8(priv);
+ gf100_grctx_generate_r406800(priv);
- nvc0_graph_icmd(priv, oclass->icmd);
+ gf100_gr_icmd(priv, oclass->icmd);
nv_wr32(priv, 0x404154, 0x00000400);
- nvc0_graph_mthd(priv, oclass->mthd);
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 1);
+ gf100_gr_mthd(priv, oclass->mthd);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 1);
}
int
-nvc0_grctx_generate(struct nvc0_graph_priv *priv)
+gf100_grctx_generate(struct gf100_gr_priv *priv)
{
- struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
- struct nouveau_bar *bar = nouveau_bar(priv);
- struct nouveau_gpuobj *chan;
- struct nvc0_grctx info;
+ struct gf100_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+ struct nvkm_bar *bar = nvkm_bar(priv);
+ struct nvkm_gpuobj *chan;
+ struct gf100_grctx info;
int ret, i;
/* allocate memory to for a "channel", which we'll use to generate
* the default context values
*/
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x80000 + priv->size,
- 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x80000 + priv->size,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &chan);
if (ret) {
nv_error(priv, "failed to allocate channel memory, %d\n", ret);
return ret;
@@ -1353,34 +1357,34 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
}
done:
- nouveau_gpuobj_ref(NULL, &chan);
+ nvkm_gpuobj_ref(NULL, &chan);
return ret;
}
-struct nouveau_oclass *
-nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gf100_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nvc0_grctx_generate_main,
- .unkn = nvc0_grctx_generate_unkn,
- .hub = nvc0_grctx_pack_hub,
- .gpc = nvc0_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nvc0_grctx_pack_tpc,
- .icmd = nvc0_grctx_pack_icmd,
- .mthd = nvc0_grctx_pack_mthd,
- .bundle = nvc0_grctx_generate_bundle,
+ .main = gf100_grctx_generate_main,
+ .unkn = gf100_grctx_generate_unkn,
+ .hub = gf100_grctx_pack_hub,
+ .gpc = gf100_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gf100_grctx_pack_tpc,
+ .icmd = gf100_grctx_pack_icmd,
+ .mthd = gf100_grctx_pack_mthd,
+ .bundle = gf100_grctx_generate_bundle,
.bundle_size = 0x1800,
- .pagepool = nvc0_grctx_generate_pagepool,
+ .pagepool = gf100_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvc0_grctx_generate_attrib,
+ .attrib = gf100_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
new file mode 100644
index 000000000000..1166b1aa1525
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
@@ -0,0 +1,199 @@
+#ifndef __NVKM_GRCTX_NVC0_H__
+#define __NVKM_GRCTX_NVC0_H__
+#include "gf100.h"
+
+struct gf100_grctx {
+ struct gf100_gr_priv *priv;
+ struct gf100_gr_data *data;
+ struct gf100_gr_mmio *mmio;
+ int buffer_nr;
+ u64 buffer[4];
+ u64 addr;
+};
+
+int gf100_grctx_mmio_data(struct gf100_grctx *, u32 size, u32 align, u32 access);
+void gf100_grctx_mmio_item(struct gf100_grctx *, u32 addr, u32 data, int s, int);
+
+#define mmio_vram(a,b,c,d) gf100_grctx_mmio_data((a), (b), (c), (d))
+#define mmio_refn(a,b,c,d,e) gf100_grctx_mmio_item((a), (b), (c), (d), (e))
+#define mmio_skip(a,b,c) mmio_refn((a), (b), (c), -1, -1)
+#define mmio_wr32(a,b,c) mmio_refn((a), (b), (c), 0, -1)
+
+struct gf100_grctx_oclass {
+ struct nvkm_oclass base;
+ /* main context generation function */
+ void (*main)(struct gf100_gr_priv *, struct gf100_grctx *);
+ /* context-specific modify-on-first-load list generation function */
+ void (*unkn)(struct gf100_gr_priv *);
+ /* mmio context data */
+ const struct gf100_gr_pack *hub;
+ const struct gf100_gr_pack *gpc;
+ const struct gf100_gr_pack *zcull;
+ const struct gf100_gr_pack *tpc;
+ const struct gf100_gr_pack *ppc;
+ /* indirect context data, generated with icmds/mthds */
+ const struct gf100_gr_pack *icmd;
+ const struct gf100_gr_pack *mthd;
+ /* bundle circular buffer */
+ void (*bundle)(struct gf100_grctx *);
+ u32 bundle_size;
+ u32 bundle_min_gpm_fifo_depth;
+ u32 bundle_token_limit;
+ /* pagepool */
+ void (*pagepool)(struct gf100_grctx *);
+ u32 pagepool_size;
+ /* attribute(/alpha) circular buffer */
+ void (*attrib)(struct gf100_grctx *);
+ u32 attrib_nr_max;
+ u32 attrib_nr;
+ u32 alpha_nr_max;
+ u32 alpha_nr;
+};
+
+static inline const struct gf100_grctx_oclass *
+gf100_grctx_impl(struct gf100_gr_priv *priv)
+{
+ return (void *)nv_engine(priv)->cclass;
+}
+
+extern struct nvkm_oclass *gf100_grctx_oclass;
+int gf100_grctx_generate(struct gf100_gr_priv *);
+void gf100_grctx_generate_main(struct gf100_gr_priv *, struct gf100_grctx *);
+void gf100_grctx_generate_bundle(struct gf100_grctx *);
+void gf100_grctx_generate_pagepool(struct gf100_grctx *);
+void gf100_grctx_generate_attrib(struct gf100_grctx *);
+void gf100_grctx_generate_unkn(struct gf100_gr_priv *);
+void gf100_grctx_generate_tpcid(struct gf100_gr_priv *);
+void gf100_grctx_generate_r406028(struct gf100_gr_priv *);
+void gf100_grctx_generate_r4060a8(struct gf100_gr_priv *);
+void gf100_grctx_generate_r418bb8(struct gf100_gr_priv *);
+void gf100_grctx_generate_r406800(struct gf100_gr_priv *);
+
+extern struct nvkm_oclass *gf108_grctx_oclass;
+void gf108_grctx_generate_attrib(struct gf100_grctx *);
+void gf108_grctx_generate_unkn(struct gf100_gr_priv *);
+
+extern struct nvkm_oclass *gf104_grctx_oclass;
+extern struct nvkm_oclass *gf110_grctx_oclass;
+
+extern struct nvkm_oclass *gf117_grctx_oclass;
+void gf117_grctx_generate_attrib(struct gf100_grctx *);
+
+extern struct nvkm_oclass *gf119_grctx_oclass;
+
+extern struct nvkm_oclass *gk104_grctx_oclass;
+extern struct nvkm_oclass *gk20a_grctx_oclass;
+void gk104_grctx_generate_main(struct gf100_gr_priv *, struct gf100_grctx *);
+void gk104_grctx_generate_bundle(struct gf100_grctx *);
+void gk104_grctx_generate_pagepool(struct gf100_grctx *);
+void gk104_grctx_generate_unkn(struct gf100_gr_priv *);
+void gk104_grctx_generate_r418bb8(struct gf100_gr_priv *);
+
+extern struct nvkm_oclass *gk110_grctx_oclass;
+extern struct nvkm_oclass *gk110b_grctx_oclass;
+extern struct nvkm_oclass *gk208_grctx_oclass;
+extern struct nvkm_oclass *gm107_grctx_oclass;
+
+/* context init value lists */
+
+extern const struct gf100_gr_pack gf100_grctx_pack_icmd[];
+
+extern const struct gf100_gr_pack gf100_grctx_pack_mthd[];
+extern const struct gf100_gr_init gf100_grctx_init_902d_0[];
+extern const struct gf100_gr_init gf100_grctx_init_9039_0[];
+extern const struct gf100_gr_init gf100_grctx_init_90c0_0[];
+
+extern const struct gf100_gr_pack gf100_grctx_pack_hub[];
+extern const struct gf100_gr_init gf100_grctx_init_main_0[];
+extern const struct gf100_gr_init gf100_grctx_init_fe_0[];
+extern const struct gf100_gr_init gf100_grctx_init_pri_0[];
+extern const struct gf100_gr_init gf100_grctx_init_memfmt_0[];
+extern const struct gf100_gr_init gf100_grctx_init_rstr2d_0[];
+extern const struct gf100_gr_init gf100_grctx_init_scc_0[];
+
+extern const struct gf100_gr_pack gf100_grctx_pack_gpc[];
+extern const struct gf100_gr_init gf100_grctx_init_gpc_unk_0[];
+extern const struct gf100_gr_init gf100_grctx_init_prop_0[];
+extern const struct gf100_gr_init gf100_grctx_init_gpc_unk_1[];
+extern const struct gf100_gr_init gf100_grctx_init_zcull_0[];
+extern const struct gf100_gr_init gf100_grctx_init_crstr_0[];
+extern const struct gf100_gr_init gf100_grctx_init_gpm_0[];
+extern const struct gf100_gr_init gf100_grctx_init_gcc_0[];
+
+extern const struct gf100_gr_pack gf100_grctx_pack_zcull[];
+
+extern const struct gf100_gr_pack gf100_grctx_pack_tpc[];
+extern const struct gf100_gr_init gf100_grctx_init_pe_0[];
+extern const struct gf100_gr_init gf100_grctx_init_wwdx_0[];
+extern const struct gf100_gr_init gf100_grctx_init_mpc_0[];
+extern const struct gf100_gr_init gf100_grctx_init_tpccs_0[];
+
+extern const struct gf100_gr_init gf104_grctx_init_tex_0[];
+extern const struct gf100_gr_init gf104_grctx_init_l1c_0[];
+extern const struct gf100_gr_init gf104_grctx_init_sm_0[];
+
+extern const struct gf100_gr_init gf108_grctx_init_9097_0[];
+
+extern const struct gf100_gr_init gf108_grctx_init_gpm_0[];
+
+extern const struct gf100_gr_init gf108_grctx_init_pe_0[];
+extern const struct gf100_gr_init gf108_grctx_init_wwdx_0[];
+extern const struct gf100_gr_init gf108_grctx_init_tpccs_0[];
+
+extern const struct gf100_gr_init gf110_grctx_init_9197_0[];
+extern const struct gf100_gr_init gf110_grctx_init_9297_0[];
+
+extern const struct gf100_gr_pack gf119_grctx_pack_icmd[];
+
+extern const struct gf100_gr_pack gf119_grctx_pack_mthd[];
+
+extern const struct gf100_gr_init gf119_grctx_init_fe_0[];
+extern const struct gf100_gr_init gf119_grctx_init_be_0[];
+
+extern const struct gf100_gr_init gf119_grctx_init_prop_0[];
+extern const struct gf100_gr_init gf119_grctx_init_gpc_unk_1[];
+extern const struct gf100_gr_init gf119_grctx_init_crstr_0[];
+
+extern const struct gf100_gr_init gf119_grctx_init_sm_0[];
+
+extern const struct gf100_gr_init gf117_grctx_init_pe_0[];
+
+extern const struct gf100_gr_init gf117_grctx_init_wwdx_0[];
+
+extern const struct gf100_gr_init gk104_grctx_init_memfmt_0[];
+extern const struct gf100_gr_init gk104_grctx_init_ds_0[];
+extern const struct gf100_gr_init gk104_grctx_init_scc_0[];
+
+extern const struct gf100_gr_init gk104_grctx_init_gpm_0[];
+
+extern const struct gf100_gr_init gk104_grctx_init_pes_0[];
+
+extern const struct gf100_gr_pack gk104_grctx_pack_hub[];
+extern const struct gf100_gr_pack gk104_grctx_pack_gpc[];
+extern const struct gf100_gr_pack gk104_grctx_pack_tpc[];
+extern const struct gf100_gr_pack gk104_grctx_pack_ppc[];
+extern const struct gf100_gr_pack gk104_grctx_pack_icmd[];
+extern const struct gf100_gr_init gk104_grctx_init_a097_0[];
+
+extern const struct gf100_gr_pack gk110_grctx_pack_icmd[];
+
+extern const struct gf100_gr_pack gk110_grctx_pack_mthd[];
+
+extern const struct gf100_gr_pack gk110_grctx_pack_hub[];
+extern const struct gf100_gr_init gk110_grctx_init_pri_0[];
+extern const struct gf100_gr_init gk110_grctx_init_cwd_0[];
+
+extern const struct gf100_gr_pack gk110_grctx_pack_gpc[];
+extern const struct gf100_gr_init gk110_grctx_init_gpc_unk_2[];
+
+extern const struct gf100_gr_init gk110_grctx_init_tex_0[];
+extern const struct gf100_gr_init gk110_grctx_init_mpc_0[];
+extern const struct gf100_gr_init gk110_grctx_init_l1c_0[];
+
+extern const struct gf100_gr_pack gk110_grctx_pack_ppc[];
+
+extern const struct gf100_gr_init gk208_grctx_init_rstr2d_0[];
+
+extern const struct gf100_gr_init gk208_grctx_init_prop_0[];
+extern const struct gf100_gr_init gk208_grctx_init_crstr_0[];
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c
index 41705c60cc47..c5a8d55e2cac 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf104.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "ctxnvc0.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-const struct nvc0_graph_init
-nvc4_grctx_init_tex_0[] = {
+const struct gf100_gr_init
+gf104_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000001f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000023 },
@@ -42,16 +41,16 @@ nvc4_grctx_init_tex_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc4_grctx_init_l1c_0[] = {
+const struct gf100_gr_init
+gf104_grctx_init_l1c_0[] = {
{ 0x419cb0, 1, 0x04, 0x00020048 },
{ 0x419ce8, 1, 0x04, 0x00000000 },
{ 0x419cf4, 1, 0x04, 0x00000183 },
{}
};
-const struct nvc0_graph_init
-nvc4_grctx_init_sm_0[] = {
+const struct gf100_gr_init
+gf104_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00000002 },
{ 0x419e44, 1, 0x04, 0x001beff2 },
@@ -64,15 +63,15 @@ nvc4_grctx_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc4_grctx_pack_tpc[] = {
- { nvc0_grctx_init_pe_0 },
- { nvc4_grctx_init_tex_0 },
- { nvc0_grctx_init_wwdx_0 },
- { nvc0_grctx_init_mpc_0 },
- { nvc4_grctx_init_l1c_0 },
- { nvc0_grctx_init_tpccs_0 },
- { nvc4_grctx_init_sm_0 },
+static const struct gf100_gr_pack
+gf104_grctx_pack_tpc[] = {
+ { gf100_grctx_init_pe_0 },
+ { gf104_grctx_init_tex_0 },
+ { gf100_grctx_init_wwdx_0 },
+ { gf100_grctx_init_mpc_0 },
+ { gf104_grctx_init_l1c_0 },
+ { gf100_grctx_init_tpccs_0 },
+ { gf104_grctx_init_sm_0 },
{}
};
@@ -80,30 +79,30 @@ nvc4_grctx_pack_tpc[] = {
* PGRAPH context implementation
******************************************************************************/
-struct nouveau_oclass *
-nvc4_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gf104_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xc3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nvc0_grctx_generate_main,
- .unkn = nvc0_grctx_generate_unkn,
- .hub = nvc0_grctx_pack_hub,
- .gpc = nvc0_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nvc4_grctx_pack_tpc,
- .icmd = nvc0_grctx_pack_icmd,
- .mthd = nvc0_grctx_pack_mthd,
- .bundle = nvc0_grctx_generate_bundle,
+ .main = gf100_grctx_generate_main,
+ .unkn = gf100_grctx_generate_unkn,
+ .hub = gf100_grctx_pack_hub,
+ .gpc = gf100_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gf104_grctx_pack_tpc,
+ .icmd = gf100_grctx_pack_icmd,
+ .mthd = gf100_grctx_pack_mthd,
+ .bundle = gf100_grctx_generate_bundle,
.bundle_size = 0x1800,
- .pagepool = nvc0_grctx_generate_pagepool,
+ .pagepool = gf100_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvc0_grctx_generate_attrib,
+ .attrib = gf100_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c
index c6ba8fed18f1..87c844a5f34b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf108.c
@@ -21,15 +21,16 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "ctxgf100.h"
-#include "ctxnvc0.h"
+#include <subdev/fb.h>
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvc1_grctx_init_icmd_0[] = {
+static const struct gf100_gr_init
+gf108_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
@@ -267,14 +268,14 @@ nvc1_grctx_init_icmd_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc1_grctx_pack_icmd[] = {
- { nvc1_grctx_init_icmd_0 },
+static const struct gf100_gr_pack
+gf108_grctx_pack_icmd[] = {
+ { gf108_grctx_init_icmd_0 },
{}
};
-const struct nvc0_graph_init
-nvc1_grctx_init_9097_0[] = {
+const struct gf100_gr_init
+gf108_grctx_init_9097_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
{ 0x000808, 8, 0x40, 0x00000400 },
@@ -575,25 +576,25 @@ nvc1_grctx_init_9097_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc1_grctx_init_9197_0[] = {
+static const struct gf100_gr_init
+gf108_grctx_init_9197_0[] = {
{ 0x003400, 128, 0x04, 0x00000000 },
{ 0x0002e4, 1, 0x04, 0x0000b001 },
{}
};
-static const struct nvc0_graph_pack
-nvc1_grctx_pack_mthd[] = {
- { nvc1_grctx_init_9097_0, 0x9097 },
- { nvc1_grctx_init_9197_0, 0x9197 },
- { nvc0_grctx_init_902d_0, 0x902d },
- { nvc0_grctx_init_9039_0, 0x9039 },
- { nvc0_grctx_init_90c0_0, 0x90c0 },
+static const struct gf100_gr_pack
+gf108_grctx_pack_mthd[] = {
+ { gf108_grctx_init_9097_0, 0x9097 },
+ { gf108_grctx_init_9197_0, 0x9197 },
+ { gf100_grctx_init_902d_0, 0x902d },
+ { gf100_grctx_init_9039_0, 0x9039 },
+ { gf100_grctx_init_90c0_0, 0x90c0 },
{}
};
-static const struct nvc0_graph_init
-nvc1_grctx_init_ds_0[] = {
+static const struct gf100_gr_init
+gf108_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180218 },
{ 0x405834, 2, 0x04, 0x00000000 },
@@ -604,8 +605,8 @@ nvc1_grctx_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc1_grctx_init_pd_0[] = {
+static const struct gf100_gr_init
+gf108_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x000103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
@@ -616,8 +617,8 @@ nvc1_grctx_init_pd_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc1_grctx_init_be_0[] = {
+static const struct gf100_gr_init
+gf108_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x02802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1003e005 },
@@ -628,22 +629,22 @@ nvc1_grctx_init_be_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc1_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
- { nvc0_grctx_init_fe_0 },
- { nvc0_grctx_init_pri_0 },
- { nvc0_grctx_init_memfmt_0 },
- { nvc1_grctx_init_ds_0 },
- { nvc1_grctx_init_pd_0 },
- { nvc0_grctx_init_rstr2d_0 },
- { nvc0_grctx_init_scc_0 },
- { nvc1_grctx_init_be_0 },
+static const struct gf100_gr_pack
+gf108_grctx_pack_hub[] = {
+ { gf100_grctx_init_main_0 },
+ { gf100_grctx_init_fe_0 },
+ { gf100_grctx_init_pri_0 },
+ { gf100_grctx_init_memfmt_0 },
+ { gf108_grctx_init_ds_0 },
+ { gf108_grctx_init_pd_0 },
+ { gf100_grctx_init_rstr2d_0 },
+ { gf100_grctx_init_scc_0 },
+ { gf108_grctx_init_be_0 },
{}
};
-static const struct nvc0_graph_init
-nvc1_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gf108_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x0006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
@@ -655,8 +656,8 @@ nvc1_grctx_init_setup_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc1_grctx_init_gpm_0[] = {
+const struct gf100_gr_init
+gf108_grctx_init_gpm_0[] = {
{ 0x418c08, 1, 0x04, 0x00000001 },
{ 0x418c10, 8, 0x04, 0x00000000 },
{ 0x418c6c, 1, 0x04, 0x00000001 },
@@ -665,21 +666,21 @@ nvc1_grctx_init_gpm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc1_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nvc0_grctx_init_prop_0 },
- { nvc0_grctx_init_gpc_unk_1 },
- { nvc1_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nvc0_grctx_init_crstr_0 },
- { nvc1_grctx_init_gpm_0 },
- { nvc0_grctx_init_gcc_0 },
+static const struct gf100_gr_pack
+gf108_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gf100_grctx_init_prop_0 },
+ { gf100_grctx_init_gpc_unk_1 },
+ { gf108_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gf100_grctx_init_crstr_0 },
+ { gf108_grctx_init_gpm_0 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-const struct nvc0_graph_init
-nvc1_grctx_init_pe_0[] = {
+const struct gf100_gr_init
+gf108_grctx_init_pe_0[] = {
{ 0x419818, 1, 0x04, 0x00000000 },
{ 0x41983c, 1, 0x04, 0x00038bc7 },
{ 0x419848, 1, 0x04, 0x00000000 },
@@ -688,8 +689,8 @@ nvc1_grctx_init_pe_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc1_grctx_init_wwdx_0[] = {
+const struct gf100_gr_init
+gf108_grctx_init_wwdx_0[] = {
{ 0x419b00, 1, 0x04, 0x0a418820 },
{ 0x419b04, 1, 0x04, 0x062080e6 },
{ 0x419b08, 1, 0x04, 0x020398a4 },
@@ -702,23 +703,23 @@ nvc1_grctx_init_wwdx_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc1_grctx_init_tpccs_0[] = {
+const struct gf100_gr_init
+gf108_grctx_init_tpccs_0[] = {
{ 0x419d20, 1, 0x04, 0x12180000 },
{ 0x419d24, 1, 0x04, 0x00001fff },
{ 0x419d44, 1, 0x04, 0x02180218 },
{}
};
-static const struct nvc0_graph_pack
-nvc1_grctx_pack_tpc[] = {
- { nvc1_grctx_init_pe_0 },
- { nvc4_grctx_init_tex_0 },
- { nvc1_grctx_init_wwdx_0 },
- { nvc0_grctx_init_mpc_0 },
- { nvc4_grctx_init_l1c_0 },
- { nvc1_grctx_init_tpccs_0 },
- { nvc4_grctx_init_sm_0 },
+static const struct gf100_gr_pack
+gf108_grctx_pack_tpc[] = {
+ { gf108_grctx_init_pe_0 },
+ { gf104_grctx_init_tex_0 },
+ { gf108_grctx_init_wwdx_0 },
+ { gf100_grctx_init_mpc_0 },
+ { gf104_grctx_init_l1c_0 },
+ { gf108_grctx_init_tpccs_0 },
+ { gf104_grctx_init_sm_0 },
{}
};
@@ -727,10 +728,10 @@ nvc1_grctx_pack_tpc[] = {
******************************************************************************/
void
-nvc1_grctx_generate_attrib(struct nvc0_grctx *info)
+gf108_grctx_generate_attrib(struct gf100_grctx *info)
{
- struct nvc0_graph_priv *priv = info->priv;
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(priv);
+ struct gf100_gr_priv *priv = info->priv;
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(priv);
const u32 alpha = impl->alpha_nr;
const u32 beta = impl->attrib_nr;
const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max);
@@ -764,7 +765,7 @@ nvc1_grctx_generate_attrib(struct nvc0_grctx *info)
}
void
-nvc1_grctx_generate_unkn(struct nvc0_graph_priv *priv)
+gf108_grctx_generate_unkn(struct gf100_gr_priv *priv)
{
nv_mask(priv, 0x418c6c, 0x00000001, 0x00000001);
nv_mask(priv, 0x41980c, 0x00000010, 0x00000010);
@@ -774,30 +775,30 @@ nvc1_grctx_generate_unkn(struct nvc0_graph_priv *priv)
nv_mask(priv, 0x419c00, 0x00000008, 0x00000008);
}
-struct nouveau_oclass *
-nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gf108_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xc1),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nvc0_grctx_generate_main,
- .unkn = nvc1_grctx_generate_unkn,
- .hub = nvc1_grctx_pack_hub,
- .gpc = nvc1_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nvc1_grctx_pack_tpc,
- .icmd = nvc1_grctx_pack_icmd,
- .mthd = nvc1_grctx_pack_mthd,
- .bundle = nvc0_grctx_generate_bundle,
+ .main = gf100_grctx_generate_main,
+ .unkn = gf108_grctx_generate_unkn,
+ .hub = gf108_grctx_pack_hub,
+ .gpc = gf108_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gf108_grctx_pack_tpc,
+ .icmd = gf108_grctx_pack_icmd,
+ .mthd = gf108_grctx_pack_mthd,
+ .bundle = gf100_grctx_generate_bundle,
.bundle_size = 0x1800,
- .pagepool = nvc0_grctx_generate_pagepool,
+ .pagepool = gf100_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvc1_grctx_generate_attrib,
+ .attrib = gf108_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
.alpha_nr_max = 0x324,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c
index 8f804cd8f9c7..b3acd931b978 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf110.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "ctxnvc0.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvc8_grctx_init_icmd_0[] = {
+static const struct gf100_gr_init
+gf110_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
@@ -268,20 +267,20 @@ nvc8_grctx_init_icmd_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc8_grctx_pack_icmd[] = {
- { nvc8_grctx_init_icmd_0 },
+static const struct gf100_gr_pack
+gf110_grctx_pack_icmd[] = {
+ { gf110_grctx_init_icmd_0 },
{}
};
-const struct nvc0_graph_init
-nvc8_grctx_init_9197_0[] = {
+const struct gf100_gr_init
+gf110_grctx_init_9197_0[] = {
{ 0x0002e4, 1, 0x04, 0x0000b001 },
{}
};
-const struct nvc0_graph_init
-nvc8_grctx_init_9297_0[] = {
+const struct gf100_gr_init
+gf110_grctx_init_9297_0[] = {
{ 0x003400, 128, 0x04, 0x00000000 },
{ 0x00036c, 2, 0x04, 0x00000000 },
{ 0x0007a4, 2, 0x04, 0x00000000 },
@@ -290,19 +289,19 @@ nvc8_grctx_init_9297_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc8_grctx_pack_mthd[] = {
- { nvc1_grctx_init_9097_0, 0x9097 },
- { nvc8_grctx_init_9197_0, 0x9197 },
- { nvc8_grctx_init_9297_0, 0x9297 },
- { nvc0_grctx_init_902d_0, 0x902d },
- { nvc0_grctx_init_9039_0, 0x9039 },
- { nvc0_grctx_init_90c0_0, 0x90c0 },
+static const struct gf100_gr_pack
+gf110_grctx_pack_mthd[] = {
+ { gf108_grctx_init_9097_0, 0x9097 },
+ { gf110_grctx_init_9197_0, 0x9197 },
+ { gf110_grctx_init_9297_0, 0x9297 },
+ { gf100_grctx_init_902d_0, 0x902d },
+ { gf100_grctx_init_9039_0, 0x9039 },
+ { gf100_grctx_init_90c0_0, 0x90c0 },
{}
};
-static const struct nvc0_graph_init
-nvc8_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gf110_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x0006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
@@ -314,16 +313,16 @@ nvc8_grctx_init_setup_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc8_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nvc0_grctx_init_prop_0 },
- { nvc0_grctx_init_gpc_unk_1 },
- { nvc8_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nvc0_grctx_init_crstr_0 },
- { nvc0_grctx_init_gpm_0 },
- { nvc0_grctx_init_gcc_0 },
+static const struct gf100_gr_pack
+gf110_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gf100_grctx_init_prop_0 },
+ { gf100_grctx_init_gpc_unk_1 },
+ { gf110_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gf100_grctx_init_crstr_0 },
+ { gf100_grctx_init_gpm_0 },
+ { gf100_grctx_init_gcc_0 },
{}
};
@@ -331,30 +330,30 @@ nvc8_grctx_pack_gpc[] = {
* PGRAPH context implementation
******************************************************************************/
-struct nouveau_oclass *
-nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gf110_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xc8),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nvc0_grctx_generate_main,
- .unkn = nvc0_grctx_generate_unkn,
- .hub = nvc0_grctx_pack_hub,
- .gpc = nvc8_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nvc0_grctx_pack_tpc,
- .icmd = nvc8_grctx_pack_icmd,
- .mthd = nvc8_grctx_pack_mthd,
- .bundle = nvc0_grctx_generate_bundle,
+ .main = gf100_grctx_generate_main,
+ .unkn = gf100_grctx_generate_unkn,
+ .hub = gf100_grctx_pack_hub,
+ .gpc = gf110_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gf100_grctx_pack_tpc,
+ .icmd = gf110_grctx_pack_icmd,
+ .mthd = gf110_grctx_pack_mthd,
+ .bundle = gf100_grctx_generate_bundle,
.bundle_size = 0x1800,
- .pagepool = nvc0_grctx_generate_pagepool,
+ .pagepool = gf100_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvc0_grctx_generate_attrib,
+ .attrib = gf100_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
index fcf534fd9e65..9bbe2c97552e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
@@ -21,15 +21,17 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "ctxgf100.h"
-#include "ctxnvc0.h"
+#include <subdev/fb.h>
+#include <subdev/mc.h>
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvd7_grctx_init_ds_0[] = {
+static const struct gf100_gr_init
+gf117_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180324 },
{ 0x405834, 1, 0x04, 0x08000000 },
@@ -41,8 +43,8 @@ nvd7_grctx_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvd7_grctx_init_pd_0[] = {
+static const struct gf100_gr_init
+gf117_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x000103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
@@ -54,22 +56,22 @@ nvd7_grctx_init_pd_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvd7_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
- { nvd9_grctx_init_fe_0 },
- { nvc0_grctx_init_pri_0 },
- { nvc0_grctx_init_memfmt_0 },
- { nvd7_grctx_init_ds_0 },
- { nvd7_grctx_init_pd_0 },
- { nvc0_grctx_init_rstr2d_0 },
- { nvc0_grctx_init_scc_0 },
- { nvd9_grctx_init_be_0 },
+static const struct gf100_gr_pack
+gf117_grctx_pack_hub[] = {
+ { gf100_grctx_init_main_0 },
+ { gf119_grctx_init_fe_0 },
+ { gf100_grctx_init_pri_0 },
+ { gf100_grctx_init_memfmt_0 },
+ { gf117_grctx_init_ds_0 },
+ { gf117_grctx_init_pd_0 },
+ { gf100_grctx_init_rstr2d_0 },
+ { gf100_grctx_init_scc_0 },
+ { gf119_grctx_init_be_0 },
{}
};
-static const struct nvc0_graph_init
-nvd7_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gf117_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
@@ -81,29 +83,29 @@ nvd7_grctx_init_setup_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvd7_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nvd9_grctx_init_prop_0 },
- { nvd9_grctx_init_gpc_unk_1 },
- { nvd7_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nvd9_grctx_init_crstr_0 },
- { nvc1_grctx_init_gpm_0 },
- { nvc0_grctx_init_gcc_0 },
+static const struct gf100_gr_pack
+gf117_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gf119_grctx_init_prop_0 },
+ { gf119_grctx_init_gpc_unk_1 },
+ { gf117_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gf119_grctx_init_crstr_0 },
+ { gf108_grctx_init_gpm_0 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-const struct nvc0_graph_init
-nvd7_grctx_init_pe_0[] = {
+const struct gf100_gr_init
+gf117_grctx_init_pe_0[] = {
{ 0x419848, 1, 0x04, 0x00000000 },
{ 0x419864, 1, 0x04, 0x00000129 },
{ 0x419888, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-nvd7_grctx_init_tex_0[] = {
+static const struct gf100_gr_init
+gf117_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000001f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000023 },
@@ -116,8 +118,8 @@ nvd7_grctx_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvd7_grctx_init_mpc_0[] = {
+static const struct gf100_gr_init
+gf117_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000000a },
{ 0x419c04, 1, 0x04, 0x00000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
@@ -127,32 +129,32 @@ nvd7_grctx_init_mpc_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvd7_grctx_pack_tpc[] = {
- { nvd7_grctx_init_pe_0 },
- { nvd7_grctx_init_tex_0 },
- { nvd7_grctx_init_mpc_0 },
- { nvc4_grctx_init_l1c_0 },
- { nvd9_grctx_init_sm_0 },
+static const struct gf100_gr_pack
+gf117_grctx_pack_tpc[] = {
+ { gf117_grctx_init_pe_0 },
+ { gf117_grctx_init_tex_0 },
+ { gf117_grctx_init_mpc_0 },
+ { gf104_grctx_init_l1c_0 },
+ { gf119_grctx_init_sm_0 },
{}
};
-static const struct nvc0_graph_init
-nvd7_grctx_init_pes_0[] = {
+static const struct gf100_gr_init
+gf117_grctx_init_pes_0[] = {
{ 0x41be24, 1, 0x04, 0x00000002 },
{}
};
-static const struct nvc0_graph_init
-nvd7_grctx_init_cbm_0[] = {
+static const struct gf100_gr_init
+gf117_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x12180000 },
{ 0x41bec4, 1, 0x04, 0x00003fff },
{ 0x41bee4, 1, 0x04, 0x03240218 },
{}
};
-const struct nvc0_graph_init
-nvd7_grctx_init_wwdx_0[] = {
+const struct gf100_gr_init
+gf117_grctx_init_wwdx_0[] = {
{ 0x41bf00, 1, 0x04, 0x0a418820 },
{ 0x41bf04, 1, 0x04, 0x062080e6 },
{ 0x41bf08, 1, 0x04, 0x020398a4 },
@@ -165,11 +167,11 @@ nvd7_grctx_init_wwdx_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvd7_grctx_pack_ppc[] = {
- { nvd7_grctx_init_pes_0 },
- { nvd7_grctx_init_cbm_0 },
- { nvd7_grctx_init_wwdx_0 },
+static const struct gf100_gr_pack
+gf117_grctx_pack_ppc[] = {
+ { gf117_grctx_init_pes_0 },
+ { gf117_grctx_init_cbm_0 },
+ { gf117_grctx_init_wwdx_0 },
{}
};
@@ -178,10 +180,10 @@ nvd7_grctx_pack_ppc[] = {
******************************************************************************/
void
-nvd7_grctx_generate_attrib(struct nvc0_grctx *info)
+gf117_grctx_generate_attrib(struct gf100_grctx *info)
{
- struct nvc0_graph_priv *priv = info->priv;
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(priv);
+ struct gf100_gr_priv *priv = info->priv;
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(priv);
const u32 alpha = impl->alpha_nr;
const u32 beta = impl->attrib_nr;
const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max);
@@ -215,18 +217,18 @@ nvd7_grctx_generate_attrib(struct nvc0_grctx *info)
}
void
-nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+gf117_grctx_generate_main(struct gf100_gr_priv *priv, struct gf100_grctx *info)
{
- struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+ struct gf100_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
int i;
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 0);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 0);
- nvc0_graph_mmio(priv, oclass->hub);
- nvc0_graph_mmio(priv, oclass->gpc);
- nvc0_graph_mmio(priv, oclass->zcull);
- nvc0_graph_mmio(priv, oclass->tpc);
- nvc0_graph_mmio(priv, oclass->ppc);
+ gf100_gr_mmio(priv, oclass->hub);
+ gf100_gr_mmio(priv, oclass->gpc);
+ gf100_gr_mmio(priv, oclass->zcull);
+ gf100_gr_mmio(priv, oclass->tpc);
+ gf100_gr_mmio(priv, oclass->ppc);
nv_wr32(priv, 0x404154, 0x00000000);
@@ -235,46 +237,46 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
oclass->attrib(info);
oclass->unkn(priv);
- nvc0_grctx_generate_tpcid(priv);
- nvc0_grctx_generate_r406028(priv);
- nvc0_grctx_generate_r4060a8(priv);
- nve4_grctx_generate_r418bb8(priv);
- nvc0_grctx_generate_r406800(priv);
+ gf100_grctx_generate_tpcid(priv);
+ gf100_grctx_generate_r406028(priv);
+ gf100_grctx_generate_r4060a8(priv);
+ gk104_grctx_generate_r418bb8(priv);
+ gf100_grctx_generate_r406800(priv);
for (i = 0; i < 8; i++)
nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
- nvc0_graph_icmd(priv, oclass->icmd);
+ gf100_gr_icmd(priv, oclass->icmd);
nv_wr32(priv, 0x404154, 0x00000400);
- nvc0_graph_mthd(priv, oclass->mthd);
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 1);
+ gf100_gr_mthd(priv, oclass->mthd);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 1);
}
-struct nouveau_oclass *
-nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gf117_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xd7),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nvd7_grctx_generate_main,
- .unkn = nve4_grctx_generate_unkn,
- .hub = nvd7_grctx_pack_hub,
- .gpc = nvd7_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nvd7_grctx_pack_tpc,
- .ppc = nvd7_grctx_pack_ppc,
- .icmd = nvd9_grctx_pack_icmd,
- .mthd = nvd9_grctx_pack_mthd,
- .bundle = nvc0_grctx_generate_bundle,
+ .main = gf117_grctx_generate_main,
+ .unkn = gk104_grctx_generate_unkn,
+ .hub = gf117_grctx_pack_hub,
+ .gpc = gf117_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gf117_grctx_pack_tpc,
+ .ppc = gf117_grctx_pack_ppc,
+ .icmd = gf119_grctx_pack_icmd,
+ .mthd = gf119_grctx_pack_mthd,
+ .bundle = gf100_grctx_generate_bundle,
.bundle_size = 0x1800,
- .pagepool = nvc0_grctx_generate_pagepool,
+ .pagepool = gf100_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvd7_grctx_generate_attrib,
+ .attrib = gf117_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
.alpha_nr_max = 0x7ff,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c
index b9a301b6fd9f..8d8761443809 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf119.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "ctxnvc0.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvd9_grctx_init_icmd_0[] = {
+static const struct gf100_gr_init
+gf119_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
@@ -270,14 +269,14 @@ nvd9_grctx_init_icmd_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvd9_grctx_pack_icmd[] = {
- { nvd9_grctx_init_icmd_0 },
+const struct gf100_gr_pack
+gf119_grctx_pack_icmd[] = {
+ { gf119_grctx_init_icmd_0 },
{}
};
-static const struct nvc0_graph_init
-nvd9_grctx_init_90c0_0[] = {
+static const struct gf100_gr_init
+gf119_grctx_init_90c0_0[] = {
{ 0x002700, 8, 0x20, 0x00000000 },
{ 0x002704, 8, 0x20, 0x00000000 },
{ 0x002708, 8, 0x20, 0x00000000 },
@@ -299,19 +298,19 @@ nvd9_grctx_init_90c0_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvd9_grctx_pack_mthd[] = {
- { nvc1_grctx_init_9097_0, 0x9097 },
- { nvc8_grctx_init_9197_0, 0x9197 },
- { nvc8_grctx_init_9297_0, 0x9297 },
- { nvc0_grctx_init_902d_0, 0x902d },
- { nvc0_grctx_init_9039_0, 0x9039 },
- { nvd9_grctx_init_90c0_0, 0x90c0 },
+const struct gf100_gr_pack
+gf119_grctx_pack_mthd[] = {
+ { gf108_grctx_init_9097_0, 0x9097 },
+ { gf110_grctx_init_9197_0, 0x9197 },
+ { gf110_grctx_init_9297_0, 0x9297 },
+ { gf100_grctx_init_902d_0, 0x902d },
+ { gf100_grctx_init_9039_0, 0x9039 },
+ { gf119_grctx_init_90c0_0, 0x90c0 },
{}
};
-const struct nvc0_graph_init
-nvd9_grctx_init_fe_0[] = {
+const struct gf100_gr_init
+gf119_grctx_init_fe_0[] = {
{ 0x404004, 10, 0x04, 0x00000000 },
{ 0x404044, 1, 0x04, 0x00000000 },
{ 0x404094, 13, 0x04, 0x00000000 },
@@ -331,8 +330,8 @@ nvd9_grctx_init_fe_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvd9_grctx_init_ds_0[] = {
+static const struct gf100_gr_init
+gf119_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180218 },
{ 0x405834, 1, 0x04, 0x08000000 },
@@ -344,8 +343,8 @@ nvd9_grctx_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvd9_grctx_init_pd_0[] = {
+static const struct gf100_gr_init
+gf119_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x000103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
@@ -356,8 +355,8 @@ nvd9_grctx_init_pd_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_grctx_init_be_0[] = {
+const struct gf100_gr_init
+gf119_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x02802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1043e005 },
@@ -368,22 +367,22 @@ nvd9_grctx_init_be_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvd9_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
- { nvd9_grctx_init_fe_0 },
- { nvc0_grctx_init_pri_0 },
- { nvc0_grctx_init_memfmt_0 },
- { nvd9_grctx_init_ds_0 },
- { nvd9_grctx_init_pd_0 },
- { nvc0_grctx_init_rstr2d_0 },
- { nvc0_grctx_init_scc_0 },
- { nvd9_grctx_init_be_0 },
+static const struct gf100_gr_pack
+gf119_grctx_pack_hub[] = {
+ { gf100_grctx_init_main_0 },
+ { gf119_grctx_init_fe_0 },
+ { gf100_grctx_init_pri_0 },
+ { gf100_grctx_init_memfmt_0 },
+ { gf119_grctx_init_ds_0 },
+ { gf119_grctx_init_pd_0 },
+ { gf100_grctx_init_rstr2d_0 },
+ { gf100_grctx_init_scc_0 },
+ { gf119_grctx_init_be_0 },
{}
};
-const struct nvc0_graph_init
-nvd9_grctx_init_prop_0[] = {
+const struct gf100_gr_init
+gf119_grctx_init_prop_0[] = {
{ 0x418400, 1, 0x04, 0x38004e00 },
{ 0x418404, 1, 0x04, 0x71e0ffff },
{ 0x41840c, 1, 0x04, 0x00001008 },
@@ -395,8 +394,8 @@ nvd9_grctx_init_prop_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_grctx_init_gpc_unk_1[] = {
+const struct gf100_gr_init
+gf119_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000001f },
{ 0x418684, 1, 0x04, 0x0000000f },
{ 0x418700, 1, 0x04, 0x00000002 },
@@ -405,8 +404,8 @@ nvd9_grctx_init_gpc_unk_1[] = {
{}
};
-static const struct nvc0_graph_init
-nvd9_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gf119_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
@@ -418,8 +417,8 @@ nvd9_grctx_init_setup_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_grctx_init_crstr_0[] = {
+const struct gf100_gr_init
+gf119_grctx_init_crstr_0[] = {
{ 0x418b00, 1, 0x04, 0x00000006 },
{ 0x418b08, 1, 0x04, 0x0a418820 },
{ 0x418b0c, 1, 0x04, 0x062080e6 },
@@ -431,21 +430,21 @@ nvd9_grctx_init_crstr_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvd9_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nvd9_grctx_init_prop_0 },
- { nvd9_grctx_init_gpc_unk_1 },
- { nvd9_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nvd9_grctx_init_crstr_0 },
- { nvc1_grctx_init_gpm_0 },
- { nvc0_grctx_init_gcc_0 },
+static const struct gf100_gr_pack
+gf119_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gf119_grctx_init_prop_0 },
+ { gf119_grctx_init_gpc_unk_1 },
+ { gf119_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gf119_grctx_init_crstr_0 },
+ { gf108_grctx_init_gpm_0 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-static const struct nvc0_graph_init
-nvd9_grctx_init_tex_0[] = {
+static const struct gf100_gr_init
+gf119_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000001f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000023 },
@@ -458,8 +457,8 @@ nvd9_grctx_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvd9_grctx_init_mpc_0[] = {
+static const struct gf100_gr_init
+gf119_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000000a },
{ 0x419c04, 1, 0x04, 0x00000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
@@ -469,8 +468,8 @@ nvd9_grctx_init_mpc_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_grctx_init_sm_0[] = {
+const struct gf100_gr_init
+gf119_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00000002 },
{ 0x419e44, 1, 0x04, 0x001beff2 },
@@ -483,15 +482,15 @@ nvd9_grctx_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvd9_grctx_pack_tpc[] = {
- { nvc1_grctx_init_pe_0 },
- { nvd9_grctx_init_tex_0 },
- { nvc1_grctx_init_wwdx_0 },
- { nvd9_grctx_init_mpc_0 },
- { nvc4_grctx_init_l1c_0 },
- { nvc1_grctx_init_tpccs_0 },
- { nvd9_grctx_init_sm_0 },
+static const struct gf100_gr_pack
+gf119_grctx_pack_tpc[] = {
+ { gf108_grctx_init_pe_0 },
+ { gf119_grctx_init_tex_0 },
+ { gf108_grctx_init_wwdx_0 },
+ { gf119_grctx_init_mpc_0 },
+ { gf104_grctx_init_l1c_0 },
+ { gf108_grctx_init_tpccs_0 },
+ { gf119_grctx_init_sm_0 },
{}
};
@@ -499,30 +498,30 @@ nvd9_grctx_pack_tpc[] = {
* PGRAPH context implementation
******************************************************************************/
-struct nouveau_oclass *
-nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gf119_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xd9),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nvc0_grctx_generate_main,
- .unkn = nvc1_grctx_generate_unkn,
- .hub = nvd9_grctx_pack_hub,
- .gpc = nvd9_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nvd9_grctx_pack_tpc,
- .icmd = nvd9_grctx_pack_icmd,
- .mthd = nvd9_grctx_pack_mthd,
- .bundle = nvc0_grctx_generate_bundle,
+ .main = gf100_grctx_generate_main,
+ .unkn = gf108_grctx_generate_unkn,
+ .hub = gf119_grctx_pack_hub,
+ .gpc = gf119_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gf119_grctx_pack_tpc,
+ .icmd = gf119_grctx_pack_icmd,
+ .mthd = gf119_grctx_pack_mthd,
+ .bundle = gf100_grctx_generate_bundle,
.bundle_size = 0x1800,
- .pagepool = nvc0_grctx_generate_pagepool,
+ .pagepool = gf100_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvc1_grctx_generate_attrib,
+ .attrib = gf108_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
.alpha_nr_max = 0x324,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
index ccac2ee1a1cb..b52300d8861a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
@@ -21,15 +21,17 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "ctxgf100.h"
-#include "ctxnvc0.h"
+#include <subdev/fb.h>
+#include <subdev/mc.h>
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nve4_grctx_init_icmd_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
@@ -272,14 +274,14 @@ nve4_grctx_init_icmd_0[] = {
{}
};
-const struct nvc0_graph_pack
-nve4_grctx_pack_icmd[] = {
- { nve4_grctx_init_icmd_0 },
+const struct gf100_gr_pack
+gk104_grctx_pack_icmd[] = {
+ { gk104_grctx_init_icmd_0 },
{}
};
-const struct nvc0_graph_init
-nve4_grctx_init_a097_0[] = {
+const struct gf100_gr_init
+gk104_grctx_init_a097_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
{ 0x000808, 8, 0x40, 0x00000400 },
@@ -578,15 +580,15 @@ nve4_grctx_init_a097_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nve4_grctx_pack_mthd[] = {
- { nve4_grctx_init_a097_0, 0xa097 },
- { nvc0_grctx_init_902d_0, 0x902d },
+static const struct gf100_gr_pack
+gk104_grctx_pack_mthd[] = {
+ { gk104_grctx_init_a097_0, 0xa097 },
+ { gf100_grctx_init_902d_0, 0x902d },
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_fe_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_fe_0[] = {
{ 0x404010, 5, 0x04, 0x00000000 },
{ 0x404024, 1, 0x04, 0x0000e000 },
{ 0x404028, 1, 0x04, 0x00000000 },
@@ -606,8 +608,8 @@ nve4_grctx_init_fe_0[] = {
{}
};
-const struct nvc0_graph_init
-nve4_grctx_init_memfmt_0[] = {
+const struct gf100_gr_init
+gk104_grctx_init_memfmt_0[] = {
{ 0x404604, 1, 0x04, 0x00000014 },
{ 0x404608, 1, 0x04, 0x00000000 },
{ 0x40460c, 1, 0x04, 0x00003fff },
@@ -632,8 +634,8 @@ nve4_grctx_init_memfmt_0[] = {
{}
};
-const struct nvc0_graph_init
-nve4_grctx_init_ds_0[] = {
+const struct gf100_gr_init
+gk104_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180648 },
{ 0x405834, 1, 0x04, 0x08000000 },
@@ -645,15 +647,15 @@ nve4_grctx_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_cwd_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_cwd_0[] = {
{ 0x405b00, 1, 0x04, 0x00000000 },
{ 0x405b10, 1, 0x04, 0x00001000 },
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_pd_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x004103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
@@ -667,14 +669,14 @@ nve4_grctx_init_pd_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_sked_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_sked_0[] = {
{ 0x407040, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nve4_grctx_init_scc_0[] = {
+const struct gf100_gr_init
+gk104_grctx_init_scc_0[] = {
{ 0x408000, 2, 0x04, 0x00000000 },
{ 0x408008, 1, 0x04, 0x00000030 },
{ 0x40800c, 2, 0x04, 0x00000000 },
@@ -684,8 +686,8 @@ nve4_grctx_init_scc_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_be_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x02802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1043e005 },
@@ -697,24 +699,24 @@ nve4_grctx_init_be_0[] = {
{}
};
-const struct nvc0_graph_pack
-nve4_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
- { nve4_grctx_init_fe_0 },
- { nvc0_grctx_init_pri_0 },
- { nve4_grctx_init_memfmt_0 },
- { nve4_grctx_init_ds_0 },
- { nve4_grctx_init_cwd_0 },
- { nve4_grctx_init_pd_0 },
- { nve4_grctx_init_sked_0 },
- { nvc0_grctx_init_rstr2d_0 },
- { nve4_grctx_init_scc_0 },
- { nve4_grctx_init_be_0 },
+const struct gf100_gr_pack
+gk104_grctx_pack_hub[] = {
+ { gf100_grctx_init_main_0 },
+ { gk104_grctx_init_fe_0 },
+ { gf100_grctx_init_pri_0 },
+ { gk104_grctx_init_memfmt_0 },
+ { gk104_grctx_init_ds_0 },
+ { gk104_grctx_init_cwd_0 },
+ { gk104_grctx_init_pd_0 },
+ { gk104_grctx_init_sked_0 },
+ { gf100_grctx_init_rstr2d_0 },
+ { gk104_grctx_init_scc_0 },
+ { gk104_grctx_init_be_0 },
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00000044 },
@@ -726,8 +728,8 @@ nve4_grctx_init_setup_0[] = {
{}
};
-const struct nvc0_graph_init
-nve4_grctx_init_gpm_0[] = {
+const struct gf100_gr_init
+gk104_grctx_init_gpm_0[] = {
{ 0x418c08, 1, 0x04, 0x00000001 },
{ 0x418c10, 8, 0x04, 0x00000000 },
{ 0x418c40, 1, 0x04, 0xffffffff },
@@ -737,21 +739,21 @@ nve4_grctx_init_gpm_0[] = {
{}
};
-const struct nvc0_graph_pack
-nve4_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nvd9_grctx_init_prop_0 },
- { nvd9_grctx_init_gpc_unk_1 },
- { nve4_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nvd9_grctx_init_crstr_0 },
- { nve4_grctx_init_gpm_0 },
- { nvc0_grctx_init_gcc_0 },
+const struct gf100_gr_pack
+gk104_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gf119_grctx_init_prop_0 },
+ { gf119_grctx_init_gpc_unk_1 },
+ { gk104_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gf119_grctx_init_crstr_0 },
+ { gk104_grctx_init_gpm_0 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_tex_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000000f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000021 },
@@ -765,8 +767,8 @@ nve4_grctx_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_mpc_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000000a },
{ 0x419c04, 1, 0x04, 0x80000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
@@ -776,15 +778,15 @@ nve4_grctx_init_mpc_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_l1c_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_l1c_0[] = {
{ 0x419ce8, 1, 0x04, 0x00000000 },
{ 0x419cf4, 1, 0x04, 0x00003203 },
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_sm_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00000402 },
{ 0x419e44, 1, 0x04, 0x0013eff2 },
@@ -802,35 +804,35 @@ nve4_grctx_init_sm_0[] = {
{}
};
-const struct nvc0_graph_pack
-nve4_grctx_pack_tpc[] = {
- { nvd7_grctx_init_pe_0 },
- { nve4_grctx_init_tex_0 },
- { nve4_grctx_init_mpc_0 },
- { nve4_grctx_init_l1c_0 },
- { nve4_grctx_init_sm_0 },
+const struct gf100_gr_pack
+gk104_grctx_pack_tpc[] = {
+ { gf117_grctx_init_pe_0 },
+ { gk104_grctx_init_tex_0 },
+ { gk104_grctx_init_mpc_0 },
+ { gk104_grctx_init_l1c_0 },
+ { gk104_grctx_init_sm_0 },
{}
};
-const struct nvc0_graph_init
-nve4_grctx_init_pes_0[] = {
+const struct gf100_gr_init
+gk104_grctx_init_pes_0[] = {
{ 0x41be24, 1, 0x04, 0x00000006 },
{}
};
-static const struct nvc0_graph_init
-nve4_grctx_init_cbm_0[] = {
+static const struct gf100_gr_init
+gk104_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x12180000 },
{ 0x41bec4, 1, 0x04, 0x00037f7f },
{ 0x41bee4, 1, 0x04, 0x06480430 },
{}
};
-const struct nvc0_graph_pack
-nve4_grctx_pack_ppc[] = {
- { nve4_grctx_init_pes_0 },
- { nve4_grctx_init_cbm_0 },
- { nvd7_grctx_init_wwdx_0 },
+const struct gf100_gr_pack
+gk104_grctx_pack_ppc[] = {
+ { gk104_grctx_init_pes_0 },
+ { gk104_grctx_init_cbm_0 },
+ { gf117_grctx_init_wwdx_0 },
{}
};
@@ -839,9 +841,9 @@ nve4_grctx_pack_ppc[] = {
******************************************************************************/
void
-nve4_grctx_generate_bundle(struct nvc0_grctx *info)
+gk104_grctx_generate_bundle(struct gf100_grctx *info)
{
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv);
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(info->priv);
const u32 state_limit = min(impl->bundle_min_gpm_fifo_depth,
impl->bundle_size / 0x20);
const u32 token_limit = impl->bundle_token_limit;
@@ -856,9 +858,9 @@ nve4_grctx_generate_bundle(struct nvc0_grctx *info)
}
void
-nve4_grctx_generate_pagepool(struct nvc0_grctx *info)
+gk104_grctx_generate_pagepool(struct gf100_grctx *info)
{
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv);
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(info->priv);
const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS;
const int s = 8;
const int b = mmio_vram(info, impl->pagepool_size, (1 << s), access);
@@ -870,7 +872,7 @@ nve4_grctx_generate_pagepool(struct nvc0_grctx *info)
}
void
-nve4_grctx_generate_unkn(struct nvc0_graph_priv *priv)
+gk104_grctx_generate_unkn(struct gf100_gr_priv *priv)
{
nv_mask(priv, 0x418c6c, 0x00000001, 0x00000001);
nv_mask(priv, 0x41980c, 0x00000010, 0x00000010);
@@ -881,7 +883,7 @@ nve4_grctx_generate_unkn(struct nvc0_graph_priv *priv)
}
void
-nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *priv)
+gk104_grctx_generate_r418bb8(struct gf100_gr_priv *priv)
{
u32 data[6] = {}, data2[2] = {};
u8 tpcnr[GPC_MAX];
@@ -939,18 +941,18 @@ nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *priv)
}
void
-nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+gk104_grctx_generate_main(struct gf100_gr_priv *priv, struct gf100_grctx *info)
{
- struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+ struct gf100_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
int i;
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 0);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 0);
- nvc0_graph_mmio(priv, oclass->hub);
- nvc0_graph_mmio(priv, oclass->gpc);
- nvc0_graph_mmio(priv, oclass->zcull);
- nvc0_graph_mmio(priv, oclass->tpc);
- nvc0_graph_mmio(priv, oclass->ppc);
+ gf100_gr_mmio(priv, oclass->hub);
+ gf100_gr_mmio(priv, oclass->gpc);
+ gf100_gr_mmio(priv, oclass->zcull);
+ gf100_gr_mmio(priv, oclass->tpc);
+ gf100_gr_mmio(priv, oclass->ppc);
nv_wr32(priv, 0x404154, 0x00000000);
@@ -959,10 +961,10 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
oclass->attrib(info);
oclass->unkn(priv);
- nvc0_grctx_generate_tpcid(priv);
- nvc0_grctx_generate_r406028(priv);
- nve4_grctx_generate_r418bb8(priv);
- nvc0_grctx_generate_r406800(priv);
+ gf100_grctx_generate_tpcid(priv);
+ gf100_grctx_generate_r406028(priv);
+ gk104_grctx_generate_r418bb8(priv);
+ gf100_grctx_generate_r406800(priv);
for (i = 0; i < 8; i++)
nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
@@ -977,42 +979,42 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
}
nv_mask(priv, 0x419f78, 0x00000001, 0x00000000);
- nvc0_graph_icmd(priv, oclass->icmd);
+ gf100_gr_icmd(priv, oclass->icmd);
nv_wr32(priv, 0x404154, 0x00000400);
- nvc0_graph_mthd(priv, oclass->mthd);
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 1);
+ gf100_gr_mthd(priv, oclass->mthd);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 1);
nv_mask(priv, 0x418800, 0x00200000, 0x00200000);
nv_mask(priv, 0x41be10, 0x00800000, 0x00800000);
}
-struct nouveau_oclass *
-nve4_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gk104_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xe4),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nve4_grctx_generate_main,
- .unkn = nve4_grctx_generate_unkn,
- .hub = nve4_grctx_pack_hub,
- .gpc = nve4_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nve4_grctx_pack_tpc,
- .ppc = nve4_grctx_pack_ppc,
- .icmd = nve4_grctx_pack_icmd,
- .mthd = nve4_grctx_pack_mthd,
- .bundle = nve4_grctx_generate_bundle,
+ .main = gk104_grctx_generate_main,
+ .unkn = gk104_grctx_generate_unkn,
+ .hub = gk104_grctx_pack_hub,
+ .gpc = gk104_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gk104_grctx_pack_tpc,
+ .ppc = gk104_grctx_pack_ppc,
+ .icmd = gk104_grctx_pack_icmd,
+ .mthd = gk104_grctx_pack_mthd,
+ .bundle = gk104_grctx_generate_bundle,
.bundle_size = 0x3000,
.bundle_min_gpm_fifo_depth = 0x180,
.bundle_token_limit = 0x600,
- .pagepool = nve4_grctx_generate_pagepool,
+ .pagepool = gk104_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvd7_grctx_generate_attrib,
+ .attrib = gf117_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
.alpha_nr_max = 0x7ff,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c
index e9b0dcf95a49..b3f58be04e9c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "ctxnvc0.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvf0_grctx_init_icmd_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
@@ -279,14 +278,14 @@ nvf0_grctx_init_icmd_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvf0_grctx_pack_icmd[] = {
- { nvf0_grctx_init_icmd_0 },
+const struct gf100_gr_pack
+gk110_grctx_pack_icmd[] = {
+ { gk110_grctx_init_icmd_0 },
{}
};
-static const struct nvc0_graph_init
-nvf0_grctx_init_a197_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_a197_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
{ 0x000808, 8, 0x40, 0x00000400 },
@@ -587,15 +586,15 @@ nvf0_grctx_init_a197_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvf0_grctx_pack_mthd[] = {
- { nvf0_grctx_init_a197_0, 0xa197 },
- { nvc0_grctx_init_902d_0, 0x902d },
+const struct gf100_gr_pack
+gk110_grctx_pack_mthd[] = {
+ { gk110_grctx_init_a197_0, 0xa197 },
+ { gf100_grctx_init_902d_0, 0x902d },
{}
};
-static const struct nvc0_graph_init
-nvf0_grctx_init_fe_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_fe_0[] = {
{ 0x404004, 8, 0x04, 0x00000000 },
{ 0x404024, 1, 0x04, 0x0000e000 },
{ 0x404028, 8, 0x04, 0x00000000 },
@@ -620,8 +619,8 @@ nvf0_grctx_init_fe_0[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_grctx_init_pri_0[] = {
+const struct gf100_gr_init
+gk110_grctx_init_pri_0[] = {
{ 0x404404, 12, 0x04, 0x00000000 },
{ 0x404438, 1, 0x04, 0x00000000 },
{ 0x404460, 2, 0x04, 0x00000000 },
@@ -632,16 +631,16 @@ nvf0_grctx_init_pri_0[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_grctx_init_cwd_0[] = {
+const struct gf100_gr_init
+gk110_grctx_init_cwd_0[] = {
{ 0x405b00, 1, 0x04, 0x00000000 },
{ 0x405b10, 1, 0x04, 0x00001000 },
{ 0x405b20, 1, 0x04, 0x04000000 },
{}
};
-static const struct nvc0_graph_init
-nvf0_grctx_init_pd_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x034103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
@@ -655,8 +654,8 @@ nvf0_grctx_init_pd_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvf0_grctx_init_be_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x12802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1003e005 },
@@ -668,23 +667,23 @@ nvf0_grctx_init_be_0[] = {
{}
};
-const struct nvc0_graph_pack
-nvf0_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
- { nvf0_grctx_init_fe_0 },
- { nvf0_grctx_init_pri_0 },
- { nve4_grctx_init_memfmt_0 },
- { nve4_grctx_init_ds_0 },
- { nvf0_grctx_init_cwd_0 },
- { nvf0_grctx_init_pd_0 },
- { nvc0_grctx_init_rstr2d_0 },
- { nve4_grctx_init_scc_0 },
- { nvf0_grctx_init_be_0 },
+const struct gf100_gr_pack
+gk110_grctx_pack_hub[] = {
+ { gf100_grctx_init_main_0 },
+ { gk110_grctx_init_fe_0 },
+ { gk110_grctx_init_pri_0 },
+ { gk104_grctx_init_memfmt_0 },
+ { gk104_grctx_init_ds_0 },
+ { gk110_grctx_init_cwd_0 },
+ { gk110_grctx_init_pd_0 },
+ { gf100_grctx_init_rstr2d_0 },
+ { gk104_grctx_init_scc_0 },
+ { gk110_grctx_init_be_0 },
{}
};
-static const struct nvc0_graph_init
-nvf0_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006860a },
{ 0x418808, 1, 0x04, 0x00000000 },
{ 0x41880c, 1, 0x04, 0x00000030 },
@@ -698,28 +697,28 @@ nvf0_grctx_init_setup_0[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_grctx_init_gpc_unk_2[] = {
+const struct gf100_gr_init
+gk110_grctx_init_gpc_unk_2[] = {
{ 0x418d24, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_pack
-nvf0_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nvd9_grctx_init_prop_0 },
- { nvd9_grctx_init_gpc_unk_1 },
- { nvf0_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nvd9_grctx_init_crstr_0 },
- { nve4_grctx_init_gpm_0 },
- { nvf0_grctx_init_gpc_unk_2 },
- { nvc0_grctx_init_gcc_0 },
+const struct gf100_gr_pack
+gk110_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gf119_grctx_init_prop_0 },
+ { gf119_grctx_init_gpc_unk_1 },
+ { gk110_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gf119_grctx_init_crstr_0 },
+ { gk104_grctx_init_gpm_0 },
+ { gk110_grctx_init_gpc_unk_2 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-const struct nvc0_graph_init
-nvf0_grctx_init_tex_0[] = {
+const struct gf100_gr_init
+gk110_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000000f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000021 },
@@ -733,8 +732,8 @@ nvf0_grctx_init_tex_0[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_grctx_init_mpc_0[] = {
+const struct gf100_gr_init
+gk110_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000001a },
{ 0x419c04, 1, 0x04, 0x80000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
@@ -744,15 +743,15 @@ nvf0_grctx_init_mpc_0[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_grctx_init_l1c_0[] = {
+const struct gf100_gr_init
+gk110_grctx_init_l1c_0[] = {
{ 0x419ce8, 1, 0x04, 0x00000000 },
{ 0x419cf4, 1, 0x04, 0x00000203 },
{}
};
-static const struct nvc0_graph_init
-nvf0_grctx_init_sm_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_sm_0[] = {
{ 0x419e04, 1, 0x04, 0x00000000 },
{ 0x419e08, 1, 0x04, 0x0000001d },
{ 0x419e0c, 1, 0x04, 0x00000000 },
@@ -779,29 +778,29 @@ nvf0_grctx_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvf0_grctx_pack_tpc[] = {
- { nvd7_grctx_init_pe_0 },
- { nvf0_grctx_init_tex_0 },
- { nvf0_grctx_init_mpc_0 },
- { nvf0_grctx_init_l1c_0 },
- { nvf0_grctx_init_sm_0 },
+static const struct gf100_gr_pack
+gk110_grctx_pack_tpc[] = {
+ { gf117_grctx_init_pe_0 },
+ { gk110_grctx_init_tex_0 },
+ { gk110_grctx_init_mpc_0 },
+ { gk110_grctx_init_l1c_0 },
+ { gk110_grctx_init_sm_0 },
{}
};
-static const struct nvc0_graph_init
-nvf0_grctx_init_cbm_0[] = {
+static const struct gf100_gr_init
+gk110_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x10000000 },
{ 0x41bec4, 1, 0x04, 0x00037f7f },
{ 0x41bee4, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_pack
-nvf0_grctx_pack_ppc[] = {
- { nve4_grctx_init_pes_0 },
- { nvf0_grctx_init_cbm_0 },
- { nvd7_grctx_init_wwdx_0 },
+const struct gf100_gr_pack
+gk110_grctx_pack_ppc[] = {
+ { gk104_grctx_init_pes_0 },
+ { gk110_grctx_init_cbm_0 },
+ { gf117_grctx_init_wwdx_0 },
{}
};
@@ -809,33 +808,33 @@ nvf0_grctx_pack_ppc[] = {
* PGRAPH context implementation
******************************************************************************/
-struct nouveau_oclass *
-nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gk110_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xf0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nve4_grctx_generate_main,
- .unkn = nve4_grctx_generate_unkn,
- .hub = nvf0_grctx_pack_hub,
- .gpc = nvf0_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nvf0_grctx_pack_tpc,
- .ppc = nvf0_grctx_pack_ppc,
- .icmd = nvf0_grctx_pack_icmd,
- .mthd = nvf0_grctx_pack_mthd,
- .bundle = nve4_grctx_generate_bundle,
+ .main = gk104_grctx_generate_main,
+ .unkn = gk104_grctx_generate_unkn,
+ .hub = gk110_grctx_pack_hub,
+ .gpc = gk110_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gk110_grctx_pack_tpc,
+ .ppc = gk110_grctx_pack_ppc,
+ .icmd = gk110_grctx_pack_icmd,
+ .mthd = gk110_grctx_pack_mthd,
+ .bundle = gk104_grctx_generate_bundle,
.bundle_size = 0x3000,
.bundle_min_gpm_fifo_depth = 0x180,
.bundle_token_limit = 0x7c0,
- .pagepool = nve4_grctx_generate_pagepool,
+ .pagepool = gk104_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvd7_grctx_generate_attrib,
+ .attrib = gf117_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
.alpha_nr_max = 0x7ff,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c
index 3adb7fe91772..b11c26794fde 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk110b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c
@@ -21,14 +21,13 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "ctxnvc0.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gk110b_grctx_init_sm_0[] = {
{ 0x419e04, 1, 0x04, 0x00000000 },
{ 0x419e08, 1, 0x04, 0x0000001d },
@@ -56,12 +55,12 @@ gk110b_grctx_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gk110b_grctx_pack_tpc[] = {
- { nvd7_grctx_init_pe_0 },
- { nvf0_grctx_init_tex_0 },
- { nvf0_grctx_init_mpc_0 },
- { nvf0_grctx_init_l1c_0 },
+ { gf117_grctx_init_pe_0 },
+ { gk110_grctx_init_tex_0 },
+ { gk110_grctx_init_mpc_0 },
+ { gk110_grctx_init_l1c_0 },
{ gk110b_grctx_init_sm_0 },
{}
};
@@ -70,33 +69,33 @@ gk110b_grctx_pack_tpc[] = {
* PGRAPH context implementation
******************************************************************************/
-struct nouveau_oclass *
-gk110b_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gk110b_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xf1),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nve4_grctx_generate_main,
- .unkn = nve4_grctx_generate_unkn,
- .hub = nvf0_grctx_pack_hub,
- .gpc = nvf0_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
+ .main = gk104_grctx_generate_main,
+ .unkn = gk104_grctx_generate_unkn,
+ .hub = gk110_grctx_pack_hub,
+ .gpc = gk110_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
.tpc = gk110b_grctx_pack_tpc,
- .ppc = nvf0_grctx_pack_ppc,
- .icmd = nvf0_grctx_pack_icmd,
- .mthd = nvf0_grctx_pack_mthd,
- .bundle = nve4_grctx_generate_bundle,
+ .ppc = gk110_grctx_pack_ppc,
+ .icmd = gk110_grctx_pack_icmd,
+ .mthd = gk110_grctx_pack_mthd,
+ .bundle = gk104_grctx_generate_bundle,
.bundle_size = 0x3000,
.bundle_min_gpm_fifo_depth = 0x180,
.bundle_token_limit = 0x600,
- .pagepool = nve4_grctx_generate_pagepool,
+ .pagepool = gk104_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvd7_grctx_generate_attrib,
+ .attrib = gf117_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
.alpha_nr_max = 0x7ff,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c
index ce252adbef81..6e8ce9fc311a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "ctxnvc0.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nv108_grctx_init_icmd_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
@@ -278,14 +277,14 @@ nv108_grctx_init_icmd_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nv108_grctx_pack_icmd[] = {
- { nv108_grctx_init_icmd_0 },
+static const struct gf100_gr_pack
+gk208_grctx_pack_icmd[] = {
+ { gk208_grctx_init_icmd_0 },
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_fe_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_fe_0[] = {
{ 0x404004, 8, 0x04, 0x00000000 },
{ 0x404024, 1, 0x04, 0x0000e000 },
{ 0x404028, 8, 0x04, 0x00000000 },
@@ -311,8 +310,8 @@ nv108_grctx_init_fe_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_ds_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180648 },
{ 0x405834, 1, 0x04, 0x08000000 },
@@ -325,8 +324,8 @@ nv108_grctx_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_pd_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x034103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
@@ -340,8 +339,8 @@ nv108_grctx_init_pd_0[] = {
{}
};
-const struct nvc0_graph_init
-nv108_grctx_init_rstr2d_0[] = {
+const struct gf100_gr_init
+gk208_grctx_init_rstr2d_0[] = {
{ 0x407804, 1, 0x04, 0x00000063 },
{ 0x40780c, 1, 0x04, 0x0a418820 },
{ 0x407810, 1, 0x04, 0x062080e6 },
@@ -353,8 +352,8 @@ nv108_grctx_init_rstr2d_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_be_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x32802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1003e005 },
@@ -366,23 +365,23 @@ nv108_grctx_init_be_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nv108_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
- { nv108_grctx_init_fe_0 },
- { nvf0_grctx_init_pri_0 },
- { nve4_grctx_init_memfmt_0 },
- { nv108_grctx_init_ds_0 },
- { nvf0_grctx_init_cwd_0 },
- { nv108_grctx_init_pd_0 },
- { nv108_grctx_init_rstr2d_0 },
- { nve4_grctx_init_scc_0 },
- { nv108_grctx_init_be_0 },
+static const struct gf100_gr_pack
+gk208_grctx_pack_hub[] = {
+ { gf100_grctx_init_main_0 },
+ { gk208_grctx_init_fe_0 },
+ { gk110_grctx_init_pri_0 },
+ { gk104_grctx_init_memfmt_0 },
+ { gk208_grctx_init_ds_0 },
+ { gk110_grctx_init_cwd_0 },
+ { gk208_grctx_init_pd_0 },
+ { gk208_grctx_init_rstr2d_0 },
+ { gk104_grctx_init_scc_0 },
+ { gk208_grctx_init_be_0 },
{}
};
-const struct nvc0_graph_init
-nv108_grctx_init_prop_0[] = {
+const struct gf100_gr_init
+gk208_grctx_init_prop_0[] = {
{ 0x418400, 1, 0x04, 0x38005e00 },
{ 0x418404, 1, 0x04, 0x71e0ffff },
{ 0x41840c, 1, 0x04, 0x00001008 },
@@ -394,8 +393,8 @@ nv108_grctx_init_prop_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_gpc_unk_1[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000007f },
{ 0x418684, 1, 0x04, 0x0000001f },
{ 0x418700, 1, 0x04, 0x00000002 },
@@ -404,8 +403,8 @@ nv108_grctx_init_gpc_unk_1[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_setup_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006863a },
{ 0x418808, 1, 0x04, 0x00000000 },
{ 0x41880c, 1, 0x04, 0x00000030 },
@@ -419,8 +418,8 @@ nv108_grctx_init_setup_0[] = {
{}
};
-const struct nvc0_graph_init
-nv108_grctx_init_crstr_0[] = {
+const struct gf100_gr_init
+gk208_grctx_init_crstr_0[] = {
{ 0x418b00, 1, 0x04, 0x0000001e },
{ 0x418b08, 1, 0x04, 0x0a418820 },
{ 0x418b0c, 1, 0x04, 0x062080e6 },
@@ -432,8 +431,8 @@ nv108_grctx_init_crstr_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_gpm_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_gpm_0[] = {
{ 0x418c08, 1, 0x04, 0x00000001 },
{ 0x418c10, 8, 0x04, 0x00000000 },
{ 0x418c40, 1, 0x04, 0xffffffff },
@@ -443,22 +442,22 @@ nv108_grctx_init_gpm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nv108_grctx_pack_gpc[] = {
- { nvc0_grctx_init_gpc_unk_0 },
- { nv108_grctx_init_prop_0 },
- { nv108_grctx_init_gpc_unk_1 },
- { nv108_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nv108_grctx_init_crstr_0 },
- { nv108_grctx_init_gpm_0 },
- { nvf0_grctx_init_gpc_unk_2 },
- { nvc0_grctx_init_gcc_0 },
+static const struct gf100_gr_pack
+gk208_grctx_pack_gpc[] = {
+ { gf100_grctx_init_gpc_unk_0 },
+ { gk208_grctx_init_prop_0 },
+ { gk208_grctx_init_gpc_unk_1 },
+ { gk208_grctx_init_setup_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gk208_grctx_init_crstr_0 },
+ { gk208_grctx_init_gpm_0 },
+ { gk110_grctx_init_gpc_unk_2 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_tex_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000100f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000421 },
@@ -472,8 +471,8 @@ nv108_grctx_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_sm_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_sm_0[] = {
{ 0x419e04, 1, 0x04, 0x00000000 },
{ 0x419e08, 1, 0x04, 0x0000001d },
{ 0x419e0c, 1, 0x04, 0x00000000 },
@@ -500,18 +499,18 @@ nv108_grctx_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nv108_grctx_pack_tpc[] = {
- { nvd7_grctx_init_pe_0 },
- { nv108_grctx_init_tex_0 },
- { nvf0_grctx_init_mpc_0 },
- { nvf0_grctx_init_l1c_0 },
- { nv108_grctx_init_sm_0 },
+static const struct gf100_gr_pack
+gk208_grctx_pack_tpc[] = {
+ { gf117_grctx_init_pe_0 },
+ { gk208_grctx_init_tex_0 },
+ { gk110_grctx_init_mpc_0 },
+ { gk110_grctx_init_l1c_0 },
+ { gk208_grctx_init_sm_0 },
{}
};
-static const struct nvc0_graph_init
-nv108_grctx_init_cbm_0[] = {
+static const struct gf100_gr_init
+gk208_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x10000000 },
{ 0x41bec4, 1, 0x04, 0x00037f7f },
{ 0x41bee4, 1, 0x04, 0x00000000 },
@@ -519,11 +518,11 @@ nv108_grctx_init_cbm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nv108_grctx_pack_ppc[] = {
- { nve4_grctx_init_pes_0 },
- { nv108_grctx_init_cbm_0 },
- { nvd7_grctx_init_wwdx_0 },
+static const struct gf100_gr_pack
+gk208_grctx_pack_ppc[] = {
+ { gk104_grctx_init_pes_0 },
+ { gk208_grctx_init_cbm_0 },
+ { gf117_grctx_init_wwdx_0 },
{}
};
@@ -531,33 +530,33 @@ nv108_grctx_pack_ppc[] = {
* PGRAPH context implementation
******************************************************************************/
-struct nouveau_oclass *
-nv108_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gk208_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0x08),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nve4_grctx_generate_main,
- .unkn = nve4_grctx_generate_unkn,
- .hub = nv108_grctx_pack_hub,
- .gpc = nv108_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nv108_grctx_pack_tpc,
- .ppc = nv108_grctx_pack_ppc,
- .icmd = nv108_grctx_pack_icmd,
- .mthd = nvf0_grctx_pack_mthd,
- .bundle = nve4_grctx_generate_bundle,
+ .main = gk104_grctx_generate_main,
+ .unkn = gk104_grctx_generate_unkn,
+ .hub = gk208_grctx_pack_hub,
+ .gpc = gk208_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gk208_grctx_pack_tpc,
+ .ppc = gk208_grctx_pack_ppc,
+ .icmd = gk208_grctx_pack_icmd,
+ .mthd = gk110_grctx_pack_mthd,
+ .bundle = gk104_grctx_generate_bundle,
.bundle_size = 0x3000,
.bundle_min_gpm_fifo_depth = 0xc2,
.bundle_token_limit = 0x200,
- .pagepool = nve4_grctx_generate_pagepool,
+ .pagepool = gk104_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvd7_grctx_generate_attrib,
+ .attrib = gf117_grctx_generate_attrib,
.attrib_nr_max = 0x324,
.attrib_nr = 0x218,
.alpha_nr_max = 0x7ff,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c
index 36fc9831cc93..2f241f6f0f0a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c
@@ -19,43 +19,42 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+#include "ctxgf100.h"
-#include "ctxnvc0.h"
-
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gk20a_grctx_pack_mthd[] = {
- { nve4_grctx_init_a097_0, 0xa297 },
- { nvc0_grctx_init_902d_0, 0x902d },
+ { gk104_grctx_init_a097_0, 0xa297 },
+ { gf100_grctx_init_902d_0, 0x902d },
{}
};
-struct nouveau_oclass *
-gk20a_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gk20a_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xea),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
- .main = nve4_grctx_generate_main,
- .unkn = nve4_grctx_generate_unkn,
- .hub = nve4_grctx_pack_hub,
- .gpc = nve4_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
- .tpc = nve4_grctx_pack_tpc,
- .ppc = nve4_grctx_pack_ppc,
- .icmd = nve4_grctx_pack_icmd,
+ .main = gk104_grctx_generate_main,
+ .unkn = gk104_grctx_generate_unkn,
+ .hub = gk104_grctx_pack_hub,
+ .gpc = gk104_grctx_pack_gpc,
+ .zcull = gf100_grctx_pack_zcull,
+ .tpc = gk104_grctx_pack_tpc,
+ .ppc = gk104_grctx_pack_ppc,
+ .icmd = gk104_grctx_pack_icmd,
.mthd = gk20a_grctx_pack_mthd,
- .bundle = nve4_grctx_generate_bundle,
+ .bundle = gk104_grctx_generate_bundle,
.bundle_size = 0x1800,
.bundle_min_gpm_fifo_depth = 0x62,
.bundle_token_limit = 0x100,
- .pagepool = nve4_grctx_generate_pagepool,
+ .pagepool = gk104_grctx_generate_pagepool,
.pagepool_size = 0x8000,
- .attrib = nvd7_grctx_generate_attrib,
+ .attrib = gf117_grctx_generate_attrib,
.attrib_nr_max = 0x240,
.attrib_nr = 0x240,
.alpha_nr_max = 0x648 + (0x648 / 2),
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
index 62e918b9fa81..956f4dce960c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
@@ -21,14 +21,16 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "ctxgf100.h"
-#include "ctxnvc0.h"
+#include <subdev/fb.h>
+#include <subdev/mc.h>
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x000039, 3, 0x01, 0x00000000 },
@@ -287,13 +289,13 @@ gm107_grctx_init_icmd_0[] = {
{}
};
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gm107_grctx_pack_icmd[] = {
{ gm107_grctx_init_icmd_0 },
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_b097_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
@@ -610,14 +612,14 @@ gm107_grctx_init_b097_0[] = {
{}
};
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gm107_grctx_pack_mthd[] = {
{ gm107_grctx_init_b097_0, 0xb097 },
- { nvc0_grctx_init_902d_0, 0x902d },
+ { gf100_grctx_init_902d_0, 0x902d },
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_fe_0[] = {
{ 0x404004, 8, 0x04, 0x00000000 },
{ 0x404024, 1, 0x04, 0x0000e000 },
@@ -639,7 +641,7 @@ gm107_grctx_init_fe_0[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8001bf },
{ 0x405830, 1, 0x04, 0x0aa01000 },
@@ -653,7 +655,7 @@ gm107_grctx_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x07410001 },
{ 0x406028, 4, 0x04, 0x00000001 },
@@ -669,7 +671,7 @@ gm107_grctx_init_pd_0[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x32802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
@@ -682,28 +684,28 @@ gm107_grctx_init_be_0[] = {
{}
};
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gm107_grctx_pack_hub[] = {
- { nvc0_grctx_init_main_0 },
+ { gf100_grctx_init_main_0 },
{ gm107_grctx_init_fe_0 },
- { nvf0_grctx_init_pri_0 },
- { nve4_grctx_init_memfmt_0 },
+ { gk110_grctx_init_pri_0 },
+ { gk104_grctx_init_memfmt_0 },
{ gm107_grctx_init_ds_0 },
- { nvf0_grctx_init_cwd_0 },
+ { gk110_grctx_init_cwd_0 },
{ gm107_grctx_init_pd_0 },
- { nv108_grctx_init_rstr2d_0 },
- { nve4_grctx_init_scc_0 },
+ { gk208_grctx_init_rstr2d_0 },
+ { gk104_grctx_init_scc_0 },
{ gm107_grctx_init_be_0 },
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_gpc_unk_0[] = {
{ 0x418380, 1, 0x04, 0x00000056 },
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000007f },
{ 0x418684, 1, 0x04, 0x0000001f },
@@ -714,7 +716,7 @@ gm107_grctx_init_gpc_unk_1[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006863a },
{ 0x418810, 1, 0x04, 0x00000000 },
@@ -727,7 +729,7 @@ gm107_grctx_init_setup_0[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_gpc_unk_2[] = {
{ 0x418d24, 1, 0x04, 0x00000000 },
{ 0x418e00, 1, 0x04, 0x90000000 },
@@ -741,21 +743,21 @@ gm107_grctx_init_gpc_unk_2[] = {
{}
};
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gm107_grctx_pack_gpc[] = {
{ gm107_grctx_init_gpc_unk_0 },
- { nv108_grctx_init_prop_0 },
+ { gk208_grctx_init_prop_0 },
{ gm107_grctx_init_gpc_unk_1 },
{ gm107_grctx_init_setup_0 },
- { nvc0_grctx_init_zcull_0 },
- { nv108_grctx_init_crstr_0 },
- { nve4_grctx_init_gpm_0 },
+ { gf100_grctx_init_zcull_0 },
+ { gk208_grctx_init_crstr_0 },
+ { gk104_grctx_init_gpm_0 },
{ gm107_grctx_init_gpc_unk_2 },
- { nvc0_grctx_init_gcc_0 },
+ { gf100_grctx_init_gcc_0 },
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000300f0 },
{ 0x419a04, 1, 0x04, 0x00000005 },
@@ -771,7 +773,7 @@ gm107_grctx_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000001a },
{ 0x419c04, 1, 0x04, 0x80000006 },
@@ -785,13 +787,13 @@ gm107_grctx_init_mpc_0[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_l1c_0[] = {
{ 0x419c84, 1, 0x04, 0x00000020 },
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00001c02 },
@@ -812,9 +814,9 @@ gm107_grctx_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gm107_grctx_pack_tpc[] = {
- { nvd7_grctx_init_pe_0 },
+ { gf117_grctx_init_pe_0 },
{ gm107_grctx_init_tex_0 },
{ gm107_grctx_init_mpc_0 },
{ gm107_grctx_init_l1c_0 },
@@ -822,7 +824,7 @@ gm107_grctx_pack_tpc[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x00000000 },
{ 0x41bec4, 1, 0x04, 0x01050000 },
@@ -832,7 +834,7 @@ gm107_grctx_init_cbm_0[] = {
{}
};
-static const struct nvc0_graph_init
+static const struct gf100_gr_init
gm107_grctx_init_wwdx_0[] = {
{ 0x41bf00, 1, 0x04, 0x0a418820 },
{ 0x41bf04, 1, 0x04, 0x062080e6 },
@@ -846,9 +848,9 @@ gm107_grctx_init_wwdx_0[] = {
{}
};
-static const struct nvc0_graph_pack
+static const struct gf100_gr_pack
gm107_grctx_pack_ppc[] = {
- { nve4_grctx_init_pes_0 },
+ { gk104_grctx_init_pes_0 },
{ gm107_grctx_init_cbm_0 },
{ gm107_grctx_init_wwdx_0 },
{}
@@ -859,9 +861,9 @@ gm107_grctx_pack_ppc[] = {
******************************************************************************/
static void
-gm107_grctx_generate_bundle(struct nvc0_grctx *info)
+gm107_grctx_generate_bundle(struct gf100_grctx *info)
{
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv);
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(info->priv);
const u32 state_limit = min(impl->bundle_min_gpm_fifo_depth,
impl->bundle_size / 0x20);
const u32 token_limit = impl->bundle_token_limit;
@@ -876,9 +878,9 @@ gm107_grctx_generate_bundle(struct nvc0_grctx *info)
}
static void
-gm107_grctx_generate_pagepool(struct nvc0_grctx *info)
+gm107_grctx_generate_pagepool(struct gf100_grctx *info)
{
- const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv);
+ const struct gf100_grctx_oclass *impl = gf100_grctx_impl(info->priv);
const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS;
const int s = 8;
const int b = mmio_vram(info, impl->pagepool_size, (1 << s), access);
@@ -891,10 +893,10 @@ gm107_grctx_generate_pagepool(struct nvc0_grctx *info)
}
static void
-gm107_grctx_generate_attrib(struct nvc0_grctx *info)
+gm107_grctx_generate_attrib(struct gf100_grctx *info)
{
- struct nvc0_graph_priv *priv = info->priv;
- const struct nvc0_grctx_oclass *impl = (void *)nvc0_grctx_impl(priv);
+ struct gf100_gr_priv *priv = info->priv;
+ const struct gf100_grctx_oclass *impl = (void *)gf100_grctx_impl(priv);
const u32 alpha = impl->alpha_nr;
const u32 attrib = impl->attrib_nr;
const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max);
@@ -930,7 +932,7 @@ gm107_grctx_generate_attrib(struct nvc0_grctx *info)
}
static void
-gm107_grctx_generate_tpcid(struct nvc0_graph_priv *priv)
+gm107_grctx_generate_tpcid(struct gf100_gr_priv *priv)
{
int gpc, tpc, id;
@@ -950,16 +952,16 @@ gm107_grctx_generate_tpcid(struct nvc0_graph_priv *priv)
}
static void
-gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+gm107_grctx_generate_main(struct gf100_gr_priv *priv, struct gf100_grctx *info)
{
- struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+ struct gf100_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
int i;
- nvc0_graph_mmio(priv, oclass->hub);
- nvc0_graph_mmio(priv, oclass->gpc);
- nvc0_graph_mmio(priv, oclass->zcull);
- nvc0_graph_mmio(priv, oclass->tpc);
- nvc0_graph_mmio(priv, oclass->ppc);
+ gf100_gr_mmio(priv, oclass->hub);
+ gf100_gr_mmio(priv, oclass->gpc);
+ gf100_gr_mmio(priv, oclass->zcull);
+ gf100_gr_mmio(priv, oclass->tpc);
+ gf100_gr_mmio(priv, oclass->ppc);
nv_wr32(priv, 0x404154, 0x00000000);
@@ -969,9 +971,9 @@ gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
oclass->unkn(priv);
gm107_grctx_generate_tpcid(priv);
- nvc0_grctx_generate_r406028(priv);
- nve4_grctx_generate_r418bb8(priv);
- nvc0_grctx_generate_r406800(priv);
+ gf100_grctx_generate_r406028(priv);
+ gk104_grctx_generate_r418bb8(priv);
+ gf100_grctx_generate_r406800(priv);
nv_wr32(priv, 0x4064d0, 0x00000001);
for (i = 1; i < 8; i++)
@@ -988,9 +990,9 @@ gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr);
}
- nvc0_graph_icmd(priv, oclass->icmd);
+ gf100_gr_icmd(priv, oclass->icmd);
nv_wr32(priv, 0x404154, 0x00000400);
- nvc0_graph_mthd(priv, oclass->mthd);
+ gf100_gr_mthd(priv, oclass->mthd);
nv_mask(priv, 0x419e00, 0x00808080, 0x00808080);
nv_mask(priv, 0x419ccc, 0x80000000, 0x80000000);
@@ -998,22 +1000,22 @@ gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
nv_mask(priv, 0x419f88, 0x80000000, 0x80000000);
}
-struct nouveau_oclass *
-gm107_grctx_oclass = &(struct nvc0_grctx_oclass) {
+struct nvkm_oclass *
+gm107_grctx_oclass = &(struct gf100_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0x08),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_context_ctor,
- .dtor = nvc0_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_context_ctor,
+ .dtor = gf100_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
.main = gm107_grctx_generate_main,
- .unkn = nve4_grctx_generate_unkn,
+ .unkn = gk104_grctx_generate_unkn,
.hub = gm107_grctx_pack_hub,
.gpc = gm107_grctx_pack_gpc,
- .zcull = nvc0_grctx_pack_zcull,
+ .zcull = gf100_grctx_pack_zcull,
.tpc = gm107_grctx_pack_tpc,
.ppc = gm107_grctx_pack_ppc,
.icmd = gm107_grctx_pack_icmd,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.c
index 7bbb1e1b7a8d..dc31462afe65 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.c
@@ -22,8 +22,6 @@
* Authors: Ben Skeggs
*/
-#include <core/gpuobj.h>
-
/* NVIDIA context programs handle a number of other conditions which are
* not implemented in our versions. It's not clear why NVIDIA context
* programs have this code, nor whether it's strictly necessary for
@@ -111,15 +109,16 @@
#define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */
#define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */
+#include "ctxnv40.h"
#include "nv40.h"
-#include "ctx.h"
+#include <core/device.h>
/* TODO:
* - get vs count from 0x1540
*/
static int
-nv40_graph_vs_count(struct nouveau_device *device)
+nv40_gr_vs_count(struct nvkm_device *device)
{
switch (device->chipset) {
@@ -158,9 +157,9 @@ enum cp_label {
};
static void
-nv40_graph_construct_general(struct nouveau_grctx *ctx)
+nv40_gr_construct_general(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i;
cp_ctx(ctx, 0x4000a4, 1);
@@ -208,7 +207,7 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
gr_def(ctx, 0x4009dc, 0x80000000);
} else {
cp_ctx(ctx, 0x400840, 20);
- if (nv44_graph_class(ctx->device)) {
+ if (nv44_gr_class(ctx->device)) {
for (i = 0; i < 8; i++)
gr_def(ctx, 0x400860 + (i * 4), 0x00000001);
}
@@ -217,7 +216,7 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
gr_def(ctx, 0x400888, 0x00000040);
cp_ctx(ctx, 0x400894, 11);
gr_def(ctx, 0x400894, 0x00000040);
- if (!nv44_graph_class(ctx->device)) {
+ if (!nv44_gr_class(ctx->device)) {
for (i = 0; i < 8; i++)
gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000);
}
@@ -264,9 +263,9 @@ nv40_graph_construct_general(struct nouveau_grctx *ctx)
}
static void
-nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
+nv40_gr_construct_state3d(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i;
if (device->chipset == 0x40) {
@@ -369,9 +368,9 @@ nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
}
static void
-nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
+nv40_gr_construct_state3d_2(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i;
cp_ctx(ctx, 0x402000, 1);
@@ -504,8 +503,8 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
cp_ctx(ctx, 0x403400, device->chipset == 0x40 ? 4 : 3);
cp_ctx(ctx, 0x403410, device->chipset == 0x40 ? 4 : 3);
- cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->device));
- for (i = 0; i < nv40_graph_vs_count(ctx->device); i++)
+ cp_ctx(ctx, 0x403420, nv40_gr_vs_count(ctx->device));
+ for (i = 0; i < nv40_gr_vs_count(ctx->device); i++)
gr_def(ctx, 0x403420 + (i * 4), 0x00005555);
if (device->chipset != 0x40) {
@@ -533,9 +532,9 @@ nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
}
static void
-nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
+nv40_gr_construct_state3d_3(struct nvkm_grctx *ctx)
{
- int len = nv44_graph_class(ctx->device) ? 0x0084 : 0x0684;
+ int len = nv44_gr_class(ctx->device) ? 0x0084 : 0x0684;
cp_out (ctx, 0x300000);
cp_lsr (ctx, len - 4);
@@ -548,14 +547,14 @@ nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
}
static void
-nv40_graph_construct_shader(struct nouveau_grctx *ctx)
+nv40_gr_construct_shader(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
- struct nouveau_gpuobj *obj = ctx->data;
+ struct nvkm_device *device = ctx->device;
+ struct nvkm_gpuobj *obj = ctx->data;
int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset;
int offset, i;
- vs_nr = nv40_graph_vs_count(ctx->device);
+ vs_nr = nv40_gr_vs_count(ctx->device);
vs_nr_b0 = 363;
vs_nr_b1 = device->chipset == 0x40 ? 128 : 64;
if (device->chipset == 0x40) {
@@ -570,16 +569,16 @@ nv40_graph_construct_shader(struct nouveau_grctx *ctx)
} else {
b0_offset = 0x1d40/4; /* 2200 */
b1_offset = 0x3f40/4; /* 0b00 : 0a40 */
- vs_len = nv44_graph_class(device) ? 0x4980/4 : 0x4a40/4;
+ vs_len = nv44_gr_class(device) ? 0x4980/4 : 0x4a40/4;
}
cp_lsr(ctx, vs_len * vs_nr + 0x300/4);
- cp_out(ctx, nv44_graph_class(device) ? 0x800029 : 0x800041);
+ cp_out(ctx, nv44_gr_class(device) ? 0x800029 : 0x800041);
offset = ctx->ctxvals_pos;
ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len));
- if (ctx->mode != NOUVEAU_GRCTX_VALS)
+ if (ctx->mode != NVKM_GRCTX_VALS)
return;
offset += 0x0280/4;
@@ -595,7 +594,7 @@ nv40_graph_construct_shader(struct nouveau_grctx *ctx)
}
static void
-nv40_grctx_generate(struct nouveau_grctx *ctx)
+nv40_grctx_generate(struct nvkm_grctx *ctx)
{
/* decide whether we're loading/unloading the context */
cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
@@ -629,23 +628,23 @@ nv40_grctx_generate(struct nouveau_grctx *ctx)
/* general PGRAPH state */
cp_name(ctx, cp_swap_state);
cp_pos (ctx, 0x00020/4);
- nv40_graph_construct_general(ctx);
+ nv40_gr_construct_general(ctx);
cp_wait(ctx, STATUS, IDLE);
/* 3D state, block 1 */
cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit);
- nv40_graph_construct_state3d(ctx);
+ nv40_gr_construct_state3d(ctx);
cp_wait(ctx, STATUS, IDLE);
/* 3D state, block 2 */
- nv40_graph_construct_state3d_2(ctx);
+ nv40_gr_construct_state3d_2(ctx);
/* Some other block of "random" state */
- nv40_graph_construct_state3d_3(ctx);
+ nv40_gr_construct_state3d_3(ctx);
/* Per-vertex shader state */
cp_pos (ctx, ctx->ctxvals_pos);
- nv40_graph_construct_shader(ctx);
+ nv40_gr_construct_shader(ctx);
/* pre-exit state updates */
cp_name(ctx, cp_prepare_exit);
@@ -660,22 +659,22 @@ nv40_grctx_generate(struct nouveau_grctx *ctx)
}
void
-nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
+nv40_grctx_fill(struct nvkm_device *device, struct nvkm_gpuobj *mem)
{
- nv40_grctx_generate(&(struct nouveau_grctx) {
+ nv40_grctx_generate(&(struct nvkm_grctx) {
.device = device,
- .mode = NOUVEAU_GRCTX_VALS,
+ .mode = NVKM_GRCTX_VALS,
.data = mem,
});
}
int
-nv40_grctx_init(struct nouveau_device *device, u32 *size)
+nv40_grctx_init(struct nvkm_device *device, u32 *size)
{
u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i;
- struct nouveau_grctx ctx = {
+ struct nvkm_grctx ctx = {
.device = device,
- .mode = NOUVEAU_GRCTX_PROG,
+ .mode = NVKM_GRCTX_PROG,
.data = ctxprog,
.ctxprog_max = 256,
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctx.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.h
index e1947013d3bc..8a89961956af 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctx.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.h
@@ -1,12 +1,13 @@
-#ifndef __NOUVEAU_GRCTX_H__
-#define __NOUVEAU_GRCTX_H__
+#ifndef __NVKM_GRCTX_H__
+#define __NVKM_GRCTX_H__
+#include <core/gpuobj.h>
-struct nouveau_grctx {
- struct nouveau_device *device;
+struct nvkm_grctx {
+ struct nvkm_device *device;
enum {
- NOUVEAU_GRCTX_PROG,
- NOUVEAU_GRCTX_VALS
+ NVKM_GRCTX_PROG,
+ NVKM_GRCTX_VALS
} mode;
void *data;
@@ -19,11 +20,11 @@ struct nouveau_grctx {
};
static inline void
-cp_out(struct nouveau_grctx *ctx, u32 inst)
+cp_out(struct nvkm_grctx *ctx, u32 inst)
{
u32 *ctxprog = ctx->data;
- if (ctx->mode != NOUVEAU_GRCTX_PROG)
+ if (ctx->mode != NVKM_GRCTX_PROG)
return;
BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max);
@@ -31,13 +32,13 @@ cp_out(struct nouveau_grctx *ctx, u32 inst)
}
static inline void
-cp_lsr(struct nouveau_grctx *ctx, u32 val)
+cp_lsr(struct nvkm_grctx *ctx, u32 val)
{
cp_out(ctx, CP_LOAD_SR | val);
}
static inline void
-cp_ctx(struct nouveau_grctx *ctx, u32 reg, u32 length)
+cp_ctx(struct nvkm_grctx *ctx, u32 reg, u32 length)
{
ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
@@ -53,12 +54,12 @@ cp_ctx(struct nouveau_grctx *ctx, u32 reg, u32 length)
}
static inline void
-cp_name(struct nouveau_grctx *ctx, int name)
+cp_name(struct nvkm_grctx *ctx, int name)
{
u32 *ctxprog = ctx->data;
int i;
- if (ctx->mode != NOUVEAU_GRCTX_PROG)
+ if (ctx->mode != NVKM_GRCTX_PROG)
return;
ctx->ctxprog_label[name] = ctx->ctxprog_len;
@@ -73,7 +74,7 @@ cp_name(struct nouveau_grctx *ctx, int name)
}
static inline void
-_cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name)
+_cp_bra(struct nvkm_grctx *ctx, u32 mod, int flag, int state, int name)
{
int ip = 0;
@@ -91,21 +92,21 @@ _cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name)
#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
static inline void
-_cp_wait(struct nouveau_grctx *ctx, int flag, int state)
+_cp_wait(struct nvkm_grctx *ctx, int flag, int state)
{
cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
}
#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
static inline void
-_cp_set(struct nouveau_grctx *ctx, int flag, int state)
+_cp_set(struct nvkm_grctx *ctx, int flag, int state)
{
cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
}
#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
static inline void
-cp_pos(struct nouveau_grctx *ctx, int offset)
+cp_pos(struct nvkm_grctx *ctx, int offset)
{
ctx->ctxvals_pos = offset;
ctx->ctxvals_base = ctx->ctxvals_pos;
@@ -115,9 +116,9 @@ cp_pos(struct nouveau_grctx *ctx, int offset)
}
static inline void
-gr_def(struct nouveau_grctx *ctx, u32 reg, u32 val)
+gr_def(struct nvkm_grctx *ctx, u32 reg, u32 val)
{
- if (ctx->mode != NOUVEAU_GRCTX_VALS)
+ if (ctx->mode != NVKM_GRCTX_VALS)
return;
reg = (reg - 0x00400000) / 4;
@@ -125,5 +126,4 @@ gr_def(struct nouveau_grctx *ctx, u32 reg, u32 val)
nv_wo32(ctx->data, reg * 4, val);
}
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c
index 1d0e33fb5f61..9c9528d2cd90 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c
@@ -20,8 +20,6 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <core/gpuobj.h>
-
#define CP_FLAG_CLEAR 0
#define CP_FLAG_SET 1
#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0)
@@ -107,14 +105,14 @@
#define CP_SEEK_1 0x00c000ff
#define CP_SEEK_2 0x00c800ff
-#include "nv50.h"
-#include "ctx.h"
+#include "ctxnv40.h"
+
+#include <core/device.h>
+#include <subdev/fb.h>
#define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf)
#define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac)
-#include <subdev/fb.h>
-
/*
* This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's
* the GPU itself that does context-switching, but it needs a special
@@ -169,14 +167,14 @@ enum cp_label {
cp_exit,
};
-static void nv50_graph_construct_mmio(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_xfer1(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_xfer2(struct nouveau_grctx *ctx);
+static void nv50_gr_construct_mmio(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_xfer1(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_xfer2(struct nvkm_grctx *ctx);
/* Main function: construct the ctxprog skeleton, call the other functions. */
static int
-nv50_grctx_generate(struct nouveau_grctx *ctx)
+nv50_grctx_generate(struct nvkm_grctx *ctx)
{
cp_set (ctx, STATE, RUNNING);
cp_set (ctx, XFER_SWITCH, ENABLE);
@@ -219,9 +217,9 @@ nv50_grctx_generate(struct nouveau_grctx *ctx)
cp_pos (ctx, 0x00004/4);
cp_ctx (ctx, 0x400828, 1); /* needed. otherwise, flickering happens. */
cp_pos (ctx, 0x00100/4);
- nv50_graph_construct_mmio(ctx);
- nv50_graph_construct_xfer1(ctx);
- nv50_graph_construct_xfer2(ctx);
+ nv50_gr_construct_mmio(ctx);
+ nv50_gr_construct_xfer1(ctx);
+ nv50_gr_construct_xfer2(ctx);
cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
@@ -255,22 +253,22 @@ nv50_grctx_generate(struct nouveau_grctx *ctx)
}
void
-nv50_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
+nv50_grctx_fill(struct nvkm_device *device, struct nvkm_gpuobj *mem)
{
- nv50_grctx_generate(&(struct nouveau_grctx) {
+ nv50_grctx_generate(&(struct nvkm_grctx) {
.device = device,
- .mode = NOUVEAU_GRCTX_VALS,
+ .mode = NVKM_GRCTX_VALS,
.data = mem,
});
}
int
-nv50_grctx_init(struct nouveau_device *device, u32 *size)
+nv50_grctx_init(struct nvkm_device *device, u32 *size)
{
u32 *ctxprog = kmalloc(512 * 4, GFP_KERNEL), i;
- struct nouveau_grctx ctx = {
+ struct nvkm_grctx ctx = {
.device = device,
- .mode = NOUVEAU_GRCTX_PROG,
+ .mode = NVKM_GRCTX_PROG,
.data = ctxprog,
.ctxprog_max = 512,
};
@@ -293,12 +291,12 @@ nv50_grctx_init(struct nouveau_device *device, u32 *size)
*/
static void
-nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx);
+nv50_gr_construct_mmio_ddata(struct nvkm_grctx *ctx);
static void
-nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
+nv50_gr_construct_mmio(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i, j;
int offset, base;
u32 units = nv_rd32 (ctx->device, 0x1540);
@@ -334,7 +332,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, 0x400b20, 0x0001629d);
}
- nv50_graph_construct_mmio_ddata(ctx);
+ nv50_gr_construct_mmio_ddata(ctx);
/* 0C00: VFETCH */
cp_ctx(ctx, 0x400c08, 0x2);
@@ -572,7 +570,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
else if (device->chipset < 0xa0)
gr_def(ctx, 0x407d08, 0x00390040);
else {
- if (nouveau_fb(device)->ram->type != NV_MEM_TYPE_GDDR5)
+ if (nvkm_fb(device)->ram->type != NV_MEM_TYPE_GDDR5)
gr_def(ctx, 0x407d08, 0x003d0040);
else
gr_def(ctx, 0x407d08, 0x003c0040);
@@ -784,18 +782,18 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
}
static void
-dd_emit(struct nouveau_grctx *ctx, int num, u32 val) {
+dd_emit(struct nvkm_grctx *ctx, int num, u32 val) {
int i;
- if (val && ctx->mode == NOUVEAU_GRCTX_VALS)
+ if (val && ctx->mode == NVKM_GRCTX_VALS)
for (i = 0; i < num; i++)
nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + i), val);
ctx->ctxvals_pos += num;
}
static void
-nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
+nv50_gr_construct_mmio_ddata(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int base, num;
base = ctx->ctxvals_pos;
@@ -1156,9 +1154,9 @@ nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
*/
static void
-xf_emit(struct nouveau_grctx *ctx, int num, u32 val) {
+xf_emit(struct nvkm_grctx *ctx, int num, u32 val) {
int i;
- if (val && ctx->mode == NOUVEAU_GRCTX_VALS)
+ if (val && ctx->mode == NVKM_GRCTX_VALS)
for (i = 0; i < num; i++)
nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + (i << 3)), val);
ctx->ctxvals_pos += num << 3;
@@ -1166,29 +1164,29 @@ xf_emit(struct nouveau_grctx *ctx, int num, u32 val) {
/* Gene declarations... */
-static void nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx);
-static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx);
+static void nv50_gr_construct_gene_dispatch(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_m2mf(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_ccache(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_unk10xx(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_unk14xx(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_zcull(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_clipid(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_unk24xx(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_vfetch(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_eng2d(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_csched(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_unk1cxx(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_strmout(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_unk34xx(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_ropm1(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_ropm2(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_gene_ropc(struct nvkm_grctx *ctx);
+static void nv50_gr_construct_xfer_tp(struct nvkm_grctx *ctx);
static void
-nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer1(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i;
int offset;
int size = 0;
@@ -1200,32 +1198,32 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
if (device->chipset < 0xa0) {
/* Strand 0 */
ctx->ctxvals_pos = offset;
- nv50_graph_construct_gene_dispatch(ctx);
- nv50_graph_construct_gene_m2mf(ctx);
- nv50_graph_construct_gene_unk24xx(ctx);
- nv50_graph_construct_gene_clipid(ctx);
- nv50_graph_construct_gene_zcull(ctx);
+ nv50_gr_construct_gene_dispatch(ctx);
+ nv50_gr_construct_gene_m2mf(ctx);
+ nv50_gr_construct_gene_unk24xx(ctx);
+ nv50_gr_construct_gene_clipid(ctx);
+ nv50_gr_construct_gene_zcull(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 1 */
ctx->ctxvals_pos = offset + 0x1;
- nv50_graph_construct_gene_vfetch(ctx);
- nv50_graph_construct_gene_eng2d(ctx);
- nv50_graph_construct_gene_csched(ctx);
- nv50_graph_construct_gene_ropm1(ctx);
- nv50_graph_construct_gene_ropm2(ctx);
+ nv50_gr_construct_gene_vfetch(ctx);
+ nv50_gr_construct_gene_eng2d(ctx);
+ nv50_gr_construct_gene_csched(ctx);
+ nv50_gr_construct_gene_ropm1(ctx);
+ nv50_gr_construct_gene_ropm2(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 2 */
ctx->ctxvals_pos = offset + 0x2;
- nv50_graph_construct_gene_ccache(ctx);
- nv50_graph_construct_gene_unk1cxx(ctx);
- nv50_graph_construct_gene_strmout(ctx);
- nv50_graph_construct_gene_unk14xx(ctx);
- nv50_graph_construct_gene_unk10xx(ctx);
- nv50_graph_construct_gene_unk34xx(ctx);
+ nv50_gr_construct_gene_ccache(ctx);
+ nv50_gr_construct_gene_unk1cxx(ctx);
+ nv50_gr_construct_gene_strmout(ctx);
+ nv50_gr_construct_gene_unk14xx(ctx);
+ nv50_gr_construct_gene_unk10xx(ctx);
+ nv50_gr_construct_gene_unk34xx(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
@@ -1233,7 +1231,7 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
ctx->ctxvals_pos = offset + 3;
for (i = 0; i < 6; i++)
if (units & (1 << (i + 16)))
- nv50_graph_construct_gene_ropc(ctx);
+ nv50_gr_construct_gene_ropc(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
@@ -1241,74 +1239,74 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
for (i = 0; i < 4; i++) {
ctx->ctxvals_pos = offset + 4 + i;
if (units & (1 << (2 * i)))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << (2 * i + 1)))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
}
} else {
/* Strand 0 */
ctx->ctxvals_pos = offset;
- nv50_graph_construct_gene_dispatch(ctx);
- nv50_graph_construct_gene_m2mf(ctx);
- nv50_graph_construct_gene_unk34xx(ctx);
- nv50_graph_construct_gene_csched(ctx);
- nv50_graph_construct_gene_unk1cxx(ctx);
- nv50_graph_construct_gene_strmout(ctx);
+ nv50_gr_construct_gene_dispatch(ctx);
+ nv50_gr_construct_gene_m2mf(ctx);
+ nv50_gr_construct_gene_unk34xx(ctx);
+ nv50_gr_construct_gene_csched(ctx);
+ nv50_gr_construct_gene_unk1cxx(ctx);
+ nv50_gr_construct_gene_strmout(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 1 */
ctx->ctxvals_pos = offset + 1;
- nv50_graph_construct_gene_unk10xx(ctx);
+ nv50_gr_construct_gene_unk10xx(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 2 */
ctx->ctxvals_pos = offset + 2;
if (device->chipset == 0xa0)
- nv50_graph_construct_gene_unk14xx(ctx);
- nv50_graph_construct_gene_unk24xx(ctx);
+ nv50_gr_construct_gene_unk14xx(ctx);
+ nv50_gr_construct_gene_unk24xx(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 3 */
ctx->ctxvals_pos = offset + 3;
- nv50_graph_construct_gene_vfetch(ctx);
+ nv50_gr_construct_gene_vfetch(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 4 */
ctx->ctxvals_pos = offset + 4;
- nv50_graph_construct_gene_ccache(ctx);
+ nv50_gr_construct_gene_ccache(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 5 */
ctx->ctxvals_pos = offset + 5;
- nv50_graph_construct_gene_ropm2(ctx);
- nv50_graph_construct_gene_ropm1(ctx);
+ nv50_gr_construct_gene_ropm2(ctx);
+ nv50_gr_construct_gene_ropm1(ctx);
/* per-ROP context */
for (i = 0; i < 8; i++)
if (units & (1<<(i+16)))
- nv50_graph_construct_gene_ropc(ctx);
+ nv50_gr_construct_gene_ropc(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 6 */
ctx->ctxvals_pos = offset + 6;
- nv50_graph_construct_gene_zcull(ctx);
- nv50_graph_construct_gene_clipid(ctx);
- nv50_graph_construct_gene_eng2d(ctx);
+ nv50_gr_construct_gene_zcull(ctx);
+ nv50_gr_construct_gene_clipid(ctx);
+ nv50_gr_construct_gene_eng2d(ctx);
if (units & (1 << 0))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 1))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 2))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 3))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
@@ -1316,19 +1314,19 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
ctx->ctxvals_pos = offset + 7;
if (device->chipset == 0xa0) {
if (units & (1 << 4))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 5))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 6))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 7))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 8))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
if (units & (1 << 9))
- nv50_graph_construct_xfer_tp(ctx);
+ nv50_gr_construct_xfer_tp(ctx);
} else {
- nv50_graph_construct_gene_unk14xx(ctx);
+ nv50_gr_construct_gene_unk14xx(ctx);
}
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
@@ -1349,10 +1347,10 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
*/
static void
-nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_dispatch(struct nvkm_grctx *ctx)
{
/* start of strand 0 */
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
/* SEEK */
if (device->chipset == 0x50)
xf_emit(ctx, 5, 0);
@@ -1405,10 +1403,10 @@ nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_m2mf(struct nvkm_grctx *ctx)
{
/* Strand 0, right after dispatch */
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int smallm2mf = 0;
if (device->chipset < 0x92 || device->chipset == 0x98)
smallm2mf = 1;
@@ -1457,9 +1455,9 @@ nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_ccache(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
xf_emit(ctx, 2, 0); /* RO */
xf_emit(ctx, 0x800, 0); /* ffffffff */
switch (device->chipset) {
@@ -1525,9 +1523,9 @@ nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_unk10xx(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i;
/* end of area 2 on pre-NVA0, area 1 on NVAx */
xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */
@@ -1585,9 +1583,9 @@ nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_unk34xx(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
/* end of area 2 on pre-NVA0, area 1 on NVAx */
xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */
xf_emit(ctx, 1, 0); /* 00000003 VIEWPORT_CLIP_MODE */
@@ -1610,9 +1608,9 @@ nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_unk14xx(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
/* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */
if (device->chipset != 0x50) {
xf_emit(ctx, 5, 0); /* ffffffff */
@@ -1721,9 +1719,9 @@ nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_zcull(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
/* end of strand 0 on pre-NVA0, beginning of strand 6 on NVAx */
/* SEEK */
xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */
@@ -1782,7 +1780,7 @@ nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_clipid(struct nvkm_grctx *ctx)
{
/* middle of strand 0 on pre-NVA0 [after 24xx], middle of area 6 on NVAx */
/* SEEK */
@@ -1802,9 +1800,9 @@ nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_unk24xx(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i;
/* middle of strand 0 on pre-NVA0 [after m2mf], end of strand 2 on NVAx */
/* SEEK */
@@ -1885,9 +1883,9 @@ nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_vfetch(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int acnt = 0x10, rep, i;
/* beginning of strand 1 on pre-NVA0, strand 3 on NVAx */
if (IS_NVA3F(device->chipset))
@@ -2071,9 +2069,9 @@ nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_eng2d(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
/* middle of strand 1 on pre-NVA0 [after vfetch], middle of strand 6 on NVAx */
/* SEEK */
xf_emit(ctx, 2, 0); /* 0001ffff CLIP_X, CLIP_Y */
@@ -2133,9 +2131,9 @@ nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_csched(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
/* middle of strand 1 on pre-NVA0 [after eng2d], middle of strand 0 on NVAx */
/* SEEK */
xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY... what is it doing here??? */
@@ -2232,9 +2230,9 @@ nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_unk1cxx(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */
xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */
xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */
@@ -2328,9 +2326,9 @@ nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_strmout(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */
xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */
xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */
@@ -2370,9 +2368,9 @@ nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_ropm1(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */
xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */
xf_emit(ctx, 1, 0); /* 00000007 */
@@ -2383,9 +2381,9 @@ nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_ropm2(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
/* SEEK */
xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */
xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */
@@ -2409,9 +2407,9 @@ nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
+nv50_gr_construct_gene_ropc(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int magic2;
if (device->chipset == 0x50) {
magic2 = 0x00003e60;
@@ -2644,9 +2642,9 @@ nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer_unk84xx(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int magic3;
switch (device->chipset) {
case 0x50:
@@ -2736,9 +2734,9 @@ nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer_tprop(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int magic1, magic2;
if (device->chipset == 0x50) {
magic1 = 0x3ff;
@@ -3036,9 +3034,9 @@ nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer_tex(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
xf_emit(ctx, 2, 0); /* 1 LINKED_TSC. yes, 2. */
if (device->chipset != 0x50)
xf_emit(ctx, 1, 0); /* 3 */
@@ -3082,9 +3080,9 @@ nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer_unk8cxx(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */
xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */
xf_emit(ctx, 2, 0); /* 7, ffff0ff3 */
@@ -3121,26 +3119,26 @@ nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer_tp(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
if (device->chipset < 0xa0) {
- nv50_graph_construct_xfer_unk84xx(ctx);
- nv50_graph_construct_xfer_tprop(ctx);
- nv50_graph_construct_xfer_tex(ctx);
- nv50_graph_construct_xfer_unk8cxx(ctx);
+ nv50_gr_construct_xfer_unk84xx(ctx);
+ nv50_gr_construct_xfer_tprop(ctx);
+ nv50_gr_construct_xfer_tex(ctx);
+ nv50_gr_construct_xfer_unk8cxx(ctx);
} else {
- nv50_graph_construct_xfer_tex(ctx);
- nv50_graph_construct_xfer_tprop(ctx);
- nv50_graph_construct_xfer_unk8cxx(ctx);
- nv50_graph_construct_xfer_unk84xx(ctx);
+ nv50_gr_construct_xfer_tex(ctx);
+ nv50_gr_construct_xfer_tprop(ctx);
+ nv50_gr_construct_xfer_unk8cxx(ctx);
+ nv50_gr_construct_xfer_unk84xx(ctx);
}
}
static void
-nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer_mpc(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i, mpcnt = 2;
switch (device->chipset) {
case 0x98:
@@ -3270,9 +3268,9 @@ nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
}
static void
-nv50_graph_construct_xfer2(struct nouveau_grctx *ctx)
+nv50_gr_construct_xfer2(struct nvkm_grctx *ctx)
{
- struct nouveau_device *device = ctx->device;
+ struct nvkm_device *device = ctx->device;
int i;
u32 offset;
u32 units = nv_rd32 (ctx->device, 0x1540);
@@ -3288,7 +3286,7 @@ nv50_graph_construct_xfer2(struct nouveau_grctx *ctx)
if (i == 0)
xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */
if (units & (1 << i))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
}
@@ -3299,40 +3297,40 @@ nv50_graph_construct_xfer2(struct nouveau_grctx *ctx)
* what it's doing here. */
xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */
if (units & (1 << 0))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if (units & (1 << 1))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 1: TPs 2, 3 */
ctx->ctxvals_pos = offset + 1;
if (units & (1 << 2))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if (units & (1 << 3))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 2: TPs 4, 5, 6 */
ctx->ctxvals_pos = offset + 2;
if (units & (1 << 4))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if (units & (1 << 5))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if (units & (1 << 6))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
/* Strand 3: TPs 7, 8, 9 */
ctx->ctxvals_pos = offset + 3;
if (units & (1 << 7))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if (units & (1 << 8))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if (units & (1 << 9))
- nv50_graph_construct_xfer_mpc(ctx);
+ nv50_gr_construct_xfer_mpc(ctx);
if ((ctx->ctxvals_pos-offset)/8 > size)
size = (ctx->ctxvals_pos-offset)/8;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/com.fuc
index e37d8106ae1a..64208bf954cf 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/com.fuc
@@ -1,4 +1,4 @@
-/* fuc microcode util functions for nvc0 PGRAPH
+/* fuc microcode util functions for gf100 PGRAPH
*
* Copyright 2011 Red Hat Inc.
*
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
index 7445f12b1d9e..eaed1599b90f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
@@ -1,4 +1,4 @@
-/* fuc microcode for nvc0 PGRAPH/GPC
+/* fuc microcode for gf100 PGRAPH/GPC
*
* Copyright 2011 Red Hat Inc.
*
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3
index 5ae06a2d64c9..7cf2bf9d95a2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3
@@ -27,13 +27,13 @@
#define CHIPSET GF100
#include "macros.fuc"
-.section #nvc0_grgpc_data
+.section #gf100_grgpc_data
#define INCLUDE_DATA
#include "com.fuc"
#include "gpc.fuc"
#undef INCLUDE_DATA
-.section #nvc0_grgpc_code
+.section #gf100_grgpc_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
index 325cc7b7b2fb..ea32f56c0a92 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvc0_grgpc_data[] = {
+uint32_t gf100_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x00000064,
/* 0x0004: gpc_mmio_list_tail */
@@ -36,7 +36,7 @@ uint32_t nvc0_grgpc_data[] = {
0x00000000,
};
-uint32_t nvc0_grgpc_code[] = {
+uint32_t gf100_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3
index c2f754edbd7d..c918f7d60004 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3
@@ -27,13 +27,13 @@
#define CHIPSET GF117
#include "macros.fuc"
-.section #nvd7_grgpc_data
+.section #gf117_grgpc_data
#define INCLUDE_DATA
#include "com.fuc"
#include "gpc.fuc"
#undef INCLUDE_DATA
-.section #nvd7_grgpc_code
+.section #gf117_grgpc_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
index d1504a4059c6..9a36d9cbb8a5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvd7_grgpc_data[] = {
+uint32_t gf117_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
@@ -40,7 +40,7 @@ uint32_t nvd7_grgpc_data[] = {
0x00000000,
};
-uint32_t nvd7_grgpc_code[] = {
+uint32_t gf117_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3
index 6b906cd2a31f..b80cdfd337a9 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3
@@ -27,13 +27,13 @@
#define CHIPSET GK100
#include "macros.fuc"
-.section #nve0_grgpc_data
+.section #gk104_grgpc_data
#define INCLUDE_DATA
#include "com.fuc"
#include "gpc.fuc"
#undef INCLUDE_DATA
-.section #nve0_grgpc_code
+.section #gk104_grgpc_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h
index 855b220378f9..49020fff4317 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nve0_grgpc_data[] = {
+uint32_t gk104_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
@@ -40,7 +40,7 @@ uint32_t nve0_grgpc_data[] = {
0x00000000,
};
-uint32_t nve0_grgpc_code[] = {
+uint32_t gk104_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3
index 90bbe525b626..98d85fe210e8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3
@@ -27,13 +27,13 @@
#define CHIPSET GK110
#include "macros.fuc"
-.section #nvf0_grgpc_data
+.section #gk110_grgpc_data
#define INCLUDE_DATA
#include "com.fuc"
#include "gpc.fuc"
#undef INCLUDE_DATA
-.section #nvf0_grgpc_code
+.section #gk110_grgpc_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h
index 1b803197d28b..c95b07e3bce5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvf0_grgpc_data[] = {
+uint32_t gk110_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
@@ -40,7 +40,7 @@ uint32_t nvf0_grgpc_data[] = {
0x00000000,
};
-uint32_t nvf0_grgpc_code[] = {
+uint32_t gk110_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5 b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5
index bd30262d635b..8f64299a3b91 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5
@@ -27,13 +27,13 @@
#define CHIPSET GK208
#include "macros.fuc"
-.section #nv108_grgpc_data
+.section #gk208_grgpc_data
#define INCLUDE_DATA
#include "com.fuc"
#include "gpc.fuc"
#undef INCLUDE_DATA
-.section #nv108_grgpc_code
+.section #gk208_grgpc_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h
index 31922707794f..7e1c28ee7591 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h
@@ -1,4 +1,4 @@
-uint32_t nv108_grgpc_data[] = {
+uint32_t gk208_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
@@ -40,7 +40,7 @@ uint32_t nv108_grgpc_data[] = {
0x00000000,
};
-uint32_t nv108_grgpc_code[] = {
+uint32_t gk208_grgpc_code[] = {
0x03140ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5 b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5
index e730603891d7..e730603891d7 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h
index 6d53b67dd3c4..6d53b67dd3c4 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc
index b4ad18bf5a26..87f99e38acbf 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc
@@ -1,4 +1,4 @@
-/* fuc microcode for nvc0 PGRAPH/HUB
+/* fuc microcode for gf100 PGRAPH/HUB
*
* Copyright 2011 Red Hat Inc.
*
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3
index 3ff52badf932..2c28e7199b7f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3
@@ -25,13 +25,13 @@
#define CHIPSET GF100
#include "macros.fuc"
-.section #nvc0_grhub_data
+.section #gf100_grhub_data
#define INCLUDE_DATA
#include "com.fuc"
#include "hub.fuc"
#undef INCLUDE_DATA
-.section #nvc0_grhub_code
+.section #gf100_grhub_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h
index 92dfe6a4ac87..f6acda505677 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvc0_grhub_data[] = {
+uint32_t gf100_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
@@ -205,7 +205,7 @@ uint32_t nvc0_grhub_data[] = {
0x0417e91c,
};
-uint32_t nvc0_grhub_code[] = {
+uint32_t gf100_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3
index afbe03ac9077..581b2d53ab0c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3
@@ -25,13 +25,13 @@
#define CHIPSET GF117
#include "macros.fuc"
-.section #nvd7_grhub_data
+.section #gf117_grhub_data
#define INCLUDE_DATA
#include "com.fuc"
#include "hub.fuc"
#undef INCLUDE_DATA
-.section #nvd7_grhub_code
+.section #gf117_grhub_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h
index 62b0c7601d8b..7cb14e59dea1 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvd7_grhub_data[] = {
+uint32_t gf117_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
@@ -205,7 +205,7 @@ uint32_t nvd7_grhub_data[] = {
0x0417e91c,
};
-uint32_t nvd7_grhub_code[] = {
+uint32_t gf117_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3
index d4840f1879fd..d977d393b679 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3
@@ -25,13 +25,13 @@
#define CHIPSET GK100
#include "macros.fuc"
-.section #nve0_grhub_data
+.section #gk104_grhub_data
#define INCLUDE_DATA
#include "com.fuc"
#include "hub.fuc"
#undef INCLUDE_DATA
-.section #nve0_grhub_code
+.section #gk104_grhub_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h
index 51c3797d8537..95ac15110049 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nve0_grhub_data[] = {
+uint32_t gk104_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
@@ -205,7 +205,7 @@ uint32_t nve0_grhub_data[] = {
0x0417e91c,
};
-uint32_t nve0_grhub_code[] = {
+uint32_t gk104_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3
index ec42ed29b50d..760b4632f22d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3
@@ -25,13 +25,13 @@
#define CHIPSET GK110
#include "macros.fuc"
-.section #nvf0_grhub_data
+.section #gk110_grhub_data
#define INCLUDE_DATA
#include "com.fuc"
#include "hub.fuc"
#undef INCLUDE_DATA
-.section #nvf0_grhub_code
+.section #gk110_grhub_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h
index a0af4b703a8e..89986878480f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvf0_grhub_data[] = {
+uint32_t gk110_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
@@ -205,7 +205,7 @@ uint32_t nvf0_grhub_data[] = {
0x0417e91c,
};
-uint32_t nvf0_grhub_code[] = {
+uint32_t gk110_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5 b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5
index 7c5d25630fa8..43243a35f6dc 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5
@@ -25,13 +25,13 @@
#define CHIPSET GK208
#include "macros.fuc"
-.section #nv108_grhub_data
+.section #gk208_grhub_data
#define INCLUDE_DATA
#include "com.fuc"
#include "hub.fuc"
#undef INCLUDE_DATA
-.section #nv108_grhub_code
+.section #gk208_grhub_code
#define INCLUDE_CODE
bra #init
#include "com.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h
index e49b5a877ae4..0e98fa4a386e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h
@@ -1,4 +1,4 @@
-uint32_t nv108_grhub_data[] = {
+uint32_t gk208_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
@@ -205,7 +205,7 @@ uint32_t nv108_grhub_data[] = {
0x0417e91c,
};
-uint32_t nv108_grhub_code[] = {
+uint32_t gk208_grhub_code[] = {
0x030e0ef5,
/* 0x0004: queue_put */
0x9800d898,
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5 b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5
index 27591b3086a5..27591b3086a5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h
index 5f953c5c20b7..5f953c5c20b7 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/macros.fuc
index 2a0b0f844299..2a0b0f844299 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/macros.fuc
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/os.h
index 1718ae4e8224..1718ae4e8224 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/os.h
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
index 17251e4b9e86..1dd482e9da77 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -21,16 +21,28 @@
*
* Authors: Ben Skeggs
*/
-
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include "gf100.h"
+#include "ctxgf100.h"
+#include "fuc/os.h"
+
+#include <core/client.h>
+#include <core/device.h>
+#include <core/handle.h>
+#include <core/option.h>
+#include <engine/fifo.h>
+#include <subdev/fb.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+
+#include <nvif/class.h>
+#include <nvif/unpack.h>
/*******************************************************************************
* Zero Bandwidth Clear
******************************************************************************/
static void
-nvc0_graph_zbc_clear_color(struct nvc0_graph_priv *priv, int zbc)
+gf100_gr_zbc_clear_color(struct gf100_gr_priv *priv, int zbc)
{
if (priv->zbc_color[zbc].format) {
nv_wr32(priv, 0x405804, priv->zbc_color[zbc].ds[0]);
@@ -44,10 +56,10 @@ nvc0_graph_zbc_clear_color(struct nvc0_graph_priv *priv, int zbc)
}
static int
-nvc0_graph_zbc_color_get(struct nvc0_graph_priv *priv, int format,
- const u32 ds[4], const u32 l2[4])
+gf100_gr_zbc_color_get(struct gf100_gr_priv *priv, int format,
+ const u32 ds[4], const u32 l2[4])
{
- struct nouveau_ltc *ltc = nouveau_ltc(priv);
+ struct nvkm_ltc *ltc = nvkm_ltc(priv);
int zbc = -ENOSPC, i;
for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) {
@@ -75,12 +87,12 @@ nvc0_graph_zbc_color_get(struct nvc0_graph_priv *priv, int format,
memcpy(priv->zbc_color[zbc].l2, l2, sizeof(priv->zbc_color[zbc].l2));
priv->zbc_color[zbc].format = format;
ltc->zbc_color_get(ltc, zbc, l2);
- nvc0_graph_zbc_clear_color(priv, zbc);
+ gf100_gr_zbc_clear_color(priv, zbc);
return zbc;
}
static void
-nvc0_graph_zbc_clear_depth(struct nvc0_graph_priv *priv, int zbc)
+gf100_gr_zbc_clear_depth(struct gf100_gr_priv *priv, int zbc)
{
if (priv->zbc_depth[zbc].format)
nv_wr32(priv, 0x405818, priv->zbc_depth[zbc].ds);
@@ -90,10 +102,10 @@ nvc0_graph_zbc_clear_depth(struct nvc0_graph_priv *priv, int zbc)
}
static int
-nvc0_graph_zbc_depth_get(struct nvc0_graph_priv *priv, int format,
- const u32 ds, const u32 l2)
+gf100_gr_zbc_depth_get(struct gf100_gr_priv *priv, int format,
+ const u32 ds, const u32 l2)
{
- struct nouveau_ltc *ltc = nouveau_ltc(priv);
+ struct nvkm_ltc *ltc = nvkm_ltc(priv);
int zbc = -ENOSPC, i;
for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) {
@@ -119,7 +131,7 @@ nvc0_graph_zbc_depth_get(struct nvc0_graph_priv *priv, int format,
priv->zbc_depth[zbc].ds = ds;
priv->zbc_depth[zbc].l2 = l2;
ltc->zbc_depth_get(ltc, zbc, l2);
- nvc0_graph_zbc_clear_depth(priv, zbc);
+ gf100_gr_zbc_clear_depth(priv, zbc);
return zbc;
}
@@ -128,9 +140,9 @@ nvc0_graph_zbc_depth_get(struct nvc0_graph_priv *priv, int format,
******************************************************************************/
static int
-nvc0_fermi_mthd_zbc_color(struct nouveau_object *object, void *data, u32 size)
+gf100_fermi_mthd_zbc_color(struct nvkm_object *object, void *data, u32 size)
{
- struct nvc0_graph_priv *priv = (void *)object->engine;
+ struct gf100_gr_priv *priv = (void *)object->engine;
union {
struct fermi_a_zbc_color_v0 v0;
} *args = data;
@@ -157,9 +169,9 @@ nvc0_fermi_mthd_zbc_color(struct nouveau_object *object, void *data, u32 size)
case FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8:
case FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10:
case FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11:
- ret = nvc0_graph_zbc_color_get(priv, args->v0.format,
- args->v0.ds,
- args->v0.l2);
+ ret = gf100_gr_zbc_color_get(priv, args->v0.format,
+ args->v0.ds,
+ args->v0.l2);
if (ret >= 0) {
args->v0.index = ret;
return 0;
@@ -174,9 +186,9 @@ nvc0_fermi_mthd_zbc_color(struct nouveau_object *object, void *data, u32 size)
}
static int
-nvc0_fermi_mthd_zbc_depth(struct nouveau_object *object, void *data, u32 size)
+gf100_fermi_mthd_zbc_depth(struct nvkm_object *object, void *data, u32 size)
{
- struct nvc0_graph_priv *priv = (void *)object->engine;
+ struct gf100_gr_priv *priv = (void *)object->engine;
union {
struct fermi_a_zbc_depth_v0 v0;
} *args = data;
@@ -185,9 +197,9 @@ nvc0_fermi_mthd_zbc_depth(struct nouveau_object *object, void *data, u32 size)
if (nvif_unpack(args->v0, 0, 0, false)) {
switch (args->v0.format) {
case FERMI_A_ZBC_DEPTH_V0_FMT_FP32:
- ret = nvc0_graph_zbc_depth_get(priv, args->v0.format,
- args->v0.ds,
- args->v0.l2);
+ ret = gf100_gr_zbc_depth_get(priv, args->v0.format,
+ args->v0.ds,
+ args->v0.l2);
return (ret >= 0) ? 0 : -ENOSPC;
default:
return -EINVAL;
@@ -198,33 +210,33 @@ nvc0_fermi_mthd_zbc_depth(struct nouveau_object *object, void *data, u32 size)
}
static int
-nvc0_fermi_mthd(struct nouveau_object *object, u32 mthd, void *data, u32 size)
+gf100_fermi_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
switch (mthd) {
case FERMI_A_ZBC_COLOR:
- return nvc0_fermi_mthd_zbc_color(object, data, size);
+ return gf100_fermi_mthd_zbc_color(object, data, size);
case FERMI_A_ZBC_DEPTH:
- return nvc0_fermi_mthd_zbc_depth(object, data, size);
+ return gf100_fermi_mthd_zbc_depth(object, data, size);
default:
break;
}
return -EINVAL;
}
-struct nouveau_ofuncs
-nvc0_fermi_ofuncs = {
- .ctor = _nouveau_object_ctor,
- .dtor = nouveau_object_destroy,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
- .mthd = nvc0_fermi_mthd,
+struct nvkm_ofuncs
+gf100_fermi_ofuncs = {
+ .ctor = _nvkm_object_ctor,
+ .dtor = nvkm_object_destroy,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
+ .mthd = gf100_fermi_mthd,
};
static int
-nvc0_graph_set_shader_exceptions(struct nouveau_object *object, u32 mthd,
- void *pdata, u32 size)
+gf100_gr_set_shader_exceptions(struct nvkm_object *object, u32 mthd,
+ void *pdata, u32 size)
{
- struct nvc0_graph_priv *priv = (void *)nv_engine(object);
+ struct gf100_gr_priv *priv = (void *)nv_engine(object);
if (size >= sizeof(u32)) {
u32 data = *(u32 *)pdata ? 0xffffffff : 0x00000000;
nv_wr32(priv, 0x419e44, data);
@@ -234,24 +246,24 @@ nvc0_graph_set_shader_exceptions(struct nouveau_object *object, u32 mthd,
return -EINVAL;
}
-struct nouveau_omthds
-nvc0_graph_9097_omthds[] = {
- { 0x1528, 0x1528, nvc0_graph_set_shader_exceptions },
+struct nvkm_omthds
+gf100_gr_9097_omthds[] = {
+ { 0x1528, 0x1528, gf100_gr_set_shader_exceptions },
{}
};
-struct nouveau_omthds
-nvc0_graph_90c0_omthds[] = {
- { 0x1528, 0x1528, nvc0_graph_set_shader_exceptions },
+struct nvkm_omthds
+gf100_gr_90c0_omthds[] = {
+ { 0x1528, 0x1528, gf100_gr_set_shader_exceptions },
{}
};
-struct nouveau_oclass
-nvc0_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0x9039, &nouveau_object_ofuncs },
- { FERMI_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { FERMI_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds },
+struct nvkm_oclass
+gf100_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0x9039, &nvkm_object_ofuncs },
+ { FERMI_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { FERMI_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
{}
};
@@ -260,22 +272,21 @@ nvc0_graph_sclass[] = {
******************************************************************************/
int
-nvc0_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *args, u32 size,
- struct nouveau_object **pobject)
+gf100_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *args, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_vm *vm = nouveau_client(parent)->vm;
- struct nvc0_graph_priv *priv = (void *)engine;
- struct nvc0_graph_data *data = priv->mmio_data;
- struct nvc0_graph_mmio *mmio = priv->mmio_list;
- struct nvc0_graph_chan *chan;
+ struct nvkm_vm *vm = nvkm_client(parent)->vm;
+ struct gf100_gr_priv *priv = (void *)engine;
+ struct gf100_gr_data *data = priv->mmio_data;
+ struct gf100_gr_mmio *mmio = priv->mmio_list;
+ struct gf100_gr_chan *chan;
int ret, i;
/* allocate memory for context, and fill with default values */
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
- priv->size, 0x100,
- NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL,
+ priv->size, 0x100,
+ NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -284,26 +295,26 @@ nvc0_graph_context_ctor(struct nouveau_object *parent,
* fuc to modify some per-context register settings on first load
* of the context.
*/
- ret = nouveau_gpuobj_new(nv_object(chan), NULL, 0x1000, 0x100, 0,
- &chan->mmio);
+ ret = nvkm_gpuobj_new(nv_object(chan), NULL, 0x1000, 0x100, 0,
+ &chan->mmio);
if (ret)
return ret;
- ret = nouveau_gpuobj_map_vm(nv_gpuobj(chan->mmio), vm,
- NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS,
- &chan->mmio_vma);
+ ret = nvkm_gpuobj_map_vm(nv_gpuobj(chan->mmio), vm,
+ NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS,
+ &chan->mmio_vma);
if (ret)
return ret;
/* allocate buffers referenced by mmio list */
for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) {
- ret = nouveau_gpuobj_new(nv_object(chan), NULL, data->size,
- data->align, 0, &chan->data[i].mem);
+ ret = nvkm_gpuobj_new(nv_object(chan), NULL, data->size,
+ data->align, 0, &chan->data[i].mem);
if (ret)
return ret;
- ret = nouveau_gpuobj_map_vm(chan->data[i].mem, vm, data->access,
- &chan->data[i].vma);
+ ret = nvkm_gpuobj_map_vm(chan->data[i].mem, vm, data->access,
+ &chan->data[i].vma);
if (ret)
return ret;
@@ -347,28 +358,28 @@ nvc0_graph_context_ctor(struct nouveau_object *parent,
}
void
-nvc0_graph_context_dtor(struct nouveau_object *object)
+gf100_gr_context_dtor(struct nvkm_object *object)
{
- struct nvc0_graph_chan *chan = (void *)object;
+ struct gf100_gr_chan *chan = (void *)object;
int i;
for (i = 0; i < ARRAY_SIZE(chan->data); i++) {
- nouveau_gpuobj_unmap(&chan->data[i].vma);
- nouveau_gpuobj_ref(NULL, &chan->data[i].mem);
+ nvkm_gpuobj_unmap(&chan->data[i].vma);
+ nvkm_gpuobj_ref(NULL, &chan->data[i].mem);
}
- nouveau_gpuobj_unmap(&chan->mmio_vma);
- nouveau_gpuobj_ref(NULL, &chan->mmio);
+ nvkm_gpuobj_unmap(&chan->mmio_vma);
+ nvkm_gpuobj_ref(NULL, &chan->mmio);
- nouveau_graph_context_destroy(&chan->base);
+ nvkm_gr_context_destroy(&chan->base);
}
/*******************************************************************************
* PGRAPH register lists
******************************************************************************/
-const struct nvc0_graph_init
-nvc0_graph_init_main_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_main_0[] = {
{ 0x400080, 1, 0x04, 0x003083c2 },
{ 0x400088, 1, 0x04, 0x00006fe7 },
{ 0x40008c, 1, 0x04, 0x00000000 },
@@ -383,53 +394,53 @@ nvc0_graph_init_main_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_fe_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_fe_0[] = {
{ 0x40415c, 1, 0x04, 0x00000000 },
{ 0x404170, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_pri_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_pri_0[] = {
{ 0x404488, 2, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_rstr2d_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_rstr2d_0[] = {
{ 0x407808, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_pd_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_pd_0[] = {
{ 0x406024, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_ds_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_ds_0[] = {
{ 0x405844, 1, 0x04, 0x00ffffff },
{ 0x405850, 1, 0x04, 0x00000000 },
{ 0x405908, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_scc_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_scc_0[] = {
{ 0x40803c, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_prop_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_prop_0[] = {
{ 0x4184a0, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_gpc_unk_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_gpc_unk_0[] = {
{ 0x418604, 1, 0x04, 0x00000000 },
{ 0x418680, 1, 0x04, 0x00000000 },
{ 0x418714, 1, 0x04, 0x80000000 },
@@ -437,20 +448,20 @@ nvc0_graph_init_gpc_unk_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_setup_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_setup_0[] = {
{ 0x418814, 3, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_crstr_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_crstr_0[] = {
{ 0x418b04, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_setup_1[] = {
+const struct gf100_gr_init
+gf100_gr_init_setup_1[] = {
{ 0x4188c8, 1, 0x04, 0x80000000 },
{ 0x4188cc, 1, 0x04, 0x00000000 },
{ 0x4188d0, 1, 0x04, 0x00010000 },
@@ -458,8 +469,8 @@ nvc0_graph_init_setup_1[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_zcull_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_zcull_0[] = {
{ 0x418910, 1, 0x04, 0x00010001 },
{ 0x418914, 1, 0x04, 0x00000301 },
{ 0x418918, 1, 0x04, 0x00800000 },
@@ -468,15 +479,15 @@ nvc0_graph_init_zcull_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_gpm_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_gpm_0[] = {
{ 0x418c04, 1, 0x04, 0x00000000 },
{ 0x418c88, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_gpc_unk_1[] = {
+const struct gf100_gr_init
+gf100_gr_init_gpc_unk_1[] = {
{ 0x418d00, 1, 0x04, 0x00000000 },
{ 0x418f08, 1, 0x04, 0x00000000 },
{ 0x418e00, 1, 0x04, 0x00000050 },
@@ -484,30 +495,30 @@ nvc0_graph_init_gpc_unk_1[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_gcc_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_gcc_0[] = {
{ 0x41900c, 1, 0x04, 0x00000000 },
{ 0x419018, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_tpccs_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_tpccs_0[] = {
{ 0x419d08, 2, 0x04, 0x00000000 },
{ 0x419d10, 1, 0x04, 0x00000014 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_tex_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_tex_0[] = {
{ 0x419ab0, 1, 0x04, 0x00000000 },
{ 0x419ab8, 1, 0x04, 0x000000e7 },
{ 0x419abc, 2, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_pe_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_pe_0[] = {
{ 0x41980c, 3, 0x04, 0x00000000 },
{ 0x419844, 1, 0x04, 0x00000000 },
{ 0x41984c, 1, 0x04, 0x00005bc5 },
@@ -515,8 +526,8 @@ nvc0_graph_init_pe_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_l1c_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_l1c_0[] = {
{ 0x419c98, 1, 0x04, 0x00000000 },
{ 0x419ca8, 1, 0x04, 0x80000000 },
{ 0x419cb4, 1, 0x04, 0x00000000 },
@@ -526,27 +537,27 @@ nvc0_graph_init_l1c_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_wwdx_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_wwdx_0[] = {
{ 0x419bd4, 1, 0x04, 0x00800000 },
{ 0x419bdc, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_tpccs_1[] = {
+const struct gf100_gr_init
+gf100_gr_init_tpccs_1[] = {
{ 0x419d2c, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_mpc_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_mpc_0[] = {
{ 0x419c0c, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-nvc0_graph_init_sm_0[] = {
+static const struct gf100_gr_init
+gf100_gr_init_sm_0[] = {
{ 0x419e00, 1, 0x04, 0x00000000 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
{ 0x419ea4, 1, 0x04, 0x00000100 },
@@ -563,8 +574,8 @@ nvc0_graph_init_sm_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_be_0[] = {
+const struct gf100_gr_init
+gf100_gr_init_be_0[] = {
{ 0x40880c, 1, 0x04, 0x00000000 },
{ 0x408910, 9, 0x04, 0x00000000 },
{ 0x408950, 1, 0x04, 0x00000000 },
@@ -575,47 +586,47 @@ nvc0_graph_init_be_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_fe_1[] = {
+const struct gf100_gr_init
+gf100_gr_init_fe_1[] = {
{ 0x4040f0, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvc0_graph_init_pe_1[] = {
+const struct gf100_gr_init
+gf100_gr_init_pe_1[] = {
{ 0x419880, 1, 0x04, 0x00000002 },
{}
};
-static const struct nvc0_graph_pack
-nvc0_graph_pack_mmio[] = {
- { nvc0_graph_init_main_0 },
- { nvc0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvc0_graph_init_pd_0 },
- { nvc0_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvc0_graph_init_prop_0 },
- { nvc0_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc0_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvc0_graph_init_gpm_0 },
- { nvc0_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nvc0_graph_init_tpccs_0 },
- { nvc0_graph_init_tex_0 },
- { nvc0_graph_init_pe_0 },
- { nvc0_graph_init_l1c_0 },
- { nvc0_graph_init_wwdx_0 },
- { nvc0_graph_init_tpccs_1 },
- { nvc0_graph_init_mpc_0 },
- { nvc0_graph_init_sm_0 },
- { nvc0_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
- { nvc0_graph_init_pe_1 },
+static const struct gf100_gr_pack
+gf100_gr_pack_mmio[] = {
+ { gf100_gr_init_main_0 },
+ { gf100_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf100_gr_init_pd_0 },
+ { gf100_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gf100_gr_init_prop_0 },
+ { gf100_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf100_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf100_gr_init_gpm_0 },
+ { gf100_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gf100_gr_init_tpccs_0 },
+ { gf100_gr_init_tex_0 },
+ { gf100_gr_init_pe_0 },
+ { gf100_gr_init_l1c_0 },
+ { gf100_gr_init_wwdx_0 },
+ { gf100_gr_init_tpccs_1 },
+ { gf100_gr_init_mpc_0 },
+ { gf100_gr_init_sm_0 },
+ { gf100_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
+ { gf100_gr_init_pe_1 },
{}
};
@@ -624,7 +635,7 @@ nvc0_graph_pack_mmio[] = {
******************************************************************************/
void
-nvc0_graph_zbc_init(struct nvc0_graph_priv *priv)
+gf100_gr_zbc_init(struct gf100_gr_priv *priv)
{
const u32 zero[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000 };
@@ -634,29 +645,29 @@ nvc0_graph_zbc_init(struct nvc0_graph_priv *priv)
0x00000000, 0x00000000, 0x00000000, 0x00000000 };
const u32 f32_1[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 };
- struct nouveau_ltc *ltc = nouveau_ltc(priv);
+ struct nvkm_ltc *ltc = nvkm_ltc(priv);
int index;
if (!priv->zbc_color[0].format) {
- nvc0_graph_zbc_color_get(priv, 1, & zero[0], &zero[4]);
- nvc0_graph_zbc_color_get(priv, 2, & one[0], &one[4]);
- nvc0_graph_zbc_color_get(priv, 4, &f32_0[0], &f32_0[4]);
- nvc0_graph_zbc_color_get(priv, 4, &f32_1[0], &f32_1[4]);
- nvc0_graph_zbc_depth_get(priv, 1, 0x00000000, 0x00000000);
- nvc0_graph_zbc_depth_get(priv, 1, 0x3f800000, 0x3f800000);
+ gf100_gr_zbc_color_get(priv, 1, & zero[0], &zero[4]);
+ gf100_gr_zbc_color_get(priv, 2, & one[0], &one[4]);
+ gf100_gr_zbc_color_get(priv, 4, &f32_0[0], &f32_0[4]);
+ gf100_gr_zbc_color_get(priv, 4, &f32_1[0], &f32_1[4]);
+ gf100_gr_zbc_depth_get(priv, 1, 0x00000000, 0x00000000);
+ gf100_gr_zbc_depth_get(priv, 1, 0x3f800000, 0x3f800000);
}
for (index = ltc->zbc_min; index <= ltc->zbc_max; index++)
- nvc0_graph_zbc_clear_color(priv, index);
+ gf100_gr_zbc_clear_color(priv, index);
for (index = ltc->zbc_min; index <= ltc->zbc_max; index++)
- nvc0_graph_zbc_clear_depth(priv, index);
+ gf100_gr_zbc_clear_depth(priv, index);
}
void
-nvc0_graph_mmio(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
+gf100_gr_mmio(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p)
{
- const struct nvc0_graph_pack *pack;
- const struct nvc0_graph_init *init;
+ const struct gf100_gr_pack *pack;
+ const struct gf100_gr_init *init;
pack_for_each_init(init, pack, p) {
u32 next = init->addr + init->count * init->pitch;
@@ -669,10 +680,10 @@ nvc0_graph_mmio(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
}
void
-nvc0_graph_icmd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
+gf100_gr_icmd(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p)
{
- const struct nvc0_graph_pack *pack;
- const struct nvc0_graph_init *init;
+ const struct gf100_gr_pack *pack;
+ const struct gf100_gr_init *init;
u32 data = 0;
nv_wr32(priv, 0x400208, 0x80000000);
@@ -697,10 +708,10 @@ nvc0_graph_icmd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
}
void
-nvc0_graph_mthd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
+gf100_gr_mthd(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p)
{
- const struct nvc0_graph_pack *pack;
- const struct nvc0_graph_init *init;
+ const struct gf100_gr_pack *pack;
+ const struct gf100_gr_init *init;
u32 data = 0;
pack_for_each_init(init, pack, p) {
@@ -721,9 +732,9 @@ nvc0_graph_mthd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
}
u64
-nvc0_graph_units(struct nouveau_graph *graph)
+gf100_gr_units(struct nvkm_gr *gr)
{
- struct nvc0_graph_priv *priv = (void *)graph;
+ struct gf100_gr_priv *priv = (void *)gr;
u64 cfg;
cfg = (u32)priv->gpc_nr;
@@ -733,7 +744,7 @@ nvc0_graph_units(struct nouveau_graph *graph)
return cfg;
}
-static const struct nouveau_enum nve0_sked_error[] = {
+static const struct nvkm_enum gk104_sked_error[] = {
{ 7, "CONSTANT_BUFFER_SIZE" },
{ 9, "LOCAL_MEMORY_SIZE_POS" },
{ 10, "LOCAL_MEMORY_SIZE_NEG" },
@@ -748,7 +759,7 @@ static const struct nouveau_enum nve0_sked_error[] = {
{}
};
-static const struct nouveau_enum nvc0_gpc_rop_error[] = {
+static const struct nvkm_enum gf100_gpc_rop_error[] = {
{ 1, "RT_PITCH_OVERRUN" },
{ 4, "RT_WIDTH_OVERRUN" },
{ 5, "RT_HEIGHT_OVERRUN" },
@@ -759,7 +770,7 @@ static const struct nouveau_enum nvc0_gpc_rop_error[] = {
};
static void
-nvc0_graph_trap_gpc_rop(struct nvc0_graph_priv *priv, int gpc)
+gf100_gr_trap_gpc_rop(struct gf100_gr_priv *priv, int gpc)
{
u32 trap[4];
int i;
@@ -774,7 +785,7 @@ nvc0_graph_trap_gpc_rop(struct nvc0_graph_priv *priv, int gpc)
if (!(trap[0] & (1 << i)))
continue;
pr_cont(" ");
- nouveau_enum_print(nvc0_gpc_rop_error, i);
+ nvkm_enum_print(gf100_gpc_rop_error, i);
}
pr_cont("\n");
@@ -784,7 +795,7 @@ nvc0_graph_trap_gpc_rop(struct nvc0_graph_priv *priv, int gpc)
nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
}
-static const struct nouveau_enum nvc0_mp_warp_error[] = {
+static const struct nvkm_enum gf100_mp_warp_error[] = {
{ 0x00, "NO_ERROR" },
{ 0x01, "STACK_MISMATCH" },
{ 0x05, "MISALIGNED_PC" },
@@ -797,23 +808,23 @@ static const struct nouveau_enum nvc0_mp_warp_error[] = {
{}
};
-static const struct nouveau_bitfield nvc0_mp_global_error[] = {
+static const struct nvkm_bitfield gf100_mp_global_error[] = {
{ 0x00000004, "MULTIPLE_WARP_ERRORS" },
{ 0x00000008, "OUT_OF_STACK_SPACE" },
{}
};
static void
-nvc0_graph_trap_mp(struct nvc0_graph_priv *priv, int gpc, int tpc)
+gf100_gr_trap_mp(struct gf100_gr_priv *priv, int gpc, int tpc)
{
u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x648));
u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x650));
nv_error(priv, "GPC%i/TPC%i/MP trap:", gpc, tpc);
- nouveau_bitfield_print(nvc0_mp_global_error, gerr);
+ nvkm_bitfield_print(gf100_mp_global_error, gerr);
if (werr) {
pr_cont(" ");
- nouveau_enum_print(nvc0_mp_warp_error, werr & 0xffff);
+ nvkm_enum_print(gf100_mp_warp_error, werr & 0xffff);
}
pr_cont("\n");
@@ -822,7 +833,7 @@ nvc0_graph_trap_mp(struct nvc0_graph_priv *priv, int gpc, int tpc)
}
static void
-nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc)
+gf100_gr_trap_tpc(struct gf100_gr_priv *priv, int gpc, int tpc)
{
u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0508));
@@ -834,7 +845,7 @@ nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc)
}
if (stat & 0x00000002) {
- nvc0_graph_trap_mp(priv, gpc, tpc);
+ gf100_gr_trap_mp(priv, gpc, tpc);
stat &= ~0x00000002;
}
@@ -858,13 +869,13 @@ nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc)
}
static void
-nvc0_graph_trap_gpc(struct nvc0_graph_priv *priv, int gpc)
+gf100_gr_trap_gpc(struct gf100_gr_priv *priv, int gpc)
{
u32 stat = nv_rd32(priv, GPC_UNIT(gpc, 0x2c90));
int tpc;
if (stat & 0x00000001) {
- nvc0_graph_trap_gpc_rop(priv, gpc);
+ gf100_gr_trap_gpc_rop(priv, gpc);
stat &= ~0x00000001;
}
@@ -892,7 +903,7 @@ nvc0_graph_trap_gpc(struct nvc0_graph_priv *priv, int gpc)
for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
u32 mask = 0x00010000 << tpc;
if (stat & mask) {
- nvc0_graph_trap_tpc(priv, gpc, tpc);
+ gf100_gr_trap_tpc(priv, gpc, tpc);
nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), mask);
stat &= ~mask;
}
@@ -904,7 +915,7 @@ nvc0_graph_trap_gpc(struct nvc0_graph_priv *priv, int gpc)
}
static void
-nvc0_graph_trap_intr(struct nvc0_graph_priv *priv)
+gf100_gr_trap_intr(struct gf100_gr_priv *priv)
{
u32 trap = nv_rd32(priv, 0x400108);
int rop, gpc, i;
@@ -965,7 +976,7 @@ nvc0_graph_trap_intr(struct nvc0_graph_priv *priv)
if (!(stat & (1 << i)))
continue;
pr_cont(" ");
- nouveau_enum_print(nve0_sked_error, i);
+ nvkm_enum_print(gk104_sked_error, i);
}
pr_cont("\n");
@@ -980,7 +991,7 @@ nvc0_graph_trap_intr(struct nvc0_graph_priv *priv)
for (gpc = 0; stat && gpc < priv->gpc_nr; gpc++) {
u32 mask = 0x00000001 << gpc;
if (stat & mask) {
- nvc0_graph_trap_gpc(priv, gpc);
+ gf100_gr_trap_gpc(priv, gpc);
nv_wr32(priv, 0x400118, mask);
stat &= ~mask;
}
@@ -1009,7 +1020,7 @@ nvc0_graph_trap_intr(struct nvc0_graph_priv *priv)
}
static void
-nvc0_graph_ctxctl_debug_unit(struct nvc0_graph_priv *priv, u32 base)
+gf100_gr_ctxctl_debug_unit(struct gf100_gr_priv *priv, u32 base)
{
nv_error(priv, "%06x - done 0x%08x\n", base,
nv_rd32(priv, base + 0x400));
@@ -1022,18 +1033,18 @@ nvc0_graph_ctxctl_debug_unit(struct nvc0_graph_priv *priv, u32 base)
}
void
-nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *priv)
+gf100_gr_ctxctl_debug(struct gf100_gr_priv *priv)
{
u32 gpcnr = nv_rd32(priv, 0x409604) & 0xffff;
u32 gpc;
- nvc0_graph_ctxctl_debug_unit(priv, 0x409000);
+ gf100_gr_ctxctl_debug_unit(priv, 0x409000);
for (gpc = 0; gpc < gpcnr; gpc++)
- nvc0_graph_ctxctl_debug_unit(priv, 0x502000 + (gpc * 0x8000));
+ gf100_gr_ctxctl_debug_unit(priv, 0x502000 + (gpc * 0x8000));
}
static void
-nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
+gf100_gr_ctxctl_isr(struct gf100_gr_priv *priv)
{
u32 stat = nv_rd32(priv, 0x409c18);
@@ -1059,26 +1070,26 @@ nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
if (stat & 0x00080000) {
nv_error(priv, "FECS watchdog timeout\n");
- nvc0_graph_ctxctl_debug(priv);
+ gf100_gr_ctxctl_debug(priv);
nv_wr32(priv, 0x409c20, 0x00080000);
stat &= ~0x00080000;
}
if (stat) {
nv_error(priv, "FECS 0x%08x\n", stat);
- nvc0_graph_ctxctl_debug(priv);
+ gf100_gr_ctxctl_debug(priv);
nv_wr32(priv, 0x409c20, stat);
}
}
static void
-nvc0_graph_intr(struct nouveau_subdev *subdev)
+gf100_gr_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nouveau_handle *handle;
- struct nvc0_graph_priv *priv = (void *)subdev;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_object *engctx;
+ struct nvkm_handle *handle;
+ struct gf100_gr_priv *priv = (void *)subdev;
u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff;
u32 stat = nv_rd32(priv, 0x400100);
u32 addr = nv_rd32(priv, 0x400704);
@@ -1089,18 +1100,18 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
u32 class = nv_rd32(priv, 0x404200 + (subc * 4));
int chid;
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & 0x00000010) {
- handle = nouveau_handle_get_class(engctx, class);
+ handle = nvkm_handle_get_class(engctx, class);
if (!handle || nv_call(handle->object, mthd, data)) {
nv_error(priv,
"ILLEGAL_MTHD ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst << 12, nouveau_client_name(engctx),
+ chid, inst << 12, nvkm_client_name(engctx),
subc, class, mthd, data);
}
- nouveau_handle_put(handle);
+ nvkm_handle_put(handle);
nv_wr32(priv, 0x400100, 0x00000010);
stat &= ~0x00000010;
}
@@ -1108,7 +1119,7 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
if (stat & 0x00000020) {
nv_error(priv,
"ILLEGAL_CLASS ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst << 12, nouveau_client_name(engctx), subc,
+ chid, inst << 12, nvkm_client_name(engctx), subc,
class, mthd, data);
nv_wr32(priv, 0x400100, 0x00000020);
stat &= ~0x00000020;
@@ -1116,9 +1127,9 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
if (stat & 0x00100000) {
nv_error(priv, "DATA_ERROR [");
- nouveau_enum_print(nv50_data_error_names, code);
+ nvkm_enum_print(nv50_data_error_names, code);
pr_cont("] ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst << 12, nouveau_client_name(engctx), subc,
+ chid, inst << 12, nvkm_client_name(engctx), subc,
class, mthd, data);
nv_wr32(priv, 0x400100, 0x00100000);
stat &= ~0x00100000;
@@ -1126,14 +1137,14 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
if (stat & 0x00200000) {
nv_error(priv, "TRAP ch %d [0x%010llx %s]\n", chid, inst << 12,
- nouveau_client_name(engctx));
- nvc0_graph_trap_intr(priv);
+ nvkm_client_name(engctx));
+ gf100_gr_trap_intr(priv);
nv_wr32(priv, 0x400100, 0x00200000);
stat &= ~0x00200000;
}
if (stat & 0x00080000) {
- nvc0_graph_ctxctl_isr(priv);
+ gf100_gr_ctxctl_isr(priv);
nv_wr32(priv, 0x400100, 0x00080000);
stat &= ~0x00080000;
}
@@ -1144,12 +1155,12 @@ nvc0_graph_intr(struct nouveau_subdev *subdev)
}
nv_wr32(priv, 0x400500, 0x00010001);
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
void
-nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base,
- struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data)
+gf100_gr_init_fw(struct gf100_gr_priv *priv, u32 fuc_base,
+ struct gf100_gr_fuc *code, struct gf100_gr_fuc *data)
{
int i;
@@ -1170,12 +1181,12 @@ nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base,
}
static void
-nvc0_graph_init_csdata(struct nvc0_graph_priv *priv,
- const struct nvc0_graph_pack *pack,
- u32 falcon, u32 starstar, u32 base)
+gf100_gr_init_csdata(struct gf100_gr_priv *priv,
+ const struct gf100_gr_pack *pack,
+ u32 falcon, u32 starstar, u32 base)
{
- const struct nvc0_graph_pack *iter;
- const struct nvc0_graph_init *init;
+ const struct gf100_gr_pack *iter;
+ const struct gf100_gr_init *init;
u32 addr = ~0, prev = ~0, xfer = 0;
u32 star, temp;
@@ -1211,20 +1222,20 @@ nvc0_graph_init_csdata(struct nvc0_graph_priv *priv,
}
int
-nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
+gf100_gr_init_ctxctl(struct gf100_gr_priv *priv)
{
- struct nvc0_graph_oclass *oclass = (void *)nv_object(priv)->oclass;
- struct nvc0_grctx_oclass *cclass = (void *)nv_engine(priv)->cclass;
+ struct gf100_gr_oclass *oclass = (void *)nv_object(priv)->oclass;
+ struct gf100_grctx_oclass *cclass = (void *)nv_engine(priv)->cclass;
int i;
if (priv->firmware) {
/* load fuc microcode */
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 0);
- nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c,
- &priv->fuc409d);
- nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac,
- &priv->fuc41ad);
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 1);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 0);
+ gf100_gr_init_fw(priv, 0x409000, &priv->fuc409c,
+ &priv->fuc409d);
+ gf100_gr_init_fw(priv, 0x41a000, &priv->fuc41ac,
+ &priv->fuc41ad);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 1);
/* start both of them running */
nv_wr32(priv, 0x409840, 0xffffffff);
@@ -1297,7 +1308,7 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
}
if (priv->data == NULL) {
- int ret = nvc0_grctx_generate(priv);
+ int ret = gf100_grctx_generate(priv);
if (ret) {
nv_error(priv, "failed to construct context\n");
return ret;
@@ -1311,7 +1322,7 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
}
/* load HUB microcode */
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 0);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 0);
nv_wr32(priv, 0x4091c0, 0x01000000);
for (i = 0; i < oclass->fecs.ucode->data.size / 4; i++)
nv_wr32(priv, 0x4091c4, oclass->fecs.ucode->data.data[i]);
@@ -1334,26 +1345,26 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
nv_wr32(priv, 0x41a188, i >> 6);
nv_wr32(priv, 0x41a184, oclass->gpccs.ucode->code.data[i]);
}
- nouveau_mc(priv)->unk260(nouveau_mc(priv), 1);
+ nvkm_mc(priv)->unk260(nvkm_mc(priv), 1);
/* load register lists */
- nvc0_graph_init_csdata(priv, cclass->hub, 0x409000, 0x000, 0x000000);
- nvc0_graph_init_csdata(priv, cclass->gpc, 0x41a000, 0x000, 0x418000);
- nvc0_graph_init_csdata(priv, cclass->tpc, 0x41a000, 0x004, 0x419800);
- nvc0_graph_init_csdata(priv, cclass->ppc, 0x41a000, 0x008, 0x41be00);
+ gf100_gr_init_csdata(priv, cclass->hub, 0x409000, 0x000, 0x000000);
+ gf100_gr_init_csdata(priv, cclass->gpc, 0x41a000, 0x000, 0x418000);
+ gf100_gr_init_csdata(priv, cclass->tpc, 0x41a000, 0x004, 0x419800);
+ gf100_gr_init_csdata(priv, cclass->ppc, 0x41a000, 0x008, 0x41be00);
/* start HUB ucode running, it'll init the GPCs */
nv_wr32(priv, 0x40910c, 0x00000000);
nv_wr32(priv, 0x409100, 0x00000002);
if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
nv_error(priv, "HUB_INIT timed out\n");
- nvc0_graph_ctxctl_debug(priv);
+ gf100_gr_ctxctl_debug(priv);
return -EBUSY;
}
priv->size = nv_rd32(priv, 0x409804);
if (priv->data == NULL) {
- int ret = nvc0_grctx_generate(priv);
+ int ret = gf100_grctx_generate(priv);
if (ret) {
nv_error(priv, "failed to construct context\n");
return ret;
@@ -1364,17 +1375,17 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
}
int
-nvc0_graph_init(struct nouveau_object *object)
+gf100_gr_init(struct nvkm_object *object)
{
- struct nvc0_graph_oclass *oclass = (void *)object->oclass;
- struct nvc0_graph_priv *priv = (void *)object;
+ struct gf100_gr_oclass *oclass = (void *)object->oclass;
+ struct gf100_gr_priv *priv = (void *)object;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
int gpc, tpc, rop;
int ret, i;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -1387,7 +1398,7 @@ nvc0_graph_init(struct nouveau_object *object)
nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
- nvc0_graph_mmio(priv, oclass->mmio);
+ gf100_gr_mmio(priv, oclass->mmio);
memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
@@ -1470,23 +1481,23 @@ nvc0_graph_init(struct nouveau_object *object)
nv_wr32(priv, 0x400054, 0x34ce3464);
- nvc0_graph_zbc_init(priv);
+ gf100_gr_zbc_init(priv);
- return nvc0_graph_init_ctxctl(priv);
+ return gf100_gr_init_ctxctl(priv);
}
static void
-nvc0_graph_dtor_fw(struct nvc0_graph_fuc *fuc)
+gf100_gr_dtor_fw(struct gf100_gr_fuc *fuc)
{
kfree(fuc->data);
fuc->data = NULL;
}
int
-nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname,
- struct nvc0_graph_fuc *fuc)
+gf100_gr_ctor_fw(struct gf100_gr_priv *priv, const char *fwname,
+ struct gf100_gr_fuc *fuc)
{
- struct nouveau_device *device = nv_device(priv);
+ struct nvkm_device *device = nv_device(priv);
const struct firmware *fw;
char f[32];
int ret;
@@ -1509,65 +1520,65 @@ nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname,
}
void
-nvc0_graph_dtor(struct nouveau_object *object)
+gf100_gr_dtor(struct nvkm_object *object)
{
- struct nvc0_graph_priv *priv = (void *)object;
+ struct gf100_gr_priv *priv = (void *)object;
kfree(priv->data);
- nvc0_graph_dtor_fw(&priv->fuc409c);
- nvc0_graph_dtor_fw(&priv->fuc409d);
- nvc0_graph_dtor_fw(&priv->fuc41ac);
- nvc0_graph_dtor_fw(&priv->fuc41ad);
+ gf100_gr_dtor_fw(&priv->fuc409c);
+ gf100_gr_dtor_fw(&priv->fuc409d);
+ gf100_gr_dtor_fw(&priv->fuc41ac);
+ gf100_gr_dtor_fw(&priv->fuc41ad);
- nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
- nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
+ nvkm_gpuobj_ref(NULL, &priv->unk4188b8);
+ nvkm_gpuobj_ref(NULL, &priv->unk4188b4);
- nouveau_graph_destroy(&priv->base);
+ nvkm_gr_destroy(&priv->base);
}
int
-nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *bclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *bclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_graph_oclass *oclass = (void *)bclass;
- struct nouveau_device *device = nv_device(parent);
- struct nvc0_graph_priv *priv;
+ struct gf100_gr_oclass *oclass = (void *)bclass;
+ struct nvkm_device *device = nv_device(parent);
+ struct gf100_gr_priv *priv;
bool use_ext_fw, enable;
int ret, i, j;
- use_ext_fw = nouveau_boolopt(device->cfgopt, "NvGrUseFW",
- oclass->fecs.ucode == NULL);
+ use_ext_fw = nvkm_boolopt(device->cfgopt, "NvGrUseFW",
+ oclass->fecs.ucode == NULL);
enable = use_ext_fw || oclass->fecs.ucode != NULL;
- ret = nouveau_graph_create(parent, engine, bclass, enable, &priv);
+ ret = nvkm_gr_create(parent, engine, bclass, enable, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x08001000;
- nv_subdev(priv)->intr = nvc0_graph_intr;
+ nv_subdev(priv)->intr = gf100_gr_intr;
- priv->base.units = nvc0_graph_units;
+ priv->base.units = gf100_gr_units;
if (use_ext_fw) {
nv_info(priv, "using external firmware\n");
- if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
- nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
- nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
- nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
+ if (gf100_gr_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
+ gf100_gr_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
+ gf100_gr_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
+ gf100_gr_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
return -ENODEV;
priv->firmware = true;
}
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
- &priv->unk4188b4);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
+ &priv->unk4188b4);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
- &priv->unk4188b8);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
+ &priv->unk4188b8);
if (ret)
return ret;
@@ -1630,38 +1641,38 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-#include "fuc/hubnvc0.fuc.h"
+#include "fuc/hubgf100.fuc3.h"
-struct nvc0_graph_ucode
-nvc0_graph_fecs_ucode = {
- .code.data = nvc0_grhub_code,
- .code.size = sizeof(nvc0_grhub_code),
- .data.data = nvc0_grhub_data,
- .data.size = sizeof(nvc0_grhub_data),
+struct gf100_gr_ucode
+gf100_gr_fecs_ucode = {
+ .code.data = gf100_grhub_code,
+ .code.size = sizeof(gf100_grhub_code),
+ .data.data = gf100_grhub_data,
+ .data.size = sizeof(gf100_grhub_data),
};
-#include "fuc/gpcnvc0.fuc.h"
+#include "fuc/gpcgf100.fuc3.h"
-struct nvc0_graph_ucode
-nvc0_graph_gpccs_ucode = {
- .code.data = nvc0_grgpc_code,
- .code.size = sizeof(nvc0_grgpc_code),
- .data.data = nvc0_grgpc_data,
- .data.size = sizeof(nvc0_grgpc_data),
+struct gf100_gr_ucode
+gf100_gr_gpccs_ucode = {
+ .code.data = gf100_grgpc_code,
+ .code.size = sizeof(gf100_grgpc_code),
+ .data.data = gf100_grgpc_data,
+ .data.size = sizeof(gf100_grgpc_data),
};
-struct nouveau_oclass *
-nvc0_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gf100_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nvc0_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gf100_gr_init,
+ .fini = _nvkm_gr_fini,
},
- .cclass = &nvc0_grctx_oclass,
- .sclass = nvc0_graph_sclass,
- .mmio = nvc0_graph_pack_mmio,
- .fecs.ucode = &nvc0_graph_fecs_ucode,
- .gpccs.ucode = &nvc0_graph_gpccs_ucode,
+ .cclass = &gf100_grctx_oclass,
+ .sclass = gf100_gr_sclass,
+ .mmio = gf100_gr_pack_mmio,
+ .fecs.ucode = &gf100_gr_fecs_ucode,
+ .gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
new file mode 100644
index 000000000000..aeeca1be9cf0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#ifndef __NVC0_GR_H__
+#define __NVC0_GR_H__
+#include <engine/gr.h>
+
+#include <subdev/ltc.h>
+
+#define GPC_MAX 32
+#define TPC_MAX (GPC_MAX * 8)
+
+#define ROP_BCAST(r) (0x408800 + (r))
+#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
+#define GPC_BCAST(r) (0x418000 + (r))
+#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r))
+#define PPC_UNIT(t, m, r) (0x503000 + (t) * 0x8000 + (m) * 0x200 + (r))
+#define TPC_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
+
+struct gf100_gr_data {
+ u32 size;
+ u32 align;
+ u32 access;
+};
+
+struct gf100_gr_mmio {
+ u32 addr;
+ u32 data;
+ u32 shift;
+ int buffer;
+};
+
+struct gf100_gr_fuc {
+ u32 *data;
+ u32 size;
+};
+
+struct gf100_gr_zbc_color {
+ u32 format;
+ u32 ds[4];
+ u32 l2[4];
+};
+
+struct gf100_gr_zbc_depth {
+ u32 format;
+ u32 ds;
+ u32 l2;
+};
+
+struct gf100_gr_priv {
+ struct nvkm_gr base;
+
+ struct gf100_gr_fuc fuc409c;
+ struct gf100_gr_fuc fuc409d;
+ struct gf100_gr_fuc fuc41ac;
+ struct gf100_gr_fuc fuc41ad;
+ bool firmware;
+
+ struct gf100_gr_zbc_color zbc_color[NVKM_LTC_MAX_ZBC_CNT];
+ struct gf100_gr_zbc_depth zbc_depth[NVKM_LTC_MAX_ZBC_CNT];
+
+ u8 rop_nr;
+ u8 gpc_nr;
+ u8 tpc_nr[GPC_MAX];
+ u8 tpc_total;
+ u8 ppc_nr[GPC_MAX];
+ u8 ppc_tpc_nr[GPC_MAX][4];
+
+ struct nvkm_gpuobj *unk4188b4;
+ struct nvkm_gpuobj *unk4188b8;
+
+ struct gf100_gr_data mmio_data[4];
+ struct gf100_gr_mmio mmio_list[4096/8];
+ u32 size;
+ u32 *data;
+
+ u8 magic_not_rop_nr;
+};
+
+struct gf100_gr_chan {
+ struct nvkm_gr_chan base;
+
+ struct nvkm_gpuobj *mmio;
+ struct nvkm_vma mmio_vma;
+ int mmio_nr;
+ struct {
+ struct nvkm_gpuobj *mem;
+ struct nvkm_vma vma;
+ } data[4];
+};
+
+int gf100_gr_context_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void gf100_gr_context_dtor(struct nvkm_object *);
+
+void gf100_gr_ctxctl_debug(struct gf100_gr_priv *);
+
+u64 gf100_gr_units(struct nvkm_gr *);
+int gf100_gr_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *data, u32 size,
+ struct nvkm_object **);
+void gf100_gr_dtor(struct nvkm_object *);
+int gf100_gr_init(struct nvkm_object *);
+void gf100_gr_zbc_init(struct gf100_gr_priv *);
+
+int gk104_gr_fini(struct nvkm_object *, bool);
+int gk104_gr_init(struct nvkm_object *);
+
+int gk110_gr_fini(struct nvkm_object *, bool);
+
+extern struct nvkm_ofuncs gf100_fermi_ofuncs;
+
+extern struct nvkm_oclass gf100_gr_sclass[];
+extern struct nvkm_omthds gf100_gr_9097_omthds[];
+extern struct nvkm_omthds gf100_gr_90c0_omthds[];
+extern struct nvkm_oclass gf110_gr_sclass[];
+extern struct nvkm_oclass gk110_gr_sclass[];
+
+struct gf100_gr_init {
+ u32 addr;
+ u8 count;
+ u8 pitch;
+ u32 data;
+};
+
+struct gf100_gr_pack {
+ const struct gf100_gr_init *init;
+ u32 type;
+};
+
+#define pack_for_each_init(init, pack, head) \
+ for (pack = head; pack && pack->init; pack++) \
+ for (init = pack->init; init && init->count; init++)
+
+struct gf100_gr_ucode {
+ struct gf100_gr_fuc code;
+ struct gf100_gr_fuc data;
+};
+
+extern struct gf100_gr_ucode gf100_gr_fecs_ucode;
+extern struct gf100_gr_ucode gf100_gr_gpccs_ucode;
+
+extern struct gf100_gr_ucode gk110_gr_fecs_ucode;
+extern struct gf100_gr_ucode gk110_gr_gpccs_ucode;
+
+struct gf100_gr_oclass {
+ struct nvkm_oclass base;
+ struct nvkm_oclass **cclass;
+ struct nvkm_oclass *sclass;
+ const struct gf100_gr_pack *mmio;
+ struct {
+ struct gf100_gr_ucode *ucode;
+ } fecs;
+ struct {
+ struct gf100_gr_ucode *ucode;
+ } gpccs;
+ int ppc_nr;
+};
+
+void gf100_gr_mmio(struct gf100_gr_priv *, const struct gf100_gr_pack *);
+void gf100_gr_icmd(struct gf100_gr_priv *, const struct gf100_gr_pack *);
+void gf100_gr_mthd(struct gf100_gr_priv *, const struct gf100_gr_pack *);
+int gf100_gr_init_ctxctl(struct gf100_gr_priv *);
+
+/* register init value lists */
+
+extern const struct gf100_gr_init gf100_gr_init_main_0[];
+extern const struct gf100_gr_init gf100_gr_init_fe_0[];
+extern const struct gf100_gr_init gf100_gr_init_pri_0[];
+extern const struct gf100_gr_init gf100_gr_init_rstr2d_0[];
+extern const struct gf100_gr_init gf100_gr_init_pd_0[];
+extern const struct gf100_gr_init gf100_gr_init_ds_0[];
+extern const struct gf100_gr_init gf100_gr_init_scc_0[];
+extern const struct gf100_gr_init gf100_gr_init_prop_0[];
+extern const struct gf100_gr_init gf100_gr_init_gpc_unk_0[];
+extern const struct gf100_gr_init gf100_gr_init_setup_0[];
+extern const struct gf100_gr_init gf100_gr_init_crstr_0[];
+extern const struct gf100_gr_init gf100_gr_init_setup_1[];
+extern const struct gf100_gr_init gf100_gr_init_zcull_0[];
+extern const struct gf100_gr_init gf100_gr_init_gpm_0[];
+extern const struct gf100_gr_init gf100_gr_init_gpc_unk_1[];
+extern const struct gf100_gr_init gf100_gr_init_gcc_0[];
+extern const struct gf100_gr_init gf100_gr_init_tpccs_0[];
+extern const struct gf100_gr_init gf100_gr_init_tex_0[];
+extern const struct gf100_gr_init gf100_gr_init_pe_0[];
+extern const struct gf100_gr_init gf100_gr_init_l1c_0[];
+extern const struct gf100_gr_init gf100_gr_init_wwdx_0[];
+extern const struct gf100_gr_init gf100_gr_init_tpccs_1[];
+extern const struct gf100_gr_init gf100_gr_init_mpc_0[];
+extern const struct gf100_gr_init gf100_gr_init_be_0[];
+extern const struct gf100_gr_init gf100_gr_init_fe_1[];
+extern const struct gf100_gr_init gf100_gr_init_pe_1[];
+
+extern const struct gf100_gr_init gf104_gr_init_ds_0[];
+extern const struct gf100_gr_init gf104_gr_init_tex_0[];
+extern const struct gf100_gr_init gf104_gr_init_sm_0[];
+
+extern const struct gf100_gr_init gf108_gr_init_gpc_unk_0[];
+extern const struct gf100_gr_init gf108_gr_init_setup_1[];
+
+extern const struct gf100_gr_init gf119_gr_init_pd_0[];
+extern const struct gf100_gr_init gf119_gr_init_ds_0[];
+extern const struct gf100_gr_init gf119_gr_init_prop_0[];
+extern const struct gf100_gr_init gf119_gr_init_gpm_0[];
+extern const struct gf100_gr_init gf119_gr_init_gpc_unk_1[];
+extern const struct gf100_gr_init gf119_gr_init_tex_0[];
+extern const struct gf100_gr_init gf119_gr_init_sm_0[];
+extern const struct gf100_gr_init gf119_gr_init_fe_1[];
+
+extern const struct gf100_gr_init gf117_gr_init_pes_0[];
+extern const struct gf100_gr_init gf117_gr_init_wwdx_0[];
+extern const struct gf100_gr_init gf117_gr_init_cbm_0[];
+
+extern const struct gf100_gr_init gk104_gr_init_main_0[];
+extern const struct gf100_gr_init gk104_gr_init_tpccs_0[];
+extern const struct gf100_gr_init gk104_gr_init_pe_0[];
+extern const struct gf100_gr_init gk104_gr_init_be_0[];
+extern const struct gf100_gr_pack gk104_gr_pack_mmio[];
+
+extern const struct gf100_gr_init gk110_gr_init_fe_0[];
+extern const struct gf100_gr_init gk110_gr_init_ds_0[];
+extern const struct gf100_gr_init gk110_gr_init_sked_0[];
+extern const struct gf100_gr_init gk110_gr_init_cwd_0[];
+extern const struct gf100_gr_init gk110_gr_init_gpc_unk_1[];
+extern const struct gf100_gr_init gk110_gr_init_tex_0[];
+extern const struct gf100_gr_init gk110_gr_init_sm_0[];
+
+extern const struct gf100_gr_init gk208_gr_init_gpc_unk_0[];
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c
index e82e70c53132..20d3b85db3b5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c
@@ -21,16 +21,15 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include "gf100.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH register lists
******************************************************************************/
-const struct nvc0_graph_init
-nvc4_graph_init_ds_0[] = {
+const struct gf100_gr_init
+gf104_gr_init_ds_0[] = {
{ 0x405844, 1, 0x04, 0x00ffffff },
{ 0x405850, 1, 0x04, 0x00000000 },
{ 0x405900, 1, 0x04, 0x00002834 },
@@ -38,8 +37,8 @@ nvc4_graph_init_ds_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc4_graph_init_tex_0[] = {
+const struct gf100_gr_init
+gf104_gr_init_tex_0[] = {
{ 0x419ab0, 1, 0x04, 0x00000000 },
{ 0x419ac8, 1, 0x04, 0x00000000 },
{ 0x419ab8, 1, 0x04, 0x000000e7 },
@@ -47,8 +46,8 @@ nvc4_graph_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvc4_graph_init_pe_0[] = {
+static const struct gf100_gr_init
+gf104_gr_init_pe_0[] = {
{ 0x41980c, 3, 0x04, 0x00000000 },
{ 0x419844, 1, 0x04, 0x00000000 },
{ 0x41984c, 1, 0x04, 0x00005bc5 },
@@ -57,8 +56,8 @@ nvc4_graph_init_pe_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc4_graph_init_sm_0[] = {
+const struct gf100_gr_init
+gf104_gr_init_sm_0[] = {
{ 0x419e00, 1, 0x04, 0x00000000 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
{ 0x419ea4, 1, 0x04, 0x00000100 },
@@ -76,34 +75,34 @@ nvc4_graph_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc4_graph_pack_mmio[] = {
- { nvc0_graph_init_main_0 },
- { nvc0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvc0_graph_init_pd_0 },
- { nvc4_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvc0_graph_init_prop_0 },
- { nvc0_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc0_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvc0_graph_init_gpm_0 },
- { nvc0_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nvc0_graph_init_tpccs_0 },
- { nvc4_graph_init_tex_0 },
- { nvc4_graph_init_pe_0 },
- { nvc0_graph_init_l1c_0 },
- { nvc0_graph_init_wwdx_0 },
- { nvc0_graph_init_tpccs_1 },
- { nvc0_graph_init_mpc_0 },
- { nvc4_graph_init_sm_0 },
- { nvc0_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
+static const struct gf100_gr_pack
+gf104_gr_pack_mmio[] = {
+ { gf100_gr_init_main_0 },
+ { gf100_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf100_gr_init_pd_0 },
+ { gf104_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gf100_gr_init_prop_0 },
+ { gf100_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf100_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf100_gr_init_gpm_0 },
+ { gf100_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gf100_gr_init_tpccs_0 },
+ { gf104_gr_init_tex_0 },
+ { gf104_gr_init_pe_0 },
+ { gf100_gr_init_l1c_0 },
+ { gf100_gr_init_wwdx_0 },
+ { gf100_gr_init_tpccs_1 },
+ { gf100_gr_init_mpc_0 },
+ { gf104_gr_init_sm_0 },
+ { gf100_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
{}
};
@@ -111,18 +110,18 @@ nvc4_graph_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
-struct nouveau_oclass *
-nvc4_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gf104_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xc3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nvc0_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gf100_gr_init,
+ .fini = _nvkm_gr_fini,
},
- .cclass = &nvc4_grctx_oclass,
- .sclass = nvc0_graph_sclass,
- .mmio = nvc4_graph_pack_mmio,
- .fecs.ucode = &nvc0_graph_fecs_ucode,
- .gpccs.ucode = &nvc0_graph_gpccs_ucode,
+ .cclass = &gf104_grctx_oclass,
+ .sclass = gf100_gr_sclass,
+ .mmio = gf104_gr_pack_mmio,
+ .fecs.ucode = &gf100_gr_fecs_ucode,
+ .gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
index 93d58e5b82c2..5362c8176e64 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
@@ -21,21 +21,22 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "gf100.h"
+#include "ctxgf100.h"
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include <nvif/class.h>
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-nvc1_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0x9039, &nouveau_object_ofuncs },
- { FERMI_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { FERMI_B, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { FERMI_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds },
+static struct nvkm_oclass
+gf108_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0x9039, &nvkm_object_ofuncs },
+ { FERMI_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { FERMI_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { FERMI_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
{}
};
@@ -43,8 +44,8 @@ nvc1_graph_sclass[] = {
* PGRAPH register lists
******************************************************************************/
-const struct nvc0_graph_init
-nvc1_graph_init_gpc_unk_0[] = {
+const struct gf100_gr_init
+gf108_gr_init_gpc_unk_0[] = {
{ 0x418604, 1, 0x04, 0x00000000 },
{ 0x418680, 1, 0x04, 0x00000000 },
{ 0x418714, 1, 0x04, 0x00000000 },
@@ -52,16 +53,16 @@ nvc1_graph_init_gpc_unk_0[] = {
{}
};
-const struct nvc0_graph_init
-nvc1_graph_init_setup_1[] = {
+const struct gf100_gr_init
+gf108_gr_init_setup_1[] = {
{ 0x4188c8, 2, 0x04, 0x00000000 },
{ 0x4188d0, 1, 0x04, 0x00010000 },
{ 0x4188d4, 1, 0x04, 0x00000001 },
{}
};
-static const struct nvc0_graph_init
-nvc1_graph_init_gpc_unk_1[] = {
+static const struct gf100_gr_init
+gf108_gr_init_gpc_unk_1[] = {
{ 0x418d00, 1, 0x04, 0x00000000 },
{ 0x418f08, 1, 0x04, 0x00000000 },
{ 0x418e00, 1, 0x04, 0x00000003 },
@@ -69,8 +70,8 @@ nvc1_graph_init_gpc_unk_1[] = {
{}
};
-static const struct nvc0_graph_init
-nvc1_graph_init_pe_0[] = {
+static const struct gf100_gr_init
+gf108_gr_init_pe_0[] = {
{ 0x41980c, 1, 0x04, 0x00000010 },
{ 0x419810, 1, 0x04, 0x00000000 },
{ 0x419814, 1, 0x04, 0x00000004 },
@@ -81,34 +82,34 @@ nvc1_graph_init_pe_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc1_graph_pack_mmio[] = {
- { nvc0_graph_init_main_0 },
- { nvc0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvc0_graph_init_pd_0 },
- { nvc4_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvc0_graph_init_prop_0 },
- { nvc1_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc1_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvc0_graph_init_gpm_0 },
- { nvc1_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nvc0_graph_init_tpccs_0 },
- { nvc4_graph_init_tex_0 },
- { nvc1_graph_init_pe_0 },
- { nvc0_graph_init_l1c_0 },
- { nvc0_graph_init_wwdx_0 },
- { nvc0_graph_init_tpccs_1 },
- { nvc0_graph_init_mpc_0 },
- { nvc4_graph_init_sm_0 },
- { nvc0_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
+static const struct gf100_gr_pack
+gf108_gr_pack_mmio[] = {
+ { gf100_gr_init_main_0 },
+ { gf100_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf100_gr_init_pd_0 },
+ { gf104_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gf100_gr_init_prop_0 },
+ { gf108_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf108_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf100_gr_init_gpm_0 },
+ { gf108_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gf100_gr_init_tpccs_0 },
+ { gf104_gr_init_tex_0 },
+ { gf108_gr_init_pe_0 },
+ { gf100_gr_init_l1c_0 },
+ { gf100_gr_init_wwdx_0 },
+ { gf100_gr_init_tpccs_1 },
+ { gf100_gr_init_mpc_0 },
+ { gf104_gr_init_sm_0 },
+ { gf100_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
{}
};
@@ -116,18 +117,18 @@ nvc1_graph_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
-struct nouveau_oclass *
-nvc1_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gf108_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xc1),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nvc0_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gf100_gr_init,
+ .fini = _nvkm_gr_fini,
},
- .cclass = &nvc1_grctx_oclass,
- .sclass = nvc1_graph_sclass,
- .mmio = nvc1_graph_pack_mmio,
- .fecs.ucode = &nvc0_graph_fecs_ucode,
- .gpccs.ucode = &nvc0_graph_gpccs_ucode,
+ .cclass = &gf108_grctx_oclass,
+ .sclass = gf108_gr_sclass,
+ .mmio = gf108_gr_pack_mmio,
+ .fecs.ucode = &gf100_gr_fecs_ucode,
+ .gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
index 692e1eda0eb4..88beb491b7b8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
@@ -21,22 +21,23 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "gf100.h"
+#include "ctxgf100.h"
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include <nvif/class.h>
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-struct nouveau_oclass
-nvc8_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0x9039, &nouveau_object_ofuncs },
- { FERMI_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { FERMI_B, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { FERMI_C, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { FERMI_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds },
+struct nvkm_oclass
+gf110_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0x9039, &nvkm_object_ofuncs },
+ { FERMI_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { FERMI_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { FERMI_C, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { FERMI_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
{}
};
@@ -44,8 +45,8 @@ nvc8_graph_sclass[] = {
* PGRAPH register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvc8_graph_init_sm_0[] = {
+static const struct gf100_gr_init
+gf110_gr_init_sm_0[] = {
{ 0x419e00, 1, 0x04, 0x00000000 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
{ 0x419ea4, 1, 0x04, 0x00000100 },
@@ -62,35 +63,35 @@ nvc8_graph_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvc8_graph_pack_mmio[] = {
- { nvc0_graph_init_main_0 },
- { nvc0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvc0_graph_init_pd_0 },
- { nvc0_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvc0_graph_init_prop_0 },
- { nvc0_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc1_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvc0_graph_init_gpm_0 },
- { nvc0_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nvc0_graph_init_tpccs_0 },
- { nvc0_graph_init_tex_0 },
- { nvc0_graph_init_pe_0 },
- { nvc0_graph_init_l1c_0 },
- { nvc0_graph_init_wwdx_0 },
- { nvc0_graph_init_tpccs_1 },
- { nvc0_graph_init_mpc_0 },
- { nvc8_graph_init_sm_0 },
- { nvc0_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
- { nvc0_graph_init_pe_1 },
+static const struct gf100_gr_pack
+gf110_gr_pack_mmio[] = {
+ { gf100_gr_init_main_0 },
+ { gf100_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf100_gr_init_pd_0 },
+ { gf100_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gf100_gr_init_prop_0 },
+ { gf100_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf108_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf100_gr_init_gpm_0 },
+ { gf100_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gf100_gr_init_tpccs_0 },
+ { gf100_gr_init_tex_0 },
+ { gf100_gr_init_pe_0 },
+ { gf100_gr_init_l1c_0 },
+ { gf100_gr_init_wwdx_0 },
+ { gf100_gr_init_tpccs_1 },
+ { gf100_gr_init_mpc_0 },
+ { gf110_gr_init_sm_0 },
+ { gf100_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
+ { gf100_gr_init_pe_1 },
{}
};
@@ -98,18 +99,18 @@ nvc8_graph_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
-struct nouveau_oclass *
-nvc8_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gf110_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xc8),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nvc0_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gf100_gr_init,
+ .fini = _nvkm_gr_fini,
},
- .cclass = &nvc8_grctx_oclass,
- .sclass = nvc8_graph_sclass,
- .mmio = nvc8_graph_pack_mmio,
- .fecs.ucode = &nvc0_graph_fecs_ucode,
- .gpccs.ucode = &nvc0_graph_gpccs_ucode,
+ .cclass = &gf110_grctx_oclass,
+ .sclass = gf110_gr_sclass,
+ .mmio = gf110_gr_pack_mmio,
+ .fecs.ucode = &gf100_gr_fecs_ucode,
+ .gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
index 41e8445c7eea..871ac5f806f6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
@@ -21,16 +21,15 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include "gf100.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nvd7_graph_init_pe_0[] = {
+static const struct gf100_gr_init
+gf117_gr_init_pe_0[] = {
{ 0x41980c, 1, 0x04, 0x00000010 },
{ 0x419844, 1, 0x04, 0x00000000 },
{ 0x41984c, 1, 0x04, 0x00005bc8 },
@@ -38,8 +37,8 @@ nvd7_graph_init_pe_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd7_graph_init_pes_0[] = {
+const struct gf100_gr_init
+gf117_gr_init_pes_0[] = {
{ 0x41be04, 1, 0x04, 0x00000000 },
{ 0x41be08, 1, 0x04, 0x00000004 },
{ 0x41be0c, 1, 0x04, 0x00000000 },
@@ -48,50 +47,50 @@ nvd7_graph_init_pes_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd7_graph_init_wwdx_0[] = {
+const struct gf100_gr_init
+gf117_gr_init_wwdx_0[] = {
{ 0x41bfd4, 1, 0x04, 0x00800000 },
{ 0x41bfdc, 1, 0x04, 0x00000000 },
{ 0x41bff8, 2, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvd7_graph_init_cbm_0[] = {
+const struct gf100_gr_init
+gf117_gr_init_cbm_0[] = {
{ 0x41becc, 1, 0x04, 0x00000000 },
{ 0x41bee8, 2, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_pack
-nvd7_graph_pack_mmio[] = {
- { nvc0_graph_init_main_0 },
- { nvc0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvd9_graph_init_pd_0 },
- { nvd9_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvd9_graph_init_prop_0 },
- { nvc1_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc1_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvd9_graph_init_gpm_0 },
- { nvd9_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nvc0_graph_init_tpccs_0 },
- { nvd9_graph_init_tex_0 },
- { nvd7_graph_init_pe_0 },
- { nvc0_graph_init_l1c_0 },
- { nvc0_graph_init_mpc_0 },
- { nvd9_graph_init_sm_0 },
- { nvd7_graph_init_pes_0 },
- { nvd7_graph_init_wwdx_0 },
- { nvd7_graph_init_cbm_0 },
- { nvc0_graph_init_be_0 },
- { nvd9_graph_init_fe_1 },
+static const struct gf100_gr_pack
+gf117_gr_pack_mmio[] = {
+ { gf100_gr_init_main_0 },
+ { gf100_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf119_gr_init_pd_0 },
+ { gf119_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gf119_gr_init_prop_0 },
+ { gf108_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf108_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf119_gr_init_gpm_0 },
+ { gf119_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gf100_gr_init_tpccs_0 },
+ { gf119_gr_init_tex_0 },
+ { gf117_gr_init_pe_0 },
+ { gf100_gr_init_l1c_0 },
+ { gf100_gr_init_mpc_0 },
+ { gf119_gr_init_sm_0 },
+ { gf117_gr_init_pes_0 },
+ { gf117_gr_init_wwdx_0 },
+ { gf117_gr_init_cbm_0 },
+ { gf100_gr_init_be_0 },
+ { gf119_gr_init_fe_1 },
{}
};
@@ -99,39 +98,39 @@ nvd7_graph_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
-#include "fuc/hubnvd7.fuc.h"
+#include "fuc/hubgf117.fuc3.h"
-struct nvc0_graph_ucode
-nvd7_graph_fecs_ucode = {
- .code.data = nvd7_grhub_code,
- .code.size = sizeof(nvd7_grhub_code),
- .data.data = nvd7_grhub_data,
- .data.size = sizeof(nvd7_grhub_data),
+struct gf100_gr_ucode
+gf117_gr_fecs_ucode = {
+ .code.data = gf117_grhub_code,
+ .code.size = sizeof(gf117_grhub_code),
+ .data.data = gf117_grhub_data,
+ .data.size = sizeof(gf117_grhub_data),
};
-#include "fuc/gpcnvd7.fuc.h"
+#include "fuc/gpcgf117.fuc3.h"
-struct nvc0_graph_ucode
-nvd7_graph_gpccs_ucode = {
- .code.data = nvd7_grgpc_code,
- .code.size = sizeof(nvd7_grgpc_code),
- .data.data = nvd7_grgpc_data,
- .data.size = sizeof(nvd7_grgpc_data),
+struct gf100_gr_ucode
+gf117_gr_gpccs_ucode = {
+ .code.data = gf117_grgpc_code,
+ .code.size = sizeof(gf117_grgpc_code),
+ .data.data = gf117_grgpc_data,
+ .data.size = sizeof(gf117_grgpc_data),
};
-struct nouveau_oclass *
-nvd7_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gf117_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xd7),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nvc0_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gf100_gr_init,
+ .fini = _nvkm_gr_fini,
},
- .cclass = &nvd7_grctx_oclass,
- .sclass = nvc8_graph_sclass,
- .mmio = nvd7_graph_pack_mmio,
- .fecs.ucode = &nvd7_graph_fecs_ucode,
- .gpccs.ucode = &nvd7_graph_gpccs_ucode,
+ .cclass = &gf117_grctx_oclass,
+ .sclass = gf110_gr_sclass,
+ .mmio = gf117_gr_pack_mmio,
+ .fecs.ucode = &gf117_gr_fecs_ucode,
+ .gpccs.ucode = &gf117_gr_gpccs_ucode,
.ppc_nr = 1,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
index 00fdf202fb92..e6dd651e2636 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
@@ -21,23 +21,22 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include "gf100.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH register lists
******************************************************************************/
-const struct nvc0_graph_init
-nvd9_graph_init_pd_0[] = {
+const struct gf100_gr_init
+gf119_gr_init_pd_0[] = {
{ 0x406024, 1, 0x04, 0x00000000 },
{ 0x4064f0, 3, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvd9_graph_init_ds_0[] = {
+const struct gf100_gr_init
+gf119_gr_init_ds_0[] = {
{ 0x405844, 1, 0x04, 0x00ffffff },
{ 0x405850, 1, 0x04, 0x00000000 },
{ 0x405900, 1, 0x04, 0x00002834 },
@@ -46,15 +45,15 @@ nvd9_graph_init_ds_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_graph_init_prop_0[] = {
+const struct gf100_gr_init
+gf119_gr_init_prop_0[] = {
{ 0x418408, 1, 0x04, 0x00000000 },
{ 0x4184a0, 3, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvd9_graph_init_gpm_0[] = {
+const struct gf100_gr_init
+gf119_gr_init_gpm_0[] = {
{ 0x418c04, 1, 0x04, 0x00000000 },
{ 0x418c64, 2, 0x04, 0x00000000 },
{ 0x418c88, 1, 0x04, 0x00000000 },
@@ -62,8 +61,8 @@ nvd9_graph_init_gpm_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_graph_init_gpc_unk_1[] = {
+const struct gf100_gr_init
+gf119_gr_init_gpc_unk_1[] = {
{ 0x418d00, 1, 0x04, 0x00000000 },
{ 0x418d28, 2, 0x04, 0x00000000 },
{ 0x418f00, 1, 0x04, 0x00000000 },
@@ -75,8 +74,8 @@ nvd9_graph_init_gpc_unk_1[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_graph_init_tex_0[] = {
+const struct gf100_gr_init
+gf119_gr_init_tex_0[] = {
{ 0x419ab0, 1, 0x04, 0x00000000 },
{ 0x419ac8, 1, 0x04, 0x00000000 },
{ 0x419ab8, 1, 0x04, 0x000000e7 },
@@ -85,8 +84,8 @@ nvd9_graph_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvd9_graph_init_pe_0[] = {
+static const struct gf100_gr_init
+gf119_gr_init_pe_0[] = {
{ 0x41980c, 1, 0x04, 0x00000010 },
{ 0x419810, 1, 0x04, 0x00000000 },
{ 0x419814, 1, 0x04, 0x00000004 },
@@ -97,23 +96,23 @@ nvd9_graph_init_pe_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvd9_graph_init_wwdx_0[] = {
+static const struct gf100_gr_init
+gf119_gr_init_wwdx_0[] = {
{ 0x419bd4, 1, 0x04, 0x00800000 },
{ 0x419bdc, 1, 0x04, 0x00000000 },
{ 0x419bf8, 2, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-nvd9_graph_init_tpccs_1[] = {
+static const struct gf100_gr_init
+gf119_gr_init_tpccs_1[] = {
{ 0x419d2c, 1, 0x04, 0x00000000 },
{ 0x419d48, 2, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvd9_graph_init_sm_0[] = {
+const struct gf100_gr_init
+gf119_gr_init_sm_0[] = {
{ 0x419e00, 1, 0x04, 0x00000000 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
{ 0x419ea4, 1, 0x04, 0x00000100 },
@@ -131,42 +130,42 @@ nvd9_graph_init_sm_0[] = {
{}
};
-const struct nvc0_graph_init
-nvd9_graph_init_fe_1[] = {
+const struct gf100_gr_init
+gf119_gr_init_fe_1[] = {
{ 0x40402c, 1, 0x04, 0x00000000 },
{ 0x4040f0, 1, 0x04, 0x00000000 },
{ 0x404174, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_pack
-nvd9_graph_pack_mmio[] = {
- { nvc0_graph_init_main_0 },
- { nvc0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvd9_graph_init_pd_0 },
- { nvd9_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvd9_graph_init_prop_0 },
- { nvc1_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc1_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvd9_graph_init_gpm_0 },
- { nvd9_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nvc0_graph_init_tpccs_0 },
- { nvd9_graph_init_tex_0 },
- { nvd9_graph_init_pe_0 },
- { nvc0_graph_init_l1c_0 },
- { nvd9_graph_init_wwdx_0 },
- { nvd9_graph_init_tpccs_1 },
- { nvc0_graph_init_mpc_0 },
- { nvd9_graph_init_sm_0 },
- { nvc0_graph_init_be_0 },
- { nvd9_graph_init_fe_1 },
+static const struct gf100_gr_pack
+gf119_gr_pack_mmio[] = {
+ { gf100_gr_init_main_0 },
+ { gf100_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf119_gr_init_pd_0 },
+ { gf119_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gf119_gr_init_prop_0 },
+ { gf108_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf108_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf119_gr_init_gpm_0 },
+ { gf119_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gf100_gr_init_tpccs_0 },
+ { gf119_gr_init_tex_0 },
+ { gf119_gr_init_pe_0 },
+ { gf100_gr_init_l1c_0 },
+ { gf119_gr_init_wwdx_0 },
+ { gf119_gr_init_tpccs_1 },
+ { gf100_gr_init_mpc_0 },
+ { gf119_gr_init_sm_0 },
+ { gf100_gr_init_be_0 },
+ { gf119_gr_init_fe_1 },
{}
};
@@ -174,18 +173,18 @@ nvd9_graph_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
-struct nouveau_oclass *
-nvd9_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gf119_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xd9),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nvc0_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gf100_gr_init,
+ .fini = _nvkm_gr_fini,
},
- .cclass = &nvd9_grctx_oclass,
- .sclass = nvc8_graph_sclass,
- .mmio = nvd9_graph_pack_mmio,
- .fecs.ucode = &nvc0_graph_fecs_ucode,
- .gpccs.ucode = &nvc0_graph_gpccs_ucode,
+ .cclass = &gf119_grctx_oclass,
+ .sclass = gf110_gr_sclass,
+ .mmio = gf119_gr_pack_mmio,
+ .fecs.ucode = &gf100_gr_fecs_ucode,
+ .gpccs.ucode = &gf100_gr_gpccs_ucode,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
index 0c71f5c67ae0..489fdd94b885 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
@@ -21,22 +21,23 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "gf100.h"
+#include "ctxgf100.h"
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include <nvif/class.h>
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-nve4_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0xa040, &nouveau_object_ofuncs },
- { KEPLER_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { KEPLER_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds },
+static struct nvkm_oclass
+gk104_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0xa040, &nvkm_object_ofuncs },
+ { KEPLER_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { KEPLER_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
{}
};
@@ -44,8 +45,8 @@ nve4_graph_sclass[] = {
* PGRAPH register lists
******************************************************************************/
-const struct nvc0_graph_init
-nve4_graph_init_main_0[] = {
+const struct gf100_gr_init
+gk104_gr_init_main_0[] = {
{ 0x400080, 1, 0x04, 0x003083c2 },
{ 0x400088, 1, 0x04, 0x0001ffe7 },
{ 0x40008c, 1, 0x04, 0x00000000 },
@@ -60,8 +61,8 @@ nve4_graph_init_main_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_graph_init_ds_0[] = {
+static const struct gf100_gr_init
+gk104_gr_init_ds_0[] = {
{ 0x405844, 1, 0x04, 0x00ffffff },
{ 0x405850, 1, 0x04, 0x00000000 },
{ 0x405900, 1, 0x04, 0x0000ff34 },
@@ -70,20 +71,20 @@ nve4_graph_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_graph_init_sked_0[] = {
+static const struct gf100_gr_init
+gk104_gr_init_sked_0[] = {
{ 0x407010, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-nve4_graph_init_cwd_0[] = {
+static const struct gf100_gr_init
+gk104_gr_init_cwd_0[] = {
{ 0x405b50, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-nve4_graph_init_gpc_unk_1[] = {
+static const struct gf100_gr_init
+gk104_gr_init_gpc_unk_1[] = {
{ 0x418d00, 1, 0x04, 0x00000000 },
{ 0x418d28, 2, 0x04, 0x00000000 },
{ 0x418f00, 1, 0x04, 0x00000000 },
@@ -95,15 +96,15 @@ nve4_graph_init_gpc_unk_1[] = {
{}
};
-const struct nvc0_graph_init
-nve4_graph_init_tpccs_0[] = {
+const struct gf100_gr_init
+gk104_gr_init_tpccs_0[] = {
{ 0x419d0c, 1, 0x04, 0x00000000 },
{ 0x419d10, 1, 0x04, 0x00000014 },
{}
};
-const struct nvc0_graph_init
-nve4_graph_init_pe_0[] = {
+const struct gf100_gr_init
+gk104_gr_init_pe_0[] = {
{ 0x41980c, 1, 0x04, 0x00000010 },
{ 0x419844, 1, 0x04, 0x00000000 },
{ 0x419850, 1, 0x04, 0x00000004 },
@@ -111,8 +112,8 @@ nve4_graph_init_pe_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_graph_init_l1c_0[] = {
+static const struct gf100_gr_init
+gk104_gr_init_l1c_0[] = {
{ 0x419c98, 1, 0x04, 0x00000000 },
{ 0x419ca8, 1, 0x04, 0x00000000 },
{ 0x419cb0, 1, 0x04, 0x01000000 },
@@ -125,8 +126,8 @@ nve4_graph_init_l1c_0[] = {
{}
};
-static const struct nvc0_graph_init
-nve4_graph_init_sm_0[] = {
+static const struct gf100_gr_init
+gk104_gr_init_sm_0[] = {
{ 0x419e00, 1, 0x04, 0x00000000 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
{ 0x419ee4, 1, 0x04, 0x00000000 },
@@ -139,8 +140,8 @@ nve4_graph_init_sm_0[] = {
{}
};
-const struct nvc0_graph_init
-nve4_graph_init_be_0[] = {
+const struct gf100_gr_init
+gk104_gr_init_be_0[] = {
{ 0x40880c, 1, 0x04, 0x00000000 },
{ 0x408850, 1, 0x04, 0x00000004 },
{ 0x408910, 9, 0x04, 0x00000000 },
@@ -153,37 +154,37 @@ nve4_graph_init_be_0[] = {
{}
};
-const struct nvc0_graph_pack
-nve4_graph_pack_mmio[] = {
- { nve4_graph_init_main_0 },
- { nvc0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvd9_graph_init_pd_0 },
- { nve4_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nve4_graph_init_sked_0 },
- { nve4_graph_init_cwd_0 },
- { nvd9_graph_init_prop_0 },
- { nvc1_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc1_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvd9_graph_init_gpm_0 },
- { nve4_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nve4_graph_init_tpccs_0 },
- { nvd9_graph_init_tex_0 },
- { nve4_graph_init_pe_0 },
- { nve4_graph_init_l1c_0 },
- { nvc0_graph_init_mpc_0 },
- { nve4_graph_init_sm_0 },
- { nvd7_graph_init_pes_0 },
- { nvd7_graph_init_wwdx_0 },
- { nvd7_graph_init_cbm_0 },
- { nve4_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
+const struct gf100_gr_pack
+gk104_gr_pack_mmio[] = {
+ { gk104_gr_init_main_0 },
+ { gf100_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf119_gr_init_pd_0 },
+ { gk104_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gk104_gr_init_sked_0 },
+ { gk104_gr_init_cwd_0 },
+ { gf119_gr_init_prop_0 },
+ { gf108_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf108_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf119_gr_init_gpm_0 },
+ { gk104_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gk104_gr_init_tpccs_0 },
+ { gf119_gr_init_tex_0 },
+ { gk104_gr_init_pe_0 },
+ { gk104_gr_init_l1c_0 },
+ { gf100_gr_init_mpc_0 },
+ { gk104_gr_init_sm_0 },
+ { gf117_gr_init_pes_0 },
+ { gf117_gr_init_wwdx_0 },
+ { gf117_gr_init_cbm_0 },
+ { gk104_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
{}
};
@@ -192,21 +193,21 @@ nve4_graph_pack_mmio[] = {
******************************************************************************/
int
-nve4_graph_init(struct nouveau_object *object)
+gk104_gr_init(struct nvkm_object *object)
{
- struct nvc0_graph_oclass *oclass = (void *)object->oclass;
- struct nvc0_graph_priv *priv = (void *)object;
- struct nouveau_pwr *ppwr = nouveau_pwr(priv);
+ struct gf100_gr_oclass *oclass = (void *)object->oclass;
+ struct gf100_gr_priv *priv = (void *)object;
+ struct nvkm_pmu *pmu = nvkm_pmu(priv);
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
int gpc, tpc, rop;
int ret, i;
- if (ppwr)
- ppwr->pgob(ppwr, false);
+ if (pmu)
+ pmu->pgob(pmu, false);
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -219,7 +220,7 @@ nve4_graph_init(struct nouveau_object *object)
nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
- nvc0_graph_mmio(priv, oclass->mmio);
+ gf100_gr_mmio(priv, oclass->mmio);
nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
@@ -304,44 +305,44 @@ nve4_graph_init(struct nouveau_object *object)
nv_wr32(priv, 0x400054, 0x34ce3464);
- nvc0_graph_zbc_init(priv);
+ gf100_gr_zbc_init(priv);
- return nvc0_graph_init_ctxctl(priv);
+ return gf100_gr_init_ctxctl(priv);
}
-#include "fuc/hubnve0.fuc.h"
+#include "fuc/hubgk104.fuc3.h"
-static struct nvc0_graph_ucode
-nve4_graph_fecs_ucode = {
- .code.data = nve0_grhub_code,
- .code.size = sizeof(nve0_grhub_code),
- .data.data = nve0_grhub_data,
- .data.size = sizeof(nve0_grhub_data),
+static struct gf100_gr_ucode
+gk104_gr_fecs_ucode = {
+ .code.data = gk104_grhub_code,
+ .code.size = sizeof(gk104_grhub_code),
+ .data.data = gk104_grhub_data,
+ .data.size = sizeof(gk104_grhub_data),
};
-#include "fuc/gpcnve0.fuc.h"
+#include "fuc/gpcgk104.fuc3.h"
-static struct nvc0_graph_ucode
-nve4_graph_gpccs_ucode = {
- .code.data = nve0_grgpc_code,
- .code.size = sizeof(nve0_grgpc_code),
- .data.data = nve0_grgpc_data,
- .data.size = sizeof(nve0_grgpc_data),
+static struct gf100_gr_ucode
+gk104_gr_gpccs_ucode = {
+ .code.data = gk104_grgpc_code,
+ .code.size = sizeof(gk104_grgpc_code),
+ .data.data = gk104_grgpc_data,
+ .data.size = sizeof(gk104_grgpc_data),
};
-struct nouveau_oclass *
-nve4_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gk104_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xe4),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nve4_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gk104_gr_init,
+ .fini = _nvkm_gr_fini,
},
- .cclass = &nve4_grctx_oclass,
- .sclass = nve4_graph_sclass,
- .mmio = nve4_graph_pack_mmio,
- .fecs.ucode = &nve4_graph_fecs_ucode,
- .gpccs.ucode = &nve4_graph_gpccs_ucode,
+ .cclass = &gk104_grctx_oclass,
+ .sclass = gk104_gr_sclass,
+ .mmio = gk104_gr_pack_mmio,
+ .fecs.ucode = &gk104_gr_fecs_ucode,
+ .gpccs.ucode = &gk104_gr_gpccs_ucode,
.ppc_nr = 1,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
index c306c0f2fc84..78e03ab1608e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
@@ -21,20 +21,23 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "gf100.h"
+#include "ctxgf100.h"
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include <subdev/timer.h>
+
+#include <nvif/class.h>
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-struct nouveau_oclass
-nvf0_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0xa140, &nouveau_object_ofuncs },
- { KEPLER_B, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { KEPLER_COMPUTE_B, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds },
+struct nvkm_oclass
+gk110_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0xa140, &nvkm_object_ofuncs },
+ { KEPLER_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { KEPLER_COMPUTE_B, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
{}
};
@@ -42,16 +45,16 @@ nvf0_graph_sclass[] = {
* PGRAPH register lists
******************************************************************************/
-const struct nvc0_graph_init
-nvf0_graph_init_fe_0[] = {
+const struct gf100_gr_init
+gk110_gr_init_fe_0[] = {
{ 0x40415c, 1, 0x04, 0x00000000 },
{ 0x404170, 1, 0x04, 0x00000000 },
{ 0x4041b4, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvf0_graph_init_ds_0[] = {
+const struct gf100_gr_init
+gk110_gr_init_ds_0[] = {
{ 0x405844, 1, 0x04, 0x00ffffff },
{ 0x405850, 1, 0x04, 0x00000000 },
{ 0x405900, 1, 0x04, 0x0000ff00 },
@@ -60,23 +63,23 @@ nvf0_graph_init_ds_0[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_graph_init_sked_0[] = {
+const struct gf100_gr_init
+gk110_gr_init_sked_0[] = {
{ 0x407010, 1, 0x04, 0x00000000 },
{ 0x407040, 1, 0x04, 0x80440424 },
{ 0x407048, 1, 0x04, 0x0000000a },
{}
};
-const struct nvc0_graph_init
-nvf0_graph_init_cwd_0[] = {
+const struct gf100_gr_init
+gk110_gr_init_cwd_0[] = {
{ 0x405b44, 1, 0x04, 0x00000000 },
{ 0x405b50, 1, 0x04, 0x00000000 },
{}
};
-const struct nvc0_graph_init
-nvf0_graph_init_gpc_unk_1[] = {
+const struct gf100_gr_init
+gk110_gr_init_gpc_unk_1[] = {
{ 0x418d00, 1, 0x04, 0x00000000 },
{ 0x418d28, 2, 0x04, 0x00000000 },
{ 0x418f00, 1, 0x04, 0x00000400 },
@@ -88,8 +91,8 @@ nvf0_graph_init_gpc_unk_1[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_graph_init_tex_0[] = {
+const struct gf100_gr_init
+gk110_gr_init_tex_0[] = {
{ 0x419ab0, 1, 0x04, 0x00000000 },
{ 0x419ac8, 1, 0x04, 0x00000000 },
{ 0x419ab8, 1, 0x04, 0x000000e7 },
@@ -100,8 +103,8 @@ nvf0_graph_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nvf0_graph_init_l1c_0[] = {
+static const struct gf100_gr_init
+gk110_gr_init_l1c_0[] = {
{ 0x419c98, 1, 0x04, 0x00000000 },
{ 0x419ca8, 1, 0x04, 0x00000000 },
{ 0x419cb0, 1, 0x04, 0x01000000 },
@@ -115,8 +118,8 @@ nvf0_graph_init_l1c_0[] = {
{}
};
-const struct nvc0_graph_init
-nvf0_graph_init_sm_0[] = {
+const struct gf100_gr_init
+gk110_gr_init_sm_0[] = {
{ 0x419e00, 1, 0x04, 0x00000080 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
{ 0x419ee4, 1, 0x04, 0x00000000 },
@@ -132,37 +135,37 @@ nvf0_graph_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nvf0_graph_pack_mmio[] = {
- { nve4_graph_init_main_0 },
- { nvf0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvd9_graph_init_pd_0 },
- { nvf0_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvf0_graph_init_sked_0 },
- { nvf0_graph_init_cwd_0 },
- { nvd9_graph_init_prop_0 },
- { nvc1_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc1_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvd9_graph_init_gpm_0 },
- { nvf0_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nve4_graph_init_tpccs_0 },
- { nvf0_graph_init_tex_0 },
- { nve4_graph_init_pe_0 },
- { nvf0_graph_init_l1c_0 },
- { nvc0_graph_init_mpc_0 },
- { nvf0_graph_init_sm_0 },
- { nvd7_graph_init_pes_0 },
- { nvd7_graph_init_wwdx_0 },
- { nvd7_graph_init_cbm_0 },
- { nve4_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
+static const struct gf100_gr_pack
+gk110_gr_pack_mmio[] = {
+ { gk104_gr_init_main_0 },
+ { gk110_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf119_gr_init_pd_0 },
+ { gk110_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gk110_gr_init_sked_0 },
+ { gk110_gr_init_cwd_0 },
+ { gf119_gr_init_prop_0 },
+ { gf108_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf108_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf119_gr_init_gpm_0 },
+ { gk110_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gk104_gr_init_tpccs_0 },
+ { gk110_gr_init_tex_0 },
+ { gk104_gr_init_pe_0 },
+ { gk110_gr_init_l1c_0 },
+ { gf100_gr_init_mpc_0 },
+ { gk110_gr_init_sm_0 },
+ { gf117_gr_init_pes_0 },
+ { gf117_gr_init_wwdx_0 },
+ { gf117_gr_init_cbm_0 },
+ { gk104_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
{}
};
@@ -171,9 +174,9 @@ nvf0_graph_pack_mmio[] = {
******************************************************************************/
int
-nvf0_graph_fini(struct nouveau_object *object, bool suspend)
+gk110_gr_fini(struct nvkm_object *object, bool suspend)
{
- struct nvc0_graph_priv *priv = (void *)object;
+ struct gf100_gr_priv *priv = (void *)object;
static const struct {
u32 addr;
u32 data;
@@ -204,42 +207,42 @@ nvf0_graph_fini(struct nouveau_object *object, bool suspend)
nv_wait(priv, magic[i].addr, 0x80000000, 0x00000000);
}
- return nouveau_graph_fini(&priv->base, suspend);
+ return nvkm_gr_fini(&priv->base, suspend);
}
-#include "fuc/hubnvf0.fuc.h"
+#include "fuc/hubgk110.fuc3.h"
-struct nvc0_graph_ucode
-nvf0_graph_fecs_ucode = {
- .code.data = nvf0_grhub_code,
- .code.size = sizeof(nvf0_grhub_code),
- .data.data = nvf0_grhub_data,
- .data.size = sizeof(nvf0_grhub_data),
+struct gf100_gr_ucode
+gk110_gr_fecs_ucode = {
+ .code.data = gk110_grhub_code,
+ .code.size = sizeof(gk110_grhub_code),
+ .data.data = gk110_grhub_data,
+ .data.size = sizeof(gk110_grhub_data),
};
-#include "fuc/gpcnvf0.fuc.h"
+#include "fuc/gpcgk110.fuc3.h"
-struct nvc0_graph_ucode
-nvf0_graph_gpccs_ucode = {
- .code.data = nvf0_grgpc_code,
- .code.size = sizeof(nvf0_grgpc_code),
- .data.data = nvf0_grgpc_data,
- .data.size = sizeof(nvf0_grgpc_data),
+struct gf100_gr_ucode
+gk110_gr_gpccs_ucode = {
+ .code.data = gk110_grgpc_code,
+ .code.size = sizeof(gk110_grgpc_code),
+ .data.data = gk110_grgpc_data,
+ .data.size = sizeof(gk110_grgpc_data),
};
-struct nouveau_oclass *
-nvf0_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gk110_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xf0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nve4_graph_init,
- .fini = nvf0_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gk104_gr_init,
+ .fini = gk110_gr_fini,
},
- .cclass = &nvf0_grctx_oclass,
- .sclass = nvf0_graph_sclass,
- .mmio = nvf0_graph_pack_mmio,
- .fecs.ucode = &nvf0_graph_fecs_ucode,
- .gpccs.ucode = &nvf0_graph_gpccs_ucode,
+ .cclass = &gk110_grctx_oclass,
+ .sclass = gk110_gr_sclass,
+ .mmio = gk110_gr_pack_mmio,
+ .fecs.ucode = &gk110_gr_fecs_ucode,
+ .gpccs.ucode = &gk110_gr_gpccs_ucode,
.ppc_nr = 2,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c
index d07b19dc168d..5292c5a9a38c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/gk110b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c
@@ -21,16 +21,15 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include "gf100.h"
+#include "ctxgf100.h"
/*******************************************************************************
* PGRAPH register lists
******************************************************************************/
-static const struct nvc0_graph_init
-gk110b_graph_init_l1c_0[] = {
+static const struct gf100_gr_init
+gk110b_gr_init_l1c_0[] = {
{ 0x419c98, 1, 0x04, 0x00000000 },
{ 0x419ca8, 1, 0x04, 0x00000000 },
{ 0x419cb0, 1, 0x04, 0x09000000 },
@@ -44,8 +43,8 @@ gk110b_graph_init_l1c_0[] = {
{}
};
-static const struct nvc0_graph_init
-gk110b_graph_init_sm_0[] = {
+static const struct gf100_gr_init
+gk110b_gr_init_sm_0[] = {
{ 0x419e00, 1, 0x04, 0x00000080 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
{ 0x419ee4, 1, 0x04, 0x00000000 },
@@ -61,37 +60,37 @@ gk110b_graph_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_pack
-gk110b_graph_pack_mmio[] = {
- { nve4_graph_init_main_0 },
- { nvf0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvd9_graph_init_pd_0 },
- { nvf0_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvf0_graph_init_sked_0 },
- { nvf0_graph_init_cwd_0 },
- { nvd9_graph_init_prop_0 },
- { nvc1_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nvc1_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvd9_graph_init_gpm_0 },
- { nvf0_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nve4_graph_init_tpccs_0 },
- { nvf0_graph_init_tex_0 },
- { nve4_graph_init_pe_0 },
- { gk110b_graph_init_l1c_0 },
- { nvc0_graph_init_mpc_0 },
- { gk110b_graph_init_sm_0 },
- { nvd7_graph_init_pes_0 },
- { nvd7_graph_init_wwdx_0 },
- { nvd7_graph_init_cbm_0 },
- { nve4_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
+static const struct gf100_gr_pack
+gk110b_gr_pack_mmio[] = {
+ { gk104_gr_init_main_0 },
+ { gk110_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf119_gr_init_pd_0 },
+ { gk110_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gk110_gr_init_sked_0 },
+ { gk110_gr_init_cwd_0 },
+ { gf119_gr_init_prop_0 },
+ { gf108_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gf108_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf119_gr_init_gpm_0 },
+ { gk110_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gk104_gr_init_tpccs_0 },
+ { gk110_gr_init_tex_0 },
+ { gk104_gr_init_pe_0 },
+ { gk110b_gr_init_l1c_0 },
+ { gf100_gr_init_mpc_0 },
+ { gk110b_gr_init_sm_0 },
+ { gf117_gr_init_pes_0 },
+ { gf117_gr_init_wwdx_0 },
+ { gf117_gr_init_cbm_0 },
+ { gk104_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
{}
};
@@ -99,19 +98,19 @@ gk110b_graph_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
-struct nouveau_oclass *
-gk110b_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gk110b_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xf1),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nve4_graph_init,
- .fini = nvf0_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gk104_gr_init,
+ .fini = gk110_gr_fini,
},
.cclass = &gk110b_grctx_oclass,
- .sclass = nvf0_graph_sclass,
- .mmio = gk110b_graph_pack_mmio,
- .fecs.ucode = &nvf0_graph_fecs_ucode,
- .gpccs.ucode = &nvf0_graph_gpccs_ucode,
+ .sclass = gk110_gr_sclass,
+ .mmio = gk110b_gr_pack_mmio,
+ .fecs.ucode = &gk110_gr_fecs_ucode,
+ .gpccs.ucode = &gk110_gr_gpccs_ucode,
.ppc_nr = 2,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c
index 2b0e8f48c029..ae6b853173b6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c
@@ -21,20 +21,23 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "gf100.h"
+#include "ctxgf100.h"
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include <subdev/timer.h>
+
+#include <nvif/class.h>
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-nv108_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0xa140, &nouveau_object_ofuncs },
- { KEPLER_B, &nvc0_fermi_ofuncs },
- { 0xa1c0, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+gk208_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0xa140, &nvkm_object_ofuncs },
+ { KEPLER_B, &gf100_fermi_ofuncs },
+ { 0xa1c0, &nvkm_object_ofuncs },
{}
};
@@ -42,8 +45,8 @@ nv108_graph_sclass[] = {
* PGRAPH register lists
******************************************************************************/
-static const struct nvc0_graph_init
-nv108_graph_init_main_0[] = {
+static const struct gf100_gr_init
+gk208_gr_init_main_0[] = {
{ 0x400080, 1, 0x04, 0x003083c2 },
{ 0x400088, 1, 0x04, 0x0001bfe7 },
{ 0x40008c, 1, 0x04, 0x00000000 },
@@ -58,8 +61,8 @@ nv108_graph_init_main_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_graph_init_ds_0[] = {
+static const struct gf100_gr_init
+gk208_gr_init_ds_0[] = {
{ 0x405844, 1, 0x04, 0x00ffffff },
{ 0x405850, 1, 0x04, 0x00000000 },
{ 0x405900, 1, 0x04, 0x00000000 },
@@ -68,8 +71,8 @@ nv108_graph_init_ds_0[] = {
{}
};
-const struct nvc0_graph_init
-nv108_graph_init_gpc_unk_0[] = {
+const struct gf100_gr_init
+gk208_gr_init_gpc_unk_0[] = {
{ 0x418604, 1, 0x04, 0x00000000 },
{ 0x418680, 1, 0x04, 0x00000000 },
{ 0x418714, 1, 0x04, 0x00000000 },
@@ -77,16 +80,16 @@ nv108_graph_init_gpc_unk_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_graph_init_setup_1[] = {
+static const struct gf100_gr_init
+gk208_gr_init_setup_1[] = {
{ 0x4188c8, 2, 0x04, 0x00000000 },
{ 0x4188d0, 1, 0x04, 0x00010000 },
{ 0x4188d4, 1, 0x04, 0x00000201 },
{}
};
-static const struct nvc0_graph_init
-nv108_graph_init_tex_0[] = {
+static const struct gf100_gr_init
+gk208_gr_init_tex_0[] = {
{ 0x419ab0, 1, 0x04, 0x00000000 },
{ 0x419ac8, 1, 0x04, 0x00000000 },
{ 0x419ab8, 1, 0x04, 0x000000e7 },
@@ -96,8 +99,8 @@ nv108_graph_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-nv108_graph_init_l1c_0[] = {
+static const struct gf100_gr_init
+gk208_gr_init_l1c_0[] = {
{ 0x419c98, 1, 0x04, 0x00000000 },
{ 0x419ca8, 1, 0x04, 0x00000000 },
{ 0x419cb0, 1, 0x04, 0x01000000 },
@@ -111,37 +114,37 @@ nv108_graph_init_l1c_0[] = {
{}
};
-static const struct nvc0_graph_pack
-nv108_graph_pack_mmio[] = {
- { nv108_graph_init_main_0 },
- { nvf0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvd9_graph_init_pd_0 },
- { nv108_graph_init_ds_0 },
- { nvc0_graph_init_scc_0 },
- { nvf0_graph_init_sked_0 },
- { nvf0_graph_init_cwd_0 },
- { nvd9_graph_init_prop_0 },
- { nv108_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { nv108_graph_init_setup_1 },
- { nvc0_graph_init_zcull_0 },
- { nvd9_graph_init_gpm_0 },
- { nvf0_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { nve4_graph_init_tpccs_0 },
- { nv108_graph_init_tex_0 },
- { nve4_graph_init_pe_0 },
- { nv108_graph_init_l1c_0 },
- { nvc0_graph_init_mpc_0 },
- { nvf0_graph_init_sm_0 },
- { nvd7_graph_init_pes_0 },
- { nvd7_graph_init_wwdx_0 },
- { nvd7_graph_init_cbm_0 },
- { nve4_graph_init_be_0 },
- { nvc0_graph_init_fe_1 },
+static const struct gf100_gr_pack
+gk208_gr_pack_mmio[] = {
+ { gk208_gr_init_main_0 },
+ { gk110_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf119_gr_init_pd_0 },
+ { gk208_gr_init_ds_0 },
+ { gf100_gr_init_scc_0 },
+ { gk110_gr_init_sked_0 },
+ { gk110_gr_init_cwd_0 },
+ { gf119_gr_init_prop_0 },
+ { gk208_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gk208_gr_init_setup_1 },
+ { gf100_gr_init_zcull_0 },
+ { gf119_gr_init_gpm_0 },
+ { gk110_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gk104_gr_init_tpccs_0 },
+ { gk208_gr_init_tex_0 },
+ { gk104_gr_init_pe_0 },
+ { gk208_gr_init_l1c_0 },
+ { gf100_gr_init_mpc_0 },
+ { gk110_gr_init_sm_0 },
+ { gf117_gr_init_pes_0 },
+ { gf117_gr_init_wwdx_0 },
+ { gf117_gr_init_cbm_0 },
+ { gk104_gr_init_be_0 },
+ { gf100_gr_init_fe_1 },
{}
};
@@ -150,9 +153,9 @@ nv108_graph_pack_mmio[] = {
******************************************************************************/
static int
-nv108_graph_fini(struct nouveau_object *object, bool suspend)
+gk208_gr_fini(struct nvkm_object *object, bool suspend)
{
- struct nvc0_graph_priv *priv = (void *)object;
+ struct gf100_gr_priv *priv = (void *)object;
static const struct {
u32 addr;
u32 data;
@@ -183,42 +186,42 @@ nv108_graph_fini(struct nouveau_object *object, bool suspend)
nv_wait(priv, magic[i].addr, 0x80000000, 0x00000000);
}
- return nouveau_graph_fini(&priv->base, suspend);
+ return nvkm_gr_fini(&priv->base, suspend);
}
-#include "fuc/hubnv108.fuc5.h"
+#include "fuc/hubgk208.fuc5.h"
-static struct nvc0_graph_ucode
-nv108_graph_fecs_ucode = {
- .code.data = nv108_grhub_code,
- .code.size = sizeof(nv108_grhub_code),
- .data.data = nv108_grhub_data,
- .data.size = sizeof(nv108_grhub_data),
+static struct gf100_gr_ucode
+gk208_gr_fecs_ucode = {
+ .code.data = gk208_grhub_code,
+ .code.size = sizeof(gk208_grhub_code),
+ .data.data = gk208_grhub_data,
+ .data.size = sizeof(gk208_grhub_data),
};
-#include "fuc/gpcnv108.fuc5.h"
+#include "fuc/gpcgk208.fuc5.h"
-static struct nvc0_graph_ucode
-nv108_graph_gpccs_ucode = {
- .code.data = nv108_grgpc_code,
- .code.size = sizeof(nv108_grgpc_code),
- .data.data = nv108_grgpc_data,
- .data.size = sizeof(nv108_grgpc_data),
+static struct gf100_gr_ucode
+gk208_gr_gpccs_ucode = {
+ .code.data = gk208_grgpc_code,
+ .code.size = sizeof(gk208_grgpc_code),
+ .data.data = gk208_grgpc_data,
+ .data.size = sizeof(gk208_grgpc_data),
};
-struct nouveau_oclass *
-nv108_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gk208_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0x08),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nve4_graph_init,
- .fini = nv108_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gk104_gr_init,
+ .fini = gk208_gr_fini,
},
- .cclass = &nv108_grctx_oclass,
- .sclass = nv108_graph_sclass,
- .mmio = nv108_graph_pack_mmio,
- .fecs.ucode = &nv108_graph_fecs_ucode,
- .gpccs.ucode = &nv108_graph_gpccs_ucode,
+ .cclass = &gk208_grctx_oclass,
+ .sclass = gk208_gr_sclass,
+ .mmio = gk208_gr_pack_mmio,
+ .fecs.ucode = &gk208_gr_fecs_ucode,
+ .gpccs.ucode = &gk208_gr_gpccs_ucode,
.ppc_nr = 1,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
index 7d0abe9f3fe7..213755534084 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
@@ -19,30 +19,31 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+#include "gf100.h"
+#include "ctxgf100.h"
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include <nvif/class.h>
-static struct nouveau_oclass
-gk20a_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0xa040, &nouveau_object_ofuncs },
- { KEPLER_C, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { KEPLER_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds },
+static struct nvkm_oclass
+gk20a_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0xa040, &nvkm_object_ofuncs },
+ { KEPLER_C, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { KEPLER_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
{}
};
-struct nouveau_oclass *
-gk20a_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gk20a_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0xea),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = nve4_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gk104_gr_init,
+ .fini = _nvkm_gr_fini,
},
.cclass = &gk20a_grctx_oclass,
- .sclass = gk20a_graph_sclass,
- .mmio = nve4_graph_pack_mmio,
+ .sclass = gk20a_gr_sclass,
+ .mmio = gk104_gr_pack_mmio,
.ppc_nr = 1,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
index 4bdbdab2fd9a..124492b8a2d6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
@@ -21,23 +21,24 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
+#include "gf100.h"
+#include "ctxgf100.h"
#include <subdev/bios.h>
#include <subdev/bios/P0260.h>
-#include "nvc0.h"
-#include "ctxnvc0.h"
+#include <nvif/class.h>
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-gm107_graph_sclass[] = {
- { 0x902d, &nouveau_object_ofuncs },
- { 0xa140, &nouveau_object_ofuncs },
- { MAXWELL_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds },
- { MAXWELL_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds },
+static struct nvkm_oclass
+gm107_gr_sclass[] = {
+ { 0x902d, &nvkm_object_ofuncs },
+ { 0xa140, &nvkm_object_ofuncs },
+ { MAXWELL_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
+ { MAXWELL_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
{}
};
@@ -45,8 +46,8 @@ gm107_graph_sclass[] = {
* PGRAPH register lists
******************************************************************************/
-static const struct nvc0_graph_init
-gm107_graph_init_main_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_main_0[] = {
{ 0x400080, 1, 0x04, 0x003003c2 },
{ 0x400088, 1, 0x04, 0x0001bfe7 },
{ 0x40008c, 1, 0x04, 0x00060000 },
@@ -61,8 +62,8 @@ gm107_graph_init_main_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_ds_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_ds_0[] = {
{ 0x405844, 1, 0x04, 0x00ffffff },
{ 0x405850, 1, 0x04, 0x00000000 },
{ 0x405900, 1, 0x04, 0x00000000 },
@@ -70,37 +71,37 @@ gm107_graph_init_ds_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_scc_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_scc_0[] = {
{ 0x40803c, 1, 0x04, 0x00000010 },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_sked_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_sked_0[] = {
{ 0x407010, 1, 0x04, 0x00000000 },
{ 0x407040, 1, 0x04, 0x40440424 },
{ 0x407048, 1, 0x04, 0x0000000a },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_prop_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_prop_0[] = {
{ 0x418408, 1, 0x04, 0x00000000 },
{ 0x4184a0, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_setup_1[] = {
+static const struct gf100_gr_init
+gm107_gr_init_setup_1[] = {
{ 0x4188c8, 2, 0x04, 0x00000000 },
{ 0x4188d0, 1, 0x04, 0x00010000 },
{ 0x4188d4, 1, 0x04, 0x00010201 },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_zcull_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_zcull_0[] = {
{ 0x418910, 1, 0x04, 0x00010001 },
{ 0x418914, 1, 0x04, 0x00000301 },
{ 0x418918, 1, 0x04, 0x00800000 },
@@ -110,8 +111,8 @@ gm107_graph_init_zcull_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_gpc_unk_1[] = {
+static const struct gf100_gr_init
+gm107_gr_init_gpc_unk_1[] = {
{ 0x418d00, 1, 0x04, 0x00000000 },
{ 0x418f00, 1, 0x04, 0x00000400 },
{ 0x418f08, 1, 0x04, 0x00000000 },
@@ -119,8 +120,8 @@ gm107_graph_init_gpc_unk_1[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_tpccs_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_tpccs_0[] = {
{ 0x419dc4, 1, 0x04, 0x00000000 },
{ 0x419dc8, 1, 0x04, 0x00000501 },
{ 0x419dd0, 1, 0x04, 0x00000000 },
@@ -133,8 +134,8 @@ gm107_graph_init_tpccs_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_tex_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_tex_0[] = {
{ 0x419ab0, 1, 0x04, 0x00000000 },
{ 0x419ab8, 1, 0x04, 0x000000e7 },
{ 0x419abc, 1, 0x04, 0x00000000 },
@@ -147,8 +148,8 @@ gm107_graph_init_tex_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_pe_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_pe_0[] = {
{ 0x419900, 1, 0x04, 0x000000ff },
{ 0x41980c, 1, 0x04, 0x00000010 },
{ 0x419844, 1, 0x04, 0x00000000 },
@@ -159,15 +160,15 @@ gm107_graph_init_pe_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_l1c_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_l1c_0[] = {
{ 0x419c98, 1, 0x04, 0x00000000 },
{ 0x419cc0, 2, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_sm_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_sm_0[] = {
{ 0x419e30, 1, 0x04, 0x000000ff },
{ 0x419e00, 1, 0x04, 0x00000000 },
{ 0x419ea0, 1, 0x04, 0x00000000 },
@@ -185,16 +186,16 @@ gm107_graph_init_sm_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_l1c_1[] = {
+static const struct gf100_gr_init
+gm107_gr_init_l1c_1[] = {
{ 0x419ccc, 2, 0x04, 0x00000000 },
{ 0x419c80, 1, 0x04, 0x3f006022 },
{ 0x419c88, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_pes_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_pes_0[] = {
{ 0x41be50, 1, 0x04, 0x000000ff },
{ 0x41be04, 1, 0x04, 0x00000000 },
{ 0x41be08, 1, 0x04, 0x00000004 },
@@ -205,21 +206,21 @@ gm107_graph_init_pes_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_wwdx_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_wwdx_0[] = {
{ 0x41bfd4, 1, 0x04, 0x00800000 },
{ 0x41bfdc, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_cbm_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_cbm_0[] = {
{ 0x41becc, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_be_0[] = {
+static const struct gf100_gr_init
+gm107_gr_init_be_0[] = {
{ 0x408890, 1, 0x04, 0x000000ff },
{ 0x40880c, 1, 0x04, 0x00000000 },
{ 0x408850, 1, 0x04, 0x00000004 },
@@ -244,45 +245,45 @@ gm107_graph_init_be_0[] = {
{}
};
-static const struct nvc0_graph_init
-gm107_graph_init_sm_1[] = {
+static const struct gf100_gr_init
+gm107_gr_init_sm_1[] = {
{ 0x419e5c, 1, 0x04, 0x00000000 },
{ 0x419e58, 1, 0x04, 0x00000000 },
{}
};
-static const struct nvc0_graph_pack
-gm107_graph_pack_mmio[] = {
- { gm107_graph_init_main_0 },
- { nvf0_graph_init_fe_0 },
- { nvc0_graph_init_pri_0 },
- { nvc0_graph_init_rstr2d_0 },
- { nvc0_graph_init_pd_0 },
- { gm107_graph_init_ds_0 },
- { gm107_graph_init_scc_0 },
- { gm107_graph_init_sked_0 },
- { nvf0_graph_init_cwd_0 },
- { gm107_graph_init_prop_0 },
- { nv108_graph_init_gpc_unk_0 },
- { nvc0_graph_init_setup_0 },
- { nvc0_graph_init_crstr_0 },
- { gm107_graph_init_setup_1 },
- { gm107_graph_init_zcull_0 },
- { nvc0_graph_init_gpm_0 },
- { gm107_graph_init_gpc_unk_1 },
- { nvc0_graph_init_gcc_0 },
- { gm107_graph_init_tpccs_0 },
- { gm107_graph_init_tex_0 },
- { gm107_graph_init_pe_0 },
- { gm107_graph_init_l1c_0 },
- { nvc0_graph_init_mpc_0 },
- { gm107_graph_init_sm_0 },
- { gm107_graph_init_l1c_1 },
- { gm107_graph_init_pes_0 },
- { gm107_graph_init_wwdx_0 },
- { gm107_graph_init_cbm_0 },
- { gm107_graph_init_be_0 },
- { gm107_graph_init_sm_1 },
+static const struct gf100_gr_pack
+gm107_gr_pack_mmio[] = {
+ { gm107_gr_init_main_0 },
+ { gk110_gr_init_fe_0 },
+ { gf100_gr_init_pri_0 },
+ { gf100_gr_init_rstr2d_0 },
+ { gf100_gr_init_pd_0 },
+ { gm107_gr_init_ds_0 },
+ { gm107_gr_init_scc_0 },
+ { gm107_gr_init_sked_0 },
+ { gk110_gr_init_cwd_0 },
+ { gm107_gr_init_prop_0 },
+ { gk208_gr_init_gpc_unk_0 },
+ { gf100_gr_init_setup_0 },
+ { gf100_gr_init_crstr_0 },
+ { gm107_gr_init_setup_1 },
+ { gm107_gr_init_zcull_0 },
+ { gf100_gr_init_gpm_0 },
+ { gm107_gr_init_gpc_unk_1 },
+ { gf100_gr_init_gcc_0 },
+ { gm107_gr_init_tpccs_0 },
+ { gm107_gr_init_tex_0 },
+ { gm107_gr_init_pe_0 },
+ { gm107_gr_init_l1c_0 },
+ { gf100_gr_init_mpc_0 },
+ { gm107_gr_init_sm_0 },
+ { gm107_gr_init_l1c_1 },
+ { gm107_gr_init_pes_0 },
+ { gm107_gr_init_wwdx_0 },
+ { gm107_gr_init_cbm_0 },
+ { gm107_gr_init_be_0 },
+ { gm107_gr_init_sm_1 },
{}
};
@@ -291,7 +292,7 @@ gm107_graph_pack_mmio[] = {
******************************************************************************/
static void
-gm107_graph_init_bios(struct nvc0_graph_priv *priv)
+gm107_gr_init_bios(struct gf100_gr_priv *priv)
{
static const struct {
u32 ctrl;
@@ -303,7 +304,7 @@ gm107_graph_init_bios(struct nvc0_graph_priv *priv)
{ 0x419af0, 0x419af4 },
{ 0x419af8, 0x419afc },
};
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_P0260E infoE;
struct nvbios_P0260X infoX;
int E = -1, X;
@@ -319,17 +320,17 @@ gm107_graph_init_bios(struct nvc0_graph_priv *priv)
}
int
-gm107_graph_init(struct nouveau_object *object)
+gm107_gr_init(struct nvkm_object *object)
{
- struct nvc0_graph_oclass *oclass = (void *)object->oclass;
- struct nvc0_graph_priv *priv = (void *)object;
+ struct gf100_gr_oclass *oclass = (void *)object->oclass;
+ struct gf100_gr_priv *priv = (void *)object;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
int gpc, tpc, ppc, rop;
int ret, i;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -339,9 +340,9 @@ gm107_graph_init(struct nouveau_object *object)
nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
- nvc0_graph_mmio(priv, oclass->mmio);
+ gf100_gr_mmio(priv, oclass->mmio);
- gm107_graph_init_bios(priv);
+ gm107_gr_init_bios(priv);
nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
@@ -426,15 +427,15 @@ gm107_graph_init(struct nouveau_object *object)
nv_wr32(priv, 0x400054, 0x2c350f63);
- nvc0_graph_zbc_init(priv);
+ gf100_gr_zbc_init(priv);
- return nvc0_graph_init_ctxctl(priv);
+ return gf100_gr_init_ctxctl(priv);
}
#include "fuc/hubgm107.fuc5.h"
-static struct nvc0_graph_ucode
-gm107_graph_fecs_ucode = {
+static struct gf100_gr_ucode
+gm107_gr_fecs_ucode = {
.code.data = gm107_grhub_code,
.code.size = sizeof(gm107_grhub_code),
.data.data = gm107_grhub_data,
@@ -443,27 +444,27 @@ gm107_graph_fecs_ucode = {
#include "fuc/gpcgm107.fuc5.h"
-static struct nvc0_graph_ucode
-gm107_graph_gpccs_ucode = {
+static struct gf100_gr_ucode
+gm107_gr_gpccs_ucode = {
.code.data = gm107_grgpc_code,
.code.size = sizeof(gm107_grgpc_code),
.data.data = gm107_grgpc_data,
.data.size = sizeof(gm107_grgpc_data),
};
-struct nouveau_oclass *
-gm107_graph_oclass = &(struct nvc0_graph_oclass) {
+struct nvkm_oclass *
+gm107_gr_oclass = &(struct gf100_gr_oclass) {
.base.handle = NV_ENGINE(GR, 0x07),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_graph_ctor,
- .dtor = nvc0_graph_dtor,
- .init = gm107_graph_init,
- .fini = _nouveau_graph_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_gr_ctor,
+ .dtor = gf100_gr_dtor,
+ .init = gm107_gr_init,
+ .fini = _nvkm_gr_fini,
},
.cclass = &gm107_grctx_oclass,
- .sclass = gm107_graph_sclass,
- .mmio = gm107_graph_pack_mmio,
- .fecs.ucode = 0 ? &gm107_graph_fecs_ucode : NULL,
- .gpccs.ucode = &gm107_graph_gpccs_ucode,
+ .sclass = gm107_gr_sclass,
+ .mmio = gm107_gr_pack_mmio,
+ .fecs.ucode = 0 ? &gm107_gr_fecs_ucode : NULL,
+ .gpccs.ucode = &gm107_gr_gpccs_ucode,
.ppc_nr = 2,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
index f70e2f67a4dd..2614510c28d0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
@@ -10,7 +10,7 @@
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
+ * paragr) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
@@ -21,23 +21,18 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+#include <engine/gr.h>
+#include "regs.h"
#include <core/client.h>
-#include <core/os.h>
+#include <core/device.h>
#include <core/handle.h>
-#include <core/namedb.h>
-
-#include <subdev/fb.h>
+#include <engine/fifo.h>
#include <subdev/instmem.h>
#include <subdev/timer.h>
-#include <engine/fifo.h>
-#include <engine/graph.h>
-
-#include "regs.h"
-
static u32
-nv04_graph_ctx_regs[] = {
+nv04_gr_ctx_regs[] = {
0x0040053c,
0x00400544,
0x00400540,
@@ -351,21 +346,21 @@ nv04_graph_ctx_regs[] = {
NV04_PGRAPH_DEBUG_3
};
-struct nv04_graph_priv {
- struct nouveau_graph base;
- struct nv04_graph_chan *chan[16];
+struct nv04_gr_priv {
+ struct nvkm_gr base;
+ struct nv04_gr_chan *chan[16];
spinlock_t lock;
};
-struct nv04_graph_chan {
- struct nouveau_object base;
+struct nv04_gr_chan {
+ struct nvkm_object base;
int chid;
- u32 nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
+ u32 nv04[ARRAY_SIZE(nv04_gr_ctx_regs)];
};
-static inline struct nv04_graph_priv *
-nv04_graph_priv(struct nv04_graph_chan *chan)
+static inline struct nv04_gr_priv *
+nv04_gr_priv(struct nv04_gr_chan *chan)
{
return (void *)nv_object(chan)->engine;
}
@@ -449,9 +444,9 @@ nv04_graph_priv(struct nv04_graph_chan *chan)
*/
static void
-nv04_graph_set_ctx1(struct nouveau_object *object, u32 mask, u32 value)
+nv04_gr_set_ctx1(struct nvkm_object *object, u32 mask, u32 value)
{
- struct nv04_graph_priv *priv = (void *)object->engine;
+ struct nv04_gr_priv *priv = (void *)object->engine;
int subc = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
u32 tmp;
@@ -465,7 +460,7 @@ nv04_graph_set_ctx1(struct nouveau_object *object, u32 mask, u32 value)
}
static void
-nv04_graph_set_ctx_val(struct nouveau_object *object, u32 mask, u32 value)
+nv04_gr_set_ctx_val(struct nvkm_object *object, u32 mask, u32 value)
{
int class, op, valid = 1;
u32 tmp, ctx1;
@@ -509,12 +504,12 @@ nv04_graph_set_ctx_val(struct nouveau_object *object, u32 mask, u32 value)
break;
}
- nv04_graph_set_ctx1(object, 0x01000000, valid << 24);
+ nv04_gr_set_ctx1(object, 0x01000000, valid << 24);
}
static int
-nv04_graph_mthd_set_operation(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_set_operation(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
u32 class = nv_ro32(object, 0) & 0xff;
u32 data = *(u32 *)args;
@@ -523,17 +518,17 @@ nv04_graph_mthd_set_operation(struct nouveau_object *object, u32 mthd,
/* Old versions of the objects only accept first three operations. */
if (data > 2 && class < 0x40)
return 1;
- nv04_graph_set_ctx1(object, 0x00038000, data << 15);
+ nv04_gr_set_ctx1(object, 0x00038000, data << 15);
/* changing operation changes set of objects needed for validation */
- nv04_graph_set_ctx_val(object, 0, 0);
+ nv04_gr_set_ctx_val(object, 0, 0);
return 0;
}
static int
-nv04_graph_mthd_surf3d_clip_h(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_surf3d_clip_h(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv04_graph_priv *priv = (void *)object->engine;
+ struct nv04_gr_priv *priv = (void *)object->engine;
u32 data = *(u32 *)args;
u32 min = data & 0xffff, max;
u32 w = data >> 16;
@@ -551,10 +546,10 @@ nv04_graph_mthd_surf3d_clip_h(struct nouveau_object *object, u32 mthd,
}
static int
-nv04_graph_mthd_surf3d_clip_v(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_surf3d_clip_v(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv04_graph_priv *priv = (void *)object->engine;
+ struct nv04_gr_priv *priv = (void *)object->engine;
u32 data = *(u32 *)args;
u32 min = data & 0xffff, max;
u32 w = data >> 16;
@@ -572,397 +567,396 @@ nv04_graph_mthd_surf3d_clip_v(struct nouveau_object *object, u32 mthd,
}
static u16
-nv04_graph_mthd_bind_class(struct nouveau_object *object, u32 *args, u32 size)
+nv04_gr_mthd_bind_class(struct nvkm_object *object, u32 *args, u32 size)
{
- struct nouveau_instmem *imem = nouveau_instmem(object);
+ struct nvkm_instmem *imem = nvkm_instmem(object);
u32 inst = *(u32 *)args << 4;
return nv_ro32(imem, inst);
}
static int
-nv04_graph_mthd_bind_surf2d(struct nouveau_object *object, u32 mthd,
+nv04_gr_mthd_bind_surf2d(struct nvkm_object *object, u32 mthd,
void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx1(object, 0x00004000, 0);
- nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ nv04_gr_set_ctx1(object, 0x00004000, 0);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0);
return 0;
case 0x42:
- nv04_graph_set_ctx1(object, 0x00004000, 0);
- nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ nv04_gr_set_ctx1(object, 0x00004000, 0);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_surf2d_swzsurf(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx1(object, 0x00004000, 0);
- nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ nv04_gr_set_ctx1(object, 0x00004000, 0);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0);
return 0;
case 0x42:
- nv04_graph_set_ctx1(object, 0x00004000, 0);
- nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ nv04_gr_set_ctx1(object, 0x00004000, 0);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
return 0;
case 0x52:
- nv04_graph_set_ctx1(object, 0x00004000, 0x00004000);
- nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ nv04_gr_set_ctx1(object, 0x00004000, 0x00004000);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
return 0;
}
return 1;
}
static int
-nv01_graph_mthd_bind_patt(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv01_gr_mthd_bind_patt(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x08000000, 0);
+ nv04_gr_set_ctx_val(object, 0x08000000, 0);
return 0;
case 0x18:
- nv04_graph_set_ctx_val(object, 0x08000000, 0x08000000);
+ nv04_gr_set_ctx_val(object, 0x08000000, 0x08000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_patt(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_patt(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x08000000, 0);
+ nv04_gr_set_ctx_val(object, 0x08000000, 0);
return 0;
case 0x44:
- nv04_graph_set_ctx_val(object, 0x08000000, 0x08000000);
+ nv04_gr_set_ctx_val(object, 0x08000000, 0x08000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_rop(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_rop(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x10000000, 0);
+ nv04_gr_set_ctx_val(object, 0x10000000, 0);
return 0;
case 0x43:
- nv04_graph_set_ctx_val(object, 0x10000000, 0x10000000);
+ nv04_gr_set_ctx_val(object, 0x10000000, 0x10000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_beta1(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_beta1(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x20000000, 0);
+ nv04_gr_set_ctx_val(object, 0x20000000, 0);
return 0;
case 0x12:
- nv04_graph_set_ctx_val(object, 0x20000000, 0x20000000);
+ nv04_gr_set_ctx_val(object, 0x20000000, 0x20000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_beta4(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_beta4(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x40000000, 0);
+ nv04_gr_set_ctx_val(object, 0x40000000, 0);
return 0;
case 0x72:
- nv04_graph_set_ctx_val(object, 0x40000000, 0x40000000);
+ nv04_gr_set_ctx_val(object, 0x40000000, 0x40000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_surf_dst(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_surf_dst(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0);
return 0;
case 0x58:
- nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_surf_src(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_surf_src(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x04000000, 0);
+ nv04_gr_set_ctx_val(object, 0x04000000, 0);
return 0;
case 0x59:
- nv04_graph_set_ctx_val(object, 0x04000000, 0x04000000);
+ nv04_gr_set_ctx_val(object, 0x04000000, 0x04000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_surf_color(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_surf_color(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x02000000, 0);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0);
return 0;
case 0x5a:
- nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000);
+ nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
return 0;
}
return 1;
}
static int
-nv04_graph_mthd_bind_surf_zeta(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_gr_mthd_bind_surf_zeta(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx_val(object, 0x04000000, 0);
+ nv04_gr_set_ctx_val(object, 0x04000000, 0);
return 0;
case 0x5b:
- nv04_graph_set_ctx_val(object, 0x04000000, 0x04000000);
+ nv04_gr_set_ctx_val(object, 0x04000000, 0x04000000);
return 0;
}
return 1;
}
static int
-nv01_graph_mthd_bind_clip(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv01_gr_mthd_bind_clip(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx1(object, 0x2000, 0);
+ nv04_gr_set_ctx1(object, 0x2000, 0);
return 0;
case 0x19:
- nv04_graph_set_ctx1(object, 0x2000, 0x2000);
+ nv04_gr_set_ctx1(object, 0x2000, 0x2000);
return 0;
}
return 1;
}
static int
-nv01_graph_mthd_bind_chroma(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv01_gr_mthd_bind_chroma(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- switch (nv04_graph_mthd_bind_class(object, args, size)) {
+ switch (nv04_gr_mthd_bind_class(object, args, size)) {
case 0x30:
- nv04_graph_set_ctx1(object, 0x1000, 0);
+ nv04_gr_set_ctx1(object, 0x1000, 0);
return 0;
/* Yes, for some reason even the old versions of objects
* accept 0x57 and not 0x17. Consistency be damned.
*/
case 0x57:
- nv04_graph_set_ctx1(object, 0x1000, 0x1000);
+ nv04_gr_set_ctx1(object, 0x1000, 0x1000);
return 0;
}
return 1;
}
-static struct nouveau_omthds
-nv03_graph_gdi_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_patt },
- { 0x0188, 0x0188, nv04_graph_mthd_bind_rop },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_beta1 },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_surf_dst },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv03_gr_gdi_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_patt },
+ { 0x0188, 0x0188, nv04_gr_mthd_bind_rop },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_beta1 },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_surf_dst },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_gdi_omthds[] = {
- { 0x0188, 0x0188, nv04_graph_mthd_bind_patt },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_rop },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_beta1 },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta4 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_surf2d },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv04_gr_gdi_omthds[] = {
+ { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv01_graph_blit_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_chroma },
- { 0x0188, 0x0188, nv01_graph_mthd_bind_clip },
- { 0x018c, 0x018c, nv01_graph_mthd_bind_patt },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_rop },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta1 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_surf_dst },
- { 0x019c, 0x019c, nv04_graph_mthd_bind_surf_src },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv01_gr_blit_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
+ { 0x018c, 0x018c, nv01_gr_mthd_bind_patt },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_surf_dst },
+ { 0x019c, 0x019c, nv04_gr_mthd_bind_surf_src },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_blit_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_chroma },
- { 0x0188, 0x0188, nv01_graph_mthd_bind_clip },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_patt },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_rop },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta1 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_beta4 },
- { 0x019c, 0x019c, nv04_graph_mthd_bind_surf2d },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv04_gr_blit_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_patt },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_beta4 },
+ { 0x019c, 0x019c, nv04_gr_mthd_bind_surf2d },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_iifc_omthds[] = {
- { 0x0188, 0x0188, nv01_graph_mthd_bind_chroma },
- { 0x018c, 0x018c, nv01_graph_mthd_bind_clip },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_patt },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_rop },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_beta1 },
- { 0x019c, 0x019c, nv04_graph_mthd_bind_beta4 },
- { 0x01a0, 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf },
- { 0x03e4, 0x03e4, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv04_gr_iifc_omthds[] = {
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_chroma },
+ { 0x018c, 0x018c, nv01_gr_mthd_bind_clip },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_patt },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_rop },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_beta1 },
+ { 0x019c, 0x019c, nv04_gr_mthd_bind_beta4 },
+ { 0x01a0, 0x01a0, nv04_gr_mthd_bind_surf2d_swzsurf },
+ { 0x03e4, 0x03e4, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv01_graph_ifc_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_chroma },
- { 0x0188, 0x0188, nv01_graph_mthd_bind_clip },
- { 0x018c, 0x018c, nv01_graph_mthd_bind_patt },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_rop },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta1 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_surf_dst },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv01_gr_ifc_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
+ { 0x018c, 0x018c, nv01_gr_mthd_bind_patt },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_surf_dst },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_ifc_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_chroma },
- { 0x0188, 0x0188, nv01_graph_mthd_bind_clip },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_patt },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_rop },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta1 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_beta4 },
- { 0x019c, 0x019c, nv04_graph_mthd_bind_surf2d },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv04_gr_ifc_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_patt },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_beta4 },
+ { 0x019c, 0x019c, nv04_gr_mthd_bind_surf2d },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv03_graph_sifc_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_chroma },
- { 0x0188, 0x0188, nv01_graph_mthd_bind_patt },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_rop },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_beta1 },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_surf_dst },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv03_gr_sifc_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_sifc_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_chroma },
- { 0x0188, 0x0188, nv04_graph_mthd_bind_patt },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_rop },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_beta1 },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta4 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_surf2d },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv04_gr_sifc_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
+ { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv03_graph_sifm_omthds[] = {
- { 0x0188, 0x0188, nv01_graph_mthd_bind_patt },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_rop },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_beta1 },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_surf_dst },
- { 0x0304, 0x0304, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv03_gr_sifm_omthds[] = {
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
+ { 0x0304, 0x0304, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_sifm_omthds[] = {
- { 0x0188, 0x0188, nv04_graph_mthd_bind_patt },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_rop },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_beta1 },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta4 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_surf2d },
- { 0x0304, 0x0304, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv04_gr_sifm_omthds[] = {
+ { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
+ { 0x0304, 0x0304, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_surf3d_omthds[] = {
- { 0x02f8, 0x02f8, nv04_graph_mthd_surf3d_clip_h },
- { 0x02fc, 0x02fc, nv04_graph_mthd_surf3d_clip_v },
+static struct nvkm_omthds
+nv04_gr_surf3d_omthds[] = {
+ { 0x02f8, 0x02f8, nv04_gr_mthd_surf3d_clip_h },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_surf3d_clip_v },
{}
};
-static struct nouveau_omthds
-nv03_graph_ttri_omthds[] = {
- { 0x0188, 0x0188, nv01_graph_mthd_bind_clip },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_surf_color },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_surf_zeta },
+static struct nvkm_omthds
+nv03_gr_ttri_omthds[] = {
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_surf_color },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_surf_zeta },
{}
};
-static struct nouveau_omthds
-nv01_graph_prim_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_clip },
- { 0x0188, 0x0188, nv01_graph_mthd_bind_patt },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_rop },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_beta1 },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_surf_dst },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv01_gr_prim_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_clip },
+ { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
-static struct nouveau_omthds
-nv04_graph_prim_omthds[] = {
- { 0x0184, 0x0184, nv01_graph_mthd_bind_clip },
- { 0x0188, 0x0188, nv04_graph_mthd_bind_patt },
- { 0x018c, 0x018c, nv04_graph_mthd_bind_rop },
- { 0x0190, 0x0190, nv04_graph_mthd_bind_beta1 },
- { 0x0194, 0x0194, nv04_graph_mthd_bind_beta4 },
- { 0x0198, 0x0198, nv04_graph_mthd_bind_surf2d },
- { 0x02fc, 0x02fc, nv04_graph_mthd_set_operation },
+static struct nvkm_omthds
+nv04_gr_prim_omthds[] = {
+ { 0x0184, 0x0184, nv01_gr_mthd_bind_clip },
+ { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
+ { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
+ { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
+ { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
+ { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
+ { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
{}
};
static int
-nv04_graph_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_gr_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_gpuobj *obj;
+ struct nvkm_gpuobj *obj;
int ret;
- ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
- 16, 16, 0, &obj);
+ ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
*pobject = nv_object(obj);
if (ret)
return ret;
@@ -977,59 +971,59 @@ nv04_graph_object_ctor(struct nouveau_object *parent,
return 0;
}
-struct nouveau_ofuncs
-nv04_graph_ofuncs = {
- .ctor = nv04_graph_object_ctor,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
+struct nvkm_ofuncs
+nv04_gr_ofuncs = {
+ .ctor = nv04_gr_object_ctor,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
};
-static struct nouveau_oclass
-nv04_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
- { 0x0017, &nv04_graph_ofuncs }, /* chroma */
- { 0x0018, &nv04_graph_ofuncs }, /* pattern (nv01) */
- { 0x0019, &nv04_graph_ofuncs }, /* clip */
- { 0x001c, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* line */
- { 0x001d, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* tri */
- { 0x001e, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* rect */
- { 0x001f, &nv04_graph_ofuncs, nv01_graph_blit_omthds },
- { 0x0021, &nv04_graph_ofuncs, nv01_graph_ifc_omthds },
- { 0x0030, &nv04_graph_ofuncs }, /* null */
- { 0x0036, &nv04_graph_ofuncs, nv03_graph_sifc_omthds },
- { 0x0037, &nv04_graph_ofuncs, nv03_graph_sifm_omthds },
- { 0x0038, &nv04_graph_ofuncs }, /* dvd subpicture */
- { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
- { 0x0042, &nv04_graph_ofuncs }, /* surf2d */
- { 0x0043, &nv04_graph_ofuncs }, /* rop */
- { 0x0044, &nv04_graph_ofuncs }, /* pattern */
- { 0x0048, &nv04_graph_ofuncs, nv03_graph_ttri_omthds },
- { 0x004a, &nv04_graph_ofuncs, nv04_graph_gdi_omthds },
- { 0x004b, &nv04_graph_ofuncs, nv03_graph_gdi_omthds },
- { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
- { 0x0053, &nv04_graph_ofuncs, nv04_graph_surf3d_omthds },
- { 0x0054, &nv04_graph_ofuncs }, /* ttri */
- { 0x0055, &nv04_graph_ofuncs }, /* mtri */
- { 0x0057, &nv04_graph_ofuncs }, /* chroma */
- { 0x0058, &nv04_graph_ofuncs }, /* surf_dst */
- { 0x0059, &nv04_graph_ofuncs }, /* surf_src */
- { 0x005a, &nv04_graph_ofuncs }, /* surf_color */
- { 0x005b, &nv04_graph_ofuncs }, /* surf_zeta */
- { 0x005c, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* line */
- { 0x005d, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* tri */
- { 0x005e, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* rect */
- { 0x005f, &nv04_graph_ofuncs, nv04_graph_blit_omthds },
- { 0x0060, &nv04_graph_ofuncs, nv04_graph_iifc_omthds },
- { 0x0061, &nv04_graph_ofuncs, nv04_graph_ifc_omthds },
- { 0x0064, &nv04_graph_ofuncs }, /* iifc (nv05) */
- { 0x0065, &nv04_graph_ofuncs }, /* ifc (nv05) */
- { 0x0066, &nv04_graph_ofuncs }, /* sifc (nv05) */
- { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
- { 0x0076, &nv04_graph_ofuncs, nv04_graph_sifc_omthds },
- { 0x0077, &nv04_graph_ofuncs, nv04_graph_sifm_omthds },
+static struct nvkm_oclass
+nv04_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
+ { 0x0017, &nv04_gr_ofuncs }, /* chroma */
+ { 0x0018, &nv04_gr_ofuncs }, /* pattern (nv01) */
+ { 0x0019, &nv04_gr_ofuncs }, /* clip */
+ { 0x001c, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* line */
+ { 0x001d, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* tri */
+ { 0x001e, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* rect */
+ { 0x001f, &nv04_gr_ofuncs, nv01_gr_blit_omthds },
+ { 0x0021, &nv04_gr_ofuncs, nv01_gr_ifc_omthds },
+ { 0x0030, &nv04_gr_ofuncs }, /* null */
+ { 0x0036, &nv04_gr_ofuncs, nv03_gr_sifc_omthds },
+ { 0x0037, &nv04_gr_ofuncs, nv03_gr_sifm_omthds },
+ { 0x0038, &nv04_gr_ofuncs }, /* dvd subpicture */
+ { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
+ { 0x0042, &nv04_gr_ofuncs }, /* surf2d */
+ { 0x0043, &nv04_gr_ofuncs }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs }, /* pattern */
+ { 0x0048, &nv04_gr_ofuncs, nv03_gr_ttri_omthds },
+ { 0x004a, &nv04_gr_ofuncs, nv04_gr_gdi_omthds },
+ { 0x004b, &nv04_gr_ofuncs, nv03_gr_gdi_omthds },
+ { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
+ { 0x0053, &nv04_gr_ofuncs, nv04_gr_surf3d_omthds },
+ { 0x0054, &nv04_gr_ofuncs }, /* ttri */
+ { 0x0055, &nv04_gr_ofuncs }, /* mtri */
+ { 0x0057, &nv04_gr_ofuncs }, /* chroma */
+ { 0x0058, &nv04_gr_ofuncs }, /* surf_dst */
+ { 0x0059, &nv04_gr_ofuncs }, /* surf_src */
+ { 0x005a, &nv04_gr_ofuncs }, /* surf_color */
+ { 0x005b, &nv04_gr_ofuncs }, /* surf_zeta */
+ { 0x005c, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* line */
+ { 0x005d, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* tri */
+ { 0x005e, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* rect */
+ { 0x005f, &nv04_gr_ofuncs, nv04_gr_blit_omthds },
+ { 0x0060, &nv04_gr_ofuncs, nv04_gr_iifc_omthds },
+ { 0x0061, &nv04_gr_ofuncs, nv04_gr_ifc_omthds },
+ { 0x0064, &nv04_gr_ofuncs }, /* iifc (nv05) */
+ { 0x0065, &nv04_gr_ofuncs }, /* ifc (nv05) */
+ { 0x0066, &nv04_gr_ofuncs }, /* sifc (nv05) */
+ { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
+ { 0x0076, &nv04_gr_ofuncs, nv04_gr_sifc_omthds },
+ { 0x0077, &nv04_gr_ofuncs, nv04_gr_sifm_omthds },
{},
};
@@ -1037,10 +1031,10 @@ nv04_graph_sclass[] = {
* PGRAPH context
******************************************************************************/
-static struct nv04_graph_chan *
-nv04_graph_channel(struct nv04_graph_priv *priv)
+static struct nv04_gr_chan *
+nv04_gr_channel(struct nv04_gr_priv *priv)
{
- struct nv04_graph_chan *chan = NULL;
+ struct nv04_gr_chan *chan = NULL;
if (nv_rd32(priv, NV04_PGRAPH_CTX_CONTROL) & 0x00010000) {
int chid = nv_rd32(priv, NV04_PGRAPH_CTX_USER) >> 24;
if (chid < ARRAY_SIZE(priv->chan))
@@ -1050,13 +1044,13 @@ nv04_graph_channel(struct nv04_graph_priv *priv)
}
static int
-nv04_graph_load_context(struct nv04_graph_chan *chan, int chid)
+nv04_gr_load_context(struct nv04_gr_chan *chan, int chid)
{
- struct nv04_graph_priv *priv = nv04_graph_priv(chan);
+ struct nv04_gr_priv *priv = nv04_gr_priv(chan);
int i;
- for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
- nv_wr32(priv, nv04_graph_ctx_regs[i], chan->nv04[i]);
+ for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++)
+ nv_wr32(priv, nv04_gr_ctx_regs[i], chan->nv04[i]);
nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10010100);
nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, chid << 24);
@@ -1065,13 +1059,13 @@ nv04_graph_load_context(struct nv04_graph_chan *chan, int chid)
}
static int
-nv04_graph_unload_context(struct nv04_graph_chan *chan)
+nv04_gr_unload_context(struct nv04_gr_chan *chan)
{
- struct nv04_graph_priv *priv = nv04_graph_priv(chan);
+ struct nv04_gr_priv *priv = nv04_gr_priv(chan);
int i;
- for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
- chan->nv04[i] = nv_rd32(priv, nv04_graph_ctx_regs[i]);
+ for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++)
+ chan->nv04[i] = nv_rd32(priv, nv04_gr_ctx_regs[i]);
nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10000000);
nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000);
@@ -1079,36 +1073,36 @@ nv04_graph_unload_context(struct nv04_graph_chan *chan)
}
static void
-nv04_graph_context_switch(struct nv04_graph_priv *priv)
+nv04_gr_context_switch(struct nv04_gr_priv *priv)
{
- struct nv04_graph_chan *prev = NULL;
- struct nv04_graph_chan *next = NULL;
+ struct nv04_gr_chan *prev = NULL;
+ struct nv04_gr_chan *next = NULL;
unsigned long flags;
int chid;
spin_lock_irqsave(&priv->lock, flags);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
/* If previous context is valid, we need to save it */
- prev = nv04_graph_channel(priv);
+ prev = nv04_gr_channel(priv);
if (prev)
- nv04_graph_unload_context(prev);
+ nv04_gr_unload_context(prev);
/* load context for next channel */
chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0x0f;
next = priv->chan[chid];
if (next)
- nv04_graph_load_context(next, chid);
+ nv04_gr_load_context(next, chid);
spin_unlock_irqrestore(&priv->lock, flags);
}
-static u32 *ctx_reg(struct nv04_graph_chan *chan, u32 reg)
+static u32 *ctx_reg(struct nv04_gr_chan *chan, u32 reg)
{
int i;
- for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) {
- if (nv04_graph_ctx_regs[i] == reg)
+ for (i = 0; i < ARRAY_SIZE(nv04_gr_ctx_regs); i++) {
+ if (nv04_gr_ctx_regs[i] == reg)
return &chan->nv04[i];
}
@@ -1116,18 +1110,18 @@ static u32 *ctx_reg(struct nv04_graph_chan *chan, u32 reg)
}
static int
-nv04_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_gr_context_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fifo_chan *fifo = (void *)parent;
- struct nv04_graph_priv *priv = (void *)engine;
- struct nv04_graph_chan *chan;
+ struct nvkm_fifo_chan *fifo = (void *)parent;
+ struct nv04_gr_priv *priv = (void *)engine;
+ struct nv04_gr_chan *chan;
unsigned long flags;
int ret;
- ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
+ ret = nvkm_object_create(parent, engine, oclass, 0, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -1137,7 +1131,7 @@ nv04_graph_context_ctor(struct nouveau_object *parent,
*pobject = nv_object(priv->chan[fifo->chid]);
atomic_inc(&(*pobject)->refcount);
spin_unlock_irqrestore(&priv->lock, flags);
- nouveau_object_destroy(&chan->base);
+ nvkm_object_destroy(&chan->base);
return 1;
}
@@ -1150,44 +1144,44 @@ nv04_graph_context_ctor(struct nouveau_object *parent,
}
static void
-nv04_graph_context_dtor(struct nouveau_object *object)
+nv04_gr_context_dtor(struct nvkm_object *object)
{
- struct nv04_graph_priv *priv = (void *)object->engine;
- struct nv04_graph_chan *chan = (void *)object;
+ struct nv04_gr_priv *priv = (void *)object->engine;
+ struct nv04_gr_chan *chan = (void *)object;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
priv->chan[chan->chid] = NULL;
spin_unlock_irqrestore(&priv->lock, flags);
- nouveau_object_destroy(&chan->base);
+ nvkm_object_destroy(&chan->base);
}
static int
-nv04_graph_context_fini(struct nouveau_object *object, bool suspend)
+nv04_gr_context_fini(struct nvkm_object *object, bool suspend)
{
- struct nv04_graph_priv *priv = (void *)object->engine;
- struct nv04_graph_chan *chan = (void *)object;
+ struct nv04_gr_priv *priv = (void *)object->engine;
+ struct nv04_gr_chan *chan = (void *)object;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
- if (nv04_graph_channel(priv) == chan)
- nv04_graph_unload_context(chan);
+ if (nv04_gr_channel(priv) == chan)
+ nv04_gr_unload_context(chan);
nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&priv->lock, flags);
- return nouveau_object_fini(&chan->base, suspend);
+ return nvkm_object_fini(&chan->base, suspend);
}
-static struct nouveau_oclass
-nv04_graph_cclass = {
+static struct nvkm_oclass
+nv04_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_graph_context_ctor,
- .dtor = nv04_graph_context_dtor,
- .init = nouveau_object_init,
- .fini = nv04_graph_context_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv04_gr_context_ctor,
+ .dtor = nv04_gr_context_dtor,
+ .init = nvkm_object_init,
+ .fini = nv04_gr_context_fini,
},
};
@@ -1196,31 +1190,31 @@ nv04_graph_cclass = {
******************************************************************************/
bool
-nv04_graph_idle(void *obj)
+nv04_gr_idle(void *obj)
{
- struct nouveau_graph *graph = nouveau_graph(obj);
+ struct nvkm_gr *gr = nvkm_gr(obj);
u32 mask = 0xffffffff;
if (nv_device(obj)->card_type == NV_40)
mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL;
- if (!nv_wait(graph, NV04_PGRAPH_STATUS, mask, 0)) {
- nv_error(graph, "idle timed out with status 0x%08x\n",
- nv_rd32(graph, NV04_PGRAPH_STATUS));
+ if (!nv_wait(gr, NV04_PGRAPH_STATUS, mask, 0)) {
+ nv_error(gr, "idle timed out with status 0x%08x\n",
+ nv_rd32(gr, NV04_PGRAPH_STATUS));
return false;
}
return true;
}
-static const struct nouveau_bitfield
-nv04_graph_intr_name[] = {
+static const struct nvkm_bitfield
+nv04_gr_intr_name[] = {
{ NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
{}
};
-static const struct nouveau_bitfield
-nv04_graph_nstatus[] = {
+static const struct nvkm_bitfield
+nv04_gr_nstatus[] = {
{ NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
{ NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
{ NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
@@ -1228,8 +1222,8 @@ nv04_graph_nstatus[] = {
{}
};
-const struct nouveau_bitfield
-nv04_graph_nsource[] = {
+const struct nvkm_bitfield
+nv04_gr_nsource[] = {
{ NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" },
{ NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" },
{ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" },
@@ -1253,12 +1247,12 @@ nv04_graph_nsource[] = {
};
static void
-nv04_graph_intr(struct nouveau_subdev *subdev)
+nv04_gr_intr(struct nvkm_subdev *subdev)
{
- struct nv04_graph_priv *priv = (void *)subdev;
- struct nv04_graph_chan *chan = NULL;
- struct nouveau_namedb *namedb = NULL;
- struct nouveau_handle *handle = NULL;
+ struct nv04_gr_priv *priv = (void *)subdev;
+ struct nv04_gr_chan *chan = NULL;
+ struct nvkm_namedb *namedb = NULL;
+ struct nvkm_handle *handle = NULL;
u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
@@ -1280,7 +1274,7 @@ nv04_graph_intr(struct nouveau_subdev *subdev)
if (stat & NV_PGRAPH_INTR_NOTIFY) {
if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
- handle = nouveau_namedb_get_vinst(namedb, inst);
+ handle = nvkm_namedb_get_vinst(namedb, inst);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~NV_PGRAPH_INTR_NOTIFY;
}
@@ -1290,7 +1284,7 @@ nv04_graph_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
- nv04_graph_context_switch(priv);
+ nv04_gr_context_switch(priv);
}
nv_wr32(priv, NV03_PGRAPH_INTR, stat);
@@ -1298,50 +1292,50 @@ nv04_graph_intr(struct nouveau_subdev *subdev)
if (show) {
nv_error(priv, "%s", "");
- nouveau_bitfield_print(nv04_graph_intr_name, show);
+ nvkm_bitfield_print(nv04_gr_intr_name, show);
pr_cont(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ nvkm_bitfield_print(nv04_gr_nsource, nsource);
pr_cont(" nstatus:");
- nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
+ nvkm_bitfield_print(nv04_gr_nstatus, nstatus);
pr_cont("\n");
nv_error(priv,
"ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, nouveau_client_name(chan), subc, class, mthd,
+ chid, nvkm_client_name(chan), subc, class, mthd,
data);
}
- nouveau_namedb_put(handle);
+ nvkm_namedb_put(handle);
}
static int
-nv04_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv04_graph_priv *priv;
+ struct nv04_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv04_graph_intr;
- nv_engine(priv)->cclass = &nv04_graph_cclass;
- nv_engine(priv)->sclass = nv04_graph_sclass;
+ nv_subdev(priv)->intr = nv04_gr_intr;
+ nv_engine(priv)->cclass = &nv04_gr_cclass;
+ nv_engine(priv)->sclass = nv04_gr_sclass;
spin_lock_init(&priv->lock);
return 0;
}
static int
-nv04_graph_init(struct nouveau_object *object)
+nv04_gr_init(struct nvkm_object *object)
{
- struct nouveau_engine *engine = nv_engine(object);
- struct nv04_graph_priv *priv = (void *)engine;
+ struct nvkm_engine *engine = nv_engine(object);
+ struct nv04_gr_priv *priv = (void *)engine;
int ret;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -1376,13 +1370,13 @@ nv04_graph_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv04_graph_oclass = {
+struct nvkm_oclass
+nv04_gr_oclass = {
.handle = NV_ENGINE(GR, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_graph_ctor,
- .dtor = _nouveau_graph_dtor,
- .init = nv04_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv04_gr_ctor,
+ .dtor = _nvkm_gr_dtor,
+ .init = nv04_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
index 2b12b09683c8..389904eb603f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
@@ -10,7 +10,7 @@
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
+ * paragr) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
@@ -21,17 +21,14 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+#include <engine/gr.h>
+#include "regs.h"
#include <core/client.h>
-#include <core/os.h>
+#include <core/device.h>
#include <core/handle.h>
-
-#include <subdev/fb.h>
-
#include <engine/fifo.h>
-#include <engine/graph.h>
-
-#include "regs.h"
+#include <subdev/fb.h>
struct pipe_state {
u32 pipe_0x0000[0x040/4];
@@ -46,7 +43,7 @@ struct pipe_state {
u32 pipe_0x7800[0x0c0/4];
};
-static int nv10_graph_ctx_regs[] = {
+static int nv10_gr_ctx_regs[] = {
NV10_PGRAPH_CTX_SWITCH(0),
NV10_PGRAPH_CTX_SWITCH(1),
NV10_PGRAPH_CTX_SWITCH(2),
@@ -368,7 +365,7 @@ static int nv10_graph_ctx_regs[] = {
NV04_PGRAPH_VALID2,
};
-static int nv17_graph_ctx_regs[] = {
+static int nv17_gr_ctx_regs[] = {
NV10_PGRAPH_DEBUG_4,
0x004006b0,
0x00400eac,
@@ -389,24 +386,24 @@ static int nv17_graph_ctx_regs[] = {
0x00400a04,
};
-struct nv10_graph_priv {
- struct nouveau_graph base;
- struct nv10_graph_chan *chan[32];
+struct nv10_gr_priv {
+ struct nvkm_gr base;
+ struct nv10_gr_chan *chan[32];
spinlock_t lock;
};
-struct nv10_graph_chan {
- struct nouveau_object base;
+struct nv10_gr_chan {
+ struct nvkm_object base;
int chid;
- int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)];
- int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)];
+ int nv10[ARRAY_SIZE(nv10_gr_ctx_regs)];
+ int nv17[ARRAY_SIZE(nv17_gr_ctx_regs)];
struct pipe_state pipe_state;
u32 lma_window[4];
};
-static inline struct nv10_graph_priv *
-nv10_graph_priv(struct nv10_graph_chan *chan)
+static inline struct nv10_gr_priv *
+nv10_gr_priv(struct nv10_gr_chan *chan)
{
return (void *)nv_object(chan)->engine;
}
@@ -431,58 +428,58 @@ nv10_graph_priv(struct nv10_graph_chan *chan)
nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, state[__i]); \
} while (0)
-static struct nouveau_oclass
-nv10_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs }, /* clip */
- { 0x0030, &nv04_graph_ofuncs }, /* null */
- { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs }, /* rop */
- { 0x0044, &nv04_graph_ofuncs }, /* pattern */
- { 0x004a, &nv04_graph_ofuncs }, /* gdi */
- { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
- { 0x005f, &nv04_graph_ofuncs }, /* blit */
- { 0x0062, &nv04_graph_ofuncs }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs }, /* ifc */
- { 0x009f, &nv04_graph_ofuncs }, /* blit */
- { 0x0093, &nv04_graph_ofuncs }, /* surf3d */
- { 0x0094, &nv04_graph_ofuncs }, /* ttri */
- { 0x0095, &nv04_graph_ofuncs }, /* mtri */
- { 0x0056, &nv04_graph_ofuncs }, /* celcius */
+static struct nvkm_oclass
+nv10_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs }, /* null */
+ { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs }, /* pattern */
+ { 0x004a, &nv04_gr_ofuncs }, /* gdi */
+ { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
+ { 0x005f, &nv04_gr_ofuncs }, /* blit */
+ { 0x0062, &nv04_gr_ofuncs }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs }, /* ifc */
+ { 0x009f, &nv04_gr_ofuncs }, /* blit */
+ { 0x0093, &nv04_gr_ofuncs }, /* surf3d */
+ { 0x0094, &nv04_gr_ofuncs }, /* ttri */
+ { 0x0095, &nv04_gr_ofuncs }, /* mtri */
+ { 0x0056, &nv04_gr_ofuncs }, /* celcius */
{},
};
-static struct nouveau_oclass
-nv15_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs }, /* clip */
- { 0x0030, &nv04_graph_ofuncs }, /* null */
- { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs }, /* rop */
- { 0x0044, &nv04_graph_ofuncs }, /* pattern */
- { 0x004a, &nv04_graph_ofuncs }, /* gdi */
- { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
- { 0x005f, &nv04_graph_ofuncs }, /* blit */
- { 0x0062, &nv04_graph_ofuncs }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs }, /* ifc */
- { 0x009f, &nv04_graph_ofuncs }, /* blit */
- { 0x0093, &nv04_graph_ofuncs }, /* surf3d */
- { 0x0094, &nv04_graph_ofuncs }, /* ttri */
- { 0x0095, &nv04_graph_ofuncs }, /* mtri */
- { 0x0096, &nv04_graph_ofuncs }, /* celcius */
+static struct nvkm_oclass
+nv15_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs }, /* null */
+ { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs }, /* pattern */
+ { 0x004a, &nv04_gr_ofuncs }, /* gdi */
+ { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
+ { 0x005f, &nv04_gr_ofuncs }, /* blit */
+ { 0x0062, &nv04_gr_ofuncs }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs }, /* ifc */
+ { 0x009f, &nv04_gr_ofuncs }, /* blit */
+ { 0x0093, &nv04_gr_ofuncs }, /* surf3d */
+ { 0x0094, &nv04_gr_ofuncs }, /* ttri */
+ { 0x0095, &nv04_gr_ofuncs }, /* mtri */
+ { 0x0096, &nv04_gr_ofuncs }, /* celcius */
{},
};
static int
-nv17_graph_mthd_lma_window(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv17_gr_mthd_lma_window(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv10_graph_chan *chan = (void *)object->parent;
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_chan *chan = (void *)object->parent;
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
struct pipe_state *pipe = &chan->pipe_state;
u32 pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
u32 xfmode0, xfmode1;
@@ -494,14 +491,14 @@ nv17_graph_mthd_lma_window(struct nouveau_object *object, u32 mthd,
if (mthd != 0x1644)
return 0;
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
PIPE_SAVE(priv, pipe_0x0040, 0x0040);
PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200);
PIPE_RESTORE(priv, chan->lma_window, 0x6790);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0);
xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1);
@@ -511,7 +508,7 @@ nv17_graph_mthd_lma_window(struct nouveau_object *object, u32 mthd,
PIPE_SAVE(priv, pipe_0x6ab0, 0x6ab0);
PIPE_SAVE(priv, pipe_0x6a80, 0x6a80);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000);
nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000);
@@ -534,7 +531,7 @@ nv17_graph_mthd_lma_window(struct nouveau_object *object, u32 mthd,
PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
PIPE_RESTORE(priv, pipe_0x0040, 0x0040);
@@ -549,55 +546,55 @@ nv17_graph_mthd_lma_window(struct nouveau_object *object, u32 mthd,
nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
return 0;
}
static int
-nv17_graph_mthd_lma_enable(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv17_gr_mthd_lma_enable(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv10_graph_chan *chan = (void *)object->parent;
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_chan *chan = (void *)object->parent;
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
nv_mask(priv, NV10_PGRAPH_DEBUG_4, 0x00000100, 0x00000100);
nv_mask(priv, 0x4006b0, 0x08000000, 0x08000000);
return 0;
}
-static struct nouveau_omthds
+static struct nvkm_omthds
nv17_celcius_omthds[] = {
- { 0x1638, 0x1638, nv17_graph_mthd_lma_window },
- { 0x163c, 0x163c, nv17_graph_mthd_lma_window },
- { 0x1640, 0x1640, nv17_graph_mthd_lma_window },
- { 0x1644, 0x1644, nv17_graph_mthd_lma_window },
- { 0x1658, 0x1658, nv17_graph_mthd_lma_enable },
+ { 0x1638, 0x1638, nv17_gr_mthd_lma_window },
+ { 0x163c, 0x163c, nv17_gr_mthd_lma_window },
+ { 0x1640, 0x1640, nv17_gr_mthd_lma_window },
+ { 0x1644, 0x1644, nv17_gr_mthd_lma_window },
+ { 0x1658, 0x1658, nv17_gr_mthd_lma_enable },
{}
};
-static struct nouveau_oclass
-nv17_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs }, /* clip */
- { 0x0030, &nv04_graph_ofuncs }, /* null */
- { 0x0039, &nv04_graph_ofuncs }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs }, /* rop */
- { 0x0044, &nv04_graph_ofuncs }, /* pattern */
- { 0x004a, &nv04_graph_ofuncs }, /* gdi */
- { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */
- { 0x005f, &nv04_graph_ofuncs }, /* blit */
- { 0x0062, &nv04_graph_ofuncs }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs }, /* ifc */
- { 0x009f, &nv04_graph_ofuncs }, /* blit */
- { 0x0093, &nv04_graph_ofuncs }, /* surf3d */
- { 0x0094, &nv04_graph_ofuncs }, /* ttri */
- { 0x0095, &nv04_graph_ofuncs }, /* mtri */
- { 0x0099, &nv04_graph_ofuncs, nv17_celcius_omthds },
+static struct nvkm_oclass
+nv17_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs }, /* null */
+ { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs }, /* pattern */
+ { 0x004a, &nv04_gr_ofuncs }, /* gdi */
+ { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
+ { 0x005f, &nv04_gr_ofuncs }, /* blit */
+ { 0x0062, &nv04_gr_ofuncs }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs }, /* ifc */
+ { 0x009f, &nv04_gr_ofuncs }, /* blit */
+ { 0x0093, &nv04_gr_ofuncs }, /* surf3d */
+ { 0x0094, &nv04_gr_ofuncs }, /* ttri */
+ { 0x0095, &nv04_gr_ofuncs }, /* mtri */
+ { 0x0099, &nv04_gr_ofuncs, nv17_celcius_omthds },
{},
};
@@ -605,10 +602,10 @@ nv17_graph_sclass[] = {
* PGRAPH context
******************************************************************************/
-static struct nv10_graph_chan *
-nv10_graph_channel(struct nv10_graph_priv *priv)
+static struct nv10_gr_chan *
+nv10_gr_channel(struct nv10_gr_priv *priv)
{
- struct nv10_graph_chan *chan = NULL;
+ struct nv10_gr_chan *chan = NULL;
if (nv_rd32(priv, 0x400144) & 0x00010000) {
int chid = nv_rd32(priv, 0x400148) >> 24;
if (chid < ARRAY_SIZE(priv->chan))
@@ -618,9 +615,9 @@ nv10_graph_channel(struct nv10_graph_priv *priv)
}
static void
-nv10_graph_save_pipe(struct nv10_graph_chan *chan)
+nv10_gr_save_pipe(struct nv10_gr_chan *chan)
{
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
struct pipe_state *pipe = &chan->pipe_state;
PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400);
@@ -636,14 +633,14 @@ nv10_graph_save_pipe(struct nv10_graph_chan *chan)
}
static void
-nv10_graph_load_pipe(struct nv10_graph_chan *chan)
+nv10_gr_load_pipe(struct nv10_gr_chan *chan)
{
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
struct pipe_state *pipe = &chan->pipe_state;
u32 xfmode0, xfmode1;
int i;
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
/* XXX check haiku comments */
xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0);
xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1);
@@ -668,7 +665,7 @@ nv10_graph_load_pipe(struct nv10_graph_chan *chan)
PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
/* restore XFMODE */
nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0);
@@ -682,13 +679,13 @@ nv10_graph_load_pipe(struct nv10_graph_chan *chan)
PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400);
PIPE_RESTORE(priv, pipe->pipe_0x0000, 0x0000);
PIPE_RESTORE(priv, pipe->pipe_0x0040, 0x0040);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
}
static void
-nv10_graph_create_pipe(struct nv10_graph_chan *chan)
+nv10_gr_create_pipe(struct nv10_gr_chan *chan)
{
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
struct pipe_state *pipe_state = &chan->pipe_state;
u32 *pipe_state_addr;
int i;
@@ -841,11 +838,11 @@ nv10_graph_create_pipe(struct nv10_graph_chan *chan)
}
static int
-nv10_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg)
+nv10_gr_ctx_regs_find_offset(struct nv10_gr_priv *priv, int reg)
{
int i;
- for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) {
- if (nv10_graph_ctx_regs[i] == reg)
+ for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++) {
+ if (nv10_gr_ctx_regs[i] == reg)
return i;
}
nv_error(priv, "unknow offset nv10_ctx_regs %d\n", reg);
@@ -853,11 +850,11 @@ nv10_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg)
}
static int
-nv17_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg)
+nv17_gr_ctx_regs_find_offset(struct nv10_gr_priv *priv, int reg)
{
int i;
- for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) {
- if (nv17_graph_ctx_regs[i] == reg)
+ for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++) {
+ if (nv17_gr_ctx_regs[i] == reg)
return i;
}
nv_error(priv, "unknow offset nv17_ctx_regs %d\n", reg);
@@ -865,9 +862,9 @@ nv17_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg)
}
static void
-nv10_graph_load_dma_vtxbuf(struct nv10_graph_chan *chan, int chid, u32 inst)
+nv10_gr_load_dma_vtxbuf(struct nv10_gr_chan *chan, int chid, u32 inst)
{
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
u32 st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
u32 ctx_user, ctx_switch[5];
int i, subchan = -1;
@@ -935,25 +932,25 @@ nv10_graph_load_dma_vtxbuf(struct nv10_graph_chan *chan, int chid, u32 inst)
}
static int
-nv10_graph_load_context(struct nv10_graph_chan *chan, int chid)
+nv10_gr_load_context(struct nv10_gr_chan *chan, int chid)
{
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
u32 inst;
int i;
- for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
- nv_wr32(priv, nv10_graph_ctx_regs[i], chan->nv10[i]);
+ for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
+ nv_wr32(priv, nv10_gr_ctx_regs[i], chan->nv10[i]);
if (nv_device(priv)->card_type >= NV_11 &&
nv_device(priv)->chipset >= 0x17) {
- for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
- nv_wr32(priv, nv17_graph_ctx_regs[i], chan->nv17[i]);
+ for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
+ nv_wr32(priv, nv17_gr_ctx_regs[i], chan->nv17[i]);
}
- nv10_graph_load_pipe(chan);
+ nv10_gr_load_pipe(chan);
inst = nv_rd32(priv, NV10_PGRAPH_GLOBALSTATE1) & 0xffff;
- nv10_graph_load_dma_vtxbuf(chan, chid, inst);
+ nv10_gr_load_dma_vtxbuf(chan, chid, inst);
nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, chid << 24);
@@ -962,21 +959,21 @@ nv10_graph_load_context(struct nv10_graph_chan *chan, int chid)
}
static int
-nv10_graph_unload_context(struct nv10_graph_chan *chan)
+nv10_gr_unload_context(struct nv10_gr_chan *chan)
{
- struct nv10_graph_priv *priv = nv10_graph_priv(chan);
+ struct nv10_gr_priv *priv = nv10_gr_priv(chan);
int i;
- for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
- chan->nv10[i] = nv_rd32(priv, nv10_graph_ctx_regs[i]);
+ for (i = 0; i < ARRAY_SIZE(nv10_gr_ctx_regs); i++)
+ chan->nv10[i] = nv_rd32(priv, nv10_gr_ctx_regs[i]);
if (nv_device(priv)->card_type >= NV_11 &&
nv_device(priv)->chipset >= 0x17) {
- for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++)
- chan->nv17[i] = nv_rd32(priv, nv17_graph_ctx_regs[i]);
+ for (i = 0; i < ARRAY_SIZE(nv17_gr_ctx_regs); i++)
+ chan->nv17[i] = nv_rd32(priv, nv17_gr_ctx_regs[i]);
}
- nv10_graph_save_pipe(chan);
+ nv10_gr_save_pipe(chan);
nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000);
@@ -984,55 +981,54 @@ nv10_graph_unload_context(struct nv10_graph_chan *chan)
}
static void
-nv10_graph_context_switch(struct nv10_graph_priv *priv)
+nv10_gr_context_switch(struct nv10_gr_priv *priv)
{
- struct nv10_graph_chan *prev = NULL;
- struct nv10_graph_chan *next = NULL;
+ struct nv10_gr_chan *prev = NULL;
+ struct nv10_gr_chan *next = NULL;
unsigned long flags;
int chid;
spin_lock_irqsave(&priv->lock, flags);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
/* If previous context is valid, we need to save it */
- prev = nv10_graph_channel(priv);
+ prev = nv10_gr_channel(priv);
if (prev)
- nv10_graph_unload_context(prev);
+ nv10_gr_unload_context(prev);
/* load context for next channel */
chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
next = priv->chan[chid];
if (next)
- nv10_graph_load_context(next, chid);
+ nv10_gr_load_context(next, chid);
spin_unlock_irqrestore(&priv->lock, flags);
}
#define NV_WRITE_CTX(reg, val) do { \
- int offset = nv10_graph_ctx_regs_find_offset(priv, reg); \
+ int offset = nv10_gr_ctx_regs_find_offset(priv, reg); \
if (offset > 0) \
chan->nv10[offset] = val; \
} while (0)
#define NV17_WRITE_CTX(reg, val) do { \
- int offset = nv17_graph_ctx_regs_find_offset(priv, reg); \
+ int offset = nv17_gr_ctx_regs_find_offset(priv, reg); \
if (offset > 0) \
chan->nv17[offset] = val; \
} while (0)
static int
-nv10_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv10_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fifo_chan *fifo = (void *)parent;
- struct nv10_graph_priv *priv = (void *)engine;
- struct nv10_graph_chan *chan;
+ struct nvkm_fifo_chan *fifo = (void *)parent;
+ struct nv10_gr_priv *priv = (void *)engine;
+ struct nv10_gr_chan *chan;
unsigned long flags;
int ret;
- ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
+ ret = nvkm_object_create(parent, engine, oclass, 0, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -1042,7 +1038,7 @@ nv10_graph_context_ctor(struct nouveau_object *parent,
*pobject = nv_object(priv->chan[fifo->chid]);
atomic_inc(&(*pobject)->refcount);
spin_unlock_irqrestore(&priv->lock, flags);
- nouveau_object_destroy(&chan->base);
+ nvkm_object_destroy(&chan->base);
return 1;
}
@@ -1066,7 +1062,7 @@ nv10_graph_context_ctor(struct nouveau_object *parent,
}
NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->chid << 24);
- nv10_graph_create_pipe(chan);
+ nv10_gr_create_pipe(chan);
priv->chan[fifo->chid] = chan;
chan->chid = fifo->chid;
@@ -1075,44 +1071,44 @@ nv10_graph_context_ctor(struct nouveau_object *parent,
}
static void
-nv10_graph_context_dtor(struct nouveau_object *object)
+nv10_gr_context_dtor(struct nvkm_object *object)
{
- struct nv10_graph_priv *priv = (void *)object->engine;
- struct nv10_graph_chan *chan = (void *)object;
+ struct nv10_gr_priv *priv = (void *)object->engine;
+ struct nv10_gr_chan *chan = (void *)object;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
priv->chan[chan->chid] = NULL;
spin_unlock_irqrestore(&priv->lock, flags);
- nouveau_object_destroy(&chan->base);
+ nvkm_object_destroy(&chan->base);
}
static int
-nv10_graph_context_fini(struct nouveau_object *object, bool suspend)
+nv10_gr_context_fini(struct nvkm_object *object, bool suspend)
{
- struct nv10_graph_priv *priv = (void *)object->engine;
- struct nv10_graph_chan *chan = (void *)object;
+ struct nv10_gr_priv *priv = (void *)object->engine;
+ struct nv10_gr_chan *chan = (void *)object;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
- if (nv10_graph_channel(priv) == chan)
- nv10_graph_unload_context(chan);
+ if (nv10_gr_channel(priv) == chan)
+ nv10_gr_unload_context(chan);
nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&priv->lock, flags);
- return nouveau_object_fini(&chan->base, suspend);
+ return nvkm_object_fini(&chan->base, suspend);
}
-static struct nouveau_oclass
-nv10_graph_cclass = {
+static struct nvkm_oclass
+nv10_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x10),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv10_graph_context_ctor,
- .dtor = nv10_graph_context_dtor,
- .init = nouveau_object_init,
- .fini = nv10_graph_context_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv10_gr_context_ctor,
+ .dtor = nv10_gr_context_dtor,
+ .init = nvkm_object_init,
+ .fini = nv10_gr_context_fini,
},
};
@@ -1121,15 +1117,15 @@ nv10_graph_cclass = {
******************************************************************************/
static void
-nv10_graph_tile_prog(struct nouveau_engine *engine, int i)
+nv10_gr_tile_prog(struct nvkm_engine *engine, int i)
{
- struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
- struct nouveau_fifo *pfifo = nouveau_fifo(engine);
- struct nv10_graph_priv *priv = (void *)engine;
+ struct nvkm_fb_tile *tile = &nvkm_fb(engine)->tile.region[i];
+ struct nvkm_fifo *pfifo = nvkm_fifo(engine);
+ struct nv10_gr_priv *priv = (void *)engine;
unsigned long flags;
pfifo->pause(pfifo, &flags);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
nv_wr32(priv, NV10_PGRAPH_TLIMIT(i), tile->limit);
nv_wr32(priv, NV10_PGRAPH_TSIZE(i), tile->pitch);
@@ -1138,13 +1134,13 @@ nv10_graph_tile_prog(struct nouveau_engine *engine, int i)
pfifo->start(pfifo, &flags);
}
-const struct nouveau_bitfield nv10_graph_intr_name[] = {
+const struct nvkm_bitfield nv10_gr_intr_name[] = {
{ NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
{ NV_PGRAPH_INTR_ERROR, "ERROR" },
{}
};
-const struct nouveau_bitfield nv10_graph_nstatus[] = {
+const struct nvkm_bitfield nv10_gr_nstatus[] = {
{ NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" },
{ NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" },
{ NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" },
@@ -1153,12 +1149,12 @@ const struct nouveau_bitfield nv10_graph_nstatus[] = {
};
static void
-nv10_graph_intr(struct nouveau_subdev *subdev)
+nv10_gr_intr(struct nvkm_subdev *subdev)
{
- struct nv10_graph_priv *priv = (void *)subdev;
- struct nv10_graph_chan *chan = NULL;
- struct nouveau_namedb *namedb = NULL;
- struct nouveau_handle *handle = NULL;
+ struct nv10_gr_priv *priv = (void *)subdev;
+ struct nv10_gr_chan *chan = NULL;
+ struct nvkm_namedb *namedb = NULL;
+ struct nvkm_handle *handle = NULL;
u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
@@ -1179,7 +1175,7 @@ nv10_graph_intr(struct nouveau_subdev *subdev)
if (stat & NV_PGRAPH_INTR_ERROR) {
if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
- handle = nouveau_namedb_get_class(namedb, class);
+ handle = nvkm_namedb_get_class(namedb, class);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~NV_PGRAPH_INTR_ERROR;
}
@@ -1189,7 +1185,7 @@ nv10_graph_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
- nv10_graph_context_switch(priv);
+ nv10_gr_context_switch(priv);
}
nv_wr32(priv, NV03_PGRAPH_INTR, stat);
@@ -1197,68 +1193,68 @@ nv10_graph_intr(struct nouveau_subdev *subdev)
if (show) {
nv_error(priv, "%s", "");
- nouveau_bitfield_print(nv10_graph_intr_name, show);
+ nvkm_bitfield_print(nv10_gr_intr_name, show);
pr_cont(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ nvkm_bitfield_print(nv04_gr_nsource, nsource);
pr_cont(" nstatus:");
- nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
+ nvkm_bitfield_print(nv10_gr_nstatus, nstatus);
pr_cont("\n");
nv_error(priv,
"ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, nouveau_client_name(chan), subc, class, mthd,
+ chid, nvkm_client_name(chan), subc, class, mthd,
data);
}
- nouveau_namedb_put(handle);
+ nvkm_namedb_put(handle);
}
static int
-nv10_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv10_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv10_graph_priv *priv;
+ struct nv10_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv10_graph_intr;
- nv_engine(priv)->cclass = &nv10_graph_cclass;
+ nv_subdev(priv)->intr = nv10_gr_intr;
+ nv_engine(priv)->cclass = &nv10_gr_cclass;
if (nv_device(priv)->chipset <= 0x10)
- nv_engine(priv)->sclass = nv10_graph_sclass;
+ nv_engine(priv)->sclass = nv10_gr_sclass;
else
if (nv_device(priv)->chipset < 0x17 ||
nv_device(priv)->card_type < NV_11)
- nv_engine(priv)->sclass = nv15_graph_sclass;
+ nv_engine(priv)->sclass = nv15_gr_sclass;
else
- nv_engine(priv)->sclass = nv17_graph_sclass;
+ nv_engine(priv)->sclass = nv17_gr_sclass;
- nv_engine(priv)->tile_prog = nv10_graph_tile_prog;
+ nv_engine(priv)->tile_prog = nv10_gr_tile_prog;
spin_lock_init(&priv->lock);
return 0;
}
static void
-nv10_graph_dtor(struct nouveau_object *object)
+nv10_gr_dtor(struct nvkm_object *object)
{
- struct nv10_graph_priv *priv = (void *)object;
- nouveau_graph_destroy(&priv->base);
+ struct nv10_gr_priv *priv = (void *)object;
+ nvkm_gr_destroy(&priv->base);
}
static int
-nv10_graph_init(struct nouveau_object *object)
+nv10_gr_init(struct nvkm_object *object)
{
- struct nouveau_engine *engine = nv_engine(object);
- struct nouveau_fb *pfb = nouveau_fb(object);
- struct nv10_graph_priv *priv = (void *)engine;
+ struct nvkm_engine *engine = nv_engine(object);
+ struct nvkm_fb *pfb = nvkm_fb(object);
+ struct nv10_gr_priv *priv = (void *)engine;
int ret, i;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -1301,19 +1297,19 @@ nv10_graph_init(struct nouveau_object *object)
}
static int
-nv10_graph_fini(struct nouveau_object *object, bool suspend)
+nv10_gr_fini(struct nvkm_object *object, bool suspend)
{
- struct nv10_graph_priv *priv = (void *)object;
- return nouveau_graph_fini(&priv->base, suspend);
+ struct nv10_gr_priv *priv = (void *)object;
+ return nvkm_gr_fini(&priv->base, suspend);
}
-struct nouveau_oclass
-nv10_graph_oclass = {
+struct nvkm_oclass
+nv10_gr_oclass = {
.handle = NV_ENGINE(GR, 0x10),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv10_graph_ctor,
- .dtor = nv10_graph_dtor,
- .init = nv10_graph_init,
- .fini = nv10_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv10_gr_ctor,
+ .dtor = nv10_gr_dtor,
+ .init = nv10_gr_init,
+ .fini = nv10_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
index ceb9c746d94e..1713ffb669e8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
@@ -1,39 +1,34 @@
+#include "nv20.h"
+#include "regs.h"
+
#include <core/client.h>
-#include <core/os.h>
-#include <core/engctx.h>
+#include <core/device.h>
#include <core/handle.h>
-#include <core/enum.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-
-#include <engine/graph.h>
#include <engine/fifo.h>
-
-#include "nv20.h"
-#include "regs.h"
+#include <subdev/fb.h>
+#include <subdev/timer.h>
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-nv20_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
- { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
- { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
- { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
- { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
- { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
- { 0x0096, &nv04_graph_ofuncs, NULL }, /* celcius */
- { 0x0097, &nv04_graph_ofuncs, NULL }, /* kelvin */
- { 0x009e, &nv04_graph_ofuncs, NULL }, /* swzsurf */
- { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
+static struct nvkm_oclass
+nv20_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_gr_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_gr_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_gr_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs, NULL }, /* ifc */
+ { 0x0096, &nv04_gr_ofuncs, NULL }, /* celcius */
+ { 0x0097, &nv04_gr_ofuncs, NULL }, /* kelvin */
+ { 0x009e, &nv04_gr_ofuncs, NULL }, /* swzsurf */
+ { 0x009f, &nv04_gr_ofuncs, NULL }, /* imageblit */
{},
};
@@ -42,22 +37,20 @@ nv20_graph_sclass[] = {
******************************************************************************/
static int
-nv20_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv20_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_chan *chan;
+ struct nv20_gr_chan *chan;
int ret, i;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
- 0x37f0, 16, NVOBJ_FLAG_ZERO_ALLOC,
- &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, 0x37f0,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- chan->chid = nouveau_fifo_chan(parent)->chid;
+ chan->chid = nvkm_fifo_chan(parent)->chid;
nv_wo32(chan, 0x0000, 0x00000001 | (chan->chid << 24));
nv_wo32(chan, 0x033c, 0xffff0000);
@@ -107,13 +100,13 @@ nv20_graph_context_ctor(struct nouveau_object *parent,
}
int
-nv20_graph_context_init(struct nouveau_object *object)
+nv20_gr_context_init(struct nvkm_object *object)
{
- struct nv20_graph_priv *priv = (void *)object->engine;
- struct nv20_graph_chan *chan = (void *)object;
+ struct nv20_gr_priv *priv = (void *)object->engine;
+ struct nv20_gr_chan *chan = (void *)object;
int ret;
- ret = nouveau_graph_context_init(&chan->base);
+ ret = nvkm_gr_context_init(&chan->base);
if (ret)
return ret;
@@ -122,10 +115,10 @@ nv20_graph_context_init(struct nouveau_object *object)
}
int
-nv20_graph_context_fini(struct nouveau_object *object, bool suspend)
+nv20_gr_context_fini(struct nvkm_object *object, bool suspend)
{
- struct nv20_graph_priv *priv = (void *)object->engine;
- struct nv20_graph_chan *chan = (void *)object;
+ struct nv20_gr_priv *priv = (void *)object->engine;
+ struct nv20_gr_chan *chan = (void *)object;
int chid = -1;
nv_mask(priv, 0x400720, 0x00000001, 0x00000000);
@@ -141,19 +134,19 @@ nv20_graph_context_fini(struct nouveau_object *object, bool suspend)
nv_mask(priv, 0x400720, 0x00000001, 0x00000001);
nv_wo32(priv->ctxtab, chan->chid * 4, 0x00000000);
- return nouveau_graph_context_fini(&chan->base, suspend);
+ return nvkm_gr_context_fini(&chan->base, suspend);
}
-static struct nouveau_oclass
-nv20_graph_cclass = {
+static struct nvkm_oclass
+nv20_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x20),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv20_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = nv20_graph_context_init,
- .fini = nv20_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv20_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = nv20_gr_context_init,
+ .fini = nv20_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -162,15 +155,15 @@ nv20_graph_cclass = {
******************************************************************************/
void
-nv20_graph_tile_prog(struct nouveau_engine *engine, int i)
+nv20_gr_tile_prog(struct nvkm_engine *engine, int i)
{
- struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
- struct nouveau_fifo *pfifo = nouveau_fifo(engine);
- struct nv20_graph_priv *priv = (void *)engine;
+ struct nvkm_fb_tile *tile = &nvkm_fb(engine)->tile.region[i];
+ struct nvkm_fifo *pfifo = nvkm_fifo(engine);
+ struct nv20_gr_priv *priv = (void *)engine;
unsigned long flags;
pfifo->pause(pfifo, &flags);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
nv_wr32(priv, NV20_PGRAPH_TLIMIT(i), tile->limit);
nv_wr32(priv, NV20_PGRAPH_TSIZE(i), tile->pitch);
@@ -193,12 +186,12 @@ nv20_graph_tile_prog(struct nouveau_engine *engine, int i)
}
void
-nv20_graph_intr(struct nouveau_subdev *subdev)
+nv20_gr_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nouveau_handle *handle;
- struct nv20_graph_priv *priv = (void *)subdev;
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_object *engctx;
+ struct nvkm_handle *handle;
+ struct nv20_gr_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
@@ -210,13 +203,13 @@ nv20_graph_intr(struct nouveau_subdev *subdev)
u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff;
u32 show = stat;
- engctx = nouveau_engctx_get(engine, chid);
+ engctx = nvkm_engctx_get(engine, chid);
if (stat & NV_PGRAPH_INTR_ERROR) {
if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
- handle = nouveau_handle_get_class(engctx, class);
+ handle = nvkm_handle_get_class(engctx, class);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~NV_PGRAPH_INTR_ERROR;
- nouveau_handle_put(handle);
+ nvkm_handle_put(handle);
}
}
@@ -225,65 +218,65 @@ nv20_graph_intr(struct nouveau_subdev *subdev)
if (show) {
nv_error(priv, "%s", "");
- nouveau_bitfield_print(nv10_graph_intr_name, show);
+ nvkm_bitfield_print(nv10_gr_intr_name, show);
pr_cont(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ nvkm_bitfield_print(nv04_gr_nsource, nsource);
pr_cont(" nstatus:");
- nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
+ nvkm_bitfield_print(nv10_gr_nstatus, nstatus);
pr_cont("\n");
nv_error(priv,
"ch %d [%s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, nouveau_client_name(engctx), subc, class, mthd,
+ chid, nvkm_client_name(engctx), subc, class, mthd,
data);
}
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
static int
-nv20_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv20_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_priv *priv;
+ struct nv20_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv20_graph_intr;
- nv_engine(priv)->cclass = &nv20_graph_cclass;
- nv_engine(priv)->sclass = nv20_graph_sclass;
- nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ nv_subdev(priv)->intr = nv20_gr_intr;
+ nv_engine(priv)->cclass = &nv20_gr_cclass;
+ nv_engine(priv)->sclass = nv20_gr_sclass;
+ nv_engine(priv)->tile_prog = nv20_gr_tile_prog;
return 0;
}
void
-nv20_graph_dtor(struct nouveau_object *object)
+nv20_gr_dtor(struct nvkm_object *object)
{
- struct nv20_graph_priv *priv = (void *)object;
- nouveau_gpuobj_ref(NULL, &priv->ctxtab);
- nouveau_graph_destroy(&priv->base);
+ struct nv20_gr_priv *priv = (void *)object;
+ nvkm_gpuobj_ref(NULL, &priv->ctxtab);
+ nvkm_gr_destroy(&priv->base);
}
int
-nv20_graph_init(struct nouveau_object *object)
+nv20_gr_init(struct nvkm_object *object)
{
- struct nouveau_engine *engine = nv_engine(object);
- struct nv20_graph_priv *priv = (void *)engine;
- struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nvkm_engine *engine = nv_engine(object);
+ struct nv20_gr_priv *priv = (void *)engine;
+ struct nvkm_fb *pfb = nvkm_fb(object);
u32 tmp, vramsz;
int ret, i;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -371,13 +364,13 @@ nv20_graph_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv20_graph_oclass = {
+struct nvkm_oclass
+nv20_gr_oclass = {
.handle = NV_ENGINE(GR, 0x20),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv20_graph_ctor,
- .dtor = nv20_graph_dtor,
- .init = nv20_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv20_gr_ctor,
+ .dtor = nv20_gr_dtor,
+ .init = nv20_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h
new file mode 100644
index 000000000000..ac4dc048fed1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.h
@@ -0,0 +1,26 @@
+#ifndef __NV20_GR_H__
+#define __NV20_GR_H__
+#include <engine/gr.h>
+
+struct nv20_gr_priv {
+ struct nvkm_gr base;
+ struct nvkm_gpuobj *ctxtab;
+};
+
+struct nv20_gr_chan {
+ struct nvkm_gr_chan base;
+ int chid;
+};
+
+extern struct nvkm_oclass nv25_gr_sclass[];
+int nv20_gr_context_init(struct nvkm_object *);
+int nv20_gr_context_fini(struct nvkm_object *, bool);
+
+void nv20_gr_tile_prog(struct nvkm_engine *, int);
+void nv20_gr_intr(struct nvkm_subdev *);
+
+void nv20_gr_dtor(struct nvkm_object *);
+int nv20_gr_init(struct nvkm_object *);
+
+int nv30_gr_init(struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c
index f8a6fdd7d5e8..bc362519cebb 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c
@@ -1,36 +1,29 @@
-#include <core/os.h>
-#include <core/engctx.h>
-#include <core/enum.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-
-#include <engine/graph.h>
-
#include "nv20.h"
#include "regs.h"
+#include <engine/fifo.h>
+
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-struct nouveau_oclass
-nv25_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
- { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
- { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
- { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
- { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
- { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
- { 0x0096, &nv04_graph_ofuncs, NULL }, /* celcius */
- { 0x009e, &nv04_graph_ofuncs, NULL }, /* swzsurf */
- { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
- { 0x0597, &nv04_graph_ofuncs, NULL }, /* kelvin */
+struct nvkm_oclass
+nv25_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_gr_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_gr_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_gr_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs, NULL }, /* ifc */
+ { 0x0096, &nv04_gr_ofuncs, NULL }, /* celcius */
+ { 0x009e, &nv04_gr_ofuncs, NULL }, /* swzsurf */
+ { 0x009f, &nv04_gr_ofuncs, NULL }, /* imageblit */
+ { 0x0597, &nv04_gr_ofuncs, NULL }, /* kelvin */
{},
};
@@ -39,21 +32,20 @@ nv25_graph_sclass[] = {
******************************************************************************/
static int
-nv25_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv25_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_chan *chan;
+ struct nv20_gr_chan *chan;
int ret, i;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x3724,
- 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, 0x3724,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- chan->chid = nouveau_fifo_chan(parent)->chid;
+ chan->chid = nvkm_fifo_chan(parent)->chid;
nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
nv_wo32(chan, 0x035c, 0xffff0000);
@@ -111,16 +103,16 @@ nv25_graph_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv25_graph_cclass = {
+static struct nvkm_oclass
+nv25_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x25),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv25_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = nv20_graph_context_init,
- .fini = nv20_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv25_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = nv20_gr_context_init,
+ .fini = nv20_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -129,38 +121,38 @@ nv25_graph_cclass = {
******************************************************************************/
static int
-nv25_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv25_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_priv *priv;
+ struct nv20_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv20_graph_intr;
- nv_engine(priv)->cclass = &nv25_graph_cclass;
- nv_engine(priv)->sclass = nv25_graph_sclass;
- nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ nv_subdev(priv)->intr = nv20_gr_intr;
+ nv_engine(priv)->cclass = &nv25_gr_cclass;
+ nv_engine(priv)->sclass = nv25_gr_sclass;
+ nv_engine(priv)->tile_prog = nv20_gr_tile_prog;
return 0;
}
-struct nouveau_oclass
-nv25_graph_oclass = {
+struct nvkm_oclass
+nv25_gr_oclass = {
.handle = NV_ENGINE(GR, 0x25),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv25_graph_ctor,
- .dtor = nv20_graph_dtor,
- .init = nv20_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv25_gr_ctor,
+ .dtor = nv20_gr_dtor,
+ .init = nv20_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c
index 5de9caa2ef67..22a5096e283d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c
@@ -1,35 +1,27 @@
-#include <core/os.h>
-#include <core/engctx.h>
-#include <core/enum.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-
-#include <engine/graph.h>
-
#include "nv20.h"
#include "regs.h"
+#include <engine/fifo.h>
+
/*******************************************************************************
* PGRAPH context
******************************************************************************/
static int
-nv2a_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv2a_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_chan *chan;
+ struct nv20_gr_chan *chan;
int ret, i;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x36b0,
- 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, 0x36b0,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- chan->chid = nouveau_fifo_chan(parent)->chid;
+ chan->chid = nvkm_fifo_chan(parent)->chid;
nv_wo32(chan, 0x0000, 0x00000001 | (chan->chid << 24));
nv_wo32(chan, 0x033c, 0xffff0000);
@@ -78,16 +70,16 @@ nv2a_graph_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv2a_graph_cclass = {
+static struct nvkm_oclass
+nv2a_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x2a),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv2a_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = nv20_graph_context_init,
- .fini = nv20_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv2a_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = nv20_gr_context_init,
+ .fini = nv20_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -96,38 +88,38 @@ nv2a_graph_cclass = {
******************************************************************************/
static int
-nv2a_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv2a_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_priv *priv;
+ struct nv20_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv20_graph_intr;
- nv_engine(priv)->cclass = &nv2a_graph_cclass;
- nv_engine(priv)->sclass = nv25_graph_sclass;
- nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ nv_subdev(priv)->intr = nv20_gr_intr;
+ nv_engine(priv)->cclass = &nv2a_gr_cclass;
+ nv_engine(priv)->sclass = nv25_gr_sclass;
+ nv_engine(priv)->tile_prog = nv20_gr_tile_prog;
return 0;
}
-struct nouveau_oclass
-nv2a_graph_oclass = {
+struct nvkm_oclass
+nv2a_gr_oclass = {
.handle = NV_ENGINE(GR, 0x2a),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv2a_graph_ctor,
- .dtor = nv20_graph_dtor,
- .init = nv20_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv2a_gr_ctor,
+ .dtor = nv20_gr_dtor,
+ .init = nv20_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c
index 2f9dbc709389..dcc84eb54fb6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c
@@ -1,38 +1,33 @@
-#include <core/os.h>
-#include <core/engctx.h>
-#include <core/enum.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-
-#include <engine/graph.h>
-
#include "nv20.h"
#include "regs.h"
+#include <core/device.h>
+#include <engine/fifo.h>
+#include <subdev/fb.h>
+
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-nv30_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
- { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
- { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
- { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
- { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
- { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
- { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
- { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */
- { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */
- { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */
- { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */
- { 0x0397, &nv04_graph_ofuncs, NULL }, /* rankine */
+static struct nvkm_oclass
+nv30_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_gr_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_gr_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_gr_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv04_gr_ofuncs, NULL }, /* imageblit */
+ { 0x0362, &nv04_gr_ofuncs, NULL }, /* surf2d (nv30) */
+ { 0x0389, &nv04_gr_ofuncs, NULL }, /* sifm (nv30) */
+ { 0x038a, &nv04_gr_ofuncs, NULL }, /* ifc (nv30) */
+ { 0x039e, &nv04_gr_ofuncs, NULL }, /* swzsurf (nv30) */
+ { 0x0397, &nv04_gr_ofuncs, NULL }, /* rankine */
{},
};
@@ -41,21 +36,20 @@ nv30_graph_sclass[] = {
******************************************************************************/
static int
-nv30_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv30_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_chan *chan;
+ struct nv20_gr_chan *chan;
int ret, i;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x5f48,
- 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, 0x5f48,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- chan->chid = nouveau_fifo_chan(parent)->chid;
+ chan->chid = nvkm_fifo_chan(parent)->chid;
nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
nv_wo32(chan, 0x0410, 0x00000101);
@@ -112,16 +106,16 @@ nv30_graph_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv30_graph_cclass = {
+static struct nvkm_oclass
+nv30_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x30),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv30_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = nv20_graph_context_init,
- .fini = nv20_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv30_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = nv20_gr_context_init,
+ .fini = nv20_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -130,40 +124,40 @@ nv30_graph_cclass = {
******************************************************************************/
static int
-nv30_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv30_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_priv *priv;
+ struct nv20_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv20_graph_intr;
- nv_engine(priv)->cclass = &nv30_graph_cclass;
- nv_engine(priv)->sclass = nv30_graph_sclass;
- nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ nv_subdev(priv)->intr = nv20_gr_intr;
+ nv_engine(priv)->cclass = &nv30_gr_cclass;
+ nv_engine(priv)->sclass = nv30_gr_sclass;
+ nv_engine(priv)->tile_prog = nv20_gr_tile_prog;
return 0;
}
int
-nv30_graph_init(struct nouveau_object *object)
+nv30_gr_init(struct nvkm_object *object)
{
- struct nouveau_engine *engine = nv_engine(object);
- struct nv20_graph_priv *priv = (void *)engine;
- struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nvkm_engine *engine = nv_engine(object);
+ struct nv20_gr_priv *priv = (void *)engine;
+ struct nvkm_fb *pfb = nvkm_fb(object);
int ret, i;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -225,13 +219,13 @@ nv30_graph_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv30_graph_oclass = {
+struct nvkm_oclass
+nv30_gr_oclass = {
.handle = NV_ENGINE(GR, 0x30),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv30_graph_ctor,
- .dtor = nv20_graph_dtor,
- .init = nv30_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv30_gr_ctor,
+ .dtor = nv20_gr_dtor,
+ .init = nv30_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c
index 34dd26c70b64..985b7f3306ae 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c
@@ -1,38 +1,31 @@
-#include <core/os.h>
-#include <core/engctx.h>
-#include <core/enum.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-
-#include <engine/graph.h>
-
#include "nv20.h"
#include "regs.h"
+#include <engine/fifo.h>
+
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-nv34_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
- { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
- { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
- { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
- { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
- { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
- { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
- { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */
- { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */
- { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */
- { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */
- { 0x0697, &nv04_graph_ofuncs, NULL }, /* rankine */
+static struct nvkm_oclass
+nv34_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_gr_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_gr_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_gr_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv04_gr_ofuncs, NULL }, /* imageblit */
+ { 0x0362, &nv04_gr_ofuncs, NULL }, /* surf2d (nv30) */
+ { 0x0389, &nv04_gr_ofuncs, NULL }, /* sifm (nv30) */
+ { 0x038a, &nv04_gr_ofuncs, NULL }, /* ifc (nv30) */
+ { 0x039e, &nv04_gr_ofuncs, NULL }, /* swzsurf (nv30) */
+ { 0x0697, &nv04_gr_ofuncs, NULL }, /* rankine */
{},
};
@@ -41,21 +34,20 @@ nv34_graph_sclass[] = {
******************************************************************************/
static int
-nv34_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv34_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_chan *chan;
+ struct nv20_gr_chan *chan;
int ret, i;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x46dc,
- 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, 0x46dc,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- chan->chid = nouveau_fifo_chan(parent)->chid;
+ chan->chid = nvkm_fifo_chan(parent)->chid;
nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
nv_wo32(chan, 0x040c, 0x01000101);
@@ -112,16 +104,16 @@ nv34_graph_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv34_graph_cclass = {
+static struct nvkm_oclass
+nv34_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x34),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv34_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = nv20_graph_context_init,
- .fini = nv20_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv34_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = nv20_gr_context_init,
+ .fini = nv20_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -130,38 +122,38 @@ nv34_graph_cclass = {
******************************************************************************/
static int
-nv34_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv34_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_priv *priv;
+ struct nv20_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv20_graph_intr;
- nv_engine(priv)->cclass = &nv34_graph_cclass;
- nv_engine(priv)->sclass = nv34_graph_sclass;
- nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ nv_subdev(priv)->intr = nv20_gr_intr;
+ nv_engine(priv)->cclass = &nv34_gr_cclass;
+ nv_engine(priv)->sclass = nv34_gr_sclass;
+ nv_engine(priv)->tile_prog = nv20_gr_tile_prog;
return 0;
}
-struct nouveau_oclass
-nv34_graph_oclass = {
+struct nvkm_oclass
+nv34_gr_oclass = {
.handle = NV_ENGINE(GR, 0x34),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv34_graph_ctor,
- .dtor = nv20_graph_dtor,
- .init = nv30_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv34_gr_ctor,
+ .dtor = nv20_gr_dtor,
+ .init = nv30_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c
index 2fb5756d9f66..707625f19ff5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c
@@ -1,36 +1,31 @@
-#include <core/os.h>
-#include <core/engctx.h>
-#include <core/enum.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-
#include "nv20.h"
#include "regs.h"
+#include <engine/fifo.h>
+
/*******************************************************************************
* Graphics object classes
******************************************************************************/
-static struct nouveau_oclass
-nv35_graph_sclass[] = {
- { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */
- { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */
- { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */
- { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */
- { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */
- { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */
- { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */
- { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */
- { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */
- { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */
- { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */
- { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */
- { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */
- { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */
- { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */
- { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */
- { 0x0497, &nv04_graph_ofuncs, NULL }, /* rankine */
+static struct nvkm_oclass
+nv35_gr_sclass[] = {
+ { 0x0012, &nv04_gr_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv04_gr_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv04_gr_ofuncs, NULL }, /* null */
+ { 0x0039, &nv04_gr_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv04_gr_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv04_gr_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv04_gr_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv04_gr_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv04_gr_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv04_gr_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv04_gr_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv04_gr_ofuncs, NULL }, /* imageblit */
+ { 0x0362, &nv04_gr_ofuncs, NULL }, /* surf2d (nv30) */
+ { 0x0389, &nv04_gr_ofuncs, NULL }, /* sifm (nv30) */
+ { 0x038a, &nv04_gr_ofuncs, NULL }, /* ifc (nv30) */
+ { 0x039e, &nv04_gr_ofuncs, NULL }, /* swzsurf (nv30) */
+ { 0x0497, &nv04_gr_ofuncs, NULL }, /* rankine */
{},
};
@@ -39,21 +34,20 @@ nv35_graph_sclass[] = {
******************************************************************************/
static int
-nv35_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv35_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_chan *chan;
+ struct nv20_gr_chan *chan;
int ret, i;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x577c,
- 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, 0x577c,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
- chan->chid = nouveau_fifo_chan(parent)->chid;
+ chan->chid = nvkm_fifo_chan(parent)->chid;
nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24));
nv_wo32(chan, 0x040c, 0x00000101);
@@ -110,16 +104,16 @@ nv35_graph_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv35_graph_cclass = {
+static struct nvkm_oclass
+nv35_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x35),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv35_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = nv20_graph_context_init,
- .fini = nv20_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv35_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = nv20_gr_context_init,
+ .fini = nv20_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -128,38 +122,38 @@ nv35_graph_cclass = {
******************************************************************************/
static int
-nv35_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv35_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv20_graph_priv *priv;
+ struct nv20_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv20_graph_intr;
- nv_engine(priv)->cclass = &nv35_graph_cclass;
- nv_engine(priv)->sclass = nv35_graph_sclass;
- nv_engine(priv)->tile_prog = nv20_graph_tile_prog;
+ nv_subdev(priv)->intr = nv20_gr_intr;
+ nv_engine(priv)->cclass = &nv35_gr_cclass;
+ nv_engine(priv)->sclass = nv35_gr_sclass;
+ nv_engine(priv)->tile_prog = nv20_gr_tile_prog;
return 0;
}
-struct nouveau_oclass
-nv35_graph_oclass = {
+struct nvkm_oclass
+nv35_gr_oclass = {
.handle = NV_ENGINE(GR, 0x35),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv35_graph_ctor,
- .dtor = nv20_graph_dtor,
- .init = nv30_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv35_gr_ctor,
+ .dtor = nv20_gr_dtor,
+ .init = nv30_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
index 4f401174868d..7e1937980e3f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
@@ -21,34 +21,28 @@
*
* Authors: Ben Skeggs
*/
+#include "nv40.h"
+#include "regs.h"
#include <core/client.h>
-#include <core/os.h>
#include <core/handle.h>
-#include <core/engctx.h>
-
#include <subdev/fb.h>
#include <subdev/timer.h>
-
-#include <engine/graph.h>
#include <engine/fifo.h>
-#include "nv40.h"
-#include "regs.h"
-
-struct nv40_graph_priv {
- struct nouveau_graph base;
+struct nv40_gr_priv {
+ struct nvkm_gr base;
u32 size;
};
-struct nv40_graph_chan {
- struct nouveau_graph_chan base;
+struct nv40_gr_chan {
+ struct nvkm_gr_chan base;
};
static u64
-nv40_graph_units(struct nouveau_graph *graph)
+nv40_gr_units(struct nvkm_gr *gr)
{
- struct nv40_graph_priv *priv = (void *)graph;
+ struct nv40_gr_priv *priv = (void *)gr;
return nv_rd32(priv, 0x1540);
}
@@ -58,16 +52,15 @@ nv40_graph_units(struct nouveau_graph *graph)
******************************************************************************/
static int
-nv40_graph_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_gr_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_gpuobj *obj;
+ struct nvkm_gpuobj *obj;
int ret;
- ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
- 20, 16, 0, &obj);
+ ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
+ 20, 16, 0, &obj);
*pobject = nv_object(obj);
if (ret)
return ret;
@@ -83,55 +76,55 @@ nv40_graph_object_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
-nv40_graph_ofuncs = {
- .ctor = nv40_graph_object_ctor,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
+static struct nvkm_ofuncs
+nv40_gr_ofuncs = {
+ .ctor = nv40_gr_object_ctor,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
};
-static struct nouveau_oclass
-nv40_graph_sclass[] = {
- { 0x0012, &nv40_graph_ofuncs, NULL }, /* beta1 */
- { 0x0019, &nv40_graph_ofuncs, NULL }, /* clip */
- { 0x0030, &nv40_graph_ofuncs, NULL }, /* null */
- { 0x0039, &nv40_graph_ofuncs, NULL }, /* m2mf */
- { 0x0043, &nv40_graph_ofuncs, NULL }, /* rop */
- { 0x0044, &nv40_graph_ofuncs, NULL }, /* patt */
- { 0x004a, &nv40_graph_ofuncs, NULL }, /* gdi */
- { 0x0062, &nv40_graph_ofuncs, NULL }, /* surf2d */
- { 0x0072, &nv40_graph_ofuncs, NULL }, /* beta4 */
- { 0x0089, &nv40_graph_ofuncs, NULL }, /* sifm */
- { 0x008a, &nv40_graph_ofuncs, NULL }, /* ifc */
- { 0x009f, &nv40_graph_ofuncs, NULL }, /* imageblit */
- { 0x3062, &nv40_graph_ofuncs, NULL }, /* surf2d (nv40) */
- { 0x3089, &nv40_graph_ofuncs, NULL }, /* sifm (nv40) */
- { 0x309e, &nv40_graph_ofuncs, NULL }, /* swzsurf (nv40) */
- { 0x4097, &nv40_graph_ofuncs, NULL }, /* curie */
+static struct nvkm_oclass
+nv40_gr_sclass[] = {
+ { 0x0012, &nv40_gr_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv40_gr_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv40_gr_ofuncs, NULL }, /* null */
+ { 0x0039, &nv40_gr_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv40_gr_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv40_gr_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv40_gr_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv40_gr_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv40_gr_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv40_gr_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv40_gr_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv40_gr_ofuncs, NULL }, /* imageblit */
+ { 0x3062, &nv40_gr_ofuncs, NULL }, /* surf2d (nv40) */
+ { 0x3089, &nv40_gr_ofuncs, NULL }, /* sifm (nv40) */
+ { 0x309e, &nv40_gr_ofuncs, NULL }, /* swzsurf (nv40) */
+ { 0x4097, &nv40_gr_ofuncs, NULL }, /* curie */
{},
};
-static struct nouveau_oclass
-nv44_graph_sclass[] = {
- { 0x0012, &nv40_graph_ofuncs, NULL }, /* beta1 */
- { 0x0019, &nv40_graph_ofuncs, NULL }, /* clip */
- { 0x0030, &nv40_graph_ofuncs, NULL }, /* null */
- { 0x0039, &nv40_graph_ofuncs, NULL }, /* m2mf */
- { 0x0043, &nv40_graph_ofuncs, NULL }, /* rop */
- { 0x0044, &nv40_graph_ofuncs, NULL }, /* patt */
- { 0x004a, &nv40_graph_ofuncs, NULL }, /* gdi */
- { 0x0062, &nv40_graph_ofuncs, NULL }, /* surf2d */
- { 0x0072, &nv40_graph_ofuncs, NULL }, /* beta4 */
- { 0x0089, &nv40_graph_ofuncs, NULL }, /* sifm */
- { 0x008a, &nv40_graph_ofuncs, NULL }, /* ifc */
- { 0x009f, &nv40_graph_ofuncs, NULL }, /* imageblit */
- { 0x3062, &nv40_graph_ofuncs, NULL }, /* surf2d (nv40) */
- { 0x3089, &nv40_graph_ofuncs, NULL }, /* sifm (nv40) */
- { 0x309e, &nv40_graph_ofuncs, NULL }, /* swzsurf (nv40) */
- { 0x4497, &nv40_graph_ofuncs, NULL }, /* curie */
+static struct nvkm_oclass
+nv44_gr_sclass[] = {
+ { 0x0012, &nv40_gr_ofuncs, NULL }, /* beta1 */
+ { 0x0019, &nv40_gr_ofuncs, NULL }, /* clip */
+ { 0x0030, &nv40_gr_ofuncs, NULL }, /* null */
+ { 0x0039, &nv40_gr_ofuncs, NULL }, /* m2mf */
+ { 0x0043, &nv40_gr_ofuncs, NULL }, /* rop */
+ { 0x0044, &nv40_gr_ofuncs, NULL }, /* patt */
+ { 0x004a, &nv40_gr_ofuncs, NULL }, /* gdi */
+ { 0x0062, &nv40_gr_ofuncs, NULL }, /* surf2d */
+ { 0x0072, &nv40_gr_ofuncs, NULL }, /* beta4 */
+ { 0x0089, &nv40_gr_ofuncs, NULL }, /* sifm */
+ { 0x008a, &nv40_gr_ofuncs, NULL }, /* ifc */
+ { 0x009f, &nv40_gr_ofuncs, NULL }, /* imageblit */
+ { 0x3062, &nv40_gr_ofuncs, NULL }, /* surf2d (nv40) */
+ { 0x3089, &nv40_gr_ofuncs, NULL }, /* sifm (nv40) */
+ { 0x309e, &nv40_gr_ofuncs, NULL }, /* swzsurf (nv40) */
+ { 0x4497, &nv40_gr_ofuncs, NULL }, /* curie */
{},
};
@@ -140,18 +133,16 @@ nv44_graph_sclass[] = {
******************************************************************************/
static int
-nv40_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv40_graph_priv *priv = (void *)engine;
- struct nv40_graph_chan *chan;
+ struct nv40_gr_priv *priv = (void *)engine;
+ struct nv40_gr_chan *chan;
int ret;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
- priv->size, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, priv->size,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -162,10 +153,10 @@ nv40_graph_context_ctor(struct nouveau_object *parent,
}
static int
-nv40_graph_context_fini(struct nouveau_object *object, bool suspend)
+nv40_gr_context_fini(struct nvkm_object *object, bool suspend)
{
- struct nv40_graph_priv *priv = (void *)object->engine;
- struct nv40_graph_chan *chan = (void *)object;
+ struct nv40_gr_priv *priv = (void *)object->engine;
+ struct nv40_gr_chan *chan = (void *)object;
u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4;
int ret = 0;
@@ -194,16 +185,16 @@ nv40_graph_context_fini(struct nouveau_object *object, bool suspend)
return ret;
}
-static struct nouveau_oclass
-nv40_graph_cclass = {
+static struct nvkm_oclass
+nv40_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = nv40_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv40_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = nv40_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -212,15 +203,15 @@ nv40_graph_cclass = {
******************************************************************************/
static void
-nv40_graph_tile_prog(struct nouveau_engine *engine, int i)
+nv40_gr_tile_prog(struct nvkm_engine *engine, int i)
{
- struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
- struct nouveau_fifo *pfifo = nouveau_fifo(engine);
- struct nv40_graph_priv *priv = (void *)engine;
+ struct nvkm_fb_tile *tile = &nvkm_fb(engine)->tile.region[i];
+ struct nvkm_fifo *pfifo = nvkm_fifo(engine);
+ struct nv40_gr_priv *priv = (void *)engine;
unsigned long flags;
pfifo->pause(pfifo, &flags);
- nv04_graph_idle(priv);
+ nv04_gr_idle(priv);
switch (nv_device(priv)->chipset) {
case 0x40:
@@ -290,13 +281,13 @@ nv40_graph_tile_prog(struct nouveau_engine *engine, int i)
}
static void
-nv40_graph_intr(struct nouveau_subdev *subdev)
+nv40_gr_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nouveau_handle *handle = NULL;
- struct nv40_graph_priv *priv = (void *)subdev;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_object *engctx;
+ struct nvkm_handle *handle = NULL;
+ struct nv40_gr_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR);
u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE);
u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS);
@@ -309,15 +300,15 @@ nv40_graph_intr(struct nouveau_subdev *subdev)
u32 show = stat;
int chid;
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & NV_PGRAPH_INTR_ERROR) {
if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
- handle = nouveau_handle_get_class(engctx, class);
+ handle = nvkm_handle_get_class(engctx, class);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~NV_PGRAPH_INTR_ERROR;
- nouveau_handle_put(handle);
+ nvkm_handle_put(handle);
}
if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) {
@@ -330,57 +321,57 @@ nv40_graph_intr(struct nouveau_subdev *subdev)
if (show) {
nv_error(priv, "%s", "");
- nouveau_bitfield_print(nv10_graph_intr_name, show);
+ nvkm_bitfield_print(nv10_gr_intr_name, show);
pr_cont(" nsource:");
- nouveau_bitfield_print(nv04_graph_nsource, nsource);
+ nvkm_bitfield_print(nv04_gr_nsource, nsource);
pr_cont(" nstatus:");
- nouveau_bitfield_print(nv10_graph_nstatus, nstatus);
+ nvkm_bitfield_print(nv10_gr_nstatus, nstatus);
pr_cont("\n");
nv_error(priv,
"ch %d [0x%08x %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, inst << 4, nouveau_client_name(engctx), subc,
+ chid, inst << 4, nvkm_client_name(engctx), subc,
class, mthd, data);
}
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
static int
-nv40_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv40_graph_priv *priv;
+ struct nv40_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00001000;
- nv_subdev(priv)->intr = nv40_graph_intr;
- nv_engine(priv)->cclass = &nv40_graph_cclass;
- if (nv44_graph_class(priv))
- nv_engine(priv)->sclass = nv44_graph_sclass;
+ nv_subdev(priv)->intr = nv40_gr_intr;
+ nv_engine(priv)->cclass = &nv40_gr_cclass;
+ if (nv44_gr_class(priv))
+ nv_engine(priv)->sclass = nv44_gr_sclass;
else
- nv_engine(priv)->sclass = nv40_graph_sclass;
- nv_engine(priv)->tile_prog = nv40_graph_tile_prog;
+ nv_engine(priv)->sclass = nv40_gr_sclass;
+ nv_engine(priv)->tile_prog = nv40_gr_tile_prog;
- priv->base.units = nv40_graph_units;
+ priv->base.units = nv40_gr_units;
return 0;
}
static int
-nv40_graph_init(struct nouveau_object *object)
+nv40_gr_init(struct nvkm_object *object)
{
- struct nouveau_engine *engine = nv_engine(object);
- struct nouveau_fb *pfb = nouveau_fb(object);
- struct nv40_graph_priv *priv = (void *)engine;
+ struct nvkm_engine *engine = nv_engine(object);
+ struct nvkm_fb *pfb = nvkm_fb(object);
+ struct nv40_gr_priv *priv = (void *)engine;
int ret, i, j;
u32 vramsz;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -524,13 +515,13 @@ nv40_graph_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv40_graph_oclass = {
+struct nvkm_oclass
+nv40_gr_oclass = {
.handle = NV_ENGINE(GR, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_graph_ctor,
- .dtor = _nouveau_graph_dtor,
- .init = nv40_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv40_gr_ctor,
+ .dtor = _nvkm_gr_dtor,
+ .init = nv40_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h
index ad8209377529..d852bd6de571 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h
@@ -1,16 +1,17 @@
-#ifndef __NV40_GRAPH_H__
-#define __NV40_GRAPH_H__
+#ifndef __NV40_GR_H__
+#define __NV40_GR_H__
+#include <engine/gr.h>
#include <core/device.h>
-#include <core/gpuobj.h>
+struct nvkm_gpuobj;
/* returns 1 if device is one of the nv4x using the 0x4497 object class,
* helpful to determine a number of other hardware features
*/
static inline int
-nv44_graph_class(void *priv)
+nv44_gr_class(void *priv)
{
- struct nouveau_device *device = nv_device(priv);
+ struct nvkm_device *device = nv_device(priv);
if ((device->chipset & 0xf0) == 0x60)
return 1;
@@ -18,7 +19,6 @@ nv44_graph_class(void *priv)
return !(0x0baf & (1 << (device->chipset & 0x0f)));
}
-int nv40_grctx_init(struct nouveau_device *, u32 *size);
-void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
-
+int nv40_grctx_init(struct nvkm_device *, u32 *size);
+void nv40_grctx_fill(struct nvkm_device *, struct nvkm_gpuobj *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
index 38e0aa26f1cd..270d7cd63fc7 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
@@ -21,36 +21,28 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
-#include <core/os.h>
#include <core/client.h>
+#include <core/device.h>
#include <core/handle.h>
-#include <core/engctx.h>
-#include <core/enum.h>
-
-#include <subdev/fb.h>
-#include <subdev/vm.h>
-#include <subdev/timer.h>
-
#include <engine/fifo.h>
-#include <engine/graph.h>
-
-#include "nv50.h"
+#include <subdev/timer.h>
-struct nv50_graph_priv {
- struct nouveau_graph base;
+struct nv50_gr_priv {
+ struct nvkm_gr base;
spinlock_t lock;
u32 size;
};
-struct nv50_graph_chan {
- struct nouveau_graph_chan base;
+struct nv50_gr_chan {
+ struct nvkm_gr_chan base;
};
static u64
-nv50_graph_units(struct nouveau_graph *graph)
+nv50_gr_units(struct nvkm_gr *gr)
{
- struct nv50_graph_priv *priv = (void *)graph;
+ struct nv50_gr_priv *priv = (void *)gr;
return nv_rd32(priv, 0x1540);
}
@@ -60,16 +52,15 @@ nv50_graph_units(struct nouveau_graph *graph)
******************************************************************************/
static int
-nv50_graph_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_gr_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_gpuobj *obj;
+ struct nvkm_gpuobj *obj;
int ret;
- ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
- 16, 16, 0, &obj);
+ ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
*pobject = nv_object(obj);
if (ret)
return ret;
@@ -81,65 +72,65 @@ nv50_graph_object_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
-nv50_graph_ofuncs = {
- .ctor = nv50_graph_object_ctor,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
+static struct nvkm_ofuncs
+nv50_gr_ofuncs = {
+ .ctor = nv50_gr_object_ctor,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
};
-static struct nouveau_oclass
-nv50_graph_sclass[] = {
- { 0x0030, &nv50_graph_ofuncs },
- { 0x502d, &nv50_graph_ofuncs },
- { 0x5039, &nv50_graph_ofuncs },
- { 0x5097, &nv50_graph_ofuncs },
- { 0x50c0, &nv50_graph_ofuncs },
+static struct nvkm_oclass
+nv50_gr_sclass[] = {
+ { 0x0030, &nv50_gr_ofuncs },
+ { 0x502d, &nv50_gr_ofuncs },
+ { 0x5039, &nv50_gr_ofuncs },
+ { 0x5097, &nv50_gr_ofuncs },
+ { 0x50c0, &nv50_gr_ofuncs },
{}
};
-static struct nouveau_oclass
-nv84_graph_sclass[] = {
- { 0x0030, &nv50_graph_ofuncs },
- { 0x502d, &nv50_graph_ofuncs },
- { 0x5039, &nv50_graph_ofuncs },
- { 0x50c0, &nv50_graph_ofuncs },
- { 0x8297, &nv50_graph_ofuncs },
+static struct nvkm_oclass
+g84_gr_sclass[] = {
+ { 0x0030, &nv50_gr_ofuncs },
+ { 0x502d, &nv50_gr_ofuncs },
+ { 0x5039, &nv50_gr_ofuncs },
+ { 0x50c0, &nv50_gr_ofuncs },
+ { 0x8297, &nv50_gr_ofuncs },
{}
};
-static struct nouveau_oclass
-nva0_graph_sclass[] = {
- { 0x0030, &nv50_graph_ofuncs },
- { 0x502d, &nv50_graph_ofuncs },
- { 0x5039, &nv50_graph_ofuncs },
- { 0x50c0, &nv50_graph_ofuncs },
- { 0x8397, &nv50_graph_ofuncs },
+static struct nvkm_oclass
+gt200_gr_sclass[] = {
+ { 0x0030, &nv50_gr_ofuncs },
+ { 0x502d, &nv50_gr_ofuncs },
+ { 0x5039, &nv50_gr_ofuncs },
+ { 0x50c0, &nv50_gr_ofuncs },
+ { 0x8397, &nv50_gr_ofuncs },
{}
};
-static struct nouveau_oclass
-nva3_graph_sclass[] = {
- { 0x0030, &nv50_graph_ofuncs },
- { 0x502d, &nv50_graph_ofuncs },
- { 0x5039, &nv50_graph_ofuncs },
- { 0x50c0, &nv50_graph_ofuncs },
- { 0x8597, &nv50_graph_ofuncs },
- { 0x85c0, &nv50_graph_ofuncs },
+static struct nvkm_oclass
+gt215_gr_sclass[] = {
+ { 0x0030, &nv50_gr_ofuncs },
+ { 0x502d, &nv50_gr_ofuncs },
+ { 0x5039, &nv50_gr_ofuncs },
+ { 0x50c0, &nv50_gr_ofuncs },
+ { 0x8597, &nv50_gr_ofuncs },
+ { 0x85c0, &nv50_gr_ofuncs },
{}
};
-static struct nouveau_oclass
-nvaf_graph_sclass[] = {
- { 0x0030, &nv50_graph_ofuncs },
- { 0x502d, &nv50_graph_ofuncs },
- { 0x5039, &nv50_graph_ofuncs },
- { 0x50c0, &nv50_graph_ofuncs },
- { 0x85c0, &nv50_graph_ofuncs },
- { 0x8697, &nv50_graph_ofuncs },
+static struct nvkm_oclass
+mcp89_gr_sclass[] = {
+ { 0x0030, &nv50_gr_ofuncs },
+ { 0x502d, &nv50_gr_ofuncs },
+ { 0x5039, &nv50_gr_ofuncs },
+ { 0x50c0, &nv50_gr_ofuncs },
+ { 0x85c0, &nv50_gr_ofuncs },
+ { 0x8697, &nv50_gr_ofuncs },
{}
};
@@ -148,18 +139,16 @@ nvaf_graph_sclass[] = {
******************************************************************************/
static int
-nv50_graph_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv50_graph_priv *priv = (void *)engine;
- struct nv50_graph_chan *chan;
+ struct nv50_gr_priv *priv = (void *)engine;
+ struct nv50_gr_chan *chan;
int ret;
- ret = nouveau_graph_context_create(parent, engine, oclass, NULL,
- priv->size, 0,
- NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_gr_context_create(parent, engine, oclass, NULL, priv->size,
+ 0, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -168,16 +157,16 @@ nv50_graph_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv50_graph_cclass = {
+static struct nvkm_oclass
+nv50_gr_cclass = {
.handle = NV_ENGCTX(GR, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_graph_context_ctor,
- .dtor = _nouveau_graph_context_dtor,
- .init = _nouveau_graph_context_init,
- .fini = _nouveau_graph_context_fini,
- .rd32 = _nouveau_graph_context_rd32,
- .wr32 = _nouveau_graph_context_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_gr_context_ctor,
+ .dtor = _nvkm_gr_context_dtor,
+ .init = _nvkm_gr_context_init,
+ .fini = _nvkm_gr_context_fini,
+ .rd32 = _nvkm_gr_context_rd32,
+ .wr32 = _nvkm_gr_context_wr32,
},
};
@@ -185,7 +174,7 @@ nv50_graph_cclass = {
* PGRAPH engine/subdev functions
******************************************************************************/
-static const struct nouveau_bitfield nv50_pgraph_status[] = {
+static const struct nvkm_bitfield nv50_pgr_status[] = {
{ 0x00000001, "BUSY" }, /* set when any bit is set */
{ 0x00000002, "DISPATCH" },
{ 0x00000004, "UNK2" },
@@ -214,22 +203,23 @@ static const struct nouveau_bitfield nv50_pgraph_status[] = {
{}
};
-static const char *const nv50_pgraph_vstatus_0[] = {
+static const char *const nv50_pgr_vstatus_0[] = {
"VFETCH", "CCACHE", "PREGEOM", "POSTGEOM", "VATTR", "STRMOUT", "VCLIP",
NULL
};
-static const char *const nv50_pgraph_vstatus_1[] = {
+static const char *const nv50_pgr_vstatus_1[] = {
"TPC_RAST", "TPC_PROP", "TPC_TEX", "TPC_GEOM", "TPC_MP", NULL
};
-static const char *const nv50_pgraph_vstatus_2[] = {
+static const char *const nv50_pgr_vstatus_2[] = {
"RATTR", "APLANE", "TRAST", "CLIPID", "ZCULL", "ENG2D", "RMASK",
"ROP", NULL
};
-static void nouveau_pgraph_vstatus_print(struct nv50_graph_priv *priv, int r,
- const char *const units[], u32 status)
+static void
+nvkm_pgr_vstatus_print(struct nv50_gr_priv *priv, int r,
+ const char *const units[], u32 status)
{
int i;
@@ -246,10 +236,10 @@ static void nouveau_pgraph_vstatus_print(struct nv50_graph_priv *priv, int r,
}
static int
-nv84_graph_tlb_flush(struct nouveau_engine *engine)
+g84_gr_tlb_flush(struct nvkm_engine *engine)
{
- struct nouveau_timer *ptimer = nouveau_timer(engine);
- struct nv50_graph_priv *priv = (void *)engine;
+ struct nvkm_timer *ptimer = nvkm_timer(engine);
+ struct nv50_gr_priv *priv = (void *)engine;
bool idle, timeout = false;
unsigned long flags;
u64 start;
@@ -284,15 +274,15 @@ nv84_graph_tlb_flush(struct nouveau_engine *engine)
tmp = nv_rd32(priv, 0x400700);
nv_error(priv, "PGRAPH_STATUS : 0x%08x", tmp);
- nouveau_bitfield_print(nv50_pgraph_status, tmp);
+ nvkm_bitfield_print(nv50_pgr_status, tmp);
pr_cont("\n");
- nouveau_pgraph_vstatus_print(priv, 0, nv50_pgraph_vstatus_0,
- nv_rd32(priv, 0x400380));
- nouveau_pgraph_vstatus_print(priv, 1, nv50_pgraph_vstatus_1,
- nv_rd32(priv, 0x400384));
- nouveau_pgraph_vstatus_print(priv, 2, nv50_pgraph_vstatus_2,
- nv_rd32(priv, 0x400388));
+ nvkm_pgr_vstatus_print(priv, 0, nv50_pgr_vstatus_0,
+ nv_rd32(priv, 0x400380));
+ nvkm_pgr_vstatus_print(priv, 1, nv50_pgr_vstatus_1,
+ nv_rd32(priv, 0x400384));
+ nvkm_pgr_vstatus_print(priv, 2, nv50_pgr_vstatus_2,
+ nv_rd32(priv, 0x400388));
}
@@ -304,7 +294,7 @@ nv84_graph_tlb_flush(struct nouveau_engine *engine)
return timeout ? -EBUSY : 0;
}
-static const struct nouveau_bitfield nv50_mp_exec_errors[] = {
+static const struct nvkm_bitfield nv50_mp_exec_errors[] = {
{ 0x01, "STACK_UNDERFLOW" },
{ 0x02, "STACK_MISMATCH" },
{ 0x04, "QUADON_ACTIVE" },
@@ -315,7 +305,7 @@ static const struct nouveau_bitfield nv50_mp_exec_errors[] = {
{}
};
-static const struct nouveau_bitfield nv50_mpc_traps[] = {
+static const struct nvkm_bitfield nv50_mpc_traps[] = {
{ 0x0000001, "LOCAL_LIMIT_READ" },
{ 0x0000010, "LOCAL_LIMIT_WRITE" },
{ 0x0000040, "STACK_LIMIT" },
@@ -329,7 +319,7 @@ static const struct nouveau_bitfield nv50_mpc_traps[] = {
{}
};
-static const struct nouveau_bitfield nv50_tex_traps[] = {
+static const struct nvkm_bitfield nv50_tex_traps[] = {
{ 0x00000001, "" }, /* any bit set? */
{ 0x00000002, "FAULT" },
{ 0x00000004, "STORAGE_TYPE_MISMATCH" },
@@ -338,30 +328,30 @@ static const struct nouveau_bitfield nv50_tex_traps[] = {
{}
};
-static const struct nouveau_bitfield nv50_graph_trap_m2mf[] = {
+static const struct nvkm_bitfield nv50_gr_trap_m2mf[] = {
{ 0x00000001, "NOTIFY" },
{ 0x00000002, "IN" },
{ 0x00000004, "OUT" },
{}
};
-static const struct nouveau_bitfield nv50_graph_trap_vfetch[] = {
+static const struct nvkm_bitfield nv50_gr_trap_vfetch[] = {
{ 0x00000001, "FAULT" },
{}
};
-static const struct nouveau_bitfield nv50_graph_trap_strmout[] = {
+static const struct nvkm_bitfield nv50_gr_trap_strmout[] = {
{ 0x00000001, "FAULT" },
{}
};
-static const struct nouveau_bitfield nv50_graph_trap_ccache[] = {
+static const struct nvkm_bitfield nv50_gr_trap_ccache[] = {
{ 0x00000001, "FAULT" },
{}
};
/* There must be a *lot* of these. Will take some time to gather them up. */
-const struct nouveau_enum nv50_data_error_names[] = {
+const struct nvkm_enum nv50_data_error_names[] = {
{ 0x00000003, "INVALID_OPERATION", NULL },
{ 0x00000004, "INVALID_VALUE", NULL },
{ 0x00000005, "INVALID_ENUM", NULL },
@@ -407,7 +397,7 @@ const struct nouveau_enum nv50_data_error_names[] = {
{}
};
-static const struct nouveau_bitfield nv50_graph_intr_name[] = {
+static const struct nvkm_bitfield nv50_gr_intr_name[] = {
{ 0x00000001, "NOTIFY" },
{ 0x00000002, "COMPUTE_QUERY" },
{ 0x00000010, "ILLEGAL_MTHD" },
@@ -421,7 +411,7 @@ static const struct nouveau_bitfield nv50_graph_intr_name[] = {
{}
};
-static const struct nouveau_bitfield nv50_graph_trap_prop[] = {
+static const struct nvkm_bitfield nv50_gr_trap_prop[] = {
{ 0x00000004, "SURF_WIDTH_OVERRUN" },
{ 0x00000008, "SURF_HEIGHT_OVERRUN" },
{ 0x00000010, "DST2D_FAULT" },
@@ -437,7 +427,7 @@ static const struct nouveau_bitfield nv50_graph_trap_prop[] = {
};
static void
-nv50_priv_prop_trap(struct nv50_graph_priv *priv,
+nv50_priv_prop_trap(struct nv50_gr_priv *priv,
u32 ustatus_addr, u32 ustatus, u32 tp)
{
u32 e0c = nv_rd32(priv, ustatus_addr + 0x04);
@@ -468,7 +458,7 @@ nv50_priv_prop_trap(struct nv50_graph_priv *priv,
}
if (ustatus) {
nv_error(priv, "TRAP_PROP - TP %d -", tp);
- nouveau_bitfield_print(nv50_graph_trap_prop, ustatus);
+ nvkm_bitfield_print(nv50_gr_trap_prop, ustatus);
pr_cont(" - Address %02x%08x\n", e14, e10);
}
nv_error(priv, "TRAP_PROP - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n",
@@ -476,7 +466,7 @@ nv50_priv_prop_trap(struct nv50_graph_priv *priv,
}
static void
-nv50_priv_mp_trap(struct nv50_graph_priv *priv, int tpid, int display)
+nv50_priv_mp_trap(struct nv50_gr_priv *priv, int tpid, int display)
{
u32 units = nv_rd32(priv, 0x1540);
u32 addr, mp10, status, pc, oplow, ophigh;
@@ -500,7 +490,7 @@ nv50_priv_mp_trap(struct nv50_graph_priv *priv, int tpid, int display)
ophigh = nv_rd32(priv, addr + 0x74);
nv_error(priv, "TRAP_MP_EXEC - "
"TP %d MP %d:", tpid, i);
- nouveau_bitfield_print(nv50_mp_exec_errors, status);
+ nvkm_bitfield_print(nv50_mp_exec_errors, status);
pr_cont(" at %06x warp %d, opcode %08x %08x\n",
pc&0xffffff, pc >> 24,
oplow, ophigh);
@@ -515,8 +505,8 @@ nv50_priv_mp_trap(struct nv50_graph_priv *priv, int tpid, int display)
}
static void
-nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old,
- u32 ustatus_new, int display, const char *name)
+nv50_priv_tp_trap(struct nv50_gr_priv *priv, int type, u32 ustatus_old,
+ u32 ustatus_new, int display, const char *name)
{
int tps = 0;
u32 units = nv_rd32(priv, 0x1540);
@@ -542,7 +532,7 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old,
nv_rd32(priv, r));
if (ustatus) {
nv_error(priv, "%s - TP%d:", name, i);
- nouveau_bitfield_print(nv50_tex_traps,
+ nvkm_bitfield_print(nv50_tex_traps,
ustatus);
pr_cont("\n");
ustatus = 0;
@@ -556,7 +546,7 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old,
}
if (ustatus && display) {
nv_error(priv, "%s - TP%d:", name, i);
- nouveau_bitfield_print(nv50_mpc_traps, ustatus);
+ nvkm_bitfield_print(nv50_mpc_traps, ustatus);
pr_cont("\n");
ustatus = 0;
}
@@ -580,8 +570,8 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old,
}
static int
-nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
- int chid, u64 inst, struct nouveau_object *engctx)
+nv50_gr_trap_handler(struct nv50_gr_priv *priv, u32 display,
+ int chid, u64 inst, struct nvkm_object *engctx)
{
u32 status = nv_rd32(priv, 0x400108);
u32 ustatus;
@@ -617,7 +607,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
nv_error(priv,
"ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x%08x 400808 0x%08x 400848 0x%08x\n",
chid, inst,
- nouveau_client_name(engctx), subc,
+ nvkm_client_name(engctx), subc,
class, mthd, datah, datal, addr, r848);
} else
if (display) {
@@ -642,7 +632,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
nv_error(priv,
"ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x 40084c 0x%08x\n",
chid, inst,
- nouveau_client_name(engctx), subc,
+ nvkm_client_name(engctx), subc,
class, mthd, data, addr);
} else
if (display) {
@@ -670,7 +660,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
u32 ustatus = nv_rd32(priv, 0x406800) & 0x7fffffff;
if (display) {
nv_error(priv, "TRAP_M2MF");
- nouveau_bitfield_print(nv50_graph_trap_m2mf, ustatus);
+ nvkm_bitfield_print(nv50_gr_trap_m2mf, ustatus);
pr_cont("\n");
nv_error(priv, "TRAP_M2MF %08x %08x %08x %08x\n",
nv_rd32(priv, 0x406804), nv_rd32(priv, 0x406808),
@@ -691,7 +681,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
u32 ustatus = nv_rd32(priv, 0x400c04) & 0x7fffffff;
if (display) {
nv_error(priv, "TRAP_VFETCH");
- nouveau_bitfield_print(nv50_graph_trap_vfetch, ustatus);
+ nvkm_bitfield_print(nv50_gr_trap_vfetch, ustatus);
pr_cont("\n");
nv_error(priv, "TRAP_VFETCH %08x %08x %08x %08x\n",
nv_rd32(priv, 0x400c00), nv_rd32(priv, 0x400c08),
@@ -708,7 +698,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
ustatus = nv_rd32(priv, 0x401800) & 0x7fffffff;
if (display) {
nv_error(priv, "TRAP_STRMOUT");
- nouveau_bitfield_print(nv50_graph_trap_strmout, ustatus);
+ nvkm_bitfield_print(nv50_gr_trap_strmout, ustatus);
pr_cont("\n");
nv_error(priv, "TRAP_STRMOUT %08x %08x %08x %08x\n",
nv_rd32(priv, 0x401804), nv_rd32(priv, 0x401808),
@@ -729,7 +719,7 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
ustatus = nv_rd32(priv, 0x405018) & 0x7fffffff;
if (display) {
nv_error(priv, "TRAP_CCACHE");
- nouveau_bitfield_print(nv50_graph_trap_ccache, ustatus);
+ nvkm_bitfield_print(nv50_gr_trap_ccache, ustatus);
pr_cont("\n");
nv_error(priv, "TRAP_CCACHE %08x %08x %08x %08x"
" %08x %08x %08x\n",
@@ -791,13 +781,13 @@ nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display,
}
static void
-nv50_graph_intr(struct nouveau_subdev *subdev)
+nv50_gr_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nouveau_handle *handle = NULL;
- struct nv50_graph_priv *priv = (void *)subdev;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_object *engctx;
+ struct nvkm_handle *handle = NULL;
+ struct nv50_gr_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, 0x400100);
u32 inst = nv_rd32(priv, 0x40032c) & 0x0fffffff;
u32 addr = nv_rd32(priv, 0x400704);
@@ -808,27 +798,27 @@ nv50_graph_intr(struct nouveau_subdev *subdev)
u32 show = stat, show_bitfield = stat;
int chid;
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & 0x00000010) {
- handle = nouveau_handle_get_class(engctx, class);
+ handle = nvkm_handle_get_class(engctx, class);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~0x00000010;
- nouveau_handle_put(handle);
+ nvkm_handle_put(handle);
}
if (show & 0x00100000) {
u32 ecode = nv_rd32(priv, 0x400110);
nv_error(priv, "DATA_ERROR ");
- nouveau_enum_print(nv50_data_error_names, ecode);
+ nvkm_enum_print(nv50_data_error_names, ecode);
pr_cont("\n");
show_bitfield &= ~0x00100000;
}
if (stat & 0x00200000) {
- if (!nv50_graph_trap_handler(priv, show, chid, (u64)inst << 12,
- engctx))
+ if (!nv50_gr_trap_handler(priv, show, chid, (u64)inst << 12,
+ engctx))
show &= ~0x00200000;
show_bitfield &= ~0x00200000;
}
@@ -840,43 +830,43 @@ nv50_graph_intr(struct nouveau_subdev *subdev)
show &= show_bitfield;
if (show) {
nv_error(priv, "%s", "");
- nouveau_bitfield_print(nv50_graph_intr_name, show);
+ nvkm_bitfield_print(nv50_gr_intr_name, show);
pr_cont("\n");
}
nv_error(priv,
"ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
- chid, (u64)inst << 12, nouveau_client_name(engctx),
+ chid, (u64)inst << 12, nvkm_client_name(engctx),
subc, class, mthd, data);
}
if (nv_rd32(priv, 0x400824) & (1 << 31))
nv_wr32(priv, 0x400824, nv_rd32(priv, 0x400824) & ~(1 << 31));
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
static int
-nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv50_graph_priv *priv;
+ struct nv50_gr_priv *priv;
int ret;
- ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
+ ret = nvkm_gr_create(parent, engine, oclass, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00201000;
- nv_subdev(priv)->intr = nv50_graph_intr;
- nv_engine(priv)->cclass = &nv50_graph_cclass;
+ nv_subdev(priv)->intr = nv50_gr_intr;
+ nv_engine(priv)->cclass = &nv50_gr_cclass;
- priv->base.units = nv50_graph_units;
+ priv->base.units = nv50_gr_units;
switch (nv_device(priv)->chipset) {
case 0x50:
- nv_engine(priv)->sclass = nv50_graph_sclass;
+ nv_engine(priv)->sclass = nv50_gr_sclass;
break;
case 0x84:
case 0x86:
@@ -884,20 +874,20 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
case 0x94:
case 0x96:
case 0x98:
- nv_engine(priv)->sclass = nv84_graph_sclass;
+ nv_engine(priv)->sclass = g84_gr_sclass;
break;
case 0xa0:
case 0xaa:
case 0xac:
- nv_engine(priv)->sclass = nva0_graph_sclass;
+ nv_engine(priv)->sclass = gt200_gr_sclass;
break;
case 0xa3:
case 0xa5:
case 0xa8:
- nv_engine(priv)->sclass = nva3_graph_sclass;
+ nv_engine(priv)->sclass = gt215_gr_sclass;
break;
case 0xaf:
- nv_engine(priv)->sclass = nvaf_graph_sclass;
+ nv_engine(priv)->sclass = mcp89_gr_sclass;
break;
}
@@ -905,19 +895,19 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
/* unfortunate hw bug workaround... */
if (nv_device(priv)->chipset != 0x50 &&
nv_device(priv)->chipset != 0xac)
- nv_engine(priv)->tlb_flush = nv84_graph_tlb_flush;
+ nv_engine(priv)->tlb_flush = g84_gr_tlb_flush;
spin_lock_init(&priv->lock);
return 0;
}
static int
-nv50_graph_init(struct nouveau_object *object)
+nv50_gr_init(struct nvkm_object *object)
{
- struct nv50_graph_priv *priv = (void *)object;
+ struct nv50_gr_priv *priv = (void *)object;
int ret, units, i;
- ret = nouveau_graph_init(&priv->base);
+ ret = nvkm_gr_init(&priv->base);
if (ret)
return ret;
@@ -997,13 +987,13 @@ nv50_graph_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv50_graph_oclass = {
+struct nvkm_oclass
+nv50_gr_oclass = {
.handle = NV_ENGINE(GR, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_graph_ctor,
- .dtor = _nouveau_graph_dtor,
- .init = nv50_graph_init,
- .fini = _nouveau_graph_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_gr_ctor,
+ .dtor = _nvkm_gr_dtor,
+ .init = nv50_gr_init,
+ .fini = _nvkm_gr_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h
new file mode 100644
index 000000000000..bcf786f6b731
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.h
@@ -0,0 +1,9 @@
+#ifndef __NV50_GR_H__
+#define __NV50_GR_H__
+#include <engine/gr.h>
+struct nvkm_device;
+struct nvkm_gpuobj;
+
+int nv50_grctx_init(struct nvkm_device *, u32 *size);
+void nv50_grctx_fill(struct nvkm_device *, struct nvkm_gpuobj *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/regs.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/regs.h
index fde8e24415e4..90a9873ce522 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/regs.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/regs.h
@@ -1,5 +1,5 @@
-#ifndef __NOUVEAU_GRAPH_REGS_H__
-#define __NOUVEAU_GRAPH_REGS_H__
+#ifndef __NVKM_GR_REGS_H__
+#define __NVKM_GR_REGS_H__
#define NV04_PGRAPH_DEBUG_0 0x00400080
#define NV04_PGRAPH_DEBUG_1 0x00400084
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/Kbuild
new file mode 100644
index 000000000000..61b7b5f98f3c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/Kbuild
@@ -0,0 +1,5 @@
+nvkm-y += nvkm/engine/mpeg/nv31.o
+nvkm-y += nvkm/engine/mpeg/nv40.o
+nvkm-y += nvkm/engine/mpeg/nv44.o
+nvkm-y += nvkm/engine/mpeg/nv50.o
+nvkm-y += nvkm/engine/mpeg/g84.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c
index e9cc8b116a24..0df889fa2611 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c
@@ -21,30 +21,22 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/os.h>
-#include <core/engctx.h>
-
-#include <subdev/vm.h>
-#include <subdev/bar.h>
-#include <subdev/timer.h>
-
#include <engine/mpeg.h>
-struct nv84_mpeg_priv {
- struct nouveau_mpeg base;
+struct g84_mpeg_priv {
+ struct nvkm_mpeg base;
};
-struct nv84_mpeg_chan {
- struct nouveau_mpeg_chan base;
+struct g84_mpeg_chan {
+ struct nvkm_mpeg_chan base;
};
/*******************************************************************************
* MPEG object classes
******************************************************************************/
-static struct nouveau_oclass
-nv84_mpeg_sclass[] = {
+static struct nvkm_oclass
+g84_mpeg_sclass[] = {
{ 0x8274, &nv50_mpeg_ofuncs },
{}
};
@@ -53,16 +45,16 @@ nv84_mpeg_sclass[] = {
* PMPEG context
******************************************************************************/
-static struct nouveau_oclass
-nv84_mpeg_cclass = {
+static struct nvkm_oclass
+g84_mpeg_cclass = {
.handle = NV_ENGCTX(MPEG, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_mpeg_context_ctor,
- .dtor = _nouveau_mpeg_context_dtor,
- .init = _nouveau_mpeg_context_init,
- .fini = _nouveau_mpeg_context_fini,
- .rd32 = _nouveau_mpeg_context_rd32,
- .wr32 = _nouveau_mpeg_context_wr32,
+ .dtor = _nvkm_mpeg_context_dtor,
+ .init = _nvkm_mpeg_context_init,
+ .fini = _nvkm_mpeg_context_fini,
+ .rd32 = _nvkm_mpeg_context_rd32,
+ .wr32 = _nvkm_mpeg_context_wr32,
},
};
@@ -71,32 +63,32 @@ nv84_mpeg_cclass = {
******************************************************************************/
static int
-nv84_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv84_mpeg_priv *priv;
+ struct g84_mpeg_priv *priv;
int ret;
- ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ ret = nvkm_mpeg_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000002;
nv_subdev(priv)->intr = nv50_mpeg_intr;
- nv_engine(priv)->cclass = &nv84_mpeg_cclass;
- nv_engine(priv)->sclass = nv84_mpeg_sclass;
+ nv_engine(priv)->cclass = &g84_mpeg_cclass;
+ nv_engine(priv)->sclass = g84_mpeg_sclass;
return 0;
}
-struct nouveau_oclass
-nv84_mpeg_oclass = {
+struct nvkm_oclass
+g84_mpeg_oclass = {
.handle = NV_ENGINE(MPEG, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_mpeg_ctor,
- .dtor = _nouveau_mpeg_dtor,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_mpeg_ctor,
+ .dtor = _nvkm_mpeg_dtor,
.init = nv50_mpeg_init,
- .fini = _nouveau_mpeg_fini,
+ .fini = _nvkm_mpeg_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
index d88c700b2f69..b5bef0718359 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
@@ -21,35 +21,30 @@
*
* Authors: Ben Skeggs
*/
+#include "nv31.h"
#include <core/client.h>
-#include <core/os.h>
-#include <core/engctx.h>
#include <core/handle.h>
-
+#include <engine/fifo.h>
+#include <subdev/instmem.h>
#include <subdev/fb.h>
#include <subdev/timer.h>
-#include <subdev/instmem.h>
-
-#include <engine/fifo.h>
-#include <engine/mpeg.h>
-#include <engine/mpeg/nv31.h>
/*******************************************************************************
* MPEG object classes
******************************************************************************/
static int
-nv31_mpeg_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv31_mpeg_object_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_gpuobj *obj;
+ struct nvkm_gpuobj *obj;
int ret;
- ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
- 20, 16, 0, &obj);
+ ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
+ 20, 16, 0, &obj);
*pobject = nv_object(obj);
if (ret)
return ret;
@@ -62,9 +57,9 @@ nv31_mpeg_object_ctor(struct nouveau_object *parent,
}
static int
-nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
+nv31_mpeg_mthd_dma(struct nvkm_object *object, u32 mthd, void *arg, u32 len)
{
- struct nouveau_instmem *imem = nouveau_instmem(object);
+ struct nvkm_instmem *imem = nvkm_instmem(object);
struct nv31_mpeg_priv *priv = (void *)object->engine;
u32 inst = *(u32 *)arg << 4;
u32 dma0 = nv_ro32(imem, inst + 0);
@@ -100,17 +95,17 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
return 0;
}
-struct nouveau_ofuncs
+struct nvkm_ofuncs
nv31_mpeg_ofuncs = {
.ctor = nv31_mpeg_object_ctor,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
};
-static struct nouveau_omthds
+static struct nvkm_omthds
nv31_mpeg_omthds[] = {
{ 0x0190, 0x0190, nv31_mpeg_mthd_dma },
{ 0x01a0, 0x01a0, nv31_mpeg_mthd_dma },
@@ -118,7 +113,7 @@ nv31_mpeg_omthds[] = {
{}
};
-struct nouveau_oclass
+struct nvkm_oclass
nv31_mpeg_sclass[] = {
{ 0x3174, &nv31_mpeg_ofuncs, nv31_mpeg_omthds },
{}
@@ -129,17 +124,17 @@ nv31_mpeg_sclass[] = {
******************************************************************************/
static int
-nv31_mpeg_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv31_mpeg_context_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv31_mpeg_priv *priv = (void *)engine;
struct nv31_mpeg_chan *chan;
unsigned long flags;
int ret;
- ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
+ ret = nvkm_object_create(parent, engine, oclass, 0, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -147,7 +142,7 @@ nv31_mpeg_context_ctor(struct nouveau_object *parent,
spin_lock_irqsave(&nv_engine(priv)->lock, flags);
if (priv->chan) {
spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
- nouveau_object_destroy(&chan->base);
+ nvkm_object_destroy(&chan->base);
*pobject = NULL;
return -EBUSY;
}
@@ -157,7 +152,7 @@ nv31_mpeg_context_ctor(struct nouveau_object *parent,
}
static void
-nv31_mpeg_context_dtor(struct nouveau_object *object)
+nv31_mpeg_context_dtor(struct nvkm_object *object)
{
struct nv31_mpeg_priv *priv = (void *)object->engine;
struct nv31_mpeg_chan *chan = (void *)object;
@@ -166,17 +161,17 @@ nv31_mpeg_context_dtor(struct nouveau_object *object)
spin_lock_irqsave(&nv_engine(priv)->lock, flags);
priv->chan = NULL;
spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
- nouveau_object_destroy(&chan->base);
+ nvkm_object_destroy(&chan->base);
}
-struct nouveau_oclass
+struct nvkm_oclass
nv31_mpeg_cclass = {
.handle = NV_ENGCTX(MPEG, 0x31),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv31_mpeg_context_ctor,
.dtor = nv31_mpeg_context_dtor,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
},
};
@@ -185,9 +180,9 @@ nv31_mpeg_cclass = {
******************************************************************************/
void
-nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i)
+nv31_mpeg_tile_prog(struct nvkm_engine *engine, int i)
{
- struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i];
+ struct nvkm_fb_tile *tile = &nvkm_fb(engine)->tile.region[i];
struct nv31_mpeg_priv *priv = (void *)engine;
nv_wr32(priv, 0x00b008 + (i * 0x10), tile->pitch);
@@ -196,12 +191,12 @@ nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i)
}
void
-nv31_mpeg_intr(struct nouveau_subdev *subdev)
+nv31_mpeg_intr(struct nvkm_subdev *subdev)
{
struct nv31_mpeg_priv *priv = (void *)subdev;
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_handle *handle;
- struct nouveau_object *engctx;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_handle *handle;
+ struct nvkm_object *engctx;
u32 stat = nv_rd32(priv, 0x00b100);
u32 type = nv_rd32(priv, 0x00b230);
u32 mthd = nv_rd32(priv, 0x00b234);
@@ -220,10 +215,10 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
}
if (type == 0x00000010 && engctx) {
- handle = nouveau_handle_get_class(engctx, 0x3174);
+ handle = nvkm_handle_get_class(engctx, 0x3174);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~0x01000000;
- nouveau_handle_put(handle);
+ nvkm_handle_put(handle);
}
}
@@ -233,21 +228,21 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
if (show) {
nv_error(priv, "ch %d [%s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
pfifo->chid(pfifo, engctx),
- nouveau_client_name(engctx), stat, type, mthd, data);
+ nvkm_client_name(engctx), stat, type, mthd, data);
}
spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
}
static int
-nv31_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv31_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv31_mpeg_priv *priv;
int ret;
- ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ ret = nvkm_mpeg_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -261,14 +256,14 @@ nv31_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
int
-nv31_mpeg_init(struct nouveau_object *object)
+nv31_mpeg_init(struct nvkm_object *object)
{
- struct nouveau_engine *engine = nv_engine(object);
+ struct nvkm_engine *engine = nv_engine(object);
struct nv31_mpeg_priv *priv = (void *)object;
- struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nvkm_fb *pfb = nvkm_fb(object);
int ret, i;
- ret = nouveau_mpeg_init(&priv->base);
+ ret = nvkm_mpeg_init(&priv->base);
if (ret)
return ret;
@@ -297,13 +292,13 @@ nv31_mpeg_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv31_mpeg_oclass = {
.handle = NV_ENGINE(MPEG, 0x31),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv31_mpeg_ctor,
- .dtor = _nouveau_mpeg_dtor,
+ .dtor = _nvkm_mpeg_dtor,
.init = nv31_mpeg_init,
- .fini = _nouveau_mpeg_fini,
+ .fini = _nvkm_mpeg_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h
index d08629d0b6ad..782b796d7458 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.h
@@ -1,15 +1,13 @@
#ifndef __NV31_MPEG_H__
#define __NV31_MPEG_H__
-
#include <engine/mpeg.h>
struct nv31_mpeg_chan {
- struct nouveau_object base;
+ struct nvkm_object base;
};
struct nv31_mpeg_priv {
- struct nouveau_mpeg base;
+ struct nvkm_mpeg base;
struct nv31_mpeg_chan *chan;
};
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
index bdb2f20ff7b1..9508bf9e140f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
@@ -21,25 +21,18 @@
*
* Authors: Ben Skeggs
*/
+#include "nv31.h"
-#include <core/os.h>
-#include <core/engctx.h>
-
-#include <subdev/fb.h>
-#include <subdev/timer.h>
#include <subdev/instmem.h>
-#include <engine/mpeg.h>
-#include <engine/mpeg/nv31.h>
-
/*******************************************************************************
* MPEG object classes
******************************************************************************/
static int
-nv40_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
+nv40_mpeg_mthd_dma(struct nvkm_object *object, u32 mthd, void *arg, u32 len)
{
- struct nouveau_instmem *imem = nouveau_instmem(object);
+ struct nvkm_instmem *imem = nvkm_instmem(object);
struct nv31_mpeg_priv *priv = (void *)object->engine;
u32 inst = *(u32 *)arg << 4;
u32 dma0 = nv_ro32(imem, inst + 0);
@@ -75,7 +68,7 @@ nv40_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
return 0;
}
-static struct nouveau_omthds
+static struct nvkm_omthds
nv40_mpeg_omthds[] = {
{ 0x0190, 0x0190, nv40_mpeg_mthd_dma },
{ 0x01a0, 0x01a0, nv40_mpeg_mthd_dma },
@@ -83,7 +76,7 @@ nv40_mpeg_omthds[] = {
{}
};
-struct nouveau_oclass
+struct nvkm_oclass
nv40_mpeg_sclass[] = {
{ 0x3174, &nv31_mpeg_ofuncs, nv40_mpeg_omthds },
{}
@@ -94,7 +87,7 @@ nv40_mpeg_sclass[] = {
******************************************************************************/
static void
-nv40_mpeg_intr(struct nouveau_subdev *subdev)
+nv40_mpeg_intr(struct nvkm_subdev *subdev)
{
struct nv31_mpeg_priv *priv = (void *)subdev;
u32 stat;
@@ -109,14 +102,14 @@ nv40_mpeg_intr(struct nouveau_subdev *subdev)
}
static int
-nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv31_mpeg_priv *priv;
int ret;
- ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ ret = nvkm_mpeg_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -129,13 +122,13 @@ nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv40_mpeg_oclass = {
.handle = NV_ENGINE(MPEG, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv40_mpeg_ctor,
- .dtor = _nouveau_mpeg_dtor,
+ .dtor = _nvkm_mpeg_dtor,
.init = nv31_mpeg_init,
- .fini = _nouveau_mpeg_fini,
+ .fini = _nvkm_mpeg_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
index 72c7f33fd29b..4720ac884468 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
@@ -21,25 +21,18 @@
*
* Authors: Ben Skeggs
*/
+#include <engine/mpeg.h>
-#include <core/os.h>
#include <core/client.h>
-#include <core/engctx.h>
#include <core/handle.h>
-
-#include <subdev/fb.h>
-#include <subdev/timer.h>
-#include <subdev/instmem.h>
-
#include <engine/fifo.h>
-#include <engine/mpeg.h>
struct nv44_mpeg_priv {
- struct nouveau_mpeg base;
+ struct nvkm_mpeg base;
};
struct nv44_mpeg_chan {
- struct nouveau_mpeg_chan base;
+ struct nvkm_mpeg_chan base;
};
/*******************************************************************************
@@ -47,17 +40,16 @@ struct nv44_mpeg_chan {
******************************************************************************/
static int
-nv44_mpeg_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv44_mpeg_context_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv44_mpeg_chan *chan;
int ret;
- ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL,
- 264 * 4, 16,
- NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_mpeg_context_create(parent, engine, oclass, NULL, 264 * 4,
+ 16, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -67,7 +59,7 @@ nv44_mpeg_context_ctor(struct nouveau_object *parent,
}
static int
-nv44_mpeg_context_fini(struct nouveau_object *object, bool suspend)
+nv44_mpeg_context_fini(struct nvkm_object *object, bool suspend)
{
struct nv44_mpeg_priv *priv = (void *)object->engine;
@@ -81,16 +73,16 @@ nv44_mpeg_context_fini(struct nouveau_object *object, bool suspend)
return 0;
}
-static struct nouveau_oclass
+static struct nvkm_oclass
nv44_mpeg_cclass = {
.handle = NV_ENGCTX(MPEG, 0x44),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv44_mpeg_context_ctor,
- .dtor = _nouveau_mpeg_context_dtor,
- .init = _nouveau_mpeg_context_init,
+ .dtor = _nvkm_mpeg_context_dtor,
+ .init = _nvkm_mpeg_context_init,
.fini = nv44_mpeg_context_fini,
- .rd32 = _nouveau_mpeg_context_rd32,
- .wr32 = _nouveau_mpeg_context_wr32,
+ .rd32 = _nvkm_mpeg_context_rd32,
+ .wr32 = _nvkm_mpeg_context_wr32,
},
};
@@ -99,12 +91,12 @@ nv44_mpeg_cclass = {
******************************************************************************/
static void
-nv44_mpeg_intr(struct nouveau_subdev *subdev)
+nv44_mpeg_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nouveau_handle *handle;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_object *engctx;
+ struct nvkm_handle *handle;
struct nv44_mpeg_priv *priv = (void *)subdev;
u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
u32 stat = nv_rd32(priv, 0x00b100);
@@ -114,7 +106,7 @@ nv44_mpeg_intr(struct nouveau_subdev *subdev)
u32 show = stat;
int chid;
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & 0x01000000) {
@@ -125,10 +117,10 @@ nv44_mpeg_intr(struct nouveau_subdev *subdev)
}
if (type == 0x00000010) {
- handle = nouveau_handle_get_class(engctx, 0x3174);
+ handle = nvkm_handle_get_class(engctx, 0x3174);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~0x01000000;
- nouveau_handle_put(handle);
+ nvkm_handle_put(handle);
}
}
@@ -138,15 +130,15 @@ nv44_mpeg_intr(struct nouveau_subdev *subdev)
if (show) {
nv_error(priv,
"ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
- chid, inst << 4, nouveau_client_name(engctx), stat,
+ chid, inst << 4, nvkm_client_name(engctx), stat,
type, mthd, data);
}
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
static void
-nv44_mpeg_me_intr(struct nouveau_subdev *subdev)
+nv44_mpeg_me_intr(struct nvkm_subdev *subdev)
{
struct nv44_mpeg_priv *priv = (void *)subdev;
u32 stat;
@@ -161,14 +153,14 @@ nv44_mpeg_me_intr(struct nouveau_subdev *subdev)
}
static int
-nv44_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv44_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv44_mpeg_priv *priv;
int ret;
- ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ ret = nvkm_mpeg_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -181,13 +173,13 @@ nv44_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv44_mpeg_oclass = {
.handle = NV_ENGINE(MPEG, 0x44),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv44_mpeg_ctor,
- .dtor = _nouveau_mpeg_dtor,
+ .dtor = _nvkm_mpeg_dtor,
.init = nv31_mpeg_init,
- .fini = _nouveau_mpeg_fini,
+ .fini = _nvkm_mpeg_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
index cae33f86b11a..b3463f3739ce 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
@@ -21,22 +21,17 @@
*
* Authors: Ben Skeggs
*/
+#include <engine/mpeg.h>
-#include <core/os.h>
-#include <core/engctx.h>
-
-#include <subdev/vm.h>
#include <subdev/bar.h>
#include <subdev/timer.h>
-#include <engine/mpeg.h>
-
struct nv50_mpeg_priv {
- struct nouveau_mpeg base;
+ struct nvkm_mpeg base;
};
struct nv50_mpeg_chan {
- struct nouveau_mpeg_chan base;
+ struct nvkm_mpeg_chan base;
};
/*******************************************************************************
@@ -44,16 +39,16 @@ struct nv50_mpeg_chan {
******************************************************************************/
static int
-nv50_mpeg_object_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_mpeg_object_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_gpuobj *obj;
+ struct nvkm_gpuobj *obj;
int ret;
- ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
- 16, 16, 0, &obj);
+ ret = nvkm_gpuobj_create(parent, engine, oclass, 0, parent,
+ 16, 16, 0, &obj);
*pobject = nv_object(obj);
if (ret)
return ret;
@@ -65,17 +60,17 @@ nv50_mpeg_object_ctor(struct nouveau_object *parent,
return 0;
}
-struct nouveau_ofuncs
+struct nvkm_ofuncs
nv50_mpeg_ofuncs = {
.ctor = nv50_mpeg_object_ctor,
- .dtor = _nouveau_gpuobj_dtor,
- .init = _nouveau_gpuobj_init,
- .fini = _nouveau_gpuobj_fini,
- .rd32 = _nouveau_gpuobj_rd32,
- .wr32 = _nouveau_gpuobj_wr32,
+ .dtor = _nvkm_gpuobj_dtor,
+ .init = _nvkm_gpuobj_init,
+ .fini = _nvkm_gpuobj_fini,
+ .rd32 = _nvkm_gpuobj_rd32,
+ .wr32 = _nvkm_gpuobj_wr32,
};
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_mpeg_sclass[] = {
{ 0x3174, &nv50_mpeg_ofuncs },
{}
@@ -86,17 +81,17 @@ nv50_mpeg_sclass[] = {
******************************************************************************/
int
-nv50_mpeg_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_mpeg_context_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_bar *bar = nouveau_bar(parent);
+ struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_mpeg_chan *chan;
int ret;
- ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL, 128 * 4,
- 0, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+ ret = nvkm_mpeg_context_create(parent, engine, oclass, NULL, 128 * 4,
+ 0, NVOBJ_FLAG_ZERO_ALLOC, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -107,16 +102,16 @@ nv50_mpeg_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_mpeg_cclass = {
.handle = NV_ENGCTX(MPEG, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_mpeg_context_ctor,
- .dtor = _nouveau_mpeg_context_dtor,
- .init = _nouveau_mpeg_context_init,
- .fini = _nouveau_mpeg_context_fini,
- .rd32 = _nouveau_mpeg_context_rd32,
- .wr32 = _nouveau_mpeg_context_wr32,
+ .dtor = _nvkm_mpeg_context_dtor,
+ .init = _nvkm_mpeg_context_init,
+ .fini = _nvkm_mpeg_context_fini,
+ .rd32 = _nvkm_mpeg_context_rd32,
+ .wr32 = _nvkm_mpeg_context_wr32,
},
};
@@ -125,7 +120,7 @@ nv50_mpeg_cclass = {
******************************************************************************/
void
-nv50_mpeg_intr(struct nouveau_subdev *subdev)
+nv50_mpeg_intr(struct nvkm_subdev *subdev)
{
struct nv50_mpeg_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, 0x00b100);
@@ -152,7 +147,7 @@ nv50_mpeg_intr(struct nouveau_subdev *subdev)
}
static void
-nv50_vpe_intr(struct nouveau_subdev *subdev)
+nv50_vpe_intr(struct nvkm_subdev *subdev)
{
struct nv50_mpeg_priv *priv = (void *)subdev;
@@ -167,14 +162,14 @@ nv50_vpe_intr(struct nouveau_subdev *subdev)
}
static int
-nv50_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_mpeg_priv *priv;
int ret;
- ret = nouveau_mpeg_create(parent, engine, oclass, &priv);
+ ret = nvkm_mpeg_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -187,12 +182,12 @@ nv50_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
int
-nv50_mpeg_init(struct nouveau_object *object)
+nv50_mpeg_init(struct nvkm_object *object)
{
struct nv50_mpeg_priv *priv = (void *)object;
int ret;
- ret = nouveau_mpeg_init(&priv->base);
+ ret = nvkm_mpeg_init(&priv->base);
if (ret)
return ret;
@@ -218,13 +213,13 @@ nv50_mpeg_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv50_mpeg_oclass = {
.handle = NV_ENGINE(MPEG, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_mpeg_ctor,
- .dtor = _nouveau_mpeg_dtor,
+ .dtor = _nvkm_mpeg_dtor,
.init = nv50_mpeg_init,
- .fini = _nouveau_mpeg_fini,
+ .fini = _nvkm_mpeg_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/Kbuild
new file mode 100644
index 000000000000..c59c83a67315
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/Kbuild
@@ -0,0 +1,3 @@
+nvkm-y += nvkm/engine/mspdec/g98.o
+nvkm-y += nvkm/engine/mspdec/gf100.o
+nvkm-y += nvkm/engine/mspdec/gk104.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
index fc9ae0ff1ef5..2174577793a4 100644
--- a/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
@@ -21,53 +21,52 @@
*
* Authors: Ben Skeggs, Maarten Lankhorst, Ilia Mirkin
*/
-
+#include <engine/mspdec.h>
#include <engine/falcon.h>
-#include <engine/vp.h>
-struct nv98_vp_priv {
- struct nouveau_falcon base;
+struct g98_mspdec_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * VP object classes
+ * MSPDEC object classes
******************************************************************************/
-static struct nouveau_oclass
-nv98_vp_sclass[] = {
- { 0x88b2, &nouveau_object_ofuncs },
- { 0x85b2, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+g98_mspdec_sclass[] = {
+ { 0x88b2, &nvkm_object_ofuncs },
+ { 0x85b2, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PVP context
+ * PMSPDEC context
******************************************************************************/
-static struct nouveau_oclass
-nv98_vp_cclass = {
- .handle = NV_ENGCTX(VP, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+g98_mspdec_cclass = {
+ .handle = NV_ENGCTX(MSPDEC, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PVP engine/subdev functions
+ * PMSPDEC engine/subdev functions
******************************************************************************/
static int
-nv98_vp_init(struct nouveau_object *object)
+g98_mspdec_init(struct nvkm_object *object)
{
- struct nv98_vp_priv *priv = (void *)object;
+ struct g98_mspdec_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -77,34 +76,34 @@ nv98_vp_init(struct nouveau_object *object)
}
static int
-nv98_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g98_mspdec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv98_vp_priv *priv;
+ struct g98_mspdec_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x085000, true,
- "PVP", "vp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x085000, true,
+ "PMSPDEC", "mspdec", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x01020000;
- nv_engine(priv)->cclass = &nv98_vp_cclass;
- nv_engine(priv)->sclass = nv98_vp_sclass;
+ nv_engine(priv)->cclass = &g98_mspdec_cclass;
+ nv_engine(priv)->sclass = g98_mspdec_sclass;
return 0;
}
-struct nouveau_oclass
-nv98_vp_oclass = {
- .handle = NV_ENGINE(VP, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv98_vp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nv98_vp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+g98_mspdec_oclass = {
+ .handle = NV_ENGINE(MSPDEC, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g98_mspdec_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = g98_mspdec_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
index ac1f62aace72..c814a5f65eb0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
@@ -21,52 +21,51 @@
*
* Authors: Maarten Lankhorst
*/
-
+#include <engine/mspdec.h>
#include <engine/falcon.h>
-#include <engine/vp.h>
-struct nvc0_vp_priv {
- struct nouveau_falcon base;
+struct gf100_mspdec_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * VP object classes
+ * MSPDEC object classes
******************************************************************************/
-static struct nouveau_oclass
-nvc0_vp_sclass[] = {
- { 0x90b2, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+gf100_mspdec_sclass[] = {
+ { 0x90b2, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PVP context
+ * PMSPDEC context
******************************************************************************/
-static struct nouveau_oclass
-nvc0_vp_cclass = {
- .handle = NV_ENGCTX(VP, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+gf100_mspdec_cclass = {
+ .handle = NV_ENGCTX(MSPDEC, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PVP engine/subdev functions
+ * PMSPDEC engine/subdev functions
******************************************************************************/
static int
-nvc0_vp_init(struct nouveau_object *object)
+gf100_mspdec_init(struct nvkm_object *object)
{
- struct nvc0_vp_priv *priv = (void *)object;
+ struct gf100_mspdec_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -76,35 +75,35 @@ nvc0_vp_init(struct nouveau_object *object)
}
static int
-nvc0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_mspdec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_vp_priv *priv;
+ struct gf100_mspdec_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x085000, true,
- "PVP", "vp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x085000, true,
+ "PMSPDEC", "mspdec", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00020000;
- nv_subdev(priv)->intr = nouveau_falcon_intr;
- nv_engine(priv)->cclass = &nvc0_vp_cclass;
- nv_engine(priv)->sclass = nvc0_vp_sclass;
+ nv_subdev(priv)->intr = nvkm_falcon_intr;
+ nv_engine(priv)->cclass = &gf100_mspdec_cclass;
+ nv_engine(priv)->sclass = gf100_mspdec_sclass;
return 0;
}
-struct nouveau_oclass
-nvc0_vp_oclass = {
- .handle = NV_ENGINE(VP, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_vp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nvc0_vp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+gf100_mspdec_oclass = {
+ .handle = NV_ENGINE(MSPDEC, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_mspdec_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = gf100_mspdec_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
index d4c3108479c9..979920650dbd 100644
--- a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
@@ -21,52 +21,51 @@
*
* Authors: Ben Skeggs
*/
-
+#include <engine/mspdec.h>
#include <engine/falcon.h>
-#include <engine/vp.h>
-struct nve0_vp_priv {
- struct nouveau_falcon base;
+struct gk104_mspdec_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * VP object classes
+ * MSPDEC object classes
******************************************************************************/
-static struct nouveau_oclass
-nve0_vp_sclass[] = {
- { 0x95b2, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+gk104_mspdec_sclass[] = {
+ { 0x95b2, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PVP context
+ * PMSPDEC context
******************************************************************************/
-static struct nouveau_oclass
-nve0_vp_cclass = {
- .handle = NV_ENGCTX(VP, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+gk104_mspdec_cclass = {
+ .handle = NV_ENGCTX(MSPDEC, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PVP engine/subdev functions
+ * PMSPDEC engine/subdev functions
******************************************************************************/
static int
-nve0_vp_init(struct nouveau_object *object)
+gk104_mspdec_init(struct nvkm_object *object)
{
- struct nve0_vp_priv *priv = (void *)object;
+ struct gk104_mspdec_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -76,35 +75,35 @@ nve0_vp_init(struct nouveau_object *object)
}
static int
-nve0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_mspdec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nve0_vp_priv *priv;
+ struct gk104_mspdec_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x085000, true,
- "PVP", "vp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x085000, true,
+ "PMSPDEC", "mspdec", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00020000;
- nv_subdev(priv)->intr = nouveau_falcon_intr;
- nv_engine(priv)->cclass = &nve0_vp_cclass;
- nv_engine(priv)->sclass = nve0_vp_sclass;
+ nv_subdev(priv)->intr = nvkm_falcon_intr;
+ nv_engine(priv)->cclass = &gk104_mspdec_cclass;
+ nv_engine(priv)->sclass = gk104_mspdec_sclass;
return 0;
}
-struct nouveau_oclass
-nve0_vp_oclass = {
- .handle = NV_ENGINE(VP, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_vp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nve0_vp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+gk104_mspdec_oclass = {
+ .handle = NV_ENGINE(MSPDEC, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_mspdec_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = gk104_mspdec_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/Kbuild
new file mode 100644
index 000000000000..4576a9eee39d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/Kbuild
@@ -0,0 +1,2 @@
+nvkm-y += nvkm/engine/msppp/g98.o
+nvkm-y += nvkm/engine/msppp/gf100.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
index 13bf31c40aa1..7a602a2dec94 100644
--- a/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
@@ -21,53 +21,52 @@
*
* Authors: Ben Skeggs, Maarten Lankhorst, Ilia Mirkin
*/
-
+#include <engine/msppp.h>
#include <engine/falcon.h>
-#include <engine/ppp.h>
-struct nv98_ppp_priv {
- struct nouveau_falcon base;
+struct g98_msppp_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * PPP object classes
+ * MSPPP object classes
******************************************************************************/
-static struct nouveau_oclass
-nv98_ppp_sclass[] = {
- { 0x88b3, &nouveau_object_ofuncs },
- { 0x85b3, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+g98_msppp_sclass[] = {
+ { 0x88b3, &nvkm_object_ofuncs },
+ { 0x85b3, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PPPP context
+ * PMSPPP context
******************************************************************************/
-static struct nouveau_oclass
-nv98_ppp_cclass = {
- .handle = NV_ENGCTX(PPP, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+g98_msppp_cclass = {
+ .handle = NV_ENGCTX(MSPPP, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PPPP engine/subdev functions
+ * PMSPPP engine/subdev functions
******************************************************************************/
static int
-nv98_ppp_init(struct nouveau_object *object)
+g98_msppp_init(struct nvkm_object *object)
{
- struct nv98_ppp_priv *priv = (void *)object;
+ struct g98_msppp_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -77,34 +76,34 @@ nv98_ppp_init(struct nouveau_object *object)
}
static int
-nv98_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g98_msppp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv98_ppp_priv *priv;
+ struct g98_msppp_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x086000, true,
- "PPPP", "ppp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x086000, true,
+ "PMSPPP", "msppp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00400002;
- nv_engine(priv)->cclass = &nv98_ppp_cclass;
- nv_engine(priv)->sclass = nv98_ppp_sclass;
+ nv_engine(priv)->cclass = &g98_msppp_cclass;
+ nv_engine(priv)->sclass = g98_msppp_sclass;
return 0;
}
-struct nouveau_oclass
-nv98_ppp_oclass = {
- .handle = NV_ENGINE(PPP, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv98_ppp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nv98_ppp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+g98_msppp_oclass = {
+ .handle = NV_ENGINE(MSPPP, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g98_msppp_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = g98_msppp_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
index 73719aaa62d6..6047baee1f75 100644
--- a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
@@ -21,52 +21,51 @@
*
* Authors: Maarten Lankhorst
*/
-
+#include <engine/msppp.h>
#include <engine/falcon.h>
-#include <engine/ppp.h>
-struct nvc0_ppp_priv {
- struct nouveau_falcon base;
+struct gf100_msppp_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * PPP object classes
+ * MSPPP object classes
******************************************************************************/
-static struct nouveau_oclass
-nvc0_ppp_sclass[] = {
- { 0x90b3, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+gf100_msppp_sclass[] = {
+ { 0x90b3, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PPPP context
+ * PMSPPP context
******************************************************************************/
-static struct nouveau_oclass
-nvc0_ppp_cclass = {
- .handle = NV_ENGCTX(PPP, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+gf100_msppp_cclass = {
+ .handle = NV_ENGCTX(MSPPP, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PPPP engine/subdev functions
+ * PMSPPP engine/subdev functions
******************************************************************************/
static int
-nvc0_ppp_init(struct nouveau_object *object)
+gf100_msppp_init(struct nvkm_object *object)
{
- struct nvc0_ppp_priv *priv = (void *)object;
+ struct gf100_msppp_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -76,35 +75,35 @@ nvc0_ppp_init(struct nouveau_object *object)
}
static int
-nvc0_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_msppp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_ppp_priv *priv;
+ struct gf100_msppp_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x086000, true,
- "PPPP", "ppp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x086000, true,
+ "PMSPPP", "msppp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000002;
- nv_subdev(priv)->intr = nouveau_falcon_intr;
- nv_engine(priv)->cclass = &nvc0_ppp_cclass;
- nv_engine(priv)->sclass = nvc0_ppp_sclass;
+ nv_subdev(priv)->intr = nvkm_falcon_intr;
+ nv_engine(priv)->cclass = &gf100_msppp_cclass;
+ nv_engine(priv)->sclass = gf100_msppp_sclass;
return 0;
}
-struct nouveau_oclass
-nvc0_ppp_oclass = {
- .handle = NV_ENGINE(PPP, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_ppp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nvc0_ppp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+gf100_msppp_oclass = {
+ .handle = NV_ENGINE(MSPPP, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_msppp_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = gf100_msppp_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/Kbuild
new file mode 100644
index 000000000000..0c9811009e28
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/Kbuild
@@ -0,0 +1,3 @@
+nvkm-y += nvkm/engine/msvld/g98.o
+nvkm-y += nvkm/engine/msvld/gf100.o
+nvkm-y += nvkm/engine/msvld/gk104.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
index 6b089e022fd2..c8a6b4ef52a1 100644
--- a/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
@@ -21,54 +21,53 @@
*
* Authors: Ben Skeggs, Maarten Lankhorst, Ilia Mirkin
*/
-
+#include <engine/msvld.h>
#include <engine/falcon.h>
-#include <engine/bsp.h>
-struct nv98_bsp_priv {
- struct nouveau_falcon base;
+struct g98_msvld_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * BSP object classes
+ * MSVLD object classes
******************************************************************************/
-static struct nouveau_oclass
-nv98_bsp_sclass[] = {
- { 0x88b1, &nouveau_object_ofuncs },
- { 0x85b1, &nouveau_object_ofuncs },
- { 0x86b1, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+g98_msvld_sclass[] = {
+ { 0x88b1, &nvkm_object_ofuncs },
+ { 0x85b1, &nvkm_object_ofuncs },
+ { 0x86b1, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PBSP context
+ * PMSVLD context
******************************************************************************/
-static struct nouveau_oclass
-nv98_bsp_cclass = {
- .handle = NV_ENGCTX(BSP, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+g98_msvld_cclass = {
+ .handle = NV_ENGCTX(MSVLD, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PBSP engine/subdev functions
+ * PMSVLD engine/subdev functions
******************************************************************************/
static int
-nv98_bsp_init(struct nouveau_object *object)
+g98_msvld_init(struct nvkm_object *object)
{
- struct nv98_bsp_priv *priv = (void *)object;
+ struct g98_msvld_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -78,34 +77,34 @@ nv98_bsp_init(struct nouveau_object *object)
}
static int
-nv98_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g98_msvld_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv98_bsp_priv *priv;
+ struct g98_msvld_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x084000, true,
- "PBSP", "bsp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x084000, true,
+ "PMSVLD", "msvld", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x04008000;
- nv_engine(priv)->cclass = &nv98_bsp_cclass;
- nv_engine(priv)->sclass = nv98_bsp_sclass;
+ nv_engine(priv)->cclass = &g98_msvld_cclass;
+ nv_engine(priv)->sclass = g98_msvld_sclass;
return 0;
}
-struct nouveau_oclass
-nv98_bsp_oclass = {
- .handle = NV_ENGINE(BSP, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv98_bsp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nv98_bsp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+g98_msvld_oclass = {
+ .handle = NV_ENGINE(MSVLD, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g98_msvld_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = g98_msvld_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
index ce860de43e61..b8d1e0f521ef 100644
--- a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
@@ -21,52 +21,51 @@
*
* Authors: Maarten Lankhorst
*/
-
+#include <engine/msvld.h>
#include <engine/falcon.h>
-#include <engine/bsp.h>
-struct nvc0_bsp_priv {
- struct nouveau_falcon base;
+struct gf100_msvld_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * BSP object classes
+ * MSVLD object classes
******************************************************************************/
-static struct nouveau_oclass
-nvc0_bsp_sclass[] = {
- { 0x90b1, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+gf100_msvld_sclass[] = {
+ { 0x90b1, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PBSP context
+ * PMSVLD context
******************************************************************************/
-static struct nouveau_oclass
-nvc0_bsp_cclass = {
- .handle = NV_ENGCTX(BSP, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+gf100_msvld_cclass = {
+ .handle = NV_ENGCTX(MSVLD, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PBSP engine/subdev functions
+ * PMSVLD engine/subdev functions
******************************************************************************/
static int
-nvc0_bsp_init(struct nouveau_object *object)
+gf100_msvld_init(struct nvkm_object *object)
{
- struct nvc0_bsp_priv *priv = (void *)object;
+ struct gf100_msvld_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -76,35 +75,35 @@ nvc0_bsp_init(struct nouveau_object *object)
}
static int
-nvc0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_msvld_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_bsp_priv *priv;
+ struct gf100_msvld_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x084000, true,
- "PBSP", "bsp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x084000, true,
+ "PMSVLD", "msvld", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00008000;
- nv_subdev(priv)->intr = nouveau_falcon_intr;
- nv_engine(priv)->cclass = &nvc0_bsp_cclass;
- nv_engine(priv)->sclass = nvc0_bsp_sclass;
+ nv_subdev(priv)->intr = nvkm_falcon_intr;
+ nv_engine(priv)->cclass = &gf100_msvld_cclass;
+ nv_engine(priv)->sclass = gf100_msvld_sclass;
return 0;
}
-struct nouveau_oclass
-nvc0_bsp_oclass = {
- .handle = NV_ENGINE(BSP, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_bsp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nvc0_bsp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+gf100_msvld_oclass = {
+ .handle = NV_ENGINE(MSVLD, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_msvld_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = gf100_msvld_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
index ba6aeca0285e..a0b0927834df 100644
--- a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
@@ -21,52 +21,51 @@
*
* Authors: Ben Skeggs
*/
-
+#include <engine/msvld.h>
#include <engine/falcon.h>
-#include <engine/bsp.h>
-struct nve0_bsp_priv {
- struct nouveau_falcon base;
+struct gk104_msvld_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
- * BSP object classes
+ * MSVLD object classes
******************************************************************************/
-static struct nouveau_oclass
-nve0_bsp_sclass[] = {
- { 0x95b1, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+gk104_msvld_sclass[] = {
+ { 0x95b1, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PBSP context
+ * PMSVLD context
******************************************************************************/
-static struct nouveau_oclass
-nve0_bsp_cclass = {
- .handle = NV_ENGCTX(BSP, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+gk104_msvld_cclass = {
+ .handle = NV_ENGCTX(MSVLD, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PBSP engine/subdev functions
+ * PMSVLD engine/subdev functions
******************************************************************************/
static int
-nve0_bsp_init(struct nouveau_object *object)
+gk104_msvld_init(struct nvkm_object *object)
{
- struct nve0_bsp_priv *priv = (void *)object;
+ struct gk104_msvld_priv *priv = (void *)object;
int ret;
- ret = nouveau_falcon_init(&priv->base);
+ ret = nvkm_falcon_init(&priv->base);
if (ret)
return ret;
@@ -76,35 +75,35 @@ nve0_bsp_init(struct nouveau_object *object)
}
static int
-nve0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_msvld_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nve0_bsp_priv *priv;
+ struct gk104_msvld_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x084000, true,
- "PBSP", "bsp", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x084000, true,
+ "PMSVLD", "msvld", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00008000;
- nv_subdev(priv)->intr = nouveau_falcon_intr;
- nv_engine(priv)->cclass = &nve0_bsp_cclass;
- nv_engine(priv)->sclass = nve0_bsp_sclass;
+ nv_subdev(priv)->intr = nvkm_falcon_intr;
+ nv_engine(priv)->cclass = &gk104_msvld_cclass;
+ nv_engine(priv)->sclass = gk104_msvld_sclass;
return 0;
}
-struct nouveau_oclass
-nve0_bsp_oclass = {
- .handle = NV_ENGINE(BSP, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_bsp_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = nve0_bsp_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+gk104_msvld_oclass = {
+ .handle = NV_ENGINE(MSVLD, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_msvld_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = gk104_msvld_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/pm/Kbuild
new file mode 100644
index 000000000000..413b6091e256
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/Kbuild
@@ -0,0 +1,9 @@
+nvkm-y += nvkm/engine/pm/base.o
+nvkm-y += nvkm/engine/pm/daemon.o
+nvkm-y += nvkm/engine/pm/nv40.o
+nvkm-y += nvkm/engine/pm/nv50.o
+nvkm-y += nvkm/engine/pm/g84.o
+nvkm-y += nvkm/engine/pm/gt215.o
+nvkm-y += nvkm/engine/pm/gf100.o
+nvkm-y += nvkm/engine/pm/gk104.o
+nvkm-y += nvkm/engine/pm/gk110.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
index 63013812f7c9..2006c445938d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
@@ -21,22 +21,21 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <core/client.h>
+#include <core/device.h>
#include <core/option.h>
-#include <nvif/unpack.h>
+
#include <nvif/class.h>
#include <nvif/ioctl.h>
-
-#include <subdev/clock.h>
-
-#include "priv.h"
+#include <nvif/unpack.h>
#define QUAD_MASK 0x0f
#define QUAD_FREE 0x01
-static struct nouveau_perfsig *
-nouveau_perfsig_find_(struct nouveau_perfdom *dom, const char *name, u32 size)
+static struct nvkm_perfsig *
+nvkm_perfsig_find_(struct nvkm_perfdom *dom, const char *name, u32 size)
{
char path[64];
int i;
@@ -58,16 +57,16 @@ nouveau_perfsig_find_(struct nouveau_perfdom *dom, const char *name, u32 size)
return NULL;
}
-struct nouveau_perfsig *
-nouveau_perfsig_find(struct nouveau_perfmon *ppm, const char *name, u32 size,
- struct nouveau_perfdom **pdom)
+struct nvkm_perfsig *
+nvkm_perfsig_find(struct nvkm_pm *ppm, const char *name, u32 size,
+ struct nvkm_perfdom **pdom)
{
- struct nouveau_perfdom *dom = *pdom;
- struct nouveau_perfsig *sig;
+ struct nvkm_perfdom *dom = *pdom;
+ struct nvkm_perfsig *sig;
if (dom == NULL) {
list_for_each_entry(dom, &ppm->domains, head) {
- sig = nouveau_perfsig_find_(dom, name, size);
+ sig = nvkm_perfsig_find_(dom, name, size);
if (sig) {
*pdom = dom;
return sig;
@@ -77,17 +76,17 @@ nouveau_perfsig_find(struct nouveau_perfmon *ppm, const char *name, u32 size,
return NULL;
}
- return nouveau_perfsig_find_(dom, name, size);
+ return nvkm_perfsig_find_(dom, name, size);
}
-struct nouveau_perfctr *
-nouveau_perfsig_wrap(struct nouveau_perfmon *ppm, const char *name,
- struct nouveau_perfdom **pdom)
+struct nvkm_perfctr *
+nvkm_perfsig_wrap(struct nvkm_pm *ppm, const char *name,
+ struct nvkm_perfdom **pdom)
{
- struct nouveau_perfsig *sig;
- struct nouveau_perfctr *ctr;
+ struct nvkm_perfsig *sig;
+ struct nvkm_perfctr *ctr;
- sig = nouveau_perfsig_find(ppm, name, strlen(name), pdom);
+ sig = nvkm_perfsig_find(ppm, name, strlen(name), pdom);
if (!sig)
return NULL;
@@ -104,16 +103,16 @@ nouveau_perfsig_wrap(struct nouveau_perfmon *ppm, const char *name,
* Perfmon object classes
******************************************************************************/
static int
-nouveau_perfctr_query(struct nouveau_object *object, void *data, u32 size)
+nvkm_perfctr_query(struct nvkm_object *object, void *data, u32 size)
{
union {
struct nvif_perfctr_query_v0 v0;
} *args = data;
- struct nouveau_device *device = nv_device(object);
- struct nouveau_perfmon *ppm = (void *)object->engine;
- struct nouveau_perfdom *dom = NULL, *chk;
- const bool all = nouveau_boolopt(device->cfgopt, "NvPmShowAll", false);
- const bool raw = nouveau_boolopt(device->cfgopt, "NvPmUnnamed", all);
+ struct nvkm_device *device = nv_device(object);
+ struct nvkm_pm *ppm = (void *)object->engine;
+ struct nvkm_perfdom *dom = NULL, *chk;
+ const bool all = nvkm_boolopt(device->cfgopt, "NvPmShowAll", false);
+ const bool raw = nvkm_boolopt(device->cfgopt, "NvPmUnnamed", all);
const char *name;
int tmp = 0, di, si;
int ret;
@@ -163,14 +162,14 @@ nouveau_perfctr_query(struct nouveau_object *object, void *data, u32 size)
}
static int
-nouveau_perfctr_sample(struct nouveau_object *object, void *data, u32 size)
+nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size)
{
union {
struct nvif_perfctr_sample none;
} *args = data;
- struct nouveau_perfmon *ppm = (void *)object->engine;
- struct nouveau_perfctr *ctr, *tmp;
- struct nouveau_perfdom *dom;
+ struct nvkm_pm *ppm = (void *)object->engine;
+ struct nvkm_perfctr *ctr, *tmp;
+ struct nvkm_perfdom *dom;
int ret;
nv_ioctl(object, "perfctr sample size %d\n", size);
@@ -187,7 +186,7 @@ nouveau_perfctr_sample(struct nouveau_object *object, void *data, u32 size)
tmp = NULL;
while (!list_empty(&dom->list)) {
ctr = list_first_entry(&dom->list,
- typeof(*ctr), head);
+ typeof(*ctr), head);
if (ctr->slot < 0) break;
if ( tmp && tmp == ctr) break;
if (!tmp) tmp = ctr;
@@ -216,12 +215,12 @@ nouveau_perfctr_sample(struct nouveau_object *object, void *data, u32 size)
}
static int
-nouveau_perfctr_read(struct nouveau_object *object, void *data, u32 size)
+nvkm_perfctr_read(struct nvkm_object *object, void *data, u32 size)
{
union {
struct nvif_perfctr_read_v0 v0;
} *args = data;
- struct nouveau_perfctr *ctr = (void *)object;
+ struct nvkm_perfctr *ctr = (void *)object;
int ret;
nv_ioctl(object, "perfctr read size %d\n", size);
@@ -239,16 +238,15 @@ nouveau_perfctr_read(struct nouveau_object *object, void *data, u32 size)
}
static int
-nouveau_perfctr_mthd(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
+nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
switch (mthd) {
case NVIF_PERFCTR_V0_QUERY:
- return nouveau_perfctr_query(object, data, size);
+ return nvkm_perfctr_query(object, data, size);
case NVIF_PERFCTR_V0_SAMPLE:
- return nouveau_perfctr_sample(object, data, size);
+ return nvkm_perfctr_sample(object, data, size);
case NVIF_PERFCTR_V0_READ:
- return nouveau_perfctr_read(object, data, size);
+ return nvkm_perfctr_read(object, data, size);
default:
break;
}
@@ -256,27 +254,26 @@ nouveau_perfctr_mthd(struct nouveau_object *object, u32 mthd,
}
static void
-nouveau_perfctr_dtor(struct nouveau_object *object)
+nvkm_perfctr_dtor(struct nvkm_object *object)
{
- struct nouveau_perfctr *ctr = (void *)object;
+ struct nvkm_perfctr *ctr = (void *)object;
if (ctr->head.next)
list_del(&ctr->head);
- nouveau_object_destroy(&ctr->base);
+ nvkm_object_destroy(&ctr->base);
}
static int
-nouveau_perfctr_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
union {
struct nvif_perfctr_v0 v0;
} *args = data;
- struct nouveau_perfmon *ppm = (void *)engine;
- struct nouveau_perfdom *dom = NULL;
- struct nouveau_perfsig *sig[4] = {};
- struct nouveau_perfctr *ctr;
+ struct nvkm_pm *ppm = (void *)engine;
+ struct nvkm_perfdom *dom = NULL;
+ struct nvkm_perfsig *sig[4] = {};
+ struct nvkm_perfctr *ctr;
int ret, i;
nv_ioctl(parent, "create perfctr size %d\n", size);
@@ -287,15 +284,15 @@ nouveau_perfctr_ctor(struct nouveau_object *parent,
return ret;
for (i = 0; i < ARRAY_SIZE(args->v0.name) && args->v0.name[i][0]; i++) {
- sig[i] = nouveau_perfsig_find(ppm, args->v0.name[i],
- strnlen(args->v0.name[i],
- sizeof(args->v0.name[i])),
- &dom);
+ sig[i] = nvkm_perfsig_find(ppm, args->v0.name[i],
+ strnlen(args->v0.name[i],
+ sizeof(args->v0.name[i])),
+ &dom);
if (!sig[i])
return -EINVAL;
}
- ret = nouveau_object_create(parent, engine, oclass, 0, &ctr);
+ ret = nvkm_object_create(parent, engine, oclass, 0, &ctr);
*pobject = nv_object(ctr);
if (ret)
return ret;
@@ -311,19 +308,19 @@ nouveau_perfctr_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_ofuncs
-nouveau_perfctr_ofuncs = {
- .ctor = nouveau_perfctr_ctor,
- .dtor = nouveau_perfctr_dtor,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
- .mthd = nouveau_perfctr_mthd,
+static struct nvkm_ofuncs
+nvkm_perfctr_ofuncs = {
+ .ctor = nvkm_perfctr_ctor,
+ .dtor = nvkm_perfctr_dtor,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
+ .mthd = nvkm_perfctr_mthd,
};
-struct nouveau_oclass
-nouveau_perfmon_sclass[] = {
+struct nvkm_oclass
+nvkm_pm_sclass[] = {
{ .handle = NVIF_IOCTL_NEW_V0_PERFCTR,
- .ofuncs = &nouveau_perfctr_ofuncs,
+ .ofuncs = &nvkm_perfctr_ofuncs,
},
{},
};
@@ -332,27 +329,25 @@ nouveau_perfmon_sclass[] = {
* PPM context
******************************************************************************/
static void
-nouveau_perfctx_dtor(struct nouveau_object *object)
+nvkm_perfctx_dtor(struct nvkm_object *object)
{
- struct nouveau_perfmon *ppm = (void *)object->engine;
+ struct nvkm_pm *ppm = (void *)object->engine;
mutex_lock(&nv_subdev(ppm)->mutex);
- nouveau_engctx_destroy(&ppm->context->base);
+ nvkm_engctx_destroy(&ppm->context->base);
ppm->context = NULL;
mutex_unlock(&nv_subdev(ppm)->mutex);
}
static int
-nouveau_perfctx_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nvkm_perfctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_perfmon *ppm = (void *)engine;
- struct nouveau_perfctx *ctx;
+ struct nvkm_pm *ppm = (void *)engine;
+ struct nvkm_perfctx *ctx;
int ret;
- ret = nouveau_engctx_create(parent, engine, oclass, NULL,
- 0, 0, 0, &ctx);
+ ret = nvkm_engctx_create(parent, engine, oclass, NULL, 0, 0, 0, &ctx);
*pobject = nv_object(ctx);
if (ret)
return ret;
@@ -368,14 +363,14 @@ nouveau_perfctx_ctor(struct nouveau_object *parent,
return 0;
}
-struct nouveau_oclass
-nouveau_perfmon_cclass = {
- .handle = NV_ENGCTX(PERFMON, 0x00),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nouveau_perfctx_ctor,
- .dtor = nouveau_perfctx_dtor,
- .init = _nouveau_engctx_init,
- .fini = _nouveau_engctx_fini,
+struct nvkm_oclass
+nvkm_pm_cclass = {
+ .handle = NV_ENGCTX(PM, 0x00),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nvkm_perfctx_ctor,
+ .dtor = nvkm_perfctx_dtor,
+ .init = _nvkm_engctx_init,
+ .fini = _nvkm_engctx_fini,
},
};
@@ -383,13 +378,13 @@ nouveau_perfmon_cclass = {
* PPM engine/subdev functions
******************************************************************************/
int
-nouveau_perfdom_new(struct nouveau_perfmon *ppm, const char *name, u32 mask,
- u32 base, u32 size_unit, u32 size_domain,
- const struct nouveau_specdom *spec)
+nvkm_perfdom_new(struct nvkm_pm *ppm, const char *name, u32 mask,
+ u32 base, u32 size_unit, u32 size_domain,
+ const struct nvkm_specdom *spec)
{
- const struct nouveau_specdom *sdom;
- const struct nouveau_specsig *ssig;
- struct nouveau_perfdom *dom;
+ const struct nvkm_specdom *sdom;
+ const struct nvkm_specsig *ssig;
+ struct nvkm_perfdom *dom;
int i;
for (i = 0; i == 0 || mask; i++) {
@@ -436,44 +431,42 @@ nouveau_perfdom_new(struct nouveau_perfmon *ppm, const char *name, u32 mask,
}
int
-_nouveau_perfmon_fini(struct nouveau_object *object, bool suspend)
+_nvkm_pm_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_perfmon *ppm = (void *)object;
- return nouveau_engine_fini(&ppm->base, suspend);
+ struct nvkm_pm *ppm = (void *)object;
+ return nvkm_engine_fini(&ppm->base, suspend);
}
int
-_nouveau_perfmon_init(struct nouveau_object *object)
+_nvkm_pm_init(struct nvkm_object *object)
{
- struct nouveau_perfmon *ppm = (void *)object;
- return nouveau_engine_init(&ppm->base);
+ struct nvkm_pm *ppm = (void *)object;
+ return nvkm_engine_init(&ppm->base);
}
void
-_nouveau_perfmon_dtor(struct nouveau_object *object)
+_nvkm_pm_dtor(struct nvkm_object *object)
{
- struct nouveau_perfmon *ppm = (void *)object;
- struct nouveau_perfdom *dom, *tmp;
+ struct nvkm_pm *ppm = (void *)object;
+ struct nvkm_perfdom *dom, *tmp;
list_for_each_entry_safe(dom, tmp, &ppm->domains, head) {
list_del(&dom->head);
kfree(dom);
}
- nouveau_engine_destroy(&ppm->base);
+ nvkm_engine_destroy(&ppm->base);
}
int
-nouveau_perfmon_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int length, void **pobject)
+nvkm_pm_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_perfmon *ppm;
+ struct nvkm_pm *ppm;
int ret;
- ret = nouveau_engine_create_(parent, engine, oclass, true, "PPM",
- "perfmon", length, pobject);
+ ret = nvkm_engine_create_(parent, engine, oclass, true, "PPM",
+ "pm", length, pobject);
ppm = *pobject;
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/daemon.c
index 50696cc7b7d7..a7a5f3a3c91b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/daemon.c
@@ -21,12 +21,11 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
static void
-pwr_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
+pwr_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
+ struct nvkm_perfctr *ctr)
{
u32 mask = 0x00000000;
u32 ctrl = 0x00000001;
@@ -41,15 +40,15 @@ pwr_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
}
static void
-pwr_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
+pwr_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
+ struct nvkm_perfctr *ctr)
{
ctr->ctr = ppm->pwr[ctr->slot];
ctr->clk = ppm->pwr[ppm->last];
}
static void
-pwr_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom)
+pwr_perfctr_next(struct nvkm_pm *ppm, struct nvkm_perfdom *dom)
{
int i;
@@ -59,16 +58,16 @@ pwr_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom)
}
}
-static const struct nouveau_funcdom
+static const struct nvkm_funcdom
pwr_perfctr_func = {
.init = pwr_perfctr_init,
.read = pwr_perfctr_read,
.next = pwr_perfctr_next,
};
-const struct nouveau_specdom
-nva3_perfmon_pwr[] = {
- { 0x20, (const struct nouveau_specsig[]) {
+const struct nvkm_specdom
+gt215_pm_pwr[] = {
+ { 0x20, (const struct nvkm_specsig[]) {
{ 0x00, "pwr_gr_idle" },
{ 0x04, "pwr_bsp_idle" },
{ 0x05, "pwr_vp_idle" },
@@ -79,9 +78,9 @@ nva3_perfmon_pwr[] = {
{}
};
-const struct nouveau_specdom
-nvc0_perfmon_pwr[] = {
- { 0x20, (const struct nouveau_specsig[]) {
+const struct nvkm_specdom
+gf100_pm_pwr[] = {
+ { 0x20, (const struct nvkm_specsig[]) {
{ 0x00, "pwr_gr_idle" },
{ 0x04, "pwr_bsp_idle" },
{ 0x05, "pwr_vp_idle" },
@@ -93,9 +92,9 @@ nvc0_perfmon_pwr[] = {
{}
};
-const struct nouveau_specdom
-nve0_perfmon_pwr[] = {
- { 0x20, (const struct nouveau_specsig[]) {
+const struct nvkm_specdom
+gk104_pm_pwr[] = {
+ { 0x20, (const struct nvkm_specsig[]) {
{ 0x00, "pwr_gr_idle" },
{ 0x04, "pwr_bsp_idle" },
{ 0x05, "pwr_vp_idle" },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/g84.c
new file mode 100644
index 000000000000..d54c6705ba17
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/g84.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "nv40.h"
+
+static const struct nvkm_specdom
+g84_pm[] = {
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x20, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ {}
+};
+
+struct nvkm_oclass *
+g84_pm_oclass = &(struct nv40_pm_oclass) {
+ .base.handle = NV_ENGINE(PM, 0x84),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv40_pm_ctor,
+ .dtor = _nvkm_pm_dtor,
+ .init = _nvkm_pm_init,
+ .fini = _nvkm_pm_fini,
+ },
+ .doms = g84_pm,
+}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c
index 74b241042502..008fed73dd82 100644
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c
@@ -21,42 +21,29 @@
*
* Authors: Ben Skeggs
*/
+#include "gf100.h"
-#include "nvc0.h"
-
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nvc0_perfmon_hub[] = {
+static const struct nvkm_specdom
+gf100_pm_hub[] = {
{}
};
-static const struct nouveau_specdom
-nvc0_perfmon_gpc[] = {
+static const struct nvkm_specdom
+gf100_pm_gpc[] = {
{}
};
-static const struct nouveau_specdom
-nvc0_perfmon_part[] = {
+static const struct nvkm_specdom
+gf100_pm_part[] = {
{}
};
static void
-nvc0_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
+gf100_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
+ struct nvkm_perfctr *ctr)
{
- struct nvc0_perfmon_priv *priv = (void *)ppm;
- struct nvc0_perfmon_cntr *cntr = (void *)ctr;
+ struct gf100_pm_priv *priv = (void *)ppm;
+ struct gf100_pm_cntr *cntr = (void *)ctr;
u32 log = ctr->logic_op;
u32 src = 0x00000000;
int i;
@@ -71,11 +58,11 @@ nvc0_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
}
static void
-nvc0_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
+gf100_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
+ struct nvkm_perfctr *ctr)
{
- struct nvc0_perfmon_priv *priv = (void *)ppm;
- struct nvc0_perfmon_cntr *cntr = (void *)ctr;
+ struct gf100_pm_priv *priv = (void *)ppm;
+ struct gf100_pm_cntr *cntr = (void *)ctr;
switch (cntr->base.slot) {
case 0: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x08c); break;
@@ -87,51 +74,50 @@ nvc0_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
}
static void
-nvc0_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom)
+gf100_perfctr_next(struct nvkm_pm *ppm, struct nvkm_perfdom *dom)
{
- struct nvc0_perfmon_priv *priv = (void *)ppm;
+ struct gf100_pm_priv *priv = (void *)ppm;
nv_wr32(priv, dom->addr + 0x06c, dom->signal_nr - 0x40 + 0x27);
nv_wr32(priv, dom->addr + 0x0ec, 0x00000011);
}
-const struct nouveau_funcdom
-nvc0_perfctr_func = {
- .init = nvc0_perfctr_init,
- .read = nvc0_perfctr_read,
- .next = nvc0_perfctr_next,
+const struct nvkm_funcdom
+gf100_perfctr_func = {
+ .init = gf100_perfctr_init,
+ .read = gf100_perfctr_read,
+ .next = gf100_perfctr_next,
};
int
-nvc0_perfmon_fini(struct nouveau_object *object, bool suspend)
+gf100_pm_fini(struct nvkm_object *object, bool suspend)
{
- struct nvc0_perfmon_priv *priv = (void *)object;
+ struct gf100_pm_priv *priv = (void *)object;
nv_mask(priv, 0x000200, 0x10000000, 0x00000000);
nv_mask(priv, 0x000200, 0x10000000, 0x10000000);
- return nouveau_perfmon_fini(&priv->base, suspend);
+ return nvkm_pm_fini(&priv->base, suspend);
}
static int
-nvc0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_perfmon_priv *priv;
+ struct gf100_pm_priv *priv;
u32 mask;
int ret;
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
+ ret = nvkm_pm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
- nvc0_perfmon_pwr);
+ ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, gf100_pm_pwr);
if (ret)
return ret;
/* HUB */
- ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
- nvc0_perfmon_hub);
+ ret = nvkm_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
+ gf100_pm_hub);
if (ret)
return ret;
@@ -140,8 +126,8 @@ nvc0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
mask &= ~nv_rd32(priv, 0x022504);
mask &= ~nv_rd32(priv, 0x022584);
- ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000,
- 0x1000, 0x200, nvc0_perfmon_gpc);
+ ret = nvkm_perfdom_new(&priv->base, "gpc", mask, 0x180000,
+ 0x1000, 0x200, gf100_pm_gpc);
if (ret)
return ret;
@@ -150,24 +136,24 @@ nvc0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
mask &= ~nv_rd32(priv, 0x022548);
mask &= ~nv_rd32(priv, 0x0225c8);
- ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000,
- 0x1000, 0x200, nvc0_perfmon_part);
+ ret = nvkm_perfdom_new(&priv->base, "part", mask, 0x1a0000,
+ 0x1000, 0x200, gf100_pm_part);
if (ret)
return ret;
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
+ nv_engine(priv)->cclass = &nvkm_pm_cclass;
+ nv_engine(priv)->sclass = nvkm_pm_sclass;
priv->base.last = 7;
return 0;
}
-struct nouveau_oclass
-nvc0_perfmon_oclass = {
- .handle = NV_ENGINE(PERFMON, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = nvc0_perfmon_fini,
+struct nvkm_oclass
+gf100_pm_oclass = {
+ .handle = NV_ENGINE(PM, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_pm_ctor,
+ .dtor = _nvkm_pm_dtor,
+ .init = _nvkm_pm_init,
+ .fini = gf100_pm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.h
new file mode 100644
index 000000000000..6a01fc7fec6f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.h
@@ -0,0 +1,15 @@
+#ifndef __NVKM_PM_NVC0_H__
+#define __NVKM_PM_NVC0_H__
+#include "priv.h"
+
+struct gf100_pm_priv {
+ struct nvkm_pm base;
+};
+
+struct gf100_pm_cntr {
+ struct nvkm_perfctr base;
+};
+
+extern const struct nvkm_funcdom gf100_perfctr_func;
+int gf100_pm_fini(struct nvkm_object *, bool);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk104.c
new file mode 100644
index 000000000000..75b9ff3d1a2c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk104.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "gf100.h"
+
+static const struct nvkm_specdom
+gk104_pm_hub[] = {
+ { 0x60, (const struct nvkm_specsig[]) {
+ { 0x47, "hub00_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0x40, (const struct nvkm_specsig[]) {
+ { 0x27, "hub01_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0x60, (const struct nvkm_specsig[]) {
+ { 0x47, "hub02_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0x60, (const struct nvkm_specsig[]) {
+ { 0x47, "hub03_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0x40, (const struct nvkm_specsig[]) {
+ { 0x03, "host_mmio_rd" },
+ { 0x27, "hub04_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0x60, (const struct nvkm_specsig[]) {
+ { 0x47, "hub05_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0xc0, (const struct nvkm_specsig[]) {
+ { 0x74, "host_fb_rd3x" },
+ { 0x75, "host_fb_rd3x_2" },
+ { 0xa7, "hub06_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0x60, (const struct nvkm_specsig[]) {
+ { 0x47, "hub07_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ {}
+};
+
+static const struct nvkm_specdom
+gk104_pm_gpc[] = {
+ { 0xe0, (const struct nvkm_specsig[]) {
+ { 0xc7, "gpc00_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ {}
+};
+
+static const struct nvkm_specdom
+gk104_pm_part[] = {
+ { 0x60, (const struct nvkm_specsig[]) {
+ { 0x47, "part00_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ { 0x60, (const struct nvkm_specsig[]) {
+ { 0x47, "part01_user_0" },
+ {}
+ }, &gf100_perfctr_func },
+ {}
+};
+
+static int
+gk104_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gf100_pm_priv *priv;
+ u32 mask;
+ int ret;
+
+ ret = nvkm_pm_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ /* PDAEMON */
+ ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, gk104_pm_pwr);
+ if (ret)
+ return ret;
+
+ /* HUB */
+ ret = nvkm_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200,
+ gk104_pm_hub);
+ if (ret)
+ return ret;
+
+ /* GPC */
+ mask = (1 << nv_rd32(priv, 0x022430)) - 1;
+ mask &= ~nv_rd32(priv, 0x022504);
+ mask &= ~nv_rd32(priv, 0x022584);
+
+ ret = nvkm_perfdom_new(&priv->base, "gpc", mask, 0x180000,
+ 0x1000, 0x200, gk104_pm_gpc);
+ if (ret)
+ return ret;
+
+ /* PART */
+ mask = (1 << nv_rd32(priv, 0x022438)) - 1;
+ mask &= ~nv_rd32(priv, 0x022548);
+ mask &= ~nv_rd32(priv, 0x0225c8);
+
+ ret = nvkm_perfdom_new(&priv->base, "part", mask, 0x1a0000,
+ 0x1000, 0x200, gk104_pm_part);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->cclass = &nvkm_pm_cclass;
+ nv_engine(priv)->sclass = nvkm_pm_sclass;
+ priv->base.last = 7;
+ return 0;
+}
+
+struct nvkm_oclass
+gk104_pm_oclass = {
+ .handle = NV_ENGINE(PM, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_pm_ctor,
+ .dtor = _nvkm_pm_dtor,
+ .init = _nvkm_pm_init,
+ .fini = gf100_pm_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c
new file mode 100644
index 000000000000..6820176e5f78
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gk110.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "gf100.h"
+
+static int
+gk110_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gf100_pm_priv *priv;
+ int ret;
+
+ ret = nvkm_pm_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, gk104_pm_pwr);
+ if (ret)
+ return ret;
+
+ nv_engine(priv)->cclass = &nvkm_pm_cclass;
+ nv_engine(priv)->sclass = nvkm_pm_sclass;
+ return 0;
+}
+
+struct nvkm_oclass
+gk110_pm_oclass = {
+ .handle = NV_ENGINE(PM, 0xf0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk110_pm_ctor,
+ .dtor = _nvkm_pm_dtor,
+ .init = _nvkm_pm_init,
+ .fini = gf100_pm_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gt215.c
index 9232c7fc6253..d065bfc59bbf 100644
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/gt215.c
@@ -21,58 +21,63 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv40.h"
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
-static const struct nouveau_specdom
-nv84_perfmon[] = {
- { 0x20, (const struct nouveau_specsig[]) {
+static const struct nvkm_specdom
+gt215_pm[] = {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
{}
};
-struct nouveau_oclass *
-nv84_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0x84),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
+static int
+gt215_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **object)
+{
+ int ret = nv40_pm_ctor(parent, engine, oclass, data, size, object);
+ if (ret == 0) {
+ struct nv40_pm_priv *priv = (void *)*object;
+ ret = nvkm_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0,
+ gt215_pm_pwr);
+ if (ret)
+ return ret;
+
+ priv->base.last = 3;
+ }
+ return ret;
+}
+
+struct nvkm_oclass *
+gt215_pm_oclass = &(struct nv40_pm_oclass) {
+ .base.handle = NV_ENGINE(PM, 0xa3),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gt215_pm_ctor,
+ .dtor = _nvkm_pm_dtor,
+ .init = _nvkm_pm_init,
+ .fini = _nvkm_pm_fini,
},
- .doms = nv84_perfmon,
+ .doms = gt215_pm,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c
index b2a10785adb1..ff22f06b22b8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.c
@@ -21,27 +21,14 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv40.h"
-/*******************************************************************************
- * Perfmon object classes
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM context
- ******************************************************************************/
-
-/*******************************************************************************
- * PPM engine/subdev functions
- ******************************************************************************/
-
static void
-nv40_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
+nv40_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
+ struct nvkm_perfctr *ctr)
{
- struct nv40_perfmon_priv *priv = (void *)ppm;
- struct nv40_perfmon_cntr *cntr = (void *)ctr;
+ struct nv40_pm_priv *priv = (void *)ppm;
+ struct nv40_pm_cntr *cntr = (void *)ctr;
u32 log = ctr->logic_op;
u32 src = 0x00000000;
int i;
@@ -55,11 +42,11 @@ nv40_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
}
static void
-nv40_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
- struct nouveau_perfctr *ctr)
+nv40_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom,
+ struct nvkm_perfctr *ctr)
{
- struct nv40_perfmon_priv *priv = (void *)ppm;
- struct nv40_perfmon_cntr *cntr = (void *)ctr;
+ struct nv40_pm_priv *priv = (void *)ppm;
+ struct nv40_pm_cntr *cntr = (void *)ctr;
switch (cntr->base.slot) {
case 0: cntr->base.ctr = nv_rd32(priv, 0x00a700 + dom->addr); break;
@@ -71,73 +58,73 @@ nv40_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom,
}
static void
-nv40_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom)
+nv40_perfctr_next(struct nvkm_pm *ppm, struct nvkm_perfdom *dom)
{
- struct nv40_perfmon_priv *priv = (void *)ppm;
+ struct nv40_pm_priv *priv = (void *)ppm;
if (priv->sequence != ppm->sequence) {
nv_wr32(priv, 0x400084, 0x00000020);
priv->sequence = ppm->sequence;
}
}
-const struct nouveau_funcdom
+const struct nvkm_funcdom
nv40_perfctr_func = {
.init = nv40_perfctr_init,
.read = nv40_perfctr_read,
.next = nv40_perfctr_next,
};
-static const struct nouveau_specdom
-nv40_perfmon[] = {
- { 0x20, (const struct nouveau_specsig[]) {
+static const struct nvkm_specdom
+nv40_pm[] = {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
- { 0x20, (const struct nouveau_specsig[]) {
+ { 0x20, (const struct nvkm_specsig[]) {
{}
}, &nv40_perfctr_func },
{}
};
int
-nv40_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_pm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv40_perfmon_oclass *mclass = (void *)oclass;
- struct nv40_perfmon_priv *priv;
+ struct nv40_pm_oclass *mclass = (void *)oclass;
+ struct nv40_pm_priv *priv;
int ret;
- ret = nouveau_perfmon_create(parent, engine, oclass, &priv);
+ ret = nvkm_pm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_perfdom_new(&priv->base, "pm", 0, 0, 0, 4, mclass->doms);
+ ret = nvkm_perfdom_new(&priv->base, "pm", 0, 0, 0, 4, mclass->doms);
if (ret)
return ret;
- nv_engine(priv)->cclass = &nouveau_perfmon_cclass;
- nv_engine(priv)->sclass = nouveau_perfmon_sclass;
+ nv_engine(priv)->cclass = &nvkm_pm_cclass;
+ nv_engine(priv)->sclass = nvkm_pm_sclass;
return 0;
}
-struct nouveau_oclass *
-nv40_perfmon_oclass = &(struct nv40_perfmon_oclass) {
- .base.handle = NV_ENGINE(PERFMON, 0x40),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_perfmon_ctor,
- .dtor = _nouveau_perfmon_dtor,
- .init = _nouveau_perfmon_init,
- .fini = _nouveau_perfmon_fini,
+struct nvkm_oclass *
+nv40_pm_oclass = &(struct nv40_pm_oclass) {
+ .base.handle = NV_ENGINE(PM, 0x40),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv40_pm_ctor,
+ .dtor = _nvkm_pm_dtor,
+ .init = _nvkm_pm_init,
+ .fini = _nvkm_pm_fini,
},
- .doms = nv40_perfmon,
+ .doms = nv40_pm,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.h b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.h
new file mode 100644
index 000000000000..2338e150420e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv40.h
@@ -0,0 +1,24 @@
+#ifndef __NVKM_PM_NV40_H__
+#define __NVKM_PM_NV40_H__
+#include "priv.h"
+
+struct nv40_pm_oclass {
+ struct nvkm_oclass base;
+ const struct nvkm_specdom *doms;
+};
+
+struct nv40_pm_priv {
+ struct nvkm_pm base;
+ u32 sequence;
+};
+
+int nv40_pm_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *data, u32 size,
+ struct nvkm_object **pobject);
+
+struct nv40_pm_cntr {
+ struct nvkm_perfctr base;
+};
+
+extern const struct nvkm_funcdom nv40_perfctr_func;
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv50.c
new file mode 100644
index 000000000000..6af83b5d1b11
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/nv50.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "nv40.h"
+
+static const struct nvkm_specdom
+nv50_pm[] = {
+ { 0x040, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x100, (const struct nvkm_specsig[]) {
+ { 0xc8, "gr_idle" },
+ {}
+ }, &nv40_perfctr_func },
+ { 0x100, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x020, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ { 0x040, (const struct nvkm_specsig[]) {
+ {}
+ }, &nv40_perfctr_func },
+ {}
+};
+
+struct nvkm_oclass *
+nv50_pm_oclass = &(struct nv40_pm_oclass) {
+ .base.handle = NV_ENGINE(PM, 0x50),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv40_pm_ctor,
+ .dtor = _nvkm_pm_dtor,
+ .init = _nvkm_pm_init,
+ .fini = _nvkm_pm_fini,
+ },
+ .doms = nv50_pm,
+}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h
new file mode 100644
index 000000000000..1e6eff2a6d79
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/priv.h
@@ -0,0 +1,90 @@
+#ifndef __NVKM_PM_PRIV_H__
+#define __NVKM_PM_PRIV_H__
+#include <engine/pm.h>
+
+struct nvkm_perfctr {
+ struct nvkm_object base;
+ struct list_head head;
+ struct nvkm_perfsig *signal[4];
+ int slot;
+ u32 logic_op;
+ u32 clk;
+ u32 ctr;
+};
+
+extern struct nvkm_oclass nvkm_pm_sclass[];
+
+#include <core/engctx.h>
+
+struct nvkm_perfctx {
+ struct nvkm_engctx base;
+};
+
+extern struct nvkm_oclass nvkm_pm_cclass;
+
+struct nvkm_specsig {
+ u8 signal;
+ const char *name;
+};
+
+struct nvkm_perfsig {
+ const char *name;
+};
+
+struct nvkm_perfdom;
+struct nvkm_perfctr *
+nvkm_perfsig_wrap(struct nvkm_pm *, const char *, struct nvkm_perfdom **);
+
+struct nvkm_specdom {
+ u16 signal_nr;
+ const struct nvkm_specsig *signal;
+ const struct nvkm_funcdom *func;
+};
+
+extern const struct nvkm_specdom gt215_pm_pwr[];
+extern const struct nvkm_specdom gf100_pm_pwr[];
+extern const struct nvkm_specdom gk104_pm_pwr[];
+
+struct nvkm_perfdom {
+ struct list_head head;
+ struct list_head list;
+ const struct nvkm_funcdom *func;
+ char name[32];
+ u32 addr;
+ u8 quad;
+ u32 signal_nr;
+ struct nvkm_perfsig signal[];
+};
+
+struct nvkm_funcdom {
+ void (*init)(struct nvkm_pm *, struct nvkm_perfdom *,
+ struct nvkm_perfctr *);
+ void (*read)(struct nvkm_pm *, struct nvkm_perfdom *,
+ struct nvkm_perfctr *);
+ void (*next)(struct nvkm_pm *, struct nvkm_perfdom *);
+};
+
+int nvkm_perfdom_new(struct nvkm_pm *, const char *, u32, u32, u32, u32,
+ const struct nvkm_specdom *);
+
+#define nvkm_pm_create(p,e,o,d) \
+ nvkm_pm_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_pm_dtor(p) ({ \
+ struct nvkm_pm *c = (p); \
+ _nvkm_pm_dtor(nv_object(c)); \
+})
+#define nvkm_pm_init(p) ({ \
+ struct nvkm_pm *c = (p); \
+ _nvkm_pm_init(nv_object(c)); \
+})
+#define nvkm_pm_fini(p,s) ({ \
+ struct nvkm_pm *c = (p); \
+ _nvkm_pm_fini(nv_object(c), (s)); \
+})
+
+int nvkm_pm_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_pm_dtor(struct nvkm_object *);
+int _nvkm_pm_init(struct nvkm_object *);
+int _nvkm_pm_fini(struct nvkm_object *, bool);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/sec/Kbuild
new file mode 100644
index 000000000000..552d40a4641f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec/Kbuild
@@ -0,0 +1 @@
+nvkm-y += nvkm/engine/sec/g98.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/g98.fuc0s
index 629da02dc352..06ee06071104 100644
--- a/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/g98.fuc0s
@@ -1,5 +1,5 @@
/*
- * fuc microcode for nv98 pcrypt engine
+ * fuc microcode for g98 psec engine
* Copyright (C) 2010 Marcin Kościelnicki
*
* This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-.section #nv98_pcrypt_data
+.section #g98_psec_data
ctx_dma:
ctx_dma_query: .b32 0
@@ -70,31 +70,31 @@ engine_cmd_dtable:
.b32 #ctx_src_address_low + 0x20000 ~0xfffffff0
.b32 #ctx_dst_address_high + 0x20000 ~0xff
.b32 #ctx_dst_address_low + 0x20000 ~0xfffffff0
-.b32 #crypt_cmd_mode + 0x00000 ~0xf
-.b32 #crypt_cmd_length + 0x10000 ~0x0ffffff0
+.b32 #sec_cmd_mode + 0x00000 ~0xf
+.b32 #sec_cmd_length + 0x10000 ~0x0ffffff0
.equ #engine_cmd_max 0xce
.align 4
-crypt_dtable:
-.b16 #crypt_copy_prep #crypt_do_inout
-.b16 #crypt_store_prep #crypt_do_out
-.b16 #crypt_ecb_e_prep #crypt_do_inout
-.b16 #crypt_ecb_d_prep #crypt_do_inout
-.b16 #crypt_cbc_e_prep #crypt_do_inout
-.b16 #crypt_cbc_d_prep #crypt_do_inout
-.b16 #crypt_pcbc_e_prep #crypt_do_inout
-.b16 #crypt_pcbc_d_prep #crypt_do_inout
-.b16 #crypt_cfb_e_prep #crypt_do_inout
-.b16 #crypt_cfb_d_prep #crypt_do_inout
-.b16 #crypt_ofb_prep #crypt_do_inout
-.b16 #crypt_ctr_prep #crypt_do_inout
-.b16 #crypt_cbc_mac_prep #crypt_do_in
-.b16 #crypt_cmac_finish_complete_prep #crypt_do_in
-.b16 #crypt_cmac_finish_partial_prep #crypt_do_in
+sec_dtable:
+.b16 #sec_copy_prep #sec_do_inout
+.b16 #sec_store_prep #sec_do_out
+.b16 #sec_ecb_e_prep #sec_do_inout
+.b16 #sec_ecb_d_prep #sec_do_inout
+.b16 #sec_cbc_e_prep #sec_do_inout
+.b16 #sec_cbc_d_prep #sec_do_inout
+.b16 #sec_pcbc_e_prep #sec_do_inout
+.b16 #sec_pcbc_d_prep #sec_do_inout
+.b16 #sec_cfb_e_prep #sec_do_inout
+.b16 #sec_cfb_d_prep #sec_do_inout
+.b16 #sec_ofb_prep #sec_do_inout
+.b16 #sec_ctr_prep #sec_do_inout
+.b16 #sec_cbc_mac_prep #sec_do_in
+.b16 #sec_cmac_finish_complete_prep #sec_do_in
+.b16 #sec_cmac_finish_partial_prep #sec_do_in
.align 0x100
-.section #nv98_pcrypt_code
+.section #g98_psec_code
// $r0 is always set to 0 in our code - this allows some space savings.
clear b32 $r0
@@ -417,23 +417,23 @@ cmd_wrcache_flush:
iowr I[$r2] $r3
ret
-crypt_cmd_mode:
+sec_cmd_mode:
// if >= 0xf, INVALID_ENUM
bset $flags $p1
or $r2 2
cmpu b32 $r3 0xf
- bra nc #crypt_cmd_mode_return
+ bra nc #sec_cmd_mode_return
bclr $flags $p1
st b32 D[$r0 + #ctx_mode] $r3
- crypt_cmd_mode_return:
+ sec_cmd_mode_return:
ret
-crypt_cmd_length:
+sec_cmd_length:
// nop if length == 0
cmpu b32 $r3 0
- bra e #crypt_cmd_mode_return
+ bra e #sec_cmd_mode_return
// init key, IV
cxset 3
@@ -471,11 +471,11 @@ crypt_cmd_length:
shl b32 $r8 2
// run prep
- ld b16 $r9 D[$r8 + #crypt_dtable]
+ ld b16 $r9 D[$r8 + #sec_dtable]
call $r9
// do it
- ld b16 $r9 D[$r8 + #crypt_dtable + 2]
+ ld b16 $r9 D[$r8 + #sec_dtable + 2]
call $r9
cxset 1
xdwait
@@ -509,25 +509,25 @@ crypt_cmd_length:
ret
-crypt_copy_prep:
+sec_copy_prep:
cs0begin 2
cxsin $c0
cxsout $c0
ret
-crypt_store_prep:
+sec_store_prep:
cs0begin 1
cxsout $c6
ret
-crypt_ecb_e_prep:
+sec_ecb_e_prep:
cs0begin 3
cxsin $c0
cenc $c0 $c0
cxsout $c0
ret
-crypt_ecb_d_prep:
+sec_ecb_d_prep:
ckexp $c7 $c7
cs0begin 3
cxsin $c0
@@ -535,7 +535,7 @@ crypt_ecb_d_prep:
cxsout $c0
ret
-crypt_cbc_e_prep:
+sec_cbc_e_prep:
cs0begin 4
cxsin $c0
cxor $c6 $c0
@@ -543,7 +543,7 @@ crypt_cbc_e_prep:
cxsout $c6
ret
-crypt_cbc_d_prep:
+sec_cbc_d_prep:
ckexp $c7 $c7
cs0begin 5
cmov $c2 $c6
@@ -553,7 +553,7 @@ crypt_cbc_d_prep:
cxsout $c0
ret
-crypt_pcbc_e_prep:
+sec_pcbc_e_prep:
cs0begin 5
cxsin $c0
cxor $c6 $c0
@@ -562,7 +562,7 @@ crypt_pcbc_e_prep:
cxor $c6 $c0
ret
-crypt_pcbc_d_prep:
+sec_pcbc_d_prep:
ckexp $c7 $c7
cs0begin 5
cxsin $c0
@@ -572,7 +572,7 @@ crypt_pcbc_d_prep:
cxor $c6 $c0
ret
-crypt_cfb_e_prep:
+sec_cfb_e_prep:
cs0begin 4
cenc $c6 $c6
cxsin $c0
@@ -580,7 +580,7 @@ crypt_cfb_e_prep:
cxsout $c6
ret
-crypt_cfb_d_prep:
+sec_cfb_d_prep:
cs0begin 4
cenc $c0 $c6
cxsin $c6
@@ -588,7 +588,7 @@ crypt_cfb_d_prep:
cxsout $c0
ret
-crypt_ofb_prep:
+sec_ofb_prep:
cs0begin 4
cenc $c6 $c6
cxsin $c0
@@ -596,7 +596,7 @@ crypt_ofb_prep:
cxsout $c0
ret
-crypt_ctr_prep:
+sec_ctr_prep:
cs0begin 5
cenc $c1 $c6
cadd $c6 1
@@ -605,14 +605,14 @@ crypt_ctr_prep:
cxsout $c0
ret
-crypt_cbc_mac_prep:
+sec_cbc_mac_prep:
cs0begin 3
cxsin $c0
cxor $c6 $c0
cenc $c6 $c6
ret
-crypt_cmac_finish_complete_prep:
+sec_cmac_finish_complete_prep:
cs0begin 7
cxsin $c0
cxor $c6 $c0
@@ -623,7 +623,7 @@ crypt_cmac_finish_complete_prep:
cenc $c6 $c6
ret
-crypt_cmac_finish_partial_prep:
+sec_cmac_finish_partial_prep:
cs0begin 8
cxsin $c0
cxor $c6 $c0
@@ -636,12 +636,12 @@ crypt_cmac_finish_partial_prep:
ret
// TODO
-crypt_do_in:
+sec_do_in:
add b32 $r3 $r5
mov $xdbase $r4
mov $r9 #swap
sethi $r9 0x20000
- crypt_do_in_loop:
+ sec_do_in_loop:
xdld $r5 $r9
xdwait
cxset 0x22
@@ -650,17 +650,17 @@ crypt_do_in:
xdwait
add b32 $r5 0x10
cmpu b32 $r5 $r3
- bra ne #crypt_do_in_loop
+ bra ne #sec_do_in_loop
cxset 1
xdwait
ret
-crypt_do_out:
+sec_do_out:
add b32 $r3 $r7
mov $xdbase $r6
mov $r9 #swap
sethi $r9 0x20000
- crypt_do_out_loop:
+ sec_do_out_loop:
cs0exec 1
cxset 0x61
xdld $r7 $r9
@@ -669,14 +669,14 @@ crypt_do_out:
xdwait
add b32 $r7 0x10
cmpu b32 $r7 $r3
- bra ne #crypt_do_out_loop
+ bra ne #sec_do_out_loop
ret
-crypt_do_inout:
+sec_do_inout:
add b32 $r3 $r5
mov $r9 #swap
sethi $r9 0x20000
- crypt_do_inout_loop:
+ sec_do_inout_loop:
mov $xdbase $r4
xdld $r5 $r9
xdwait
@@ -692,7 +692,7 @@ crypt_do_inout:
add b32 $r5 0x10
add b32 $r7 0x10
cmpu b32 $r5 $r3
- bra ne #crypt_do_inout_loop
+ bra ne #sec_do_inout_loop
ret
.align 0x100
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h b/drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/g98.fuc0s.h
index 38676c74e6e0..5d65c4fbb087 100644
--- a/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/g98.fuc0s.h
@@ -1,4 +1,4 @@
-uint32_t nv98_pcrypt_data[] = {
+uint32_t g98_psec_data[] = {
/* 0x0000: ctx_dma */
/* 0x0000: ctx_dma_query */
0x00000000,
@@ -103,7 +103,7 @@ uint32_t nv98_pcrypt_data[] = {
0xfffffff0,
0x00010285,
0xf000000f,
-/* 0x0150: crypt_dtable */
+/* 0x0150: sec_dtable */
0x04db0321,
0x04b1032f,
0x04db0339,
@@ -150,7 +150,7 @@ uint32_t nv98_pcrypt_data[] = {
0x00000000,
};
-uint32_t nv98_pcrypt_code[] = {
+uint32_t g98_psec_code[] = {
0x17f004bd,
0x0010fe35,
0xf10004fe,
@@ -329,14 +329,14 @@ uint32_t nv98_pcrypt_code[] = {
0xbd220027,
0x0133f034,
0xf80023d0,
-/* 0x0271: crypt_cmd_mode */
+/* 0x0271: sec_cmd_mode */
0x0131f400,
0xb00225f0,
0x18f40f34,
0x0132f409,
-/* 0x0283: crypt_cmd_mode_return */
+/* 0x0283: sec_cmd_mode_return */
0xf80d0380,
-/* 0x0285: crypt_cmd_length */
+/* 0x0285: sec_cmd_length */
0x0034b000,
0xf4fb0bf4,
0x47f0033c,
@@ -376,33 +376,33 @@ uint32_t nv98_pcrypt_code[] = {
0xf05047f0,
0x04fa0643,
0xf803f805,
-/* 0x0321: crypt_copy_prep */
+/* 0x0321: sec_copy_prep */
0x203cf500,
0x003cf594,
0x003cf588,
-/* 0x032f: crypt_store_prep */
+/* 0x032f: sec_store_prep */
0xf500f88c,
0xf594103c,
0xf88c063c,
-/* 0x0339: crypt_ecb_e_prep */
+/* 0x0339: sec_ecb_e_prep */
0x303cf500,
0x003cf594,
0x003cf588,
0x003cf5d0,
-/* 0x034b: crypt_ecb_d_prep */
+/* 0x034b: sec_ecb_d_prep */
0xf500f88c,
0xf5c8773c,
0xf594303c,
0xf588003c,
0xf5d4003c,
0xf88c003c,
-/* 0x0361: crypt_cbc_e_prep */
+/* 0x0361: sec_cbc_e_prep */
0x403cf500,
0x003cf594,
0x063cf588,
0x663cf5ac,
0x063cf5d0,
-/* 0x0377: crypt_cbc_d_prep */
+/* 0x0377: sec_cbc_d_prep */
0xf500f88c,
0xf5c8773c,
0xf594503c,
@@ -411,14 +411,14 @@ uint32_t nv98_pcrypt_code[] = {
0xf5d4603c,
0xf5ac203c,
0xf88c003c,
-/* 0x0395: crypt_pcbc_e_prep */
+/* 0x0395: sec_pcbc_e_prep */
0x503cf500,
0x003cf594,
0x063cf588,
0x663cf5ac,
0x063cf5d0,
0x063cf58c,
-/* 0x03af: crypt_pcbc_d_prep */
+/* 0x03af: sec_pcbc_d_prep */
0xf500f8ac,
0xf5c8773c,
0xf594503c,
@@ -427,26 +427,26 @@ uint32_t nv98_pcrypt_code[] = {
0xf5ac163c,
0xf58c063c,
0xf8ac063c,
-/* 0x03cd: crypt_cfb_e_prep */
+/* 0x03cd: sec_cfb_e_prep */
0x403cf500,
0x663cf594,
0x003cf5d0,
0x063cf588,
0x063cf5ac,
-/* 0x03e3: crypt_cfb_d_prep */
+/* 0x03e3: sec_cfb_d_prep */
0xf500f88c,
0xf594403c,
0xf5d0603c,
0xf588063c,
0xf5ac603c,
0xf88c003c,
-/* 0x03f9: crypt_ofb_prep */
+/* 0x03f9: sec_ofb_prep */
0x403cf500,
0x663cf594,
0x003cf5d0,
0x603cf588,
0x003cf5ac,
-/* 0x040f: crypt_ctr_prep */
+/* 0x040f: sec_ctr_prep */
0xf500f88c,
0xf594503c,
0xf5d0613c,
@@ -454,12 +454,12 @@ uint32_t nv98_pcrypt_code[] = {
0xf588003c,
0xf5ac103c,
0xf88c003c,
-/* 0x0429: crypt_cbc_mac_prep */
+/* 0x0429: sec_cbc_mac_prep */
0x303cf500,
0x003cf594,
0x063cf588,
0x663cf5ac,
-/* 0x043b: crypt_cmac_finish_complete_prep */
+/* 0x043b: sec_cmac_finish_complete_prep */
0xf500f8d0,
0xf594703c,
0xf588003c,
@@ -469,7 +469,7 @@ uint32_t nv98_pcrypt_code[] = {
0xf5bc003c,
0xf5ac063c,
0xf8d0663c,
-/* 0x045d: crypt_cmac_finish_partial_prep */
+/* 0x045d: sec_cmac_finish_partial_prep */
0x803cf500,
0x003cf594,
0x063cf588,
@@ -479,12 +479,12 @@ uint32_t nv98_pcrypt_code[] = {
0x003cf5bc,
0x063cf5bc,
0x663cf5ac,
-/* 0x0483: crypt_do_in */
+/* 0x0483: sec_do_in */
0xbb00f8d0,
0x47fe0035,
0x8097f100,
0x0293f000,
-/* 0x0490: crypt_do_in_loop */
+/* 0x0490: sec_do_in_loop */
0xf80559fa,
0x223cf403,
0xf50609fa,
@@ -493,11 +493,11 @@ uint32_t nv98_pcrypt_code[] = {
0xf40453b8,
0x3cf4e91b,
0xf803f801,
-/* 0x04b1: crypt_do_out */
+/* 0x04b1: sec_do_out */
0x0037bb00,
0xf10067fe,
0xf0008097,
-/* 0x04be: crypt_do_out_loop */
+/* 0x04be: sec_do_out_loop */
0x3cf50293,
0x3cf49810,
0x0579fa61,
@@ -505,11 +505,11 @@ uint32_t nv98_pcrypt_code[] = {
0x03f8013c,
0xb81070b6,
0x1bf40473,
-/* 0x04db: crypt_do_inout */
+/* 0x04db: sec_do_inout */
0xbb00f8e8,
0x97f10035,
0x93f00080,
-/* 0x04e5: crypt_do_inout_loop */
+/* 0x04e5: sec_do_inout_loop */
0x0047fe02,
0xf80559fa,
0x213cf403,
diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
index 5571c09534cb..9d5c1b8b1f8c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
@@ -21,57 +21,50 @@
*
* Authors: Ben Skeggs
*/
+#include <engine/sec.h>
+#include <engine/falcon.h>
+#include "fuc/g98.fuc0s.h"
#include <core/client.h>
-#include <core/os.h>
#include <core/enum.h>
-#include <core/engctx.h>
-
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-
-#include <engine/falcon.h>
#include <engine/fifo.h>
-#include <engine/crypt.h>
-
-#include "fuc/nv98.fuc.h"
-struct nv98_crypt_priv {
- struct nouveau_falcon base;
+struct g98_sec_priv {
+ struct nvkm_falcon base;
};
/*******************************************************************************
* Crypt object classes
******************************************************************************/
-static struct nouveau_oclass
-nv98_crypt_sclass[] = {
- { 0x88b4, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+g98_sec_sclass[] = {
+ { 0x88b4, &nvkm_object_ofuncs },
{},
};
/*******************************************************************************
- * PCRYPT context
+ * PSEC context
******************************************************************************/
-static struct nouveau_oclass
-nv98_crypt_cclass = {
- .handle = NV_ENGCTX(CRYPT, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_falcon_context_ctor,
- .dtor = _nouveau_falcon_context_dtor,
- .init = _nouveau_falcon_context_init,
- .fini = _nouveau_falcon_context_fini,
- .rd32 = _nouveau_falcon_context_rd32,
- .wr32 = _nouveau_falcon_context_wr32,
+static struct nvkm_oclass
+g98_sec_cclass = {
+ .handle = NV_ENGCTX(SEC, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_falcon_context_ctor,
+ .dtor = _nvkm_falcon_context_dtor,
+ .init = _nvkm_falcon_context_init,
+ .fini = _nvkm_falcon_context_fini,
+ .rd32 = _nvkm_falcon_context_rd32,
+ .wr32 = _nvkm_falcon_context_wr32,
},
};
/*******************************************************************************
- * PCRYPT engine/subdev functions
+ * PSEC engine/subdev functions
******************************************************************************/
-static const struct nouveau_enum nv98_crypt_isr_error_name[] = {
+static const struct nvkm_enum g98_sec_isr_error_name[] = {
{ 0x0000, "ILLEGAL_MTHD" },
{ 0x0001, "INVALID_BITFIELD" },
{ 0x0002, "INVALID_ENUM" },
@@ -80,12 +73,12 @@ static const struct nouveau_enum nv98_crypt_isr_error_name[] = {
};
static void
-nv98_crypt_intr(struct nouveau_subdev *subdev)
+g98_sec_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
- struct nv98_crypt_priv *priv = (void *)subdev;
+ struct nvkm_fifo *pfifo = nvkm_fifo(subdev);
+ struct nvkm_engine *engine = nv_engine(subdev);
+ struct nvkm_object *engctx;
+ struct g98_sec_priv *priv = (void *)subdev;
u32 disp = nv_rd32(priv, 0x08701c);
u32 stat = nv_rd32(priv, 0x087008) & disp & ~(disp >> 16);
u32 inst = nv_rd32(priv, 0x087050) & 0x3fffffff;
@@ -96,14 +89,14 @@ nv98_crypt_intr(struct nouveau_subdev *subdev)
u32 data = nv_rd32(priv, 0x087044);
int chid;
- engctx = nouveau_engctx_get(engine, inst);
+ engctx = nvkm_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & 0x00000040) {
nv_error(priv, "DISPATCH_ERROR [");
- nouveau_enum_print(nv98_crypt_isr_error_name, ssta);
+ nvkm_enum_print(g98_sec_isr_error_name, ssta);
pr_cont("] ch %d [0x%010llx %s] subc %d mthd 0x%04x data 0x%08x\n",
- chid, (u64)inst << 12, nouveau_client_name(engctx),
+ chid, (u64)inst << 12, nvkm_client_name(engctx),
subc, mthd, data);
nv_wr32(priv, 0x087004, 0x00000040);
stat &= ~0x00000040;
@@ -114,43 +107,43 @@ nv98_crypt_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, 0x087004, stat);
}
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
}
static int
-nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g98_sec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv98_crypt_priv *priv;
+ struct g98_sec_priv *priv;
int ret;
- ret = nouveau_falcon_create(parent, engine, oclass, 0x087000, true,
- "PCRYPT", "crypt", &priv);
+ ret = nvkm_falcon_create(parent, engine, oclass, 0x087000, true,
+ "PSEC", "sec", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00004000;
- nv_subdev(priv)->intr = nv98_crypt_intr;
- nv_engine(priv)->cclass = &nv98_crypt_cclass;
- nv_engine(priv)->sclass = nv98_crypt_sclass;
- nv_falcon(priv)->code.data = nv98_pcrypt_code;
- nv_falcon(priv)->code.size = sizeof(nv98_pcrypt_code);
- nv_falcon(priv)->data.data = nv98_pcrypt_data;
- nv_falcon(priv)->data.size = sizeof(nv98_pcrypt_data);
+ nv_subdev(priv)->intr = g98_sec_intr;
+ nv_engine(priv)->cclass = &g98_sec_cclass;
+ nv_engine(priv)->sclass = g98_sec_sclass;
+ nv_falcon(priv)->code.data = g98_psec_code;
+ nv_falcon(priv)->code.size = sizeof(g98_psec_code);
+ nv_falcon(priv)->data.data = g98_psec_data;
+ nv_falcon(priv)->data.size = sizeof(g98_psec_data);
return 0;
}
-struct nouveau_oclass
-nv98_crypt_oclass = {
- .handle = NV_ENGINE(CRYPT, 0x98),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv98_crypt_ctor,
- .dtor = _nouveau_falcon_dtor,
- .init = _nouveau_falcon_init,
- .fini = _nouveau_falcon_fini,
- .rd32 = _nouveau_falcon_rd32,
- .wr32 = _nouveau_falcon_wr32,
+struct nvkm_oclass
+g98_sec_oclass = {
+ .handle = NV_ENGINE(SEC, 0x98),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g98_sec_ctor,
+ .dtor = _nvkm_falcon_dtor,
+ .init = _nvkm_falcon_init,
+ .fini = _nvkm_falcon_fini,
+ .rd32 = _nvkm_falcon_rd32,
+ .wr32 = _nvkm_falcon_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/sw/Kbuild
new file mode 100644
index 000000000000..bdc3a05907d5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/Kbuild
@@ -0,0 +1,4 @@
+nvkm-y += nvkm/engine/sw/nv04.o
+nvkm-y += nvkm/engine/sw/nv10.o
+nvkm-y += nvkm/engine/sw/nv50.o
+nvkm-y += nvkm/engine/sw/gf100.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.c
index 6af370d3a06d..533d5d8ed363 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.c
@@ -21,27 +21,19 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/os.h>
-#include <core/engctx.h>
-#include <core/event.h>
+#include "nv50.h"
#include <subdev/bar.h>
-#include <engine/software.h>
-#include <engine/disp.h>
-
-#include "nv50.h"
-
/*******************************************************************************
* software object classes
******************************************************************************/
static int
-nvc0_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+gf100_sw_mthd_vblsem_offset(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
u64 data = *(u32 *)args;
if (mthd == 0x0400) {
chan->vblank.offset &= 0x00ffffffffULL;
@@ -54,11 +46,11 @@ nvc0_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd,
}
static int
-nvc0_software_mthd_mp_control(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+gf100_sw_mthd_mp_control(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
- struct nv50_software_priv *priv = (void *)nv_object(chan)->engine;
+ struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv50_sw_priv *priv = (void *)nv_object(chan)->engine;
u32 data = *(u32 *)args;
switch (mthd) {
@@ -79,22 +71,22 @@ nvc0_software_mthd_mp_control(struct nouveau_object *object, u32 mthd,
return 0;
}
-static struct nouveau_omthds
-nvc0_software_omthds[] = {
- { 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset },
- { 0x0404, 0x0404, nvc0_software_mthd_vblsem_offset },
- { 0x0408, 0x0408, nv50_software_mthd_vblsem_value },
- { 0x040c, 0x040c, nv50_software_mthd_vblsem_release },
- { 0x0500, 0x0500, nv50_software_mthd_flip },
- { 0x0600, 0x0600, nvc0_software_mthd_mp_control },
- { 0x0644, 0x0644, nvc0_software_mthd_mp_control },
- { 0x06ac, 0x06ac, nvc0_software_mthd_mp_control },
+static struct nvkm_omthds
+gf100_sw_omthds[] = {
+ { 0x0400, 0x0400, gf100_sw_mthd_vblsem_offset },
+ { 0x0404, 0x0404, gf100_sw_mthd_vblsem_offset },
+ { 0x0408, 0x0408, nv50_sw_mthd_vblsem_value },
+ { 0x040c, 0x040c, nv50_sw_mthd_vblsem_release },
+ { 0x0500, 0x0500, nv50_sw_mthd_flip },
+ { 0x0600, 0x0600, gf100_sw_mthd_mp_control },
+ { 0x0644, 0x0644, gf100_sw_mthd_mp_control },
+ { 0x06ac, 0x06ac, gf100_sw_mthd_mp_control },
{}
};
-static struct nouveau_oclass
-nvc0_software_sclass[] = {
- { 0x906e, &nouveau_object_ofuncs, nvc0_software_omthds },
+static struct nvkm_oclass
+gf100_sw_sclass[] = {
+ { 0x906e, &nvkm_object_ofuncs, gf100_sw_omthds },
{}
};
@@ -103,12 +95,12 @@ nvc0_software_sclass[] = {
******************************************************************************/
static int
-nvc0_software_vblsem_release(struct nvkm_notify *notify)
+gf100_sw_vblsem_release(struct nvkm_notify *notify)
{
- struct nv50_software_chan *chan =
+ struct nv50_sw_chan *chan =
container_of(notify, typeof(*chan), vblank.notify[notify->index]);
- struct nv50_software_priv *priv = (void *)nv_object(chan)->engine;
- struct nouveau_bar *bar = nouveau_bar(priv);
+ struct nv50_sw_priv *priv = (void *)nv_object(chan)->engine;
+ struct nvkm_bar *bar = nvkm_bar(priv);
nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
bar->flush(bar);
@@ -119,31 +111,31 @@ nvc0_software_vblsem_release(struct nvkm_notify *notify)
return NVKM_NOTIFY_DROP;
}
-static struct nv50_software_cclass
-nvc0_software_cclass = {
+static struct nv50_sw_cclass
+gf100_sw_cclass = {
.base.handle = NV_ENGCTX(SW, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_software_context_ctor,
- .dtor = nv50_software_context_dtor,
- .init = _nouveau_software_context_init,
- .fini = _nouveau_software_context_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_sw_context_ctor,
+ .dtor = nv50_sw_context_dtor,
+ .init = _nvkm_sw_context_init,
+ .fini = _nvkm_sw_context_fini,
},
- .vblank = nvc0_software_vblsem_release,
+ .vblank = gf100_sw_vblsem_release,
};
/*******************************************************************************
* software engine/subdev functions
******************************************************************************/
-struct nouveau_oclass *
-nvc0_software_oclass = &(struct nv50_software_oclass) {
+struct nvkm_oclass *
+gf100_sw_oclass = &(struct nv50_sw_oclass) {
.base.handle = NV_ENGINE(SW, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_software_ctor,
- .dtor = _nouveau_software_dtor,
- .init = _nouveau_software_init,
- .fini = _nouveau_software_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_sw_ctor,
+ .dtor = _nvkm_sw_dtor,
+ .init = _nvkm_sw_init,
+ .fini = _nvkm_sw_fini,
},
- .cclass = &nvc0_software_cclass.base,
- .sclass = nvc0_software_sclass,
+ .cclass = &gf100_sw_cclass.base,
+ .sclass = gf100_sw_sclass,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.c
index 64df15c7f051..897024421d36 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.c
@@ -21,19 +21,15 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/os.h>
-#include <core/engctx.h>
-
-#include <engine/software.h>
+#include <engine/sw.h>
#include <engine/fifo.h>
-struct nv04_software_priv {
- struct nouveau_software base;
+struct nv04_sw_priv {
+ struct nvkm_sw base;
};
-struct nv04_software_chan {
- struct nouveau_software_chan base;
+struct nv04_sw_chan {
+ struct nvkm_sw_chan base;
};
/*******************************************************************************
@@ -41,35 +37,33 @@ struct nv04_software_chan {
******************************************************************************/
static int
-nv04_software_set_ref(struct nouveau_object *object, u32 mthd,
- void *data, u32 size)
+nv04_sw_set_ref(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
- struct nouveau_object *channel = (void *)nv_engctx(object->parent);
- struct nouveau_fifo_chan *fifo = (void *)channel->parent;
+ struct nvkm_object *channel = (void *)nv_engctx(object->parent);
+ struct nvkm_fifo_chan *fifo = (void *)channel->parent;
atomic_set(&fifo->refcnt, *(u32*)data);
return 0;
}
static int
-nv04_software_flip(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv04_sw_flip(struct nvkm_object *object, u32 mthd, void *args, u32 size)
{
- struct nv04_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv04_sw_chan *chan = (void *)nv_engctx(object->parent);
if (chan->base.flip)
return chan->base.flip(chan->base.flip_data);
return -EINVAL;
}
-static struct nouveau_omthds
-nv04_software_omthds[] = {
- { 0x0150, 0x0150, nv04_software_set_ref },
- { 0x0500, 0x0500, nv04_software_flip },
+static struct nvkm_omthds
+nv04_sw_omthds[] = {
+ { 0x0150, 0x0150, nv04_sw_set_ref },
+ { 0x0500, 0x0500, nv04_sw_flip },
{}
};
-static struct nouveau_oclass
-nv04_software_sclass[] = {
- { 0x006e, &nouveau_object_ofuncs, nv04_software_omthds },
+static struct nvkm_oclass
+nv04_sw_sclass[] = {
+ { 0x006e, &nvkm_object_ofuncs, nv04_sw_omthds },
{}
};
@@ -78,15 +72,14 @@ nv04_software_sclass[] = {
******************************************************************************/
static int
-nv04_software_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_sw_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv04_software_chan *chan;
+ struct nv04_sw_chan *chan;
int ret;
- ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ ret = nvkm_sw_context_create(parent, engine, oclass, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -94,14 +87,14 @@ nv04_software_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv04_software_cclass = {
+static struct nvkm_oclass
+nv04_sw_cclass = {
.handle = NV_ENGCTX(SW, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_software_context_ctor,
- .dtor = _nouveau_software_context_dtor,
- .init = _nouveau_software_context_init,
- .fini = _nouveau_software_context_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv04_sw_context_ctor,
+ .dtor = _nvkm_sw_context_dtor,
+ .init = _nvkm_sw_context_init,
+ .fini = _nvkm_sw_context_fini,
},
};
@@ -110,37 +103,37 @@ nv04_software_cclass = {
******************************************************************************/
void
-nv04_software_intr(struct nouveau_subdev *subdev)
+nv04_sw_intr(struct nvkm_subdev *subdev)
{
nv_mask(subdev, 0x000100, 0x80000000, 0x00000000);
}
static int
-nv04_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_sw_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv04_software_priv *priv;
+ struct nv04_sw_priv *priv;
int ret;
- ret = nouveau_software_create(parent, engine, oclass, &priv);
+ ret = nvkm_sw_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nv_engine(priv)->cclass = &nv04_software_cclass;
- nv_engine(priv)->sclass = nv04_software_sclass;
- nv_subdev(priv)->intr = nv04_software_intr;
+ nv_engine(priv)->cclass = &nv04_sw_cclass;
+ nv_engine(priv)->sclass = nv04_sw_sclass;
+ nv_subdev(priv)->intr = nv04_sw_intr;
return 0;
}
-struct nouveau_oclass *
-nv04_software_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+nv04_sw_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(SW, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_software_ctor,
- .dtor = _nouveau_software_dtor,
- .init = _nouveau_software_init,
- .fini = _nouveau_software_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv04_sw_ctor,
+ .dtor = _nvkm_sw_dtor,
+ .init = _nvkm_sw_init,
+ .fini = _nvkm_sw_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.c
index f54a2253deca..c61153a3fb8b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.c
@@ -21,18 +21,14 @@
*
* Authors: Ben Skeggs
*/
+#include <engine/sw.h>
-#include <core/os.h>
-#include <core/engctx.h>
-
-#include <engine/software.h>
-
-struct nv10_software_priv {
- struct nouveau_software base;
+struct nv10_sw_priv {
+ struct nvkm_sw base;
};
-struct nv10_software_chan {
- struct nouveau_software_chan base;
+struct nv10_sw_chan {
+ struct nvkm_sw_chan base;
};
/*******************************************************************************
@@ -40,24 +36,23 @@ struct nv10_software_chan {
******************************************************************************/
static int
-nv10_software_flip(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv10_sw_flip(struct nvkm_object *object, u32 mthd, void *args, u32 size)
{
- struct nv10_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv10_sw_chan *chan = (void *)nv_engctx(object->parent);
if (chan->base.flip)
return chan->base.flip(chan->base.flip_data);
return -EINVAL;
}
-static struct nouveau_omthds
-nv10_software_omthds[] = {
- { 0x0500, 0x0500, nv10_software_flip },
+static struct nvkm_omthds
+nv10_sw_omthds[] = {
+ { 0x0500, 0x0500, nv10_sw_flip },
{}
};
-static struct nouveau_oclass
-nv10_software_sclass[] = {
- { 0x016e, &nouveau_object_ofuncs, nv10_software_omthds },
+static struct nvkm_oclass
+nv10_sw_sclass[] = {
+ { 0x016e, &nvkm_object_ofuncs, nv10_sw_omthds },
{}
};
@@ -66,15 +61,14 @@ nv10_software_sclass[] = {
******************************************************************************/
static int
-nv10_software_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv10_sw_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv10_software_chan *chan;
+ struct nv10_sw_chan *chan;
int ret;
- ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ ret = nvkm_sw_context_create(parent, engine, oclass, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -82,14 +76,14 @@ nv10_software_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nouveau_oclass
-nv10_software_cclass = {
+static struct nvkm_oclass
+nv10_sw_cclass = {
.handle = NV_ENGCTX(SW, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv10_software_context_ctor,
- .dtor = _nouveau_software_context_dtor,
- .init = _nouveau_software_context_init,
- .fini = _nouveau_software_context_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv10_sw_context_ctor,
+ .dtor = _nvkm_sw_context_dtor,
+ .init = _nvkm_sw_context_init,
+ .fini = _nvkm_sw_context_fini,
},
};
@@ -98,31 +92,31 @@ nv10_software_cclass = {
******************************************************************************/
static int
-nv10_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv10_sw_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv10_software_priv *priv;
+ struct nv10_sw_priv *priv;
int ret;
- ret = nouveau_software_create(parent, engine, oclass, &priv);
+ ret = nvkm_sw_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nv_engine(priv)->cclass = &nv10_software_cclass;
- nv_engine(priv)->sclass = nv10_software_sclass;
- nv_subdev(priv)->intr = nv04_software_intr;
+ nv_engine(priv)->cclass = &nv10_sw_cclass;
+ nv_engine(priv)->sclass = nv10_sw_sclass;
+ nv_subdev(priv)->intr = nv04_sw_intr;
return 0;
}
-struct nouveau_oclass *
-nv10_software_oclass = &(struct nouveau_oclass) {
+struct nvkm_oclass *
+nv10_sw_oclass = &(struct nvkm_oclass) {
.handle = NV_ENGINE(SW, 0x10),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv10_software_ctor,
- .dtor = _nouveau_software_dtor,
- .init = _nouveau_software_init,
- .fini = _nouveau_software_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv10_sw_ctor,
+ .dtor = _nvkm_sw_dtor,
+ .init = _nvkm_sw_init,
+ .fini = _nvkm_sw_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c
index a0fec205f9db..401fcd73086b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c
@@ -21,72 +21,67 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
-#include <core/os.h>
-#include <core/engctx.h>
-#include <core/namedb.h>
+#include <core/device.h>
#include <core/handle.h>
-#include <core/gpuobj.h>
-#include <core/event.h>
-#include <nvif/event.h>
-
-#include <subdev/bar.h>
-
+#include <core/namedb.h>
#include <engine/disp.h>
+#include <subdev/bar.h>
-#include "nv50.h"
+#include <nvif/event.h>
/*******************************************************************************
* software object classes
******************************************************************************/
static int
-nv50_software_mthd_dma_vblsem(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv50_sw_mthd_dma_vblsem(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
- struct nouveau_fifo_chan *fifo = (void *)nv_object(chan)->parent;
- struct nouveau_handle *handle;
+ struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
+ struct nvkm_fifo_chan *fifo = (void *)nv_object(chan)->parent;
+ struct nvkm_handle *handle;
int ret = -EINVAL;
- handle = nouveau_namedb_get(nv_namedb(fifo), *(u32 *)args);
+ handle = nvkm_namedb_get(nv_namedb(fifo), *(u32 *)args);
if (!handle)
return -ENOENT;
if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
- struct nouveau_gpuobj *gpuobj = nv_gpuobj(handle->object);
+ struct nvkm_gpuobj *gpuobj = nv_gpuobj(handle->object);
chan->vblank.ctxdma = gpuobj->node->offset >> 4;
ret = 0;
}
- nouveau_namedb_put(handle);
+ nvkm_namedb_put(handle);
return ret;
}
static int
-nv50_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv50_sw_mthd_vblsem_offset(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
chan->vblank.offset = *(u32 *)args;
return 0;
}
int
-nv50_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv50_sw_mthd_vblsem_value(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
chan->vblank.value = *(u32 *)args;
return 0;
}
int
-nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv50_sw_mthd_vblsem_release(struct nvkm_object *object, u32 mthd,
+ void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
u32 head = *(u32 *)args;
- if (head >= nouveau_disp(chan)->vblank.index_nr)
+ if (head >= nvkm_disp(chan)->vblank.index_nr)
return -EINVAL;
nvkm_notify_get(&chan->vblank.notify[head]);
@@ -94,28 +89,27 @@ nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd,
}
int
-nv50_software_mthd_flip(struct nouveau_object *object, u32 mthd,
- void *args, u32 size)
+nv50_sw_mthd_flip(struct nvkm_object *object, u32 mthd, void *args, u32 size)
{
- struct nv50_software_chan *chan = (void *)nv_engctx(object->parent);
+ struct nv50_sw_chan *chan = (void *)nv_engctx(object->parent);
if (chan->base.flip)
return chan->base.flip(chan->base.flip_data);
return -EINVAL;
}
-static struct nouveau_omthds
-nv50_software_omthds[] = {
- { 0x018c, 0x018c, nv50_software_mthd_dma_vblsem },
- { 0x0400, 0x0400, nv50_software_mthd_vblsem_offset },
- { 0x0404, 0x0404, nv50_software_mthd_vblsem_value },
- { 0x0408, 0x0408, nv50_software_mthd_vblsem_release },
- { 0x0500, 0x0500, nv50_software_mthd_flip },
+static struct nvkm_omthds
+nv50_sw_omthds[] = {
+ { 0x018c, 0x018c, nv50_sw_mthd_dma_vblsem },
+ { 0x0400, 0x0400, nv50_sw_mthd_vblsem_offset },
+ { 0x0404, 0x0404, nv50_sw_mthd_vblsem_value },
+ { 0x0408, 0x0408, nv50_sw_mthd_vblsem_release },
+ { 0x0500, 0x0500, nv50_sw_mthd_flip },
{}
};
-static struct nouveau_oclass
-nv50_software_sclass[] = {
- { 0x506e, &nouveau_object_ofuncs, nv50_software_omthds },
+static struct nvkm_oclass
+nv50_sw_sclass[] = {
+ { 0x506e, &nvkm_object_ofuncs, nv50_sw_omthds },
{}
};
@@ -124,12 +118,12 @@ nv50_software_sclass[] = {
******************************************************************************/
static int
-nv50_software_vblsem_release(struct nvkm_notify *notify)
+nv50_sw_vblsem_release(struct nvkm_notify *notify)
{
- struct nv50_software_chan *chan =
+ struct nv50_sw_chan *chan =
container_of(notify, typeof(*chan), vblank.notify[notify->index]);
- struct nv50_software_priv *priv = (void *)nv_object(chan)->engine;
- struct nouveau_bar *bar = nouveau_bar(priv);
+ struct nv50_sw_priv *priv = (void *)nv_object(chan)->engine;
+ struct nvkm_bar *bar = nvkm_bar(priv);
nv_wr32(priv, 0x001704, chan->vblank.channel);
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
@@ -147,29 +141,28 @@ nv50_software_vblsem_release(struct nvkm_notify *notify)
}
void
-nv50_software_context_dtor(struct nouveau_object *object)
+nv50_sw_context_dtor(struct nvkm_object *object)
{
- struct nv50_software_chan *chan = (void *)object;
+ struct nv50_sw_chan *chan = (void *)object;
int i;
for (i = 0; i < ARRAY_SIZE(chan->vblank.notify); i++)
nvkm_notify_fini(&chan->vblank.notify[i]);
- nouveau_software_context_destroy(&chan->base);
+ nvkm_sw_context_destroy(&chan->base);
}
int
-nv50_software_context_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_sw_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_disp *pdisp = nouveau_disp(parent);
- struct nv50_software_cclass *pclass = (void *)oclass;
- struct nv50_software_chan *chan;
+ struct nvkm_disp *pdisp = nvkm_disp(parent);
+ struct nv50_sw_cclass *pclass = (void *)oclass;
+ struct nv50_sw_chan *chan;
int ret, i;
- ret = nouveau_software_context_create(parent, engine, oclass, &chan);
+ ret = nvkm_sw_context_create(parent, engine, oclass, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -191,16 +184,16 @@ nv50_software_context_ctor(struct nouveau_object *parent,
return 0;
}
-static struct nv50_software_cclass
-nv50_software_cclass = {
+static struct nv50_sw_cclass
+nv50_sw_cclass = {
.base.handle = NV_ENGCTX(SW, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_software_context_ctor,
- .dtor = nv50_software_context_dtor,
- .init = _nouveau_software_context_init,
- .fini = _nouveau_software_context_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_sw_context_ctor,
+ .dtor = nv50_sw_context_dtor,
+ .init = _nvkm_sw_context_init,
+ .fini = _nvkm_sw_context_fini,
},
- .vblank = nv50_software_vblsem_release,
+ .vblank = nv50_sw_vblsem_release,
};
/*******************************************************************************
@@ -208,34 +201,34 @@ nv50_software_cclass = {
******************************************************************************/
int
-nv50_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_sw_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv50_software_oclass *pclass = (void *)oclass;
- struct nv50_software_priv *priv;
+ struct nv50_sw_oclass *pclass = (void *)oclass;
+ struct nv50_sw_priv *priv;
int ret;
- ret = nouveau_software_create(parent, engine, oclass, &priv);
+ ret = nvkm_sw_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->cclass = pclass->cclass;
nv_engine(priv)->sclass = pclass->sclass;
- nv_subdev(priv)->intr = nv04_software_intr;
+ nv_subdev(priv)->intr = nv04_sw_intr;
return 0;
}
-struct nouveau_oclass *
-nv50_software_oclass = &(struct nv50_software_oclass) {
+struct nvkm_oclass *
+nv50_sw_oclass = &(struct nv50_sw_oclass) {
.base.handle = NV_ENGINE(SW, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_software_ctor,
- .dtor = _nouveau_software_dtor,
- .init = _nouveau_software_init,
- .fini = _nouveau_software_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_sw_ctor,
+ .dtor = _nvkm_sw_dtor,
+ .init = _nvkm_sw_init,
+ .fini = _nvkm_sw_fini,
},
- .cclass = &nv50_software_cclass.base,
- .sclass = nv50_software_sclass,
+ .cclass = &nv50_sw_cclass.base,
+ .sclass = nv50_sw_sclass,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.h
new file mode 100644
index 000000000000..d8adc1108467
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.h
@@ -0,0 +1,45 @@
+#ifndef __NVKM_SW_NV50_H__
+#define __NVKM_SW_NV50_H__
+#include <engine/sw.h>
+#include <core/notify.h>
+
+struct nv50_sw_oclass {
+ struct nvkm_oclass base;
+ struct nvkm_oclass *cclass;
+ struct nvkm_oclass *sclass;
+};
+
+struct nv50_sw_priv {
+ struct nvkm_sw base;
+};
+
+int nv50_sw_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+
+struct nv50_sw_cclass {
+ struct nvkm_oclass base;
+ int (*vblank)(struct nvkm_notify *);
+};
+
+struct nv50_sw_chan {
+ struct nvkm_sw_chan base;
+ struct {
+ struct nvkm_notify notify[4];
+ u32 channel;
+ u32 ctxdma;
+ u64 offset;
+ u32 value;
+ } vblank;
+};
+
+int nv50_sw_context_ctor(struct nvkm_object *,
+ struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv50_sw_context_dtor(struct nvkm_object *);
+
+int nv50_sw_mthd_vblsem_value(struct nvkm_object *, u32, void *, u32);
+int nv50_sw_mthd_vblsem_release(struct nvkm_object *, u32, void *, u32);
+int nv50_sw_mthd_flip(struct nvkm_object *, u32, void *, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/vp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/vp/Kbuild
new file mode 100644
index 000000000000..6b390eb92b0e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/vp/Kbuild
@@ -0,0 +1 @@
+nvkm-y += nvkm/engine/vp/g84.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c b/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c
index fd6272b8cdb2..45f4e186befc 100644
--- a/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c
@@ -21,17 +21,18 @@
*
* Authors: Ben Skeggs, Ilia Mirkin
*/
-
-#include <engine/xtensa.h>
#include <engine/vp.h>
+#include <engine/xtensa.h>
+
+#include <core/engctx.h>
/*******************************************************************************
* VP object classes
******************************************************************************/
-static struct nouveau_oclass
-nv84_vp_sclass[] = {
- { 0x7476, &nouveau_object_ofuncs },
+static struct nvkm_oclass
+g84_vp_sclass[] = {
+ { 0x7476, &nvkm_object_ofuncs },
{},
};
@@ -39,16 +40,16 @@ nv84_vp_sclass[] = {
* PVP context
******************************************************************************/
-static struct nouveau_oclass
-nv84_vp_cclass = {
+static struct nvkm_oclass
+g84_vp_cclass = {
.handle = NV_ENGCTX(VP, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_xtensa_engctx_ctor,
- .dtor = _nouveau_engctx_dtor,
- .init = _nouveau_engctx_init,
- .fini = _nouveau_engctx_fini,
- .rd32 = _nouveau_engctx_rd32,
- .wr32 = _nouveau_engctx_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_xtensa_engctx_ctor,
+ .dtor = _nvkm_engctx_dtor,
+ .init = _nvkm_engctx_init,
+ .fini = _nvkm_engctx_fini,
+ .rd32 = _nvkm_engctx_rd32,
+ .wr32 = _nvkm_engctx_wr32,
},
};
@@ -57,36 +58,36 @@ nv84_vp_cclass = {
******************************************************************************/
static int
-nv84_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_vp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_xtensa *priv;
+ struct nvkm_xtensa *priv;
int ret;
- ret = nouveau_xtensa_create(parent, engine, oclass, 0xf000, true,
- "PVP", "vp", &priv);
+ ret = nvkm_xtensa_create(parent, engine, oclass, 0xf000, true,
+ "PVP", "vp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x01020000;
- nv_engine(priv)->cclass = &nv84_vp_cclass;
- nv_engine(priv)->sclass = nv84_vp_sclass;
+ nv_engine(priv)->cclass = &g84_vp_cclass;
+ nv_engine(priv)->sclass = g84_vp_sclass;
priv->fifo_val = 0x111;
priv->unkd28 = 0x9c544;
return 0;
}
-struct nouveau_oclass
-nv84_vp_oclass = {
+struct nvkm_oclass
+g84_vp_oclass = {
.handle = NV_ENGINE(VP, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_vp_ctor,
- .dtor = _nouveau_xtensa_dtor,
- .init = _nouveau_xtensa_init,
- .fini = _nouveau_xtensa_fini,
- .rd32 = _nouveau_xtensa_rd32,
- .wr32 = _nouveau_xtensa_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_vp_ctor,
+ .dtor = _nvkm_xtensa_dtor,
+ .init = _nvkm_xtensa_init,
+ .fini = _nvkm_xtensa_fini,
+ .rd32 = _nvkm_xtensa_rd32,
+ .wr32 = _nvkm_xtensa_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/engine/xtensa.c b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
index 92384759d2f5..cea90df533d9 100644
--- a/drivers/gpu/drm/nouveau/core/engine/xtensa.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
@@ -19,43 +19,43 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
-
#include <engine/xtensa.h>
+#include <core/device.h>
+
+#include <core/engctx.h>
u32
-_nouveau_xtensa_rd32(struct nouveau_object *object, u64 addr)
+_nvkm_xtensa_rd32(struct nvkm_object *object, u64 addr)
{
- struct nouveau_xtensa *xtensa = (void *)object;
+ struct nvkm_xtensa *xtensa = (void *)object;
return nv_rd32(xtensa, xtensa->addr + addr);
}
void
-_nouveau_xtensa_wr32(struct nouveau_object *object, u64 addr, u32 data)
+_nvkm_xtensa_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
- struct nouveau_xtensa *xtensa = (void *)object;
+ struct nvkm_xtensa *xtensa = (void *)object;
nv_wr32(xtensa, xtensa->addr + addr, data);
}
int
-_nouveau_xtensa_engctx_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+_nvkm_xtensa_engctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_engctx *engctx;
+ struct nvkm_engctx *engctx;
int ret;
- ret = nouveau_engctx_create(parent, engine, oclass, NULL,
- 0x10000, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &engctx);
+ ret = nvkm_engctx_create(parent, engine, oclass, NULL, 0x10000, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &engctx);
*pobject = nv_object(engctx);
return ret;
}
void
-_nouveau_xtensa_intr(struct nouveau_subdev *subdev)
+_nvkm_xtensa_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_xtensa *xtensa = (void *)subdev;
+ struct nvkm_xtensa *xtensa = (void *)subdev;
u32 unk104 = nv_ro32(xtensa, 0xd04);
u32 intr = nv_ro32(xtensa, 0xc20);
u32 chan = nv_ro32(xtensa, 0xc28);
@@ -72,39 +72,36 @@ _nouveau_xtensa_intr(struct nouveau_subdev *subdev)
}
int
-nouveau_xtensa_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 addr, bool enable,
- const char *iname, const char *fname,
- int length, void **pobject)
+nvkm_xtensa_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 addr, bool enable,
+ const char *iname, const char *fname,
+ int length, void **pobject)
{
- struct nouveau_xtensa *xtensa;
+ struct nvkm_xtensa *xtensa;
int ret;
- ret = nouveau_engine_create_(parent, engine, oclass, enable, iname,
- fname, length, pobject);
+ ret = nvkm_engine_create_(parent, engine, oclass, enable, iname,
+ fname, length, pobject);
xtensa = *pobject;
if (ret)
return ret;
- nv_subdev(xtensa)->intr = _nouveau_xtensa_intr;
-
+ nv_subdev(xtensa)->intr = _nvkm_xtensa_intr;
xtensa->addr = addr;
-
return 0;
}
int
-_nouveau_xtensa_init(struct nouveau_object *object)
+_nvkm_xtensa_init(struct nvkm_object *object)
{
- struct nouveau_device *device = nv_device(object);
- struct nouveau_xtensa *xtensa = (void *)object;
+ struct nvkm_device *device = nv_device(object);
+ struct nvkm_xtensa *xtensa = (void *)object;
const struct firmware *fw;
char name[32];
int i, ret;
u32 tmp;
- ret = nouveau_engine_init(&xtensa->base);
+ ret = nvkm_engine_init(&xtensa->base);
if (ret)
return ret;
@@ -124,8 +121,8 @@ _nouveau_xtensa_init(struct nouveau_object *object)
return -EINVAL;
}
- ret = nouveau_gpuobj_new(object, NULL, 0x40000, 0x1000, 0,
- &xtensa->gpu_fw);
+ ret = nvkm_gpuobj_new(object, NULL, 0x40000, 0x1000, 0,
+ &xtensa->gpu_fw);
if (ret) {
release_firmware(fw);
return ret;
@@ -157,20 +154,19 @@ _nouveau_xtensa_init(struct nouveau_object *object)
nv_wo32(xtensa, 0xc20, 0x3f); /* INTR */
nv_wo32(xtensa, 0xd84, 0x3f); /* INTR_EN */
-
return 0;
}
int
-_nouveau_xtensa_fini(struct nouveau_object *object, bool suspend)
+_nvkm_xtensa_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_xtensa *xtensa = (void *)object;
+ struct nvkm_xtensa *xtensa = (void *)object;
nv_wo32(xtensa, 0xd84, 0); /* INTR_EN */
nv_wo32(xtensa, 0xd94, 0); /* FIFO_CTRL */
if (!suspend)
- nouveau_gpuobj_ref(NULL, &xtensa->gpu_fw);
+ nvkm_gpuobj_ref(NULL, &xtensa->gpu_fw);
- return nouveau_engine_fini(&xtensa->base, suspend);
+ return nvkm_engine_fini(&xtensa->base, suspend);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
new file mode 100644
index 000000000000..a1bb3e48739c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
@@ -0,0 +1,19 @@
+include $(src)/nvkm/subdev/bar/Kbuild
+include $(src)/nvkm/subdev/bios/Kbuild
+include $(src)/nvkm/subdev/bus/Kbuild
+include $(src)/nvkm/subdev/clk/Kbuild
+include $(src)/nvkm/subdev/devinit/Kbuild
+include $(src)/nvkm/subdev/fb/Kbuild
+include $(src)/nvkm/subdev/fuse/Kbuild
+include $(src)/nvkm/subdev/gpio/Kbuild
+include $(src)/nvkm/subdev/i2c/Kbuild
+include $(src)/nvkm/subdev/ibus/Kbuild
+include $(src)/nvkm/subdev/instmem/Kbuild
+include $(src)/nvkm/subdev/ltc/Kbuild
+include $(src)/nvkm/subdev/mc/Kbuild
+include $(src)/nvkm/subdev/mmu/Kbuild
+include $(src)/nvkm/subdev/mxm/Kbuild
+include $(src)/nvkm/subdev/pmu/Kbuild
+include $(src)/nvkm/subdev/therm/Kbuild
+include $(src)/nvkm/subdev/timer/Kbuild
+include $(src)/nvkm/subdev/volt/Kbuild
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild
new file mode 100644
index 000000000000..1ab554a0b5e0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/Kbuild
@@ -0,0 +1,4 @@
+nvkm-y += nvkm/subdev/bar/base.o
+nvkm-y += nvkm/subdev/bar/nv50.o
+nvkm-y += nvkm/subdev/bar/gf100.o
+nvkm-y += nvkm/subdev/bar/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
new file mode 100644
index 000000000000..3502d00122ef
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+#include <core/device.h>
+#include <subdev/fb.h>
+#include <subdev/mmu.h>
+
+struct nvkm_barobj {
+ struct nvkm_object base;
+ struct nvkm_vma vma;
+ void __iomem *iomem;
+};
+
+static int
+nvkm_barobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_bar *bar = nvkm_bar(device);
+ struct nvkm_mem *mem = data;
+ struct nvkm_barobj *barobj;
+ int ret;
+
+ ret = nvkm_object_create(parent, engine, oclass, 0, &barobj);
+ *pobject = nv_object(barobj);
+ if (ret)
+ return ret;
+
+ ret = bar->kmap(bar, mem, NV_MEM_ACCESS_RW, &barobj->vma);
+ if (ret)
+ return ret;
+
+ barobj->iomem = ioremap(nv_device_resource_start(device, 3) +
+ (u32)barobj->vma.offset, mem->size << 12);
+ if (!barobj->iomem) {
+ nv_warn(bar, "PRAMIN ioremap failed\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void
+nvkm_barobj_dtor(struct nvkm_object *object)
+{
+ struct nvkm_bar *bar = nvkm_bar(object);
+ struct nvkm_barobj *barobj = (void *)object;
+ if (barobj->vma.node) {
+ if (barobj->iomem)
+ iounmap(barobj->iomem);
+ bar->unmap(bar, &barobj->vma);
+ }
+ nvkm_object_destroy(&barobj->base);
+}
+
+static u32
+nvkm_barobj_rd32(struct nvkm_object *object, u64 addr)
+{
+ struct nvkm_barobj *barobj = (void *)object;
+ return ioread32_native(barobj->iomem + addr);
+}
+
+static void
+nvkm_barobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
+{
+ struct nvkm_barobj *barobj = (void *)object;
+ iowrite32_native(data, barobj->iomem + addr);
+}
+
+static struct nvkm_oclass
+nvkm_barobj_oclass = {
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nvkm_barobj_ctor,
+ .dtor = nvkm_barobj_dtor,
+ .init = nvkm_object_init,
+ .fini = nvkm_object_fini,
+ .rd32 = nvkm_barobj_rd32,
+ .wr32 = nvkm_barobj_wr32,
+ },
+};
+
+int
+nvkm_bar_alloc(struct nvkm_bar *bar, struct nvkm_object *parent,
+ struct nvkm_mem *mem, struct nvkm_object **pobject)
+{
+ struct nvkm_object *gpuobj;
+ int ret = nvkm_object_ctor(parent, &parent->engine->subdev.object,
+ &nvkm_barobj_oclass, mem, 0, &gpuobj);
+ if (ret == 0)
+ *pobject = gpuobj;
+ return ret;
+}
+
+int
+nvkm_bar_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
+{
+ struct nvkm_bar *bar;
+ int ret;
+
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "BARCTL",
+ "bar", length, pobject);
+ bar = *pobject;
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void
+nvkm_bar_destroy(struct nvkm_bar *bar)
+{
+ nvkm_subdev_destroy(&bar->base);
+}
+
+void
+_nvkm_bar_dtor(struct nvkm_object *object)
+{
+ struct nvkm_bar *bar = (void *)object;
+ nvkm_bar_destroy(bar);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
new file mode 100644
index 000000000000..12a1aebd9a96
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+#include <core/device.h>
+#include <core/gpuobj.h>
+#include <subdev/fb.h>
+#include <subdev/mmu.h>
+
+struct gf100_bar_priv_vm {
+ struct nvkm_gpuobj *mem;
+ struct nvkm_gpuobj *pgd;
+ struct nvkm_vm *vm;
+};
+
+struct gf100_bar_priv {
+ struct nvkm_bar base;
+ spinlock_t lock;
+ struct gf100_bar_priv_vm bar[2];
+};
+
+static int
+gf100_bar_kmap(struct nvkm_bar *bar, struct nvkm_mem *mem, u32 flags,
+ struct nvkm_vma *vma)
+{
+ struct gf100_bar_priv *priv = (void *)bar;
+ int ret;
+
+ ret = nvkm_vm_get(priv->bar[0].vm, mem->size << 12, 12, flags, vma);
+ if (ret)
+ return ret;
+
+ nvkm_vm_map(vma, mem);
+ return 0;
+}
+
+static int
+gf100_bar_umap(struct nvkm_bar *bar, struct nvkm_mem *mem, u32 flags,
+ struct nvkm_vma *vma)
+{
+ struct gf100_bar_priv *priv = (void *)bar;
+ int ret;
+
+ ret = nvkm_vm_get(priv->bar[1].vm, mem->size << 12,
+ mem->page_shift, flags, vma);
+ if (ret)
+ return ret;
+
+ nvkm_vm_map(vma, mem);
+ return 0;
+}
+
+static void
+gf100_bar_unmap(struct nvkm_bar *bar, struct nvkm_vma *vma)
+{
+ nvkm_vm_unmap(vma);
+ nvkm_vm_put(vma);
+}
+
+static int
+gf100_bar_ctor_vm(struct gf100_bar_priv *priv, struct gf100_bar_priv_vm *bar_vm,
+ int bar_nr)
+{
+ struct nvkm_device *device = nv_device(&priv->base);
+ struct nvkm_vm *vm;
+ resource_size_t bar_len;
+ int ret;
+
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
+ &bar_vm->mem);
+ if (ret)
+ return ret;
+
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
+ &bar_vm->pgd);
+ if (ret)
+ return ret;
+
+ bar_len = nv_device_resource_len(device, bar_nr);
+
+ ret = nvkm_vm_new(device, 0, bar_len, 0, &vm);
+ if (ret)
+ return ret;
+
+ atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
+ /*
+ * Bootstrap page table lookup.
+ */
+ if (bar_nr == 3) {
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL,
+ (bar_len >> 12) * 8, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC,
+ &vm->pgt[0].obj[0]);
+ vm->pgt[0].refcount[0] = 1;
+ if (ret)
+ return ret;
+ }
+
+ ret = nvkm_vm_ref(vm, &bar_vm->vm, bar_vm->pgd);
+ nvkm_vm_ref(NULL, &vm, NULL);
+ if (ret)
+ return ret;
+
+ nv_wo32(bar_vm->mem, 0x0200, lower_32_bits(bar_vm->pgd->addr));
+ nv_wo32(bar_vm->mem, 0x0204, upper_32_bits(bar_vm->pgd->addr));
+ nv_wo32(bar_vm->mem, 0x0208, lower_32_bits(bar_len - 1));
+ nv_wo32(bar_vm->mem, 0x020c, upper_32_bits(bar_len - 1));
+ return 0;
+}
+
+int
+gf100_bar_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct nvkm_device *device = nv_device(parent);
+ struct gf100_bar_priv *priv;
+ bool has_bar3 = nv_device_resource_len(device, 3) != 0;
+ int ret;
+
+ ret = nvkm_bar_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ /* BAR3 */
+ if (has_bar3) {
+ ret = gf100_bar_ctor_vm(priv, &priv->bar[0], 3);
+ if (ret)
+ return ret;
+ }
+
+ /* BAR1 */
+ ret = gf100_bar_ctor_vm(priv, &priv->bar[1], 1);
+ if (ret)
+ return ret;
+
+ if (has_bar3) {
+ priv->base.alloc = nvkm_bar_alloc;
+ priv->base.kmap = gf100_bar_kmap;
+ }
+ priv->base.umap = gf100_bar_umap;
+ priv->base.unmap = gf100_bar_unmap;
+ priv->base.flush = g84_bar_flush;
+ spin_lock_init(&priv->lock);
+ return 0;
+}
+
+void
+gf100_bar_dtor(struct nvkm_object *object)
+{
+ struct gf100_bar_priv *priv = (void *)object;
+
+ nvkm_vm_ref(NULL, &priv->bar[1].vm, priv->bar[1].pgd);
+ nvkm_gpuobj_ref(NULL, &priv->bar[1].pgd);
+ nvkm_gpuobj_ref(NULL, &priv->bar[1].mem);
+
+ if (priv->bar[0].vm) {
+ nvkm_gpuobj_ref(NULL, &priv->bar[0].vm->pgt[0].obj[0]);
+ nvkm_vm_ref(NULL, &priv->bar[0].vm, priv->bar[0].pgd);
+ }
+ nvkm_gpuobj_ref(NULL, &priv->bar[0].pgd);
+ nvkm_gpuobj_ref(NULL, &priv->bar[0].mem);
+
+ nvkm_bar_destroy(&priv->base);
+}
+
+int
+gf100_bar_init(struct nvkm_object *object)
+{
+ struct gf100_bar_priv *priv = (void *)object;
+ int ret;
+
+ ret = nvkm_bar_init(&priv->base);
+ if (ret)
+ return ret;
+
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
+ nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
+
+ nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12);
+ if (priv->bar[0].mem)
+ nv_wr32(priv, 0x001714,
+ 0xc0000000 | priv->bar[0].mem->addr >> 12);
+ return 0;
+}
+
+struct nvkm_oclass
+gf100_bar_oclass = {
+ .handle = NV_SUBDEV(BAR, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_bar_ctor,
+ .dtor = gf100_bar_dtor,
+ .init = gf100_bar_init,
+ .fini = _nvkm_bar_fini,
+ },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c
index bf877af9d3bd..148f739a276e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c
@@ -19,36 +19,32 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-
-#include <subdev/bar.h>
-
#include "priv.h"
int
-gk20a_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk20a_bar_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_bar *bar;
+ struct nvkm_bar *bar;
int ret;
- ret = nvc0_bar_ctor(parent, engine, oclass, data, size, pobject);
+ ret = gf100_bar_ctor(parent, engine, oclass, data, size, pobject);
if (ret)
return ret;
- bar = (struct nouveau_bar *)*pobject;
+ bar = (struct nvkm_bar *)*pobject;
bar->iomap_uncached = true;
-
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gk20a_bar_oclass = {
.handle = NV_SUBDEV(BAR, 0xea),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gk20a_bar_ctor,
- .dtor = nvc0_bar_dtor,
- .init = nvc0_bar_init,
- .fini = _nouveau_bar_fini,
+ .dtor = gf100_bar_dtor,
+ .init = gf100_bar_init,
+ .fini = _nvkm_bar_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
index f748ba49dfc8..8548adb91dcc 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
@@ -21,66 +21,65 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
+#include <core/device.h>
#include <core/gpuobj.h>
-
-#include <subdev/timer.h>
#include <subdev/fb.h>
-#include <subdev/vm.h>
-
-#include "priv.h"
+#include <subdev/mmu.h>
+#include <subdev/timer.h>
struct nv50_bar_priv {
- struct nouveau_bar base;
+ struct nvkm_bar base;
spinlock_t lock;
- struct nouveau_gpuobj *mem;
- struct nouveau_gpuobj *pad;
- struct nouveau_gpuobj *pgd;
- struct nouveau_vm *bar1_vm;
- struct nouveau_gpuobj *bar1;
- struct nouveau_vm *bar3_vm;
- struct nouveau_gpuobj *bar3;
+ struct nvkm_gpuobj *mem;
+ struct nvkm_gpuobj *pad;
+ struct nvkm_gpuobj *pgd;
+ struct nvkm_vm *bar1_vm;
+ struct nvkm_gpuobj *bar1;
+ struct nvkm_vm *bar3_vm;
+ struct nvkm_gpuobj *bar3;
};
static int
-nv50_bar_kmap(struct nouveau_bar *bar, struct nouveau_mem *mem,
- u32 flags, struct nouveau_vma *vma)
+nv50_bar_kmap(struct nvkm_bar *bar, struct nvkm_mem *mem, u32 flags,
+ struct nvkm_vma *vma)
{
struct nv50_bar_priv *priv = (void *)bar;
int ret;
- ret = nouveau_vm_get(priv->bar3_vm, mem->size << 12, 12, flags, vma);
+ ret = nvkm_vm_get(priv->bar3_vm, mem->size << 12, 12, flags, vma);
if (ret)
return ret;
- nouveau_vm_map(vma, mem);
+ nvkm_vm_map(vma, mem);
return 0;
}
static int
-nv50_bar_umap(struct nouveau_bar *bar, struct nouveau_mem *mem,
- u32 flags, struct nouveau_vma *vma)
+nv50_bar_umap(struct nvkm_bar *bar, struct nvkm_mem *mem, u32 flags,
+ struct nvkm_vma *vma)
{
struct nv50_bar_priv *priv = (void *)bar;
int ret;
- ret = nouveau_vm_get(priv->bar1_vm, mem->size << 12, 12, flags, vma);
+ ret = nvkm_vm_get(priv->bar1_vm, mem->size << 12, 12, flags, vma);
if (ret)
return ret;
- nouveau_vm_map(vma, mem);
+ nvkm_vm_map(vma, mem);
return 0;
}
static void
-nv50_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
+nv50_bar_unmap(struct nvkm_bar *bar, struct nvkm_vma *vma)
{
- nouveau_vm_unmap(vma);
- nouveau_vm_put(vma);
+ nvkm_vm_unmap(vma);
+ nvkm_vm_put(vma);
}
static void
-nv50_bar_flush(struct nouveau_bar *bar)
+nv50_bar_flush(struct nvkm_bar *bar)
{
struct nv50_bar_priv *priv = (void *)bar;
unsigned long flags;
@@ -92,7 +91,7 @@ nv50_bar_flush(struct nouveau_bar *bar)
}
void
-nv84_bar_flush(struct nouveau_bar *bar)
+g84_bar_flush(struct nvkm_bar *bar)
{
struct nv50_bar_priv *priv = (void *)bar;
unsigned long flags;
@@ -104,36 +103,35 @@ nv84_bar_flush(struct nouveau_bar *bar)
}
static int
-nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_bar_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_object *heap;
- struct nouveau_vm *vm;
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_object *heap;
+ struct nvkm_vm *vm;
struct nv50_bar_priv *priv;
u64 start, limit;
int ret;
- ret = nouveau_bar_create(parent, engine, oclass, &priv);
+ ret = nvkm_bar_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
- NVOBJ_FLAG_HEAP, &priv->mem);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
+ NVOBJ_FLAG_HEAP, &priv->mem);
heap = nv_object(priv->mem);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), heap,
- (device->chipset == 0x50) ? 0x1400 : 0x0200,
- 0, 0, &priv->pad);
+ ret = nvkm_gpuobj_new(nv_object(priv), heap,
+ (device->chipset == 0x50) ? 0x1400 : 0x0200,
+ 0, 0, &priv->pad);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), heap, 0x4000, 0,
- 0, &priv->pgd);
+ ret = nvkm_gpuobj_new(nv_object(priv), heap, 0x4000, 0, 0, &priv->pgd);
if (ret)
return ret;
@@ -141,25 +139,25 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
start = 0x0100000000ULL;
limit = start + nv_device_resource_len(device, 3);
- ret = nouveau_vm_new(device, start, limit, start, &vm);
+ ret = nvkm_vm_new(device, start, limit, start, &vm);
if (ret)
return ret;
atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
- ret = nouveau_gpuobj_new(nv_object(priv), heap,
- ((limit-- - start) >> 12) * 8, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &vm->pgt[0].obj[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), heap,
+ ((limit-- - start) >> 12) * 8, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &vm->pgt[0].obj[0]);
vm->pgt[0].refcount[0] = 1;
if (ret)
return ret;
- ret = nouveau_vm_ref(vm, &priv->bar3_vm, priv->pgd);
- nouveau_vm_ref(NULL, &vm, NULL);
+ ret = nvkm_vm_ref(vm, &priv->bar3_vm, priv->pgd);
+ nvkm_vm_ref(NULL, &vm, NULL);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar3);
+ ret = nvkm_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar3);
if (ret)
return ret;
@@ -175,18 +173,18 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
start = 0x0000000000ULL;
limit = start + nv_device_resource_len(device, 1);
- ret = nouveau_vm_new(device, start, limit--, start, &vm);
+ ret = nvkm_vm_new(device, start, limit--, start, &vm);
if (ret)
return ret;
atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
- ret = nouveau_vm_ref(vm, &priv->bar1_vm, priv->pgd);
- nouveau_vm_ref(NULL, &vm, NULL);
+ ret = nvkm_vm_ref(vm, &priv->bar1_vm, priv->pgd);
+ nvkm_vm_ref(NULL, &vm, NULL);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar1);
+ ret = nvkm_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar1);
if (ret)
return ret;
@@ -198,42 +196,42 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_wo32(priv->bar1, 0x10, 0x00000000);
nv_wo32(priv->bar1, 0x14, 0x00000000);
- priv->base.alloc = nouveau_bar_alloc;
+ priv->base.alloc = nvkm_bar_alloc;
priv->base.kmap = nv50_bar_kmap;
priv->base.umap = nv50_bar_umap;
priv->base.unmap = nv50_bar_unmap;
if (device->chipset == 0x50)
priv->base.flush = nv50_bar_flush;
else
- priv->base.flush = nv84_bar_flush;
+ priv->base.flush = g84_bar_flush;
spin_lock_init(&priv->lock);
return 0;
}
static void
-nv50_bar_dtor(struct nouveau_object *object)
+nv50_bar_dtor(struct nvkm_object *object)
{
struct nv50_bar_priv *priv = (void *)object;
- nouveau_gpuobj_ref(NULL, &priv->bar1);
- nouveau_vm_ref(NULL, &priv->bar1_vm, priv->pgd);
- nouveau_gpuobj_ref(NULL, &priv->bar3);
+ nvkm_gpuobj_ref(NULL, &priv->bar1);
+ nvkm_vm_ref(NULL, &priv->bar1_vm, priv->pgd);
+ nvkm_gpuobj_ref(NULL, &priv->bar3);
if (priv->bar3_vm) {
- nouveau_gpuobj_ref(NULL, &priv->bar3_vm->pgt[0].obj[0]);
- nouveau_vm_ref(NULL, &priv->bar3_vm, priv->pgd);
+ nvkm_gpuobj_ref(NULL, &priv->bar3_vm->pgt[0].obj[0]);
+ nvkm_vm_ref(NULL, &priv->bar3_vm, priv->pgd);
}
- nouveau_gpuobj_ref(NULL, &priv->pgd);
- nouveau_gpuobj_ref(NULL, &priv->pad);
- nouveau_gpuobj_ref(NULL, &priv->mem);
- nouveau_bar_destroy(&priv->base);
+ nvkm_gpuobj_ref(NULL, &priv->pgd);
+ nvkm_gpuobj_ref(NULL, &priv->pad);
+ nvkm_gpuobj_ref(NULL, &priv->mem);
+ nvkm_bar_destroy(&priv->base);
}
static int
-nv50_bar_init(struct nouveau_object *object)
+nv50_bar_init(struct nvkm_object *object)
{
struct nv50_bar_priv *priv = (void *)object;
int ret, i;
- ret = nouveau_bar_init(&priv->base);
+ ret = nvkm_bar_init(&priv->base);
if (ret)
return ret;
@@ -255,16 +253,16 @@ nv50_bar_init(struct nouveau_object *object)
}
static int
-nv50_bar_fini(struct nouveau_object *object, bool suspend)
+nv50_bar_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_bar_priv *priv = (void *)object;
- return nouveau_bar_fini(&priv->base, suspend);
+ return nvkm_bar_fini(&priv->base, suspend);
}
-struct nouveau_oclass
+struct nvkm_oclass
nv50_bar_oclass = {
.handle = NV_SUBDEV(BAR, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_bar_ctor,
.dtor = nv50_bar_dtor,
.init = nv50_bar_init,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
new file mode 100644
index 000000000000..aa85f61b48c2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
@@ -0,0 +1,30 @@
+#ifndef __NVKM_BAR_PRIV_H__
+#define __NVKM_BAR_PRIV_H__
+#include <subdev/bar.h>
+
+#define nvkm_bar_create(p,e,o,d) \
+ nvkm_bar_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_bar_init(p) \
+ nvkm_subdev_init(&(p)->base)
+#define nvkm_bar_fini(p,s) \
+ nvkm_subdev_fini(&(p)->base, (s))
+
+int nvkm_bar_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void nvkm_bar_destroy(struct nvkm_bar *);
+
+void _nvkm_bar_dtor(struct nvkm_object *);
+#define _nvkm_bar_init _nvkm_subdev_init
+#define _nvkm_bar_fini _nvkm_subdev_fini
+
+int nvkm_bar_alloc(struct nvkm_bar *, struct nvkm_object *,
+ struct nvkm_mem *, struct nvkm_object **);
+
+void g84_bar_flush(struct nvkm_bar *);
+
+int gf100_bar_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void gf100_bar_dtor(struct nvkm_object *);
+int gf100_bar_init(struct nvkm_object *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild
new file mode 100644
index 000000000000..64730d5e9351
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild
@@ -0,0 +1,37 @@
+nvkm-y += nvkm/subdev/bios/base.o
+nvkm-y += nvkm/subdev/bios/bit.o
+nvkm-y += nvkm/subdev/bios/boost.o
+nvkm-y += nvkm/subdev/bios/conn.o
+nvkm-y += nvkm/subdev/bios/cstep.o
+nvkm-y += nvkm/subdev/bios/dcb.o
+nvkm-y += nvkm/subdev/bios/disp.o
+nvkm-y += nvkm/subdev/bios/dp.o
+nvkm-y += nvkm/subdev/bios/extdev.o
+nvkm-y += nvkm/subdev/bios/fan.o
+nvkm-y += nvkm/subdev/bios/gpio.o
+nvkm-y += nvkm/subdev/bios/i2c.o
+nvkm-y += nvkm/subdev/bios/image.o
+nvkm-y += nvkm/subdev/bios/init.o
+nvkm-y += nvkm/subdev/bios/mxm.o
+nvkm-y += nvkm/subdev/bios/npde.o
+nvkm-y += nvkm/subdev/bios/pcir.o
+nvkm-y += nvkm/subdev/bios/perf.o
+nvkm-y += nvkm/subdev/bios/pll.o
+nvkm-y += nvkm/subdev/bios/pmu.o
+nvkm-y += nvkm/subdev/bios/ramcfg.o
+nvkm-y += nvkm/subdev/bios/rammap.o
+nvkm-y += nvkm/subdev/bios/shadow.o
+nvkm-y += nvkm/subdev/bios/shadowacpi.o
+nvkm-y += nvkm/subdev/bios/shadowof.o
+nvkm-y += nvkm/subdev/bios/shadowpci.o
+nvkm-y += nvkm/subdev/bios/shadowramin.o
+nvkm-y += nvkm/subdev/bios/shadowrom.o
+nvkm-y += nvkm/subdev/bios/timing.o
+nvkm-y += nvkm/subdev/bios/therm.o
+nvkm-y += nvkm/subdev/bios/vmap.o
+nvkm-y += nvkm/subdev/bios/volt.o
+nvkm-y += nvkm/subdev/bios/xpio.o
+nvkm-y += nvkm/subdev/bios/M0203.o
+nvkm-y += nvkm/subdev/bios/M0205.o
+nvkm-y += nvkm/subdev/bios/M0209.o
+nvkm-y += nvkm/subdev/bios/P0260.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0203.c
index 28906b16d4e5..08eb03fbc203 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0203.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/M0203.h>
u32
-nvbios_M0203Te(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+nvbios_M0203Te(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_M;
u32 data = 0x00000000;
@@ -53,7 +52,7 @@ nvbios_M0203Te(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u32
-nvbios_M0203Tp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+nvbios_M0203Tp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_M0203T *info)
{
u32 data = nvbios_M0203Te(bios, ver, hdr, cnt, len);
@@ -70,7 +69,7 @@ nvbios_M0203Tp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
}
u32
-nvbios_M0203Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
+nvbios_M0203Ee(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr)
{
u8 cnt, len;
u32 data = nvbios_M0203Te(bios, ver, hdr, &cnt, &len);
@@ -83,7 +82,7 @@ nvbios_M0203Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
}
u32
-nvbios_M0203Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
+nvbios_M0203Ep(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
struct nvbios_M0203E *info)
{
u32 data = nvbios_M0203Ee(bios, idx, ver, hdr);
@@ -101,7 +100,7 @@ nvbios_M0203Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
}
u32
-nvbios_M0203Em(struct nouveau_bios *bios, u8 ramcfg, u8 *ver, u8 *hdr,
+nvbios_M0203Em(struct nvkm_bios *bios, u8 ramcfg, u8 *ver, u8 *hdr,
struct nvbios_M0203E *info)
{
struct nvbios_M0203T M0203T;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/M0205.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0205.c
index ac9617c5fc2a..e1a8ad5f3066 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/M0205.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0205.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/M0205.h>
u32
-nvbios_M0205Te(struct nouveau_bios *bios,
+nvbios_M0205Te(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
struct bit_entry bit_M;
@@ -56,7 +55,7 @@ nvbios_M0205Te(struct nouveau_bios *bios,
}
u32
-nvbios_M0205Tp(struct nouveau_bios *bios,
+nvbios_M0205Tp(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz,
struct nvbios_M0205T *info)
{
@@ -73,7 +72,7 @@ nvbios_M0205Tp(struct nouveau_bios *bios,
}
u32
-nvbios_M0205Ee(struct nouveau_bios *bios, int idx,
+nvbios_M0205Ee(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u8 snr, ssz;
@@ -89,7 +88,7 @@ nvbios_M0205Ee(struct nouveau_bios *bios, int idx,
}
u32
-nvbios_M0205Ep(struct nouveau_bios *bios, int idx,
+nvbios_M0205Ep(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_M0205E *info)
{
@@ -106,7 +105,7 @@ nvbios_M0205Ep(struct nouveau_bios *bios, int idx,
}
u32
-nvbios_M0205Se(struct nouveau_bios *bios, int ent, int idx, u8 *ver, u8 *hdr)
+nvbios_M0205Se(struct nvkm_bios *bios, int ent, int idx, u8 *ver, u8 *hdr)
{
u8 cnt, len;
@@ -120,7 +119,7 @@ nvbios_M0205Se(struct nouveau_bios *bios, int ent, int idx, u8 *ver, u8 *hdr)
}
u32
-nvbios_M0205Sp(struct nouveau_bios *bios, int ent, int idx, u8 *ver, u8 *hdr,
+nvbios_M0205Sp(struct nvkm_bios *bios, int ent, int idx, u8 *ver, u8 *hdr,
struct nvbios_M0205S *info)
{
u32 data = nvbios_M0205Se(bios, ent, idx, ver, hdr);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/M0209.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0209.c
index b142a510e89f..3026920c3358 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/M0209.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/M0209.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/M0209.h>
u32
-nvbios_M0209Te(struct nouveau_bios *bios,
+nvbios_M0209Te(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
struct bit_entry bit_M;
@@ -56,7 +55,7 @@ nvbios_M0209Te(struct nouveau_bios *bios,
}
u32
-nvbios_M0209Ee(struct nouveau_bios *bios, int idx,
+nvbios_M0209Ee(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u8 snr, ssz;
@@ -72,9 +71,8 @@ nvbios_M0209Ee(struct nouveau_bios *bios, int idx,
}
u32
-nvbios_M0209Ep(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_M0209E *info)
+nvbios_M0209Ep(struct nvkm_bios *bios, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_M0209E *info)
{
u32 data = nvbios_M0209Ee(bios, idx, ver, hdr, cnt, len);
memset(info, 0x00, sizeof(*info));
@@ -94,7 +92,7 @@ nvbios_M0209Ep(struct nouveau_bios *bios, int idx,
}
u32
-nvbios_M0209Se(struct nouveau_bios *bios, int ent, int idx, u8 *ver, u8 *hdr)
+nvbios_M0209Se(struct nvkm_bios *bios, int ent, int idx, u8 *ver, u8 *hdr)
{
u8 cnt, len;
@@ -108,7 +106,7 @@ nvbios_M0209Se(struct nouveau_bios *bios, int ent, int idx, u8 *ver, u8 *hdr)
}
u32
-nvbios_M0209Sp(struct nouveau_bios *bios, int ent, int idx, u8 *ver, u8 *hdr,
+nvbios_M0209Sp(struct nvkm_bios *bios, int ent, int idx, u8 *ver, u8 *hdr,
struct nvbios_M0209S *info)
{
struct nvbios_M0209E M0209E;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/P0260.c
index 199f4e5f7488..b72edcf849b6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/P0260.c
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
-#include <subdev/bios/ramcfg.h>
#include <subdev/bios/P0260.h>
u32
-nvbios_P0260Te(struct nouveau_bios *bios,
+nvbios_P0260Te(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz)
{
struct bit_entry bit_P;
@@ -57,7 +55,7 @@ nvbios_P0260Te(struct nouveau_bios *bios,
}
u32
-nvbios_P0260Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+nvbios_P0260Ee(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len)
{
u8 hdr, cnt, xnr, xsz;
u32 data = nvbios_P0260Te(bios, ver, &hdr, &cnt, len, &xnr, &xsz);
@@ -67,7 +65,7 @@ nvbios_P0260Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
}
u32
-nvbios_P0260Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len,
+nvbios_P0260Ep(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
struct nvbios_P0260E *info)
{
u32 data = nvbios_P0260Ee(bios, idx, ver, len);
@@ -83,7 +81,7 @@ nvbios_P0260Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len,
}
u32
-nvbios_P0260Xe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *xsz)
+nvbios_P0260Xe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *xsz)
{
u8 hdr, cnt, len, xnr;
u32 data = nvbios_P0260Te(bios, ver, &hdr, &cnt, &len, &xnr, xsz);
@@ -93,7 +91,7 @@ nvbios_P0260Xe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *xsz)
}
u32
-nvbios_P0260Xp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
+nvbios_P0260Xp(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
struct nvbios_P0260X *info)
{
u32 data = nvbios_P0260Xe(bios, idx, ver, hdr);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c
index 7df3a273553d..8db204f92ed3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c
@@ -21,18 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/object.h>
-#include <core/device.h>
-#include <core/subdev.h>
-#include <core/option.h>
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bios/bmp.h>
#include <subdev/bios/bit.h>
-#include "priv.h"
-
u8
nvbios_checksum(const u8 *data, int size)
{
@@ -59,7 +53,7 @@ nvbios_findstr(const u8 *data, int size, const char *str, int len)
}
int
-nvbios_extend(struct nouveau_bios *bios, u32 length)
+nvbios_extend(struct nvkm_bios *bios, u32 length)
{
if (bios->size < length) {
u8 *prev = bios->data;
@@ -76,59 +70,58 @@ nvbios_extend(struct nouveau_bios *bios, u32 length)
}
static u8
-nouveau_bios_rd08(struct nouveau_object *object, u64 addr)
+nvkm_bios_rd08(struct nvkm_object *object, u64 addr)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
return bios->data[addr];
}
static u16
-nouveau_bios_rd16(struct nouveau_object *object, u64 addr)
+nvkm_bios_rd16(struct nvkm_object *object, u64 addr)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
return get_unaligned_le16(&bios->data[addr]);
}
static u32
-nouveau_bios_rd32(struct nouveau_object *object, u64 addr)
+nvkm_bios_rd32(struct nvkm_object *object, u64 addr)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
return get_unaligned_le32(&bios->data[addr]);
}
static void
-nouveau_bios_wr08(struct nouveau_object *object, u64 addr, u8 data)
+nvkm_bios_wr08(struct nvkm_object *object, u64 addr, u8 data)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
bios->data[addr] = data;
}
static void
-nouveau_bios_wr16(struct nouveau_object *object, u64 addr, u16 data)
+nvkm_bios_wr16(struct nvkm_object *object, u64 addr, u16 data)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
put_unaligned_le16(data, &bios->data[addr]);
}
static void
-nouveau_bios_wr32(struct nouveau_object *object, u64 addr, u32 data)
+nvkm_bios_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
put_unaligned_le32(data, &bios->data[addr]);
}
static int
-nouveau_bios_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nvkm_bios_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_bios *bios;
+ struct nvkm_bios *bios;
struct bit_entry bit_i;
int ret;
- ret = nouveau_subdev_create(parent, engine, oclass, 0,
- "VBIOS", "bios", &bios);
+ ret = nvkm_subdev_create(parent, engine, oclass, 0,
+ "VBIOS", "bios", &bios);
*pobject = nv_object(bios);
if (ret)
return ret;
@@ -174,40 +167,40 @@ nouveau_bios_ctor(struct nouveau_object *parent,
}
static void
-nouveau_bios_dtor(struct nouveau_object *object)
+nvkm_bios_dtor(struct nvkm_object *object)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
kfree(bios->data);
- nouveau_subdev_destroy(&bios->base);
+ nvkm_subdev_destroy(&bios->base);
}
static int
-nouveau_bios_init(struct nouveau_object *object)
+nvkm_bios_init(struct nvkm_object *object)
{
- struct nouveau_bios *bios = (void *)object;
- return nouveau_subdev_init(&bios->base);
+ struct nvkm_bios *bios = (void *)object;
+ return nvkm_subdev_init(&bios->base);
}
static int
-nouveau_bios_fini(struct nouveau_object *object, bool suspend)
+nvkm_bios_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_bios *bios = (void *)object;
- return nouveau_subdev_fini(&bios->base, suspend);
+ struct nvkm_bios *bios = (void *)object;
+ return nvkm_subdev_fini(&bios->base, suspend);
}
-struct nouveau_oclass
-nouveau_bios_oclass = {
+struct nvkm_oclass
+nvkm_bios_oclass = {
.handle = NV_SUBDEV(VBIOS, 0x00),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nouveau_bios_ctor,
- .dtor = nouveau_bios_dtor,
- .init = nouveau_bios_init,
- .fini = nouveau_bios_fini,
- .rd08 = nouveau_bios_rd08,
- .rd16 = nouveau_bios_rd16,
- .rd32 = nouveau_bios_rd32,
- .wr08 = nouveau_bios_wr08,
- .wr16 = nouveau_bios_wr16,
- .wr32 = nouveau_bios_wr32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nvkm_bios_ctor,
+ .dtor = nvkm_bios_dtor,
+ .init = nvkm_bios_init,
+ .fini = nvkm_bios_fini,
+ .rd08 = nvkm_bios_rd08,
+ .rd16 = nvkm_bios_rd16,
+ .rd32 = nvkm_bios_rd32,
+ .wr08 = nvkm_bios_wr08,
+ .wr16 = nvkm_bios_wr16,
+ .wr32 = nvkm_bios_wr32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/bit.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/bit.c
index 1d03a3f2b2d2..eab540496cdf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/bit.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/bit.c
@@ -21,14 +21,11 @@
*
* Authors: Ben Skeggs
*/
-
-#include "core/object.h"
-
-#include "subdev/bios.h"
-#include "subdev/bios/bit.h"
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
int
-bit_entry(struct nouveau_bios *bios, u8 id, struct bit_entry *bit)
+bit_entry(struct nvkm_bios *bios, u8 id, struct bit_entry *bit)
{
if (likely(bios->bit_offset)) {
u8 entries = nv_ro08(bios, bios->bit_offset + 10);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/boost.c
index c1835e591c44..12e958533f46 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/boost.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/boost.h>
u16
-nvbios_boostTe(struct nouveau_bios *bios,
+nvbios_boostTe(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
struct bit_entry bit_P;
@@ -57,7 +56,7 @@ nvbios_boostTe(struct nouveau_bios *bios,
}
u16
-nvbios_boostEe(struct nouveau_bios *bios, int idx,
+nvbios_boostEe(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u8 snr, ssz;
@@ -73,7 +72,7 @@ nvbios_boostEe(struct nouveau_bios *bios, int idx,
}
u16
-nvbios_boostEp(struct nouveau_bios *bios, int idx,
+nvbios_boostEp(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info)
{
u16 data = nvbios_boostEe(bios, idx, ver, hdr, cnt, len);
@@ -87,7 +86,7 @@ nvbios_boostEp(struct nouveau_bios *bios, int idx,
}
u16
-nvbios_boostEm(struct nouveau_bios *bios, u8 pstate,
+nvbios_boostEm(struct nvkm_bios *bios, u8 pstate,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info)
{
u32 data, idx = 0;
@@ -99,7 +98,7 @@ nvbios_boostEm(struct nouveau_bios *bios, u8 pstate,
}
u16
-nvbios_boostSe(struct nouveau_bios *bios, int idx,
+nvbios_boostSe(struct nvkm_bios *bios, int idx,
u16 data, u8 *ver, u8 *hdr, u8 cnt, u8 len)
{
if (data && idx < cnt) {
@@ -111,7 +110,7 @@ nvbios_boostSe(struct nouveau_bios *bios, int idx,
}
u16
-nvbios_boostSp(struct nouveau_bios *bios, int idx,
+nvbios_boostSp(struct nvkm_bios *bios, int idx,
u16 data, u8 *ver, u8 *hdr, u8 cnt, u8 len,
struct nvbios_boostS *info)
{
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/conn.c
index 2ede3bcd96a1..706a1650a4f2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/conn.c
@@ -21,15 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/device.h>
-
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/conn.h>
u32
-nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+nvbios_connTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u32 dcb = dcb_table(bios, ver, hdr, cnt, len);
if (dcb && *ver >= 0x30 && *hdr >= 0x16) {
@@ -46,7 +43,7 @@ nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u32
-nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+nvbios_connTp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_connT *info)
{
u32 data = nvbios_connTe(bios, ver, hdr, cnt, len);
@@ -62,7 +59,7 @@ nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
}
u32
-nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
+nvbios_connEe(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *len)
{
u8 hdr, cnt;
u32 data = nvbios_connTe(bios, ver, &hdr, &cnt, len);
@@ -72,7 +69,7 @@ nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
}
u32
-nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
+nvbios_connEp(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *len,
struct nvbios_connE *info)
{
u32 data = nvbios_connEe(bios, idx, ver, len);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/cstep.c
index d3b15327fbfd..16f7ad8a4f80 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/cstep.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/cstep.h>
u16
-nvbios_cstepTe(struct nouveau_bios *bios,
+nvbios_cstepTe(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz)
{
struct bit_entry bit_P;
@@ -57,7 +56,7 @@ nvbios_cstepTe(struct nouveau_bios *bios,
}
u16
-nvbios_cstepEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
+nvbios_cstepEe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr)
{
u8 cnt, len, xnr, xsz;
u16 data = nvbios_cstepTe(bios, ver, hdr, &cnt, &len, &xnr, &xsz);
@@ -70,7 +69,7 @@ nvbios_cstepEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
}
u16
-nvbios_cstepEp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
+nvbios_cstepEp(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
struct nvbios_cstepE *info)
{
u16 data = nvbios_cstepEe(bios, idx, ver, hdr);
@@ -83,7 +82,7 @@ nvbios_cstepEp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
}
u16
-nvbios_cstepEm(struct nouveau_bios *bios, u8 pstate, u8 *ver, u8 *hdr,
+nvbios_cstepEm(struct nvkm_bios *bios, u8 pstate, u8 *ver, u8 *hdr,
struct nvbios_cstepE *info)
{
u32 data, idx = 0;
@@ -95,7 +94,7 @@ nvbios_cstepEm(struct nouveau_bios *bios, u8 pstate, u8 *ver, u8 *hdr,
}
u16
-nvbios_cstepXe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
+nvbios_cstepXe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr)
{
u8 cnt, len, xnr, xsz;
u16 data = nvbios_cstepTe(bios, ver, hdr, &cnt, &len, &xnr, &xsz);
@@ -108,7 +107,7 @@ nvbios_cstepXe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
}
u16
-nvbios_cstepXp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
+nvbios_cstepXp(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
struct nvbios_cstepX *info)
{
u16 data = nvbios_cstepXe(bios, idx, ver, hdr);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dcb.c
index 96099aff8b41..8d78140f9401 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dcb.c
@@ -21,16 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
-#include "core/device.h"
-
-#include "subdev/bios.h"
-#include "subdev/bios/dcb.h"
+#include <core/device.h>
u16
-dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+dcb_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
- struct nouveau_device *device = nv_device(bios);
+ struct nvkm_device *device = nv_device(bios);
u16 dcb = 0x0000;
if (device->card_type > NV_04)
@@ -98,7 +97,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u16
-dcb_outp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
+dcb_outp(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *len)
{
u8 hdr, cnt;
u16 dcb = dcb_table(bios, ver, &hdr, &cnt, len);
@@ -120,7 +119,7 @@ dcb_outp_hashm(struct dcb_output *outp)
}
u16
-dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
+dcb_outp_parse(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *len,
struct dcb_output *outp)
{
u16 dcb = dcb_outp(bios, idx, ver, len);
@@ -194,7 +193,7 @@ dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
}
u16
-dcb_outp_match(struct nouveau_bios *bios, u16 type, u16 mask,
+dcb_outp_match(struct nvkm_bios *bios, u16 type, u16 mask,
u8 *ver, u8 *len, struct dcb_output *outp)
{
u16 dcb, idx = 0;
@@ -208,8 +207,8 @@ dcb_outp_match(struct nouveau_bios *bios, u16 type, u16 mask,
}
int
-dcb_outp_foreach(struct nouveau_bios *bios, void *data,
- int (*exec)(struct nouveau_bios *, void *, int, u16))
+dcb_outp_foreach(struct nvkm_bios *bios, void *data,
+ int (*exec)(struct nvkm_bios *, void *, int, u16))
{
int ret, idx = -1;
u8 ver, len;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c
index 51f355599694..262c410b7ee2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/disp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/disp.h>
u16
-nvbios_disp_table(struct nouveau_bios *bios,
+nvbios_disp_table(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *sub)
{
struct bit_entry U;
@@ -57,8 +56,7 @@ nvbios_disp_table(struct nouveau_bios *bios,
}
u16
-nvbios_disp_entry(struct nouveau_bios *bios, u8 idx,
- u8 *ver, u8 *len, u8 *sub)
+nvbios_disp_entry(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *len, u8 *sub)
{
u8 hdr, cnt;
u16 data = nvbios_disp_table(bios, ver, &hdr, &cnt, len, sub);
@@ -69,8 +67,7 @@ nvbios_disp_entry(struct nouveau_bios *bios, u8 idx,
}
u16
-nvbios_disp_parse(struct nouveau_bios *bios, u8 idx,
- u8 *ver, u8 *len, u8 *sub,
+nvbios_disp_parse(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *len, u8 *sub,
struct nvbios_disp *info)
{
u16 data = nvbios_disp_entry(bios, idx, ver, len, sub);
@@ -82,7 +79,7 @@ nvbios_disp_parse(struct nouveau_bios *bios, u8 idx,
}
u16
-nvbios_outp_entry(struct nouveau_bios *bios, u8 idx,
+nvbios_outp_entry(struct nvkm_bios *bios, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct nvbios_disp info;
@@ -96,9 +93,8 @@ nvbios_outp_entry(struct nouveau_bios *bios, u8 idx,
}
u16
-nvbios_outp_parse(struct nouveau_bios *bios, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_outp *info)
+nvbios_outp_parse(struct nvkm_bios *bios, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *info)
{
u16 data = nvbios_outp_entry(bios, idx, ver, hdr, cnt, len);
if (data && *hdr >= 0x0a) {
@@ -117,9 +113,8 @@ nvbios_outp_parse(struct nouveau_bios *bios, u8 idx,
}
u16
-nvbios_outp_match(struct nouveau_bios *bios, u16 type, u16 mask,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_outp *info)
+nvbios_outp_match(struct nvkm_bios *bios, u16 type, u16 mask,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *info)
{
u16 data, idx = 0;
while ((data = nvbios_outp_parse(bios, idx++, ver, hdr, cnt, len, info)) || *ver) {
@@ -132,7 +127,7 @@ nvbios_outp_match(struct nouveau_bios *bios, u16 type, u16 mask,
}
u16
-nvbios_ocfg_entry(struct nouveau_bios *bios, u16 outp, u8 idx,
+nvbios_ocfg_entry(struct nvkm_bios *bios, u16 outp, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
if (idx < *cnt)
@@ -141,9 +136,8 @@ nvbios_ocfg_entry(struct nouveau_bios *bios, u16 outp, u8 idx,
}
u16
-nvbios_ocfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ocfg *info)
+nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info)
{
u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len);
if (data) {
@@ -155,9 +149,8 @@ nvbios_ocfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
}
u16
-nvbios_ocfg_match(struct nouveau_bios *bios, u16 outp, u16 type,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ocfg *info)
+nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u16 type,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info)
{
u16 data, idx = 0;
while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) {
@@ -168,7 +161,7 @@ nvbios_ocfg_match(struct nouveau_bios *bios, u16 outp, u16 type,
}
u16
-nvbios_oclk_match(struct nouveau_bios *bios, u16 cmp, u32 khz)
+nvbios_oclk_match(struct nvkm_bios *bios, u16 cmp, u32 khz)
{
while (cmp) {
if (khz / 10 >= nv_ro16(bios, cmp + 0x00))
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c
index cef53f81f12b..95970faae6c8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/dp.c
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
-
-#include "subdev/bios.h"
-#include "subdev/bios/bit.h"
-#include "subdev/bios/dp.h"
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/dp.h>
static u16
-nvbios_dp_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+nvbios_dp_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry d;
@@ -57,7 +55,7 @@ nvbios_dp_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
static u16
-nvbios_dpout_entry(struct nouveau_bios *bios, u8 idx,
+nvbios_dpout_entry(struct nvkm_bios *bios, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u16 data = nvbios_dp_table(bios, ver, hdr, cnt, len);
@@ -86,7 +84,7 @@ nvbios_dpout_entry(struct nouveau_bios *bios, u8 idx,
}
u16
-nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx,
+nvbios_dpout_parse(struct nvkm_bios *bios, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_dpout *info)
{
@@ -128,7 +126,7 @@ nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx,
}
u16
-nvbios_dpout_match(struct nouveau_bios *bios, u16 type, u16 mask,
+nvbios_dpout_match(struct nvkm_bios *bios, u16 type, u16 mask,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_dpout *info)
{
@@ -143,7 +141,7 @@ nvbios_dpout_match(struct nouveau_bios *bios, u16 type, u16 mask,
}
static u16
-nvbios_dpcfg_entry(struct nouveau_bios *bios, u16 outp, u8 idx,
+nvbios_dpcfg_entry(struct nvkm_bios *bios, u16 outp, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
if (*ver >= 0x40) {
@@ -160,7 +158,7 @@ nvbios_dpcfg_entry(struct nouveau_bios *bios, u16 outp, u8 idx,
}
u16
-nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
+nvbios_dpcfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_dpcfg *info)
{
@@ -190,7 +188,7 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
}
u16
-nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe,
+nvbios_dpcfg_match(struct nvkm_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_dpcfg *info)
{
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c
index 49285d4f7ca5..a8503a1854c4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c
@@ -21,13 +21,12 @@
*
* Authors: Martin Peres
*/
-
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/extdev.h>
static u16
-extdev_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
+extdev_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
{
u8 dcb_ver, dcb_hdr, dcb_cnt, dcb_len;
u16 dcb, extdev = 0;
@@ -44,12 +43,11 @@ extdev_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
*hdr = nv_ro08(bios, extdev + 1);
*cnt = nv_ro08(bios, extdev + 2);
*len = nv_ro08(bios, extdev + 3);
-
return extdev + *hdr;
}
static u16
-nvbios_extdev_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+nvbios_extdev_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len)
{
u8 hdr, cnt;
u16 extdev = extdev_table(bios, ver, &hdr, len, &cnt);
@@ -59,8 +57,8 @@ nvbios_extdev_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
}
static void
-extdev_parse_entry(struct nouveau_bios *bios, u16 offset,
- struct nvbios_extdev_func *entry)
+extdev_parse_entry(struct nvkm_bios *bios, u16 offset,
+ struct nvbios_extdev_func *entry)
{
entry->type = nv_ro08(bios, offset + 0);
entry->addr = nv_ro08(bios, offset + 1);
@@ -68,7 +66,7 @@ extdev_parse_entry(struct nouveau_bios *bios, u16 offset,
}
int
-nvbios_extdev_parse(struct nouveau_bios *bios, int idx,
+nvbios_extdev_parse(struct nvkm_bios *bios, int idx,
struct nvbios_extdev_func *func)
{
u8 ver, len;
@@ -78,12 +76,11 @@ nvbios_extdev_parse(struct nouveau_bios *bios, int idx,
return -EINVAL;
extdev_parse_entry(bios, entry, func);
-
return 0;
}
int
-nvbios_extdev_find(struct nouveau_bios *bios, enum nvbios_extdev_type type,
+nvbios_extdev_find(struct nvkm_bios *bios, enum nvbios_extdev_type type,
struct nvbios_extdev_func *func)
{
u8 ver, len, i;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/fan.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
index e419892240f5..8dba70d9d9a9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/fan.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
@@ -21,13 +21,12 @@
*
* Authors: Martin Peres
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/fan.h>
u16
-nvbios_fan_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+nvbios_fan_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_P;
u16 fan = 0x0000;
@@ -54,7 +53,7 @@ nvbios_fan_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u16
-nvbios_fan_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
+nvbios_fan_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len)
{
u16 data = nvbios_fan_table(bios, ver, hdr, cnt, len);
@@ -64,7 +63,7 @@ nvbios_fan_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
}
u16
-nvbios_fan_parse(struct nouveau_bios *bios, struct nvbios_therm_fan *fan)
+nvbios_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan)
{
u8 ver, hdr, cnt, len;
@@ -89,5 +88,6 @@ nvbios_fan_parse(struct nouveau_bios *bios, struct nvbios_therm_fan *fan)
fan->pwm_freq = nv_ro32(bios, data + 0x0b) & 0xffffff;
}
+
return data;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/gpio.c
index 172a4f999990..8ce154d88f51 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/gpio.c
@@ -21,14 +21,13 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/gpio.h>
#include <subdev/bios/xpio.h>
u16
-dcb_gpio_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+dcb_gpio_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u16 data = 0x0000;
u16 dcb = dcb_table(bios, ver, hdr, cnt, len);
@@ -59,7 +58,7 @@ dcb_gpio_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u16
-dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len)
+dcb_gpio_entry(struct nvkm_bios *bios, int idx, int ent, u8 *ver, u8 *len)
{
u8 hdr, cnt, xver; /* use gpio version for xpio entry parsing */
u16 gpio;
@@ -71,11 +70,12 @@ dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len)
if (gpio && ent < cnt)
return gpio + hdr + (ent * *len);
+
return 0x0000;
}
u16
-dcb_gpio_parse(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len,
+dcb_gpio_parse(struct nvkm_bios *bios, int idx, int ent, u8 *ver, u8 *len,
struct dcb_gpio_func *gpio)
{
u16 data = dcb_gpio_entry(bios, idx, ent, ver, len);
@@ -116,7 +116,7 @@ dcb_gpio_parse(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len,
}
u16
-dcb_gpio_match(struct nouveau_bios *bios, int idx, u8 func, u8 line,
+dcb_gpio_match(struct nvkm_bios *bios, int idx, u8 func, u8 line,
u8 *ver, u8 *len, struct dcb_gpio_func *gpio)
{
u8 hdr, cnt, i = 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/i2c.c
index 282320ba9264..d1a89b2bd5c1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/i2c.c
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
-
-#include "subdev/bios.h"
-#include "subdev/bios/dcb.h"
-#include "subdev/bios/i2c.h"
+#include <subdev/bios.h>
+#include <subdev/bios/dcb.h>
+#include <subdev/bios/i2c.h>
u16
-dcb_i2c_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+dcb_i2c_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u16 i2c = 0x0000;
u16 dcb = dcb_table(bios, ver, hdr, cnt, len);
@@ -60,7 +58,7 @@ dcb_i2c_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u16
-dcb_i2c_entry(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
+dcb_i2c_entry(struct nvkm_bios *bios, u8 idx, u8 *ver, u8 *len)
{
u8 hdr, cnt;
u16 i2c = dcb_i2c_table(bios, ver, &hdr, &cnt, len);
@@ -70,7 +68,7 @@ dcb_i2c_entry(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len)
}
int
-dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
+dcb_i2c_parse(struct nvkm_bios *bios, u8 idx, struct dcb_i2c_entry *info)
{
u8 ver, len;
u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/image.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/image.c
index 373f9a564ac9..1815540a0e8b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/image.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/image.c
@@ -21,14 +21,13 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include <subdev/bios.h>
#include <subdev/bios/image.h>
#include <subdev/bios/pcir.h>
#include <subdev/bios/npde.h>
static bool
-nvbios_imagen(struct nouveau_bios *bios, struct nvbios_image *image)
+nvbios_imagen(struct nvkm_bios *bios, struct nvbios_image *image)
{
struct nvbios_pcirT pcir;
struct nvbios_npdeT npde;
@@ -66,7 +65,7 @@ nvbios_imagen(struct nouveau_bios *bios, struct nvbios_image *image)
}
bool
-nvbios_image(struct nouveau_bios *bios, int idx, struct nvbios_image *image)
+nvbios_image(struct nvkm_bios *bios, int idx, struct nvbios_image *image)
{
memset(image, 0x00, sizeof(*image));
do {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
index c6579ef32cd1..f67cdae1e90a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
@@ -1,19 +1,41 @@
-#include <core/engine.h>
-#include <core/device.h>
-
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
#include <subdev/bios.h>
-#include <subdev/bios/bmp.h>
#include <subdev/bios/bit.h>
+#include <subdev/bios/bmp.h>
#include <subdev/bios/conn.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
#include <subdev/bios/gpio.h>
#include <subdev/bios/init.h>
#include <subdev/bios/ramcfg.h>
+
+#include <core/device.h>
#include <subdev/devinit.h>
+#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/vga.h>
-#include <subdev/gpio.h>
#define bioslog(lvl, fmt, args...) do { \
nv_printk(init->bios, lvl, "0x%04x[%c]: "fmt, init->offset, \
@@ -97,7 +119,7 @@ init_crtc(struct nvbios_init *init)
static u8
init_conn(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
struct nvbios_connE connE;
u8 ver, hdr;
u32 conn;
@@ -119,7 +141,7 @@ init_conn(struct nvbios_init *init)
static inline u32
init_nvreg(struct nvbios_init *init, u32 reg)
{
- struct nouveau_devinit *devinit = nouveau_devinit(init->bios);
+ struct nvkm_devinit *devinit = nvkm_devinit(init->bios);
/* C51 (at least) sometimes has the lower bits set which the VBIOS
* interprets to mean that access needs to go through certain IO
@@ -203,7 +225,7 @@ init_wrport(struct nvbios_init *init, u16 port, u8 value)
static u8
init_rdvgai(struct nvbios_init *init, u16 port, u8 index)
{
- struct nouveau_subdev *subdev = init->subdev;
+ struct nvkm_subdev *subdev = init->subdev;
if (init_exec(init)) {
int head = init->crtc < 0 ? 0 : init->crtc;
return nv_rdvgai(subdev, head, port, index);
@@ -232,10 +254,10 @@ init_wrvgai(struct nvbios_init *init, u16 port, u8 index, u8 value)
}
}
-static struct nouveau_i2c_port *
+static struct nvkm_i2c_port *
init_i2c(struct nvbios_init *init, int index)
{
- struct nouveau_i2c *i2c = nouveau_i2c(init->bios);
+ struct nvkm_i2c *i2c = nvkm_i2c(init->bios);
if (index == 0xff) {
index = NV_I2C_DEFAULT(0);
@@ -265,7 +287,7 @@ init_i2c(struct nvbios_init *init, int index)
static int
init_rdi2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg)
{
- struct nouveau_i2c_port *port = init_i2c(init, index);
+ struct nvkm_i2c_port *port = init_i2c(init, index);
if (port && init_exec(init))
return nv_rdi2cr(port, addr, reg);
return -ENODEV;
@@ -274,7 +296,7 @@ init_rdi2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg)
static int
init_wri2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg, u8 val)
{
- struct nouveau_i2c_port *port = init_i2c(init, index);
+ struct nvkm_i2c_port *port = init_i2c(init, index);
if (port && init_exec(init))
return nv_wri2cr(port, addr, reg, val);
return -ENODEV;
@@ -283,7 +305,7 @@ init_wri2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg, u8 val)
static u8
init_rdauxr(struct nvbios_init *init, u32 addr)
{
- struct nouveau_i2c_port *port = init_i2c(init, -2);
+ struct nvkm_i2c_port *port = init_i2c(init, -2);
u8 data;
if (port && init_exec(init)) {
@@ -299,7 +321,7 @@ init_rdauxr(struct nvbios_init *init, u32 addr)
static int
init_wrauxr(struct nvbios_init *init, u32 addr, u8 data)
{
- struct nouveau_i2c_port *port = init_i2c(init, -2);
+ struct nvkm_i2c_port *port = init_i2c(init, -2);
if (port && init_exec(init)) {
int ret = nv_wraux(port, addr, &data, 1);
if (ret)
@@ -312,7 +334,7 @@ init_wrauxr(struct nvbios_init *init, u32 addr, u8 data)
static void
init_prog_pll(struct nvbios_init *init, u32 id, u32 freq)
{
- struct nouveau_devinit *devinit = nouveau_devinit(init->bios);
+ struct nvkm_devinit *devinit = nvkm_devinit(init->bios);
if (devinit->pll_set && init_exec(init)) {
int ret = devinit->pll_set(devinit, id, freq);
if (ret)
@@ -325,7 +347,7 @@ init_prog_pll(struct nvbios_init *init, u32 id, u32 freq)
*****************************************************************************/
static u16
-init_table(struct nouveau_bios *bios, u16 *len)
+init_table(struct nvkm_bios *bios, u16 *len)
{
struct bit_entry bit_I;
@@ -345,7 +367,7 @@ init_table(struct nouveau_bios *bios, u16 *len)
static u16
init_table_(struct nvbios_init *init, u16 offset, const char *name)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 len, data = init_table(bios, &len);
if (data) {
if (len >= offset + 2) {
@@ -375,7 +397,7 @@ init_table_(struct nvbios_init *init, u16 offset, const char *name)
#define init_xlat_table(b) init_table_((b), 0x10, "xlat table");
static u16
-init_script(struct nouveau_bios *bios, int index)
+init_script(struct nvkm_bios *bios, int index)
{
struct nvbios_init init = { .bios = bios };
u16 bmp_ver = bmp_version(bios), data;
@@ -396,7 +418,7 @@ init_script(struct nouveau_bios *bios, int index)
}
static u16
-init_unknown_script(struct nouveau_bios *bios)
+init_unknown_script(struct nvkm_bios *bios)
{
u16 len, data = init_table(bios, &len);
if (data && len >= 16)
@@ -429,7 +451,7 @@ init_ram_restrict(struct nvbios_init *init)
static u8
init_xlat_(struct nvbios_init *init, u8 index, u8 offset)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 table = init_xlat_table(init);
if (table) {
u16 data = nv_ro16(bios, table + (index * 2));
@@ -447,7 +469,7 @@ init_xlat_(struct nvbios_init *init, u8 index, u8 offset)
static bool
init_condition_met(struct nvbios_init *init, u8 cond)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 table = init_condition_table(init);
if (table) {
u32 reg = nv_ro32(bios, table + (cond * 12) + 0);
@@ -463,7 +485,7 @@ init_condition_met(struct nvbios_init *init, u8 cond)
static bool
init_io_condition_met(struct nvbios_init *init, u8 cond)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 table = init_io_condition_table(init);
if (table) {
u16 port = nv_ro16(bios, table + (cond * 5) + 0);
@@ -480,7 +502,7 @@ init_io_condition_met(struct nvbios_init *init, u8 cond)
static bool
init_io_flag_condition_met(struct nvbios_init *init, u8 cond)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 table = init_io_flag_condition_table(init);
if (table) {
u16 port = nv_ro16(bios, table + (cond * 9) + 0);
@@ -515,7 +537,6 @@ init_tmds_reg(struct nvbios_init *init, u8 tmds)
* CR58 for CR57 = 0 to index a table of offsets to the basic
* 0x6808b0 address, and then flip the offset by 8.
*/
-
const int pramdac_offset[13] = {
0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 };
const u32 pramdac_table[4] = {
@@ -589,7 +610,7 @@ init_done(struct nvbios_init *init)
static void
init_io_restrict_prog(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 port = nv_ro16(bios, init->offset + 1);
u8 index = nv_ro08(bios, init->offset + 3);
u8 mask = nv_ro08(bios, init->offset + 4);
@@ -626,7 +647,7 @@ init_io_restrict_prog(struct nvbios_init *init)
static void
init_repeat(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 count = nv_ro08(bios, init->offset + 1);
u16 repeat = init->repeat;
@@ -652,7 +673,7 @@ init_repeat(struct nvbios_init *init)
static void
init_io_restrict_pll(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 port = nv_ro16(bios, init->offset + 1);
u8 index = nv_ro08(bios, init->offset + 3);
u8 mask = nv_ro08(bios, init->offset + 4);
@@ -708,7 +729,7 @@ init_end_repeat(struct nvbios_init *init)
static void
init_copy(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 reg = nv_ro32(bios, init->offset + 1);
u8 shift = nv_ro08(bios, init->offset + 5);
u8 smask = nv_ro08(bios, init->offset + 6);
@@ -747,7 +768,7 @@ init_not(struct nvbios_init *init)
static void
init_io_flag_condition(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 cond = nv_ro08(bios, init->offset + 1);
trace("IO_FLAG_CONDITION\t0x%02x\n", cond);
@@ -764,7 +785,7 @@ init_io_flag_condition(struct nvbios_init *init)
static void
init_dp_condition(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
struct nvbios_dpout info;
u8 cond = nv_ro08(bios, init->offset + 1);
u8 unkn = nv_ro08(bios, init->offset + 2);
@@ -812,7 +833,7 @@ init_dp_condition(struct nvbios_init *init)
static void
init_io_mask_or(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u8 or = init_or(init);
u8 data;
@@ -831,7 +852,7 @@ init_io_mask_or(struct nvbios_init *init)
static void
init_io_or(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u8 or = init_or(init);
u8 data;
@@ -850,7 +871,7 @@ init_io_or(struct nvbios_init *init)
static void
init_andn_reg(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 reg = nv_ro32(bios, init->offset + 1);
u32 mask = nv_ro32(bios, init->offset + 5);
@@ -867,7 +888,7 @@ init_andn_reg(struct nvbios_init *init)
static void
init_or_reg(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 reg = nv_ro32(bios, init->offset + 1);
u32 mask = nv_ro32(bios, init->offset + 5);
@@ -884,7 +905,7 @@ init_or_reg(struct nvbios_init *init)
static void
init_idx_addr_latched(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 creg = nv_ro32(bios, init->offset + 1);
u32 dreg = nv_ro32(bios, init->offset + 5);
u32 mask = nv_ro32(bios, init->offset + 9);
@@ -914,7 +935,7 @@ init_idx_addr_latched(struct nvbios_init *init)
static void
init_io_restrict_pll2(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 port = nv_ro16(bios, init->offset + 1);
u8 index = nv_ro08(bios, init->offset + 3);
u8 mask = nv_ro08(bios, init->offset + 4);
@@ -949,7 +970,7 @@ init_io_restrict_pll2(struct nvbios_init *init)
static void
init_pll2(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 reg = nv_ro32(bios, init->offset + 1);
u32 freq = nv_ro32(bios, init->offset + 5);
@@ -966,7 +987,7 @@ init_pll2(struct nvbios_init *init)
static void
init_i2c_byte(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
u8 count = nv_ro08(bios, init->offset + 3);
@@ -997,7 +1018,7 @@ init_i2c_byte(struct nvbios_init *init)
static void
init_zm_i2c_byte(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
u8 count = nv_ro08(bios, init->offset + 3);
@@ -1014,7 +1035,6 @@ init_zm_i2c_byte(struct nvbios_init *init)
init_wri2cr(init, index, addr, reg, data);
}
-
}
/**
@@ -1024,7 +1044,7 @@ init_zm_i2c_byte(struct nvbios_init *init)
static void
init_zm_i2c(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
u8 count = nv_ro08(bios, init->offset + 3);
@@ -1040,7 +1060,7 @@ init_zm_i2c(struct nvbios_init *init)
}
if (init_exec(init)) {
- struct nouveau_i2c_port *port = init_i2c(init, index);
+ struct nvkm_i2c_port *port = init_i2c(init, index);
struct i2c_msg msg = {
.addr = addr, .flags = 0, .len = count, .buf = data,
};
@@ -1058,7 +1078,7 @@ init_zm_i2c(struct nvbios_init *init)
static void
init_tmds(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 tmds = nv_ro08(bios, init->offset + 1);
u8 addr = nv_ro08(bios, init->offset + 2);
u8 mask = nv_ro08(bios, init->offset + 3);
@@ -1084,7 +1104,7 @@ init_tmds(struct nvbios_init *init)
static void
init_zm_tmds_group(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 tmds = nv_ro08(bios, init->offset + 1);
u8 count = nv_ro08(bios, init->offset + 2);
u32 reg = init_tmds_reg(init, tmds);
@@ -1111,7 +1131,7 @@ init_zm_tmds_group(struct nvbios_init *init)
static void
init_cr_idx_adr_latch(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 addr0 = nv_ro08(bios, init->offset + 1);
u8 addr1 = nv_ro08(bios, init->offset + 2);
u8 base = nv_ro08(bios, init->offset + 3);
@@ -1141,7 +1161,7 @@ init_cr_idx_adr_latch(struct nvbios_init *init)
static void
init_cr(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 addr = nv_ro08(bios, init->offset + 1);
u8 mask = nv_ro08(bios, init->offset + 2);
u8 data = nv_ro08(bios, init->offset + 3);
@@ -1161,7 +1181,7 @@ init_cr(struct nvbios_init *init)
static void
init_zm_cr(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 addr = nv_ro08(bios, init->offset + 1);
u8 data = nv_ro08(bios, init->offset + 2);
@@ -1178,7 +1198,7 @@ init_zm_cr(struct nvbios_init *init)
static void
init_zm_cr_group(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 count = nv_ro08(bios, init->offset + 1);
trace("ZM_CR_GROUP\n");
@@ -1202,7 +1222,7 @@ init_zm_cr_group(struct nvbios_init *init)
static void
init_condition_time(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 cond = nv_ro08(bios, init->offset + 1);
u8 retry = nv_ro08(bios, init->offset + 2);
u8 wait = min((u16)retry * 50, 100);
@@ -1229,7 +1249,7 @@ init_condition_time(struct nvbios_init *init)
static void
init_ltime(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 msec = nv_ro16(bios, init->offset + 1);
trace("LTIME\t0x%04x\n", msec);
@@ -1246,7 +1266,7 @@ init_ltime(struct nvbios_init *init)
static void
init_zm_reg_sequence(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 base = nv_ro32(bios, init->offset + 1);
u8 count = nv_ro08(bios, init->offset + 5);
@@ -1271,7 +1291,7 @@ init_zm_reg_sequence(struct nvbios_init *init)
static void
init_sub_direct(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 addr = nv_ro16(bios, init->offset + 1);
u16 save;
@@ -1297,7 +1317,7 @@ init_sub_direct(struct nvbios_init *init)
static void
init_jump(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 offset = nv_ro16(bios, init->offset + 1);
trace("JUMP\t0x%04x\n", offset);
@@ -1315,7 +1335,7 @@ init_jump(struct nvbios_init *init)
static void
init_i2c_if(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u8 addr = nv_ro08(bios, init->offset + 2);
u8 reg = nv_ro08(bios, init->offset + 3);
@@ -1342,7 +1362,7 @@ init_i2c_if(struct nvbios_init *init)
static void
init_copy_nv_reg(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 sreg = nv_ro32(bios, init->offset + 1);
u8 shift = nv_ro08(bios, init->offset + 5);
u32 smask = nv_ro32(bios, init->offset + 6);
@@ -1368,7 +1388,7 @@ init_copy_nv_reg(struct nvbios_init *init)
static void
init_zm_index_io(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 port = nv_ro16(bios, init->offset + 1);
u8 index = nv_ro08(bios, init->offset + 3);
u8 data = nv_ro08(bios, init->offset + 4);
@@ -1386,7 +1406,7 @@ init_zm_index_io(struct nvbios_init *init)
static void
init_compute_mem(struct nvbios_init *init)
{
- struct nouveau_devinit *devinit = nouveau_devinit(init->bios);
+ struct nvkm_devinit *devinit = nvkm_devinit(init->bios);
trace("COMPUTE_MEM\n");
init->offset += 1;
@@ -1404,7 +1424,7 @@ init_compute_mem(struct nvbios_init *init)
static void
init_reset(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 reg = nv_ro32(bios, init->offset + 1);
u32 data1 = nv_ro32(bios, init->offset + 5);
u32 data2 = nv_ro32(bios, init->offset + 9);
@@ -1440,7 +1460,7 @@ init_configure_mem_clk(struct nvbios_init *init)
static void
init_configure_mem(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 mdata, sdata;
u32 addr, data;
@@ -1490,7 +1510,7 @@ init_configure_mem(struct nvbios_init *init)
static void
init_configure_clk(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 mdata, clock;
trace("CONFIGURE_CLK\n");
@@ -1524,7 +1544,7 @@ init_configure_clk(struct nvbios_init *init)
static void
init_configure_preinit(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 strap;
trace("CONFIGURE_PREINIT\n");
@@ -1550,7 +1570,7 @@ init_configure_preinit(struct nvbios_init *init)
static void
init_io(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 port = nv_ro16(bios, init->offset + 1);
u8 mask = nv_ro16(bios, init->offset + 3);
u8 data = nv_ro16(bios, init->offset + 4);
@@ -1590,7 +1610,7 @@ init_io(struct nvbios_init *init)
static void
init_sub(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u16 addr, save;
@@ -1617,7 +1637,7 @@ init_sub(struct nvbios_init *init)
static void
init_ram_condition(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 mask = nv_ro08(bios, init->offset + 1);
u8 value = nv_ro08(bios, init->offset + 2);
@@ -1636,7 +1656,7 @@ init_ram_condition(struct nvbios_init *init)
static void
init_nv_reg(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 reg = nv_ro32(bios, init->offset + 1);
u32 mask = nv_ro32(bios, init->offset + 5);
u32 data = nv_ro32(bios, init->offset + 9);
@@ -1654,7 +1674,7 @@ init_nv_reg(struct nvbios_init *init)
static void
init_macro(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 macro = nv_ro08(bios, init->offset + 1);
u16 table;
@@ -1690,7 +1710,7 @@ init_resume(struct nvbios_init *init)
static void
init_time(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 usec = nv_ro16(bios, init->offset + 1);
trace("TIME\t0x%04x\n", usec);
@@ -1711,7 +1731,7 @@ init_time(struct nvbios_init *init)
static void
init_condition(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 cond = nv_ro08(bios, init->offset + 1);
trace("CONDITION\t0x%02x\n", cond);
@@ -1728,7 +1748,7 @@ init_condition(struct nvbios_init *init)
static void
init_io_condition(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 cond = nv_ro08(bios, init->offset + 1);
trace("IO_CONDITION\t0x%02x\n", cond);
@@ -1745,7 +1765,7 @@ init_io_condition(struct nvbios_init *init)
static void
init_index_io(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u16 port = nv_ro16(bios, init->offset + 1);
u8 index = nv_ro16(bios, init->offset + 3);
u8 mask = nv_ro08(bios, init->offset + 4);
@@ -1767,7 +1787,7 @@ init_index_io(struct nvbios_init *init)
static void
init_pll(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 reg = nv_ro32(bios, init->offset + 1);
u32 freq = nv_ro16(bios, init->offset + 5) * 10;
@@ -1784,7 +1804,7 @@ init_pll(struct nvbios_init *init)
static void
init_zm_reg(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 addr = nv_ro32(bios, init->offset + 1);
u32 data = nv_ro32(bios, init->offset + 5);
@@ -1804,7 +1824,7 @@ init_zm_reg(struct nvbios_init *init)
static void
init_ram_restrict_pll(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 type = nv_ro08(bios, init->offset + 1);
u8 count = init_ram_restrict_group_count(init);
u8 strap = init_ram_restrict(init);
@@ -1834,7 +1854,7 @@ init_ram_restrict_pll(struct nvbios_init *init)
static void
init_gpio(struct nvbios_init *init)
{
- struct nouveau_gpio *gpio = nouveau_gpio(init->bios);
+ struct nvkm_gpio *gpio = nvkm_gpio(init->bios);
trace("GPIO\n");
init->offset += 1;
@@ -1850,7 +1870,7 @@ init_gpio(struct nvbios_init *init)
static void
init_ram_restrict_zm_reg_group(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 addr = nv_ro32(bios, init->offset + 1);
u8 incr = nv_ro08(bios, init->offset + 5);
u8 num = nv_ro08(bios, init->offset + 6);
@@ -1888,7 +1908,7 @@ init_ram_restrict_zm_reg_group(struct nvbios_init *init)
static void
init_copy_zm_reg(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 sreg = nv_ro32(bios, init->offset + 1);
u32 dreg = nv_ro32(bios, init->offset + 5);
@@ -1905,7 +1925,7 @@ init_copy_zm_reg(struct nvbios_init *init)
static void
init_zm_reg_group(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 addr = nv_ro32(bios, init->offset + 1);
u8 count = nv_ro08(bios, init->offset + 5);
@@ -1927,7 +1947,7 @@ init_zm_reg_group(struct nvbios_init *init)
static void
init_xlat(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 saddr = nv_ro32(bios, init->offset + 1);
u8 sshift = nv_ro08(bios, init->offset + 5);
u8 smask = nv_ro08(bios, init->offset + 6);
@@ -1955,7 +1975,7 @@ init_xlat(struct nvbios_init *init)
static void
init_zm_mask_add(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 addr = nv_ro32(bios, init->offset + 1);
u32 mask = nv_ro32(bios, init->offset + 5);
u32 add = nv_ro32(bios, init->offset + 9);
@@ -1976,7 +1996,7 @@ init_zm_mask_add(struct nvbios_init *init)
static void
init_auxch(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 addr = nv_ro32(bios, init->offset + 1);
u8 count = nv_ro08(bios, init->offset + 5);
@@ -2000,7 +2020,7 @@ init_auxch(struct nvbios_init *init)
static void
init_zm_auxch(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u32 addr = nv_ro32(bios, init->offset + 1);
u8 count = nv_ro08(bios, init->offset + 5);
@@ -2022,14 +2042,14 @@ init_zm_auxch(struct nvbios_init *init)
static void
init_i2c_long_if(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
+ struct nvkm_bios *bios = init->bios;
u8 index = nv_ro08(bios, init->offset + 1);
u8 addr = nv_ro08(bios, init->offset + 2) >> 1;
u8 reglo = nv_ro08(bios, init->offset + 3);
u8 reghi = nv_ro08(bios, init->offset + 4);
u8 mask = nv_ro08(bios, init->offset + 5);
u8 data = nv_ro08(bios, init->offset + 6);
- struct nouveau_i2c_port *port;
+ struct nvkm_i2c_port *port;
trace("I2C_LONG_IF\t"
"I2C[0x%02x][0x%02x][0x%02x%02x] & 0x%02x == 0x%02x\n",
@@ -2061,8 +2081,8 @@ init_i2c_long_if(struct nvbios_init *init)
static void
init_gpio_ne(struct nvbios_init *init)
{
- struct nouveau_bios *bios = init->bios;
- struct nouveau_gpio *gpio = nouveau_gpio(bios);
+ struct nvkm_bios *bios = init->bios;
+ struct nvkm_gpio *gpio = nvkm_gpio(bios);
struct dcb_gpio_func func;
u8 count = nv_ro08(bios, init->offset + 1);
u8 idx = 0, ver, len;
@@ -2185,9 +2205,9 @@ nvbios_exec(struct nvbios_init *init)
}
int
-nvbios_init(struct nouveau_subdev *subdev, bool execute)
+nvbios_init(struct nvkm_subdev *subdev, bool execute)
{
- struct nouveau_bios *bios = nouveau_bios(subdev);
+ struct nvkm_bios *bios = nvkm_bios(subdev);
int ret = 0;
int i = -1;
u16 data;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/mxm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/mxm.c
index 2610b11a99b3..c4087df4f85e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/mxm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/mxm.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/mxm.h>
u16
-mxm_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr)
+mxm_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr)
{
struct bit_entry x;
@@ -51,28 +50,28 @@ mxm_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr)
*
* MXM v3.x VBIOS are nicer and provide pointers to these tables.
*/
-static u8 nv84_sor_map[16] = {
+static u8 g84_sor_map[16] = {
0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static u8 nv92_sor_map[16] = {
+static u8 g92_sor_map[16] = {
0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static u8 nv94_sor_map[16] = {
+static u8 g94_sor_map[16] = {
0x00, 0x14, 0x24, 0x11, 0x34, 0x31, 0x11, 0x31,
0x11, 0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static u8 nv98_sor_map[16] = {
+static u8 g98_sor_map[16] = {
0x00, 0x14, 0x12, 0x11, 0x00, 0x31, 0x11, 0x31,
0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
u8
-mxm_sor_map(struct nouveau_bios *bios, u8 conn)
+mxm_sor_map(struct nvkm_bios *bios, u8 conn)
{
u8 ver, hdr;
u16 mxm = mxm_table(bios, &ver, &hdr);
@@ -95,20 +94,20 @@ mxm_sor_map(struct nouveau_bios *bios, u8 conn)
}
if (bios->version.chip == 0x84 || bios->version.chip == 0x86)
- return nv84_sor_map[conn];
+ return g84_sor_map[conn];
if (bios->version.chip == 0x92)
- return nv92_sor_map[conn];
+ return g92_sor_map[conn];
if (bios->version.chip == 0x94 || bios->version.chip == 0x96)
- return nv94_sor_map[conn];
+ return g94_sor_map[conn];
if (bios->version.chip == 0x98)
- return nv98_sor_map[conn];
+ return g98_sor_map[conn];
nv_warn(bios, "missing sor map\n");
return 0x00;
}
u8
-mxm_ddc_map(struct nouveau_bios *bios, u8 port)
+mxm_ddc_map(struct nvkm_bios *bios, u8 port)
{
u8 ver, hdr;
u16 mxm = mxm_table(bios, &ver, &hdr);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/npde.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/npde.c
index d694716a166c..fd7dd718b2bf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/npde.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/npde.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include <subdev/bios.h>
#include <subdev/bios/npde.h>
#include <subdev/bios/pcir.h>
u32
-nvbios_npdeTe(struct nouveau_bios *bios, u32 base)
+nvbios_npdeTe(struct nvkm_bios *bios, u32 base)
{
struct nvbios_pcirT pcir;
u8 ver; u16 hdr;
@@ -47,7 +46,7 @@ nvbios_npdeTe(struct nouveau_bios *bios, u32 base)
}
u32
-nvbios_npdeTp(struct nouveau_bios *bios, u32 base, struct nvbios_npdeT *info)
+nvbios_npdeTp(struct nvkm_bios *bios, u32 base, struct nvbios_npdeT *info)
{
u32 data = nvbios_npdeTe(bios, base);
memset(info, 0x00, sizeof(*info));
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pcir.c
index 91dae26bc50f..df5978753ae8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pcir.c
@@ -21,12 +21,11 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include <subdev/bios.h>
#include <subdev/bios/pcir.h>
u32
-nvbios_pcirTe(struct nouveau_bios *bios, u32 base, u8 *ver, u16 *hdr)
+nvbios_pcirTe(struct nvkm_bios *bios, u32 base, u8 *ver, u16 *hdr)
{
u32 data = nv_ro16(bios, base + 0x18);
if (data) {
@@ -49,7 +48,7 @@ nvbios_pcirTe(struct nouveau_bios *bios, u32 base, u8 *ver, u16 *hdr)
}
u32
-nvbios_pcirTp(struct nouveau_bios *bios, u32 base, u8 *ver, u16 *hdr,
+nvbios_pcirTp(struct nvkm_bios *bios, u32 base, u8 *ver, u16 *hdr,
struct nvbios_pcirT *info)
{
u32 data = nvbios_pcirTe(bios, base, ver, hdr);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
index 675e221680aa..382ae9cdbf58 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/perf.c
@@ -21,13 +21,14 @@
*
* Authors: Martin Peres
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/perf.h>
+#include <core/device.h>
+
u16
-nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
+nvbios_perf_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
struct bit_entry bit_P;
@@ -76,7 +77,7 @@ nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
}
u16
-nvbios_perf_entry(struct nouveau_bios *bios, int idx,
+nvbios_perf_entry(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u8 snr, ssz;
@@ -92,9 +93,8 @@ nvbios_perf_entry(struct nouveau_bios *bios, int idx,
}
u16
-nvbios_perfEp(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_perfE *info)
+nvbios_perfEp(struct nvkm_bios *bios, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_perfE *info)
{
u16 perf = nvbios_perf_entry(bios, idx, ver, hdr, cnt, len);
memset(info, 0x00, sizeof(*info));
@@ -155,7 +155,7 @@ nvbios_perfEp(struct nouveau_bios *bios, int idx,
}
u32
-nvbios_perfSe(struct nouveau_bios *bios, u32 perfE, int idx,
+nvbios_perfSe(struct nvkm_bios *bios, u32 perfE, int idx,
u8 *ver, u8 *hdr, u8 cnt, u8 len)
{
u32 data = 0x00000000;
@@ -167,7 +167,7 @@ nvbios_perfSe(struct nouveau_bios *bios, u32 perfE, int idx,
}
u32
-nvbios_perfSp(struct nouveau_bios *bios, u32 perfE, int idx,
+nvbios_perfSp(struct nvkm_bios *bios, u32 perfE, int idx,
u8 *ver, u8 *hdr, u8 cnt, u8 len,
struct nvbios_perfS *info)
{
@@ -184,7 +184,7 @@ nvbios_perfSp(struct nouveau_bios *bios, u32 perfE, int idx,
}
int
-nvbios_perf_fan_parse(struct nouveau_bios *bios,
+nvbios_perf_fan_parse(struct nvkm_bios *bios,
struct nvbios_perf_fan *fan)
{
u8 ver, hdr, cnt, len, snr, ssz;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c
index 1f76de597d4b..ebd402e19dbf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c
@@ -21,12 +21,13 @@
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
-#include <subdev/vga.h>
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/bmp.h>
#include <subdev/bios/pll.h>
+#include <subdev/vga.h>
+
+#include <core/device.h>
struct pll_mapping {
u8 type;
@@ -66,7 +67,7 @@ nv50_pll_mapping[] = {
};
static struct pll_mapping
-nv84_pll_mapping[] = {
+g84_pll_mapping[] = {
{ PLL_CORE , 0x004028 },
{ PLL_SHADER, 0x004020 },
{ PLL_MEMORY, 0x004008 },
@@ -78,7 +79,7 @@ nv84_pll_mapping[] = {
};
static u16
-pll_limits_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_C;
@@ -109,7 +110,7 @@ pll_limits_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
static struct pll_mapping *
-pll_map(struct nouveau_bios *bios)
+pll_map(struct nvkm_bios *bios)
{
switch (nv_device(bios)->card_type) {
case NV_04:
@@ -128,14 +129,14 @@ pll_map(struct nouveau_bios *bios)
if (nv_device(bios)->chipset < 0xa3 ||
nv_device(bios)->chipset == 0xaa ||
nv_device(bios)->chipset == 0xac)
- return nv84_pll_mapping;
+ return g84_pll_mapping;
default:
return NULL;
}
}
static u16
-pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
+pll_map_reg(struct nvkm_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
{
struct pll_mapping *map;
u8 hdr, cnt;
@@ -177,7 +178,7 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
}
static u16
-pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
+pll_map_type(struct nvkm_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
{
struct pll_mapping *map;
u8 hdr, cnt;
@@ -219,7 +220,7 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
}
int
-nvbios_pll_parse(struct nouveau_bios *bios, u32 type, struct nvbios_pll *info)
+nvbios_pll_parse(struct nvkm_bios *bios, u32 type, struct nvbios_pll *info)
{
u8 ver, len;
u32 reg = type;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c
index 66c56ba07d1b..20c5ce0cd573 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c
@@ -21,14 +21,13 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/image.h>
#include <subdev/bios/pmu.h>
static u32
-weirdo_pointer(struct nouveau_bios *bios, u32 data)
+weirdo_pointer(struct nvkm_bios *bios, u32 data)
{
struct nvbios_image image;
int idx = 0;
@@ -43,7 +42,7 @@ weirdo_pointer(struct nouveau_bios *bios, u32 data)
}
u32
-nvbios_pmuTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+nvbios_pmuTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_p;
u32 data = 0;
@@ -63,7 +62,7 @@ nvbios_pmuTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u32
-nvbios_pmuTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+nvbios_pmuTp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_pmuT *info)
{
u32 data = nvbios_pmuTe(bios, ver, hdr, cnt, len);
@@ -76,7 +75,7 @@ nvbios_pmuTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
}
u32
-nvbios_pmuEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
+nvbios_pmuEe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr)
{
u8 cnt, len;
u32 data = nvbios_pmuTe(bios, ver, hdr, &cnt, &len);
@@ -89,7 +88,7 @@ nvbios_pmuEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
}
u32
-nvbios_pmuEp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
+nvbios_pmuEp(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
struct nvbios_pmuE *info)
{
u32 data = nvbios_pmuEe(bios, idx, ver, hdr);
@@ -104,7 +103,7 @@ nvbios_pmuEp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
}
bool
-nvbios_pmuRm(struct nouveau_bios *bios, u8 type, struct nvbios_pmuR *info)
+nvbios_pmuRm(struct nvkm_bios *bios, u8 type, struct nvbios_pmuR *info)
{
struct nvbios_pmuE pmuE;
u8 ver, hdr, idx = 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
index 187d225bd1e9..95e4fa1531d6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
@@ -1,18 +1,17 @@
#ifndef __NVKM_BIOS_PRIV_H__
#define __NVKM_BIOS_PRIV_H__
-
#include <subdev/bios.h>
struct nvbios_source {
const char *name;
- void *(*init)(struct nouveau_bios *, const char *);
+ void *(*init)(struct nvkm_bios *, const char *);
void (*fini)(void *);
- u32 (*read)(void *, u32 offset, u32 length, struct nouveau_bios *);
+ u32 (*read)(void *, u32 offset, u32 length, struct nvkm_bios *);
bool rw;
};
-int nvbios_extend(struct nouveau_bios *, u32 length);
-int nvbios_shadow(struct nouveau_bios *);
+int nvbios_extend(struct nvkm_bios *, u32 length);
+int nvbios_shadow(struct nvkm_bios *);
extern const struct nvbios_source nvbios_rom;
extern const struct nvbios_source nvbios_ramin;
@@ -21,5 +20,4 @@ extern const struct nvbios_source nvbios_acpi_slow;
extern const struct nvbios_source nvbios_pcirom;
extern const struct nvbios_source nvbios_platform;
extern const struct nvbios_source nvbios_of;
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/ramcfg.c
index 1623c8dfe797..a17b221119b2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/ramcfg.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/ramcfg.h>
#include <subdev/bios/M0203.h>
static u8
-nvbios_ramcfg_strap(struct nouveau_subdev *subdev)
+nvbios_ramcfg_strap(struct nvkm_subdev *subdev)
{
return (nv_rd32(subdev, 0x101000) & 0x0000003c) >> 2;
}
u8
-nvbios_ramcfg_count(struct nouveau_bios *bios)
+nvbios_ramcfg_count(struct nvkm_bios *bios)
{
struct bit_entry bit_M;
@@ -49,9 +48,9 @@ nvbios_ramcfg_count(struct nouveau_bios *bios)
}
u8
-nvbios_ramcfg_index(struct nouveau_subdev *subdev)
+nvbios_ramcfg_index(struct nvkm_subdev *subdev)
{
- struct nouveau_bios *bios = nouveau_bios(subdev);
+ struct nvkm_bios *bios = nvkm_bios(subdev);
u8 strap = nvbios_ramcfg_strap(subdev);
u32 xlat = 0x00000000;
struct bit_entry bit_M;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index c5685228c322..8b17bb4b220c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
-#include <subdev/bios/ramcfg.h>
#include <subdev/bios/rammap.h>
u32
-nvbios_rammapTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
+nvbios_rammapTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
struct bit_entry bit_P;
@@ -59,7 +57,7 @@ nvbios_rammapTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr,
}
u32
-nvbios_rammapEe(struct nouveau_bios *bios, int idx,
+nvbios_rammapEe(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u8 snr, ssz;
@@ -75,9 +73,8 @@ nvbios_rammapEe(struct nouveau_bios *bios, int idx,
}
u32
-nvbios_rammapEp(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ramcfg *p)
+nvbios_rammapEp(struct nvkm_bios *bios, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *p)
{
u32 data = nvbios_rammapEe(bios, idx, ver, hdr, cnt, len), temp;
memset(p, 0x00, sizeof(*p));
@@ -118,9 +115,8 @@ nvbios_rammapEp(struct nouveau_bios *bios, int idx,
}
u32
-nvbios_rammapEm(struct nouveau_bios *bios, u16 mhz,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ramcfg *info)
+nvbios_rammapEm(struct nvkm_bios *bios, u16 mhz,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *info)
{
int idx = 0;
u32 data;
@@ -132,9 +128,8 @@ nvbios_rammapEm(struct nouveau_bios *bios, u16 mhz,
}
u32
-nvbios_rammapSe(struct nouveau_bios *bios, u32 data,
- u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
- u8 *ver, u8 *hdr)
+nvbios_rammapSe(struct nvkm_bios *bios, u32 data,
+ u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx, u8 *ver, u8 *hdr)
{
if (idx < ecnt) {
data = data + ehdr + (idx * elen);
@@ -146,7 +141,7 @@ nvbios_rammapSe(struct nouveau_bios *bios, u32 data,
}
u32
-nvbios_rammapSp(struct nouveau_bios *bios, u32 data,
+nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx,
u8 *ver, u8 *hdr, struct nvbios_ramcfg *p)
{
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
index bb9e0018d936..8c2b7cba5cff 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
@@ -21,13 +21,15 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include "priv.h"
+
+#include <core/device.h>
#include <core/option.h>
+#include <subdev/bios.h>
#include <subdev/bios/image.h>
struct shadow {
- struct nouveau_oclass base;
+ struct nvkm_oclass base;
u32 skip;
const struct nvbios_source *func;
void *data;
@@ -36,7 +38,7 @@ struct shadow {
};
static bool
-shadow_fetch(struct nouveau_bios *bios, u32 upto)
+shadow_fetch(struct nvkm_bios *bios, u32 upto)
{
struct shadow *mthd = (void *)nv_object(bios)->oclass;
const u32 limit = (upto + 3) & ~3;
@@ -50,36 +52,36 @@ shadow_fetch(struct nouveau_bios *bios, u32 upto)
}
static u8
-shadow_rd08(struct nouveau_object *object, u64 addr)
+shadow_rd08(struct nvkm_object *object, u64 addr)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
if (shadow_fetch(bios, addr + 1))
return bios->data[addr];
return 0x00;
}
static u16
-shadow_rd16(struct nouveau_object *object, u64 addr)
+shadow_rd16(struct nvkm_object *object, u64 addr)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
if (shadow_fetch(bios, addr + 2))
return get_unaligned_le16(&bios->data[addr]);
return 0x0000;
}
static u32
-shadow_rd32(struct nouveau_object *object, u64 addr)
+shadow_rd32(struct nvkm_object *object, u64 addr)
{
- struct nouveau_bios *bios = (void *)object;
+ struct nvkm_bios *bios = (void *)object;
if (shadow_fetch(bios, addr + 4))
return get_unaligned_le32(&bios->data[addr]);
return 0x00000000;
}
-static struct nouveau_oclass
+static struct nvkm_oclass
shadow_class = {
.handle = NV_SUBDEV(VBIOS, 0x00),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.rd08 = shadow_rd08,
.rd16 = shadow_rd16,
.rd32 = shadow_rd32,
@@ -87,7 +89,7 @@ shadow_class = {
};
static int
-shadow_image(struct nouveau_bios *bios, int idx, struct shadow *mthd)
+shadow_image(struct nvkm_bios *bios, int idx, struct shadow *mthd)
{
struct nvbios_image image;
int score = 1;
@@ -126,9 +128,9 @@ shadow_image(struct nouveau_bios *bios, int idx, struct shadow *mthd)
}
static int
-shadow_score(struct nouveau_bios *bios, struct shadow *mthd)
+shadow_score(struct nvkm_bios *bios, struct shadow *mthd)
{
- struct nouveau_oclass *oclass = nv_object(bios)->oclass;
+ struct nvkm_oclass *oclass = nv_object(bios)->oclass;
int score;
nv_object(bios)->oclass = &mthd->base;
score = shadow_image(bios, 0, mthd);
@@ -138,7 +140,7 @@ shadow_score(struct nouveau_bios *bios, struct shadow *mthd)
}
static int
-shadow_method(struct nouveau_bios *bios, struct shadow *mthd, const char *name)
+shadow_method(struct nvkm_bios *bios, struct shadow *mthd, const char *name)
{
const struct nvbios_source *func = mthd->func;
if (func->name) {
@@ -163,7 +165,7 @@ shadow_method(struct nouveau_bios *bios, struct shadow *mthd, const char *name)
}
static u32
-shadow_fw_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
+shadow_fw_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
const struct firmware *fw = data;
if (offset + length <= fw->size) {
@@ -174,7 +176,7 @@ shadow_fw_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
}
static void *
-shadow_fw_init(struct nouveau_bios *bios, const char *name)
+shadow_fw_init(struct nvkm_bios *bios, const char *name)
{
struct device *dev = &nv_device(bios)->pdev->dev;
const struct firmware *fw;
@@ -194,7 +196,7 @@ shadow_fw = {
};
int
-nvbios_shadow(struct nouveau_bios *bios)
+nvbios_shadow(struct nvkm_bios *bios)
{
struct shadow mthds[] = {
{ shadow_class, 0, &nvbios_of },
@@ -211,7 +213,7 @@ nvbios_shadow(struct nouveau_bios *bios)
int optlen;
/* handle user-specified bios source */
- optarg = nouveau_stropt(nv_device(bios)->cfgopt, "NvBios", &optlen);
+ optarg = nvkm_stropt(nv_device(bios)->cfgopt, "NvBios", &optlen);
source = optarg ? kstrndup(optarg, optlen, GFP_KERNEL) : NULL;
if (source) {
/* try to match one of the built-in methods */
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
index bc130c12ec06..1fbd93bbb561 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
@@ -20,9 +20,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "priv.h"
+#include <core/device.h>
+
#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
@@ -45,7 +46,7 @@ nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
* on some systems, such as Lenovo W530.
*/
static u32
-acpi_read_fast(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
+acpi_read_fast(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
u32 limit = (offset + length + 0xfff) & ~0xfff;
u32 start = offset & ~0x00000fff;
@@ -66,7 +67,7 @@ acpi_read_fast(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
* function.
*/
static u32
-acpi_read_slow(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
+acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
u32 limit = (offset + length + 0xfff) & ~0xfff;
u32 start = offset & ~0xfff;
@@ -87,7 +88,7 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
}
static void *
-acpi_init(struct nouveau_bios *bios, const char *name)
+acpi_init(struct nvkm_bios *bios, const char *name)
{
if (!nouveau_acpi_rom_supported(nv_device(bios)->pdev))
return ERR_PTR(-ENODEV);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c
index 3abe487a6025..4c19a7dba803 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c
@@ -20,9 +20,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "priv.h"
+#include <core/device.h>
+
#if defined(__powerpc__)
struct priv {
const void __iomem *data;
@@ -30,7 +31,7 @@ struct priv {
};
static u32
-of_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
+of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
struct priv *priv = data;
if (offset + length <= priv->size) {
@@ -41,7 +42,7 @@ of_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
}
static void *
-of_init(struct nouveau_bios *bios, const char *name)
+of_init(struct nvkm_bios *bios, const char *name)
{
struct pci_dev *pdev = nv_device(bios)->pdev;
struct device_node *dn;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
index 1d0389c0abef..1b045483dc87 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
@@ -20,9 +20,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "priv.h"
+#include <core/device.h>
+
struct priv {
struct pci_dev *pdev;
void __iomem *rom;
@@ -30,7 +31,7 @@ struct priv {
};
static u32
-pcirom_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
+pcirom_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
struct priv *priv = data;
if (offset + length <= priv->size) {
@@ -50,7 +51,7 @@ pcirom_fini(void *data)
}
static void *
-pcirom_init(struct nouveau_bios *bios, const char *name)
+pcirom_init(struct nvkm_bios *bios, const char *name)
{
struct pci_dev *pdev = nv_device(bios)->pdev;
struct priv *priv = NULL;
@@ -82,7 +83,7 @@ nvbios_pcirom = {
};
static void *
-platform_init(struct nouveau_bios *bios, const char *name)
+platform_init(struct nvkm_bios *bios, const char *name)
{
struct pci_dev *pdev = nv_device(bios)->pdev;
struct priv *priv;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c
index a7a890fad1e5..abe8ae4d3a9f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c
@@ -20,16 +20,17 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "priv.h"
+#include <core/device.h>
+
struct priv {
- struct nouveau_bios *bios;
+ struct nvkm_bios *bios;
u32 bar0;
};
static u32
-pramin_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
+pramin_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
u32 i;
if (offset + length <= 0x00100000) {
@@ -51,7 +52,7 @@ pramin_fini(void *data)
}
static void *
-pramin_init(struct nouveau_bios *bios, const char *name)
+pramin_init(struct nvkm_bios *bios, const char *name)
{
struct priv *priv = NULL;
u64 addr = 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowrom.c
index b7992bc3ffa5..6ec3b237925e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowrom.c
@@ -20,11 +20,12 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "priv.h"
+#include <core/device.h>
+
static u32
-prom_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
+prom_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
{
u32 i;
if (offset + length <= 0x00100000) {
@@ -38,7 +39,7 @@ prom_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
static void
prom_fini(void *data)
{
- struct nouveau_bios *bios = data;
+ struct nvkm_bios *bios = data;
if (nv_device(bios)->card_type < NV_50)
nv_mask(bios, 0x001850, 0x00000001, 0x00000001);
else
@@ -46,7 +47,7 @@ prom_fini(void *data)
}
static void *
-prom_init(struct nouveau_bios *bios, const char *name)
+prom_init(struct nvkm_bios *bios, const char *name)
{
if (nv_device(bios)->card_type < NV_50) {
if (nv_device(bios)->card_type == NV_40 &&
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/therm.c
index d15854094078..249ff6d583df 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/therm.c
@@ -21,13 +21,14 @@
*
* Authors: Martin Peres
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/therm.h>
+#include <core/device.h>
+
static u16
-therm_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
+therm_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
{
struct bit_entry bit_P;
u16 therm = 0;
@@ -51,12 +52,11 @@ therm_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
*hdr = nv_ro08(bios, therm + 1);
*len = nv_ro08(bios, therm + 2);
*cnt = nv_ro08(bios, therm + 3);
-
return therm + nv_ro08(bios, therm + 1);
}
static u16
-nvbios_therm_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+nvbios_therm_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len)
{
u8 hdr, cnt;
u16 therm = therm_table(bios, ver, &hdr, len, &cnt);
@@ -66,7 +66,7 @@ nvbios_therm_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
}
int
-nvbios_therm_sensor_parse(struct nouveau_bios *bios,
+nvbios_therm_sensor_parse(struct nvkm_bios *bios,
enum nvbios_therm_domain domain,
struct nvbios_therm_sensor *sensor)
{
@@ -152,10 +152,9 @@ nvbios_therm_sensor_parse(struct nouveau_bios *bios,
}
int
-nvbios_therm_fan_parse(struct nouveau_bios *bios,
- struct nvbios_therm_fan *fan)
+nvbios_therm_fan_parse(struct nvkm_bios *bios, struct nvbios_therm_fan *fan)
{
- struct nouveau_therm_trip_point *cur_trip = NULL;
+ struct nvbios_therm_trip_point *cur_trip = NULL;
u8 ver, len, i;
u16 entry;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
index 8521eca1ed9c..763fd29a58f2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/timing.c
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
-#include <subdev/bios/ramcfg.h>
#include <subdev/bios/timing.h>
u16
-nvbios_timingTe(struct nouveau_bios *bios,
+nvbios_timingTe(struct nvkm_bios *bios,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz)
{
struct bit_entry bit_P;
@@ -68,7 +66,7 @@ nvbios_timingTe(struct nouveau_bios *bios,
}
u16
-nvbios_timingEe(struct nouveau_bios *bios, int idx,
+nvbios_timingEe(struct nvkm_bios *bios, int idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u8 snr, ssz;
@@ -84,9 +82,8 @@ nvbios_timingEe(struct nouveau_bios *bios, int idx,
}
u16
-nvbios_timingEp(struct nouveau_bios *bios, int idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_ramcfg *p)
+nvbios_timingEp(struct nvkm_bios *bios, int idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *p)
{
u16 data = nvbios_timingEe(bios, idx, ver, hdr, cnt, len), temp;
p->timing_ver = *ver;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/vmap.c
index f343a1b060e8..e95b69faa82e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/vmap.c
@@ -21,13 +21,12 @@
*
* Authors: Martin Peres
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/vmap.h>
u16
-nvbios_vmap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+nvbios_vmap_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_P;
u16 vmap = 0x0000;
@@ -55,7 +54,7 @@ nvbios_vmap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u16
-nvbios_vmap_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+nvbios_vmap_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_vmap *info)
{
u16 vmap = nvbios_vmap_table(bios, ver, hdr, cnt, len);
@@ -69,7 +68,7 @@ nvbios_vmap_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
}
u16
-nvbios_vmap_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+nvbios_vmap_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len)
{
u8 hdr, cnt;
u16 vmap = nvbios_vmap_table(bios, ver, &hdr, &cnt, len);
@@ -81,7 +80,7 @@ nvbios_vmap_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
}
u16
-nvbios_vmap_entry_parse(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len,
+nvbios_vmap_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
struct nvbios_vmap_entry *info)
{
u16 vmap = nvbios_vmap_entry(bios, idx, ver, len);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c
index bb590de4ecb2..8454ab7c4a3d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c
@@ -21,13 +21,12 @@
*
* Authors: Martin Peres
*/
-
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/volt.h>
u16
-nvbios_volt_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+nvbios_volt_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_P;
u16 volt = 0x0000;
@@ -67,7 +66,7 @@ nvbios_volt_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u16
-nvbios_volt_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
+nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_volt *info)
{
u16 volt = nvbios_volt_table(bios, ver, hdr, cnt, len);
@@ -102,7 +101,7 @@ nvbios_volt_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
}
u16
-nvbios_volt_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+nvbios_volt_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len)
{
u8 hdr, cnt;
u16 volt = nvbios_volt_table(bios, ver, &hdr, &cnt, len);
@@ -114,7 +113,7 @@ nvbios_volt_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
}
u16
-nvbios_volt_entry_parse(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len,
+nvbios_volt_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len,
struct nvbios_volt_entry *info)
{
u16 volt = nvbios_volt_entry(bios, idx, ver, len);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/xpio.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/xpio.c
index e9b8e5d30a7a..63a5e1b5cb3c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/xpio.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/xpio.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/bios.h>
#include <subdev/bios/gpio.h>
#include <subdev/bios/xpio.h>
static u16
-dcb_xpiod_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
+dcb_xpiod_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u16 data = dcb_gpio_table(bios, ver, hdr, cnt, len);
if (data && *ver >= 0x40 && *hdr >= 0x06) {
@@ -44,7 +43,7 @@ dcb_xpiod_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
u16
-dcb_xpio_table(struct nouveau_bios *bios, u8 idx,
+dcb_xpio_table(struct nvkm_bios *bios, u8 idx,
u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
u16 data = dcb_xpiod_table(bios, ver, hdr, cnt, len);
@@ -62,9 +61,8 @@ dcb_xpio_table(struct nouveau_bios *bios, u8 idx,
}
u16
-dcb_xpio_parse(struct nouveau_bios *bios, u8 idx,
- u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
- struct nvbios_xpio *info)
+dcb_xpio_parse(struct nvkm_bios *bios, u8 idx,
+ u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_xpio *info)
{
u16 data = dcb_xpio_table(bios, idx, ver, hdr, cnt, len);
if (data && *len >= 6) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/Kbuild
new file mode 100644
index 000000000000..83d80b13f149
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/Kbuild
@@ -0,0 +1,6 @@
+nvkm-y += nvkm/subdev/bus/hwsq.o
+nvkm-y += nvkm/subdev/bus/nv04.o
+nvkm-y += nvkm/subdev/bus/nv31.o
+nvkm-y += nvkm/subdev/bus/nv50.o
+nvkm-y += nvkm/subdev/bus/g94.o
+nvkm-y += nvkm/subdev/bus/gf100.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/g94.c
index d3659055fa4b..cbe699e82593 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/g94.c
@@ -22,13 +22,12 @@
* Authors: Martin Peres <martin.peres@labri.fr>
* Ben Skeggs
*/
+#include "nv04.h"
#include <subdev/timer.h>
-#include "nv04.h"
-
static int
-nv94_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size)
+g94_bus_hwsq_exec(struct nvkm_bus *pbus, u32 *data, u32 size)
{
struct nv50_bus_priv *priv = (void *)pbus;
int i;
@@ -44,16 +43,16 @@ nv94_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size)
return nv_wait(pbus, 0x001308, 0x00000100, 0x00000000) ? 0 : -ETIMEDOUT;
}
-struct nouveau_oclass *
-nv94_bus_oclass = &(struct nv04_bus_impl) {
+struct nvkm_oclass *
+g94_bus_oclass = &(struct nv04_bus_impl) {
.base.handle = NV_SUBDEV(BUS, 0x94),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_bus_ctor,
- .dtor = _nouveau_bus_dtor,
+ .dtor = _nvkm_bus_dtor,
.init = nv50_bus_init,
- .fini = _nouveau_bus_fini,
+ .fini = _nvkm_bus_fini,
},
.intr = nv50_bus_intr,
- .hwsq_exec = nv94_bus_hwsq_exec,
+ .hwsq_exec = g94_bus_hwsq_exec,
.hwsq_size = 128,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/gf100.c
index 73839d7151a7..ebc63ba968d4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/gf100.c
@@ -22,13 +22,12 @@
* Authors: Martin Peres <martin.peres@labri.fr>
* Ben Skeggs
*/
-
#include "nv04.h"
static void
-nvc0_bus_intr(struct nouveau_subdev *subdev)
+gf100_bus_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_bus *pbus = nouveau_bus(subdev);
+ struct nvkm_bus *pbus = nvkm_bus(subdev);
u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140);
if (stat & 0x0000000e) {
@@ -54,12 +53,12 @@ nvc0_bus_intr(struct nouveau_subdev *subdev)
}
static int
-nvc0_bus_init(struct nouveau_object *object)
+gf100_bus_init(struct nvkm_object *object)
{
struct nv04_bus_priv *priv = (void *)object;
int ret;
- ret = nouveau_bus_init(&priv->base);
+ ret = nvkm_bus_init(&priv->base);
if (ret)
return ret;
@@ -68,14 +67,14 @@ nvc0_bus_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
-nvc0_bus_oclass = &(struct nv04_bus_impl) {
+struct nvkm_oclass *
+gf100_bus_oclass = &(struct nv04_bus_impl) {
.base.handle = NV_SUBDEV(BUS, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_bus_ctor,
- .dtor = _nouveau_bus_dtor,
- .init = nvc0_bus_init,
- .fini = _nouveau_bus_fini,
+ .dtor = _nvkm_bus_dtor,
+ .init = gf100_bus_init,
+ .fini = _nvkm_bus_fini,
},
- .intr = nvc0_bus_intr,
+ .intr = gf100_bus_intr,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
index f757470e2284..b8853bf16b23 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
@@ -21,12 +21,10 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include <subdev/timer.h>
#include <subdev/bus.h>
-struct nouveau_hwsq {
- struct nouveau_bus *pbus;
+struct nvkm_hwsq {
+ struct nvkm_bus *pbus;
u32 addr;
u32 data;
struct {
@@ -36,16 +34,16 @@ struct nouveau_hwsq {
};
static void
-hwsq_cmd(struct nouveau_hwsq *hwsq, int size, u8 data[])
+hwsq_cmd(struct nvkm_hwsq *hwsq, int size, u8 data[])
{
memcpy(&hwsq->c.data[hwsq->c.size], data, size * sizeof(data[0]));
hwsq->c.size += size;
}
int
-nouveau_hwsq_init(struct nouveau_bus *pbus, struct nouveau_hwsq **phwsq)
+nvkm_hwsq_init(struct nvkm_bus *pbus, struct nvkm_hwsq **phwsq)
{
- struct nouveau_hwsq *hwsq;
+ struct nvkm_hwsq *hwsq;
hwsq = *phwsq = kmalloc(sizeof(*hwsq), GFP_KERNEL);
if (hwsq) {
@@ -60,12 +58,12 @@ nouveau_hwsq_init(struct nouveau_bus *pbus, struct nouveau_hwsq **phwsq)
}
int
-nouveau_hwsq_fini(struct nouveau_hwsq **phwsq, bool exec)
+nvkm_hwsq_fini(struct nvkm_hwsq **phwsq, bool exec)
{
- struct nouveau_hwsq *hwsq = *phwsq;
+ struct nvkm_hwsq *hwsq = *phwsq;
int ret = 0, i;
if (hwsq) {
- struct nouveau_bus *pbus = hwsq->pbus;
+ struct nvkm_bus *pbus = hwsq->pbus;
hwsq->c.size = (hwsq->c.size + 4) / 4;
if (hwsq->c.size <= pbus->hwsq_size) {
if (exec)
@@ -88,7 +86,7 @@ nouveau_hwsq_fini(struct nouveau_hwsq **phwsq, bool exec)
}
void
-nouveau_hwsq_wr32(struct nouveau_hwsq *hwsq, u32 addr, u32 data)
+nvkm_hwsq_wr32(struct nvkm_hwsq *hwsq, u32 addr, u32 data)
{
nv_debug(hwsq->pbus, "R[%06x] = 0x%08x\n", addr, data);
@@ -113,7 +111,7 @@ nouveau_hwsq_wr32(struct nouveau_hwsq *hwsq, u32 addr, u32 data)
}
void
-nouveau_hwsq_setf(struct nouveau_hwsq *hwsq, u8 flag, int data)
+nvkm_hwsq_setf(struct nvkm_hwsq *hwsq, u8 flag, int data)
{
nv_debug(hwsq->pbus, " FLAG[%02x] = %d\n", flag, data);
flag += 0x80;
@@ -125,14 +123,14 @@ nouveau_hwsq_setf(struct nouveau_hwsq *hwsq, u8 flag, int data)
}
void
-nouveau_hwsq_wait(struct nouveau_hwsq *hwsq, u8 flag, u8 data)
+nvkm_hwsq_wait(struct nvkm_hwsq *hwsq, u8 flag, u8 data)
{
nv_debug(hwsq->pbus, " WAIT[%02x] = %d\n", flag, data);
hwsq_cmd(hwsq, 3, (u8[]){ 0x5f, flag, data });
}
void
-nouveau_hwsq_nsec(struct nouveau_hwsq *hwsq, u32 nsec)
+nvkm_hwsq_nsec(struct nvkm_hwsq *hwsq, u32 nsec)
{
u8 shift = 0, usec = nsec / 1000;
while (usec & ~3) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
index 12176f9c1bc6..3394a5ea8a9f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
@@ -1,11 +1,10 @@
#ifndef __NVKM_BUS_HWSQ_H__
#define __NVKM_BUS_HWSQ_H__
-
#include <subdev/bus.h>
struct hwsq {
- struct nouveau_subdev *subdev;
- struct nouveau_hwsq *hwsq;
+ struct nvkm_subdev *subdev;
+ struct nvkm_hwsq *hwsq;
int sequence;
};
@@ -34,12 +33,12 @@ hwsq_reg(u32 addr)
}
static inline int
-hwsq_init(struct hwsq *ram, struct nouveau_subdev *subdev)
+hwsq_init(struct hwsq *ram, struct nvkm_subdev *subdev)
{
- struct nouveau_bus *pbus = nouveau_bus(subdev);
+ struct nvkm_bus *pbus = nvkm_bus(subdev);
int ret;
- ret = nouveau_hwsq_init(pbus, &ram->hwsq);
+ ret = nvkm_hwsq_init(pbus, &ram->hwsq);
if (ret)
return ret;
@@ -53,7 +52,7 @@ hwsq_exec(struct hwsq *ram, bool exec)
{
int ret = 0;
if (ram->subdev) {
- ret = nouveau_hwsq_fini(&ram->hwsq, exec);
+ ret = nvkm_hwsq_fini(&ram->hwsq, exec);
ram->subdev = NULL;
}
return ret;
@@ -73,8 +72,8 @@ hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data)
reg->sequence = ram->sequence;
reg->data = data;
if (reg->addr[0] != reg->addr[1])
- nouveau_hwsq_wr32(ram->hwsq, reg->addr[1], reg->data);
- nouveau_hwsq_wr32(ram->hwsq, reg->addr[0], reg->data);
+ nvkm_hwsq_wr32(ram->hwsq, reg->addr[1], reg->data);
+ nvkm_hwsq_wr32(ram->hwsq, reg->addr[0], reg->data);
}
static inline void
@@ -95,19 +94,18 @@ hwsq_mask(struct hwsq *ram, struct hwsq_reg *reg, u32 mask, u32 data)
static inline void
hwsq_setf(struct hwsq *ram, u8 flag, int data)
{
- nouveau_hwsq_setf(ram->hwsq, flag, data);
+ nvkm_hwsq_setf(ram->hwsq, flag, data);
}
static inline void
hwsq_wait(struct hwsq *ram, u8 flag, u8 data)
{
- nouveau_hwsq_wait(ram->hwsq, flag, data);
+ nvkm_hwsq_wait(ram->hwsq, flag, data);
}
static inline void
hwsq_nsec(struct hwsq *ram, u32 nsec)
{
- nouveau_hwsq_nsec(ram->hwsq, nsec);
+ nvkm_hwsq_nsec(ram->hwsq, nsec);
}
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.c
index 23921b5351db..19c8e50eeff7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.c
@@ -22,13 +22,12 @@
* Authors: Martin Peres <martin.peres@labri.fr>
* Ben Skeggs
*/
-
#include "nv04.h"
static void
-nv04_bus_intr(struct nouveau_subdev *subdev)
+nv04_bus_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_bus *pbus = nouveau_bus(subdev);
+ struct nvkm_bus *pbus = nvkm_bus(subdev);
u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140);
if (stat & 0x00000001) {
@@ -38,7 +37,7 @@ nv04_bus_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x00000110) {
- subdev = nouveau_subdev(subdev, NVDEV_SUBDEV_GPIO);
+ subdev = nvkm_subdev(subdev, NVDEV_SUBDEV_GPIO);
if (subdev && subdev->intr)
subdev->intr(subdev);
stat &= ~0x00000110;
@@ -52,26 +51,26 @@ nv04_bus_intr(struct nouveau_subdev *subdev)
}
static int
-nv04_bus_init(struct nouveau_object *object)
+nv04_bus_init(struct nvkm_object *object)
{
struct nv04_bus_priv *priv = (void *)object;
nv_wr32(priv, 0x001100, 0xffffffff);
nv_wr32(priv, 0x001140, 0x00000111);
- return nouveau_bus_init(&priv->base);
+ return nvkm_bus_init(&priv->base);
}
int
-nv04_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_bus_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_bus_impl *impl = (void *)oclass;
struct nv04_bus_priv *priv;
int ret;
- ret = nouveau_bus_create(parent, engine, oclass, &priv);
+ ret = nvkm_bus_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -82,14 +81,14 @@ nv04_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv04_bus_oclass = &(struct nv04_bus_impl) {
.base.handle = NV_SUBDEV(BUS, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_bus_ctor,
- .dtor = _nouveau_bus_dtor,
+ .dtor = _nvkm_bus_dtor,
.init = nv04_bus_init,
- .fini = _nouveau_bus_fini,
+ .fini = _nvkm_bus_fini,
},
.intr = nv04_bus_intr,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.h
new file mode 100644
index 000000000000..3ddc8f91b1e3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.h
@@ -0,0 +1,21 @@
+#ifndef __NVKM_BUS_NV04_H__
+#define __NVKM_BUS_NV04_H__
+#include <subdev/bus.h>
+
+struct nv04_bus_priv {
+ struct nvkm_bus base;
+};
+
+int nv04_bus_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+int nv50_bus_init(struct nvkm_object *);
+void nv50_bus_intr(struct nvkm_subdev *);
+
+struct nv04_bus_impl {
+ struct nvkm_oclass base;
+ void (*intr)(struct nvkm_subdev *);
+ int (*hwsq_exec)(struct nvkm_bus *, u32 *, u32);
+ u32 hwsq_size;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv31.c
index 94da46f61627..c5739bce8052 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv31.c
@@ -22,18 +22,17 @@
* Authors: Martin Peres <martin.peres@labri.fr>
* Ben Skeggs
*/
-
#include "nv04.h"
static void
-nv31_bus_intr(struct nouveau_subdev *subdev)
+nv31_bus_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_bus *pbus = nouveau_bus(subdev);
+ struct nvkm_bus *pbus = nvkm_bus(subdev);
u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140);
u32 gpio = nv_rd32(pbus, 0x001104) & nv_rd32(pbus, 0x001144);
if (gpio) {
- subdev = nouveau_subdev(pbus, NVDEV_SUBDEV_GPIO);
+ subdev = nvkm_subdev(pbus, NVDEV_SUBDEV_GPIO);
if (subdev && subdev->intr)
subdev->intr(subdev);
}
@@ -51,7 +50,7 @@ nv31_bus_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x00070000) {
- subdev = nouveau_subdev(pbus, NVDEV_SUBDEV_THERM);
+ subdev = nvkm_subdev(pbus, NVDEV_SUBDEV_THERM);
if (subdev && subdev->intr)
subdev->intr(subdev);
stat &= ~0x00070000;
@@ -65,12 +64,12 @@ nv31_bus_intr(struct nouveau_subdev *subdev)
}
static int
-nv31_bus_init(struct nouveau_object *object)
+nv31_bus_init(struct nvkm_object *object)
{
struct nv04_bus_priv *priv = (void *)object;
int ret;
- ret = nouveau_bus_init(&priv->base);
+ ret = nvkm_bus_init(&priv->base);
if (ret)
return ret;
@@ -79,14 +78,14 @@ nv31_bus_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv31_bus_oclass = &(struct nv04_bus_impl) {
.base.handle = NV_SUBDEV(BUS, 0x31),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_bus_ctor,
- .dtor = _nouveau_bus_dtor,
+ .dtor = _nvkm_bus_dtor,
.init = nv31_bus_init,
- .fini = _nouveau_bus_fini,
+ .fini = _nvkm_bus_fini,
},
.intr = nv31_bus_intr,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv50.c
index 11918f7e2aca..1987863d71ee 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv50.c
@@ -22,13 +22,12 @@
* Authors: Martin Peres <martin.peres@labri.fr>
* Ben Skeggs
*/
+#include "nv04.h"
#include <subdev/timer.h>
-#include "nv04.h"
-
static int
-nv50_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size)
+nv50_bus_hwsq_exec(struct nvkm_bus *pbus, u32 *data, u32 size)
{
struct nv50_bus_priv *priv = (void *)pbus;
int i;
@@ -44,9 +43,9 @@ nv50_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size)
}
void
-nv50_bus_intr(struct nouveau_subdev *subdev)
+nv50_bus_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_bus *pbus = nouveau_bus(subdev);
+ struct nvkm_bus *pbus = nvkm_bus(subdev);
u32 stat = nv_rd32(pbus, 0x001100) & nv_rd32(pbus, 0x001140);
if (stat & 0x00000008) {
@@ -62,7 +61,7 @@ nv50_bus_intr(struct nouveau_subdev *subdev)
}
if (stat & 0x00010000) {
- subdev = nouveau_subdev(pbus, NVDEV_SUBDEV_THERM);
+ subdev = nvkm_subdev(pbus, NVDEV_SUBDEV_THERM);
if (subdev && subdev->intr)
subdev->intr(subdev);
stat &= ~0x00010000;
@@ -76,12 +75,12 @@ nv50_bus_intr(struct nouveau_subdev *subdev)
}
int
-nv50_bus_init(struct nouveau_object *object)
+nv50_bus_init(struct nvkm_object *object)
{
struct nv04_bus_priv *priv = (void *)object;
int ret;
- ret = nouveau_bus_init(&priv->base);
+ ret = nvkm_bus_init(&priv->base);
if (ret)
return ret;
@@ -90,14 +89,14 @@ nv50_bus_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv50_bus_oclass = &(struct nv04_bus_impl) {
.base.handle = NV_SUBDEV(BUS, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_bus_ctor,
- .dtor = _nouveau_bus_dtor,
+ .dtor = _nvkm_bus_dtor,
.init = nv50_bus_init,
- .fini = _nouveau_bus_fini,
+ .fini = _nvkm_bus_fini,
},
.intr = nv50_bus_intr,
.hwsq_exec = nv50_bus_hwsq_exec,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild
new file mode 100644
index 000000000000..9c2f688c9602
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild
@@ -0,0 +1,12 @@
+nvkm-y += nvkm/subdev/clk/base.o
+nvkm-y += nvkm/subdev/clk/nv04.o
+nvkm-y += nvkm/subdev/clk/nv40.o
+nvkm-y += nvkm/subdev/clk/nv50.o
+nvkm-y += nvkm/subdev/clk/g84.o
+nvkm-y += nvkm/subdev/clk/gt215.o
+nvkm-y += nvkm/subdev/clk/mcp77.o
+nvkm-y += nvkm/subdev/clk/gf100.o
+nvkm-y += nvkm/subdev/clk/gk104.o
+nvkm-y += nvkm/subdev/clk/gk20a.o
+nvkm-y += nvkm/subdev/clk/pllnv04.o
+nvkm-y += nvkm/subdev/clk/pllgt215.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index e51b72d47129..b24a9cc04b73 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -21,27 +21,26 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/option.h>
-
-#include <subdev/clock.h>
-#include <subdev/therm.h>
-#include <subdev/volt.h>
-#include <subdev/fb.h>
-
+#include <subdev/clk.h>
#include <subdev/bios.h>
#include <subdev/bios/boost.h>
#include <subdev/bios/cstep.h>
#include <subdev/bios/perf.h>
+#include <subdev/fb.h>
+#include <subdev/therm.h>
+#include <subdev/volt.h>
+
+#include <core/device.h>
+#include <core/option.h>
/******************************************************************************
* misc
*****************************************************************************/
static u32
-nouveau_clock_adjust(struct nouveau_clock *clk, bool adjust,
- u8 pstate, u8 domain, u32 input)
+nvkm_clk_adjust(struct nvkm_clk *clk, bool adjust,
+ u8 pstate, u8 domain, u32 input)
{
- struct nouveau_bios *bios = nouveau_bios(clk);
+ struct nvkm_bios *bios = nvkm_bios(clk);
struct nvbios_boostE boostE;
u8 ver, hdr, cnt, len;
u16 data;
@@ -76,12 +75,11 @@ nouveau_clock_adjust(struct nouveau_clock *clk, bool adjust,
* C-States
*****************************************************************************/
static int
-nouveau_cstate_prog(struct nouveau_clock *clk,
- struct nouveau_pstate *pstate, int cstatei)
+nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
{
- struct nouveau_therm *ptherm = nouveau_therm(clk);
- struct nouveau_volt *volt = nouveau_volt(clk);
- struct nouveau_cstate *cstate;
+ struct nvkm_therm *ptherm = nvkm_therm(clk);
+ struct nvkm_volt *volt = nvkm_volt(clk);
+ struct nvkm_cstate *cstate;
int ret;
if (!list_empty(&pstate->list)) {
@@ -91,7 +89,7 @@ nouveau_cstate_prog(struct nouveau_clock *clk,
}
if (ptherm) {
- ret = nouveau_therm_cstate(ptherm, pstate->fanspeed, +1);
+ ret = nvkm_therm_cstate(ptherm, pstate->fanspeed, +1);
if (ret && ret != -ENODEV) {
nv_error(clk, "failed to raise fan speed: %d\n", ret);
return ret;
@@ -119,7 +117,7 @@ nouveau_cstate_prog(struct nouveau_clock *clk,
}
if (ptherm) {
- ret = nouveau_therm_cstate(ptherm, pstate->fanspeed, -1);
+ ret = nvkm_therm_cstate(ptherm, pstate->fanspeed, -1);
if (ret && ret != -ENODEV)
nv_error(clk, "failed to lower fan speed: %d\n", ret);
}
@@ -128,19 +126,18 @@ nouveau_cstate_prog(struct nouveau_clock *clk,
}
static void
-nouveau_cstate_del(struct nouveau_cstate *cstate)
+nvkm_cstate_del(struct nvkm_cstate *cstate)
{
list_del(&cstate->head);
kfree(cstate);
}
static int
-nouveau_cstate_new(struct nouveau_clock *clk, int idx,
- struct nouveau_pstate *pstate)
+nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate)
{
- struct nouveau_bios *bios = nouveau_bios(clk);
- struct nouveau_clocks *domain = clk->domains;
- struct nouveau_cstate *cstate = NULL;
+ struct nvkm_bios *bios = nvkm_bios(clk);
+ struct nvkm_domain *domain = clk->domains;
+ struct nvkm_cstate *cstate = NULL;
struct nvbios_cstepX cstepX;
u8 ver, hdr;
u16 data;
@@ -158,10 +155,8 @@ nouveau_cstate_new(struct nouveau_clock *clk, int idx,
while (domain && domain->name != nv_clk_src_max) {
if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) {
- u32 freq = nouveau_clock_adjust(clk, true,
- pstate->pstate,
- domain->bios,
- cstepX.freq);
+ u32 freq = nvkm_clk_adjust(clk, true, pstate->pstate,
+ domain->bios, cstepX.freq);
cstate->domain[domain->name] = freq;
}
domain++;
@@ -175,10 +170,10 @@ nouveau_cstate_new(struct nouveau_clock *clk, int idx,
* P-States
*****************************************************************************/
static int
-nouveau_pstate_prog(struct nouveau_clock *clk, int pstatei)
+nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
{
- struct nouveau_fb *pfb = nouveau_fb(clk);
- struct nouveau_pstate *pstate;
+ struct nvkm_fb *pfb = nvkm_fb(clk);
+ struct nvkm_pstate *pstate;
int ret, idx = 0;
list_for_each_entry(pstate, &clk->states, head) {
@@ -199,13 +194,13 @@ nouveau_pstate_prog(struct nouveau_clock *clk, int pstatei)
pfb->ram->tidy(pfb);
}
- return nouveau_cstate_prog(clk, pstate, 0);
+ return nvkm_cstate_prog(clk, pstate, 0);
}
static void
-nouveau_pstate_work(struct work_struct *work)
+nvkm_pstate_work(struct work_struct *work)
{
- struct nouveau_clock *clk = container_of(work, typeof(*clk), work);
+ struct nvkm_clk *clk = container_of(work, typeof(*clk), work);
int pstate;
if (!atomic_xchg(&clk->waiting, 0))
@@ -227,7 +222,7 @@ nouveau_pstate_work(struct work_struct *work)
nv_trace(clk, "-> %d\n", pstate);
if (pstate != clk->pstate) {
- int ret = nouveau_pstate_prog(clk, pstate);
+ int ret = nvkm_pstate_prog(clk, pstate);
if (ret) {
nv_error(clk, "error setting pstate %d: %d\n",
pstate, ret);
@@ -239,7 +234,7 @@ nouveau_pstate_work(struct work_struct *work)
}
static int
-nouveau_pstate_calc(struct nouveau_clock *clk, bool wait)
+nvkm_pstate_calc(struct nvkm_clk *clk, bool wait)
{
atomic_set(&clk->waiting, 1);
schedule_work(&clk->work);
@@ -249,10 +244,10 @@ nouveau_pstate_calc(struct nouveau_clock *clk, bool wait)
}
static void
-nouveau_pstate_info(struct nouveau_clock *clk, struct nouveau_pstate *pstate)
+nvkm_pstate_info(struct nvkm_clk *clk, struct nvkm_pstate *pstate)
{
- struct nouveau_clocks *clock = clk->domains - 1;
- struct nouveau_cstate *cstate;
+ struct nvkm_domain *clock = clk->domains - 1;
+ struct nvkm_cstate *cstate;
char info[3][32] = { "", "", "" };
char name[4] = "--";
int i = -1;
@@ -291,12 +286,12 @@ nouveau_pstate_info(struct nouveau_clock *clk, struct nouveau_pstate *pstate)
}
static void
-nouveau_pstate_del(struct nouveau_pstate *pstate)
+nvkm_pstate_del(struct nvkm_pstate *pstate)
{
- struct nouveau_cstate *cstate, *temp;
+ struct nvkm_cstate *cstate, *temp;
list_for_each_entry_safe(cstate, temp, &pstate->list, head) {
- nouveau_cstate_del(cstate);
+ nvkm_cstate_del(cstate);
}
list_del(&pstate->head);
@@ -304,12 +299,12 @@ nouveau_pstate_del(struct nouveau_pstate *pstate)
}
static int
-nouveau_pstate_new(struct nouveau_clock *clk, int idx)
+nvkm_pstate_new(struct nvkm_clk *clk, int idx)
{
- struct nouveau_bios *bios = nouveau_bios(clk);
- struct nouveau_clocks *domain = clk->domains - 1;
- struct nouveau_pstate *pstate;
- struct nouveau_cstate *cstate;
+ struct nvkm_bios *bios = nvkm_bios(clk);
+ struct nvkm_domain *domain = clk->domains - 1;
+ struct nvkm_pstate *pstate;
+ struct nvkm_cstate *cstate;
struct nvbios_cstepE cstepE;
struct nvbios_perfE perfE;
u8 ver, hdr, cnt, len;
@@ -346,10 +341,10 @@ nouveau_pstate_new(struct nouveau_clock *clk, int idx)
continue;
if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) {
- perfS.v40.freq = nouveau_clock_adjust(clk, false,
- pstate->pstate,
- domain->bios,
- perfS.v40.freq);
+ perfS.v40.freq = nvkm_clk_adjust(clk, false,
+ pstate->pstate,
+ domain->bios,
+ perfS.v40.freq);
}
cstate->domain[domain->name] = perfS.v40.freq;
@@ -359,11 +354,11 @@ nouveau_pstate_new(struct nouveau_clock *clk, int idx)
if (data) {
int idx = cstepE.index;
do {
- nouveau_cstate_new(clk, idx, pstate);
+ nvkm_cstate_new(clk, idx, pstate);
} while(idx--);
}
- nouveau_pstate_info(clk, pstate);
+ nvkm_pstate_info(clk, pstate);
list_add_tail(&pstate->head, &clk->states);
clk->state_nr++;
return 0;
@@ -373,9 +368,9 @@ nouveau_pstate_new(struct nouveau_clock *clk, int idx)
* Adjustment triggers
*****************************************************************************/
static int
-nouveau_clock_ustate_update(struct nouveau_clock *clk, int req)
+nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
{
- struct nouveau_pstate *pstate;
+ struct nvkm_pstate *pstate;
int i = 0;
if (!clk->allow_reclock)
@@ -397,17 +392,20 @@ nouveau_clock_ustate_update(struct nouveau_clock *clk, int req)
}
static int
-nouveau_clock_nstate(struct nouveau_clock *clk, const char *mode, int arglen)
+nvkm_clk_nstate(struct nvkm_clk *clk, const char *mode, int arglen)
{
int ret = 1;
+ if (clk->allow_reclock && !strncasecmpz(mode, "auto", arglen))
+ return -2;
+
if (strncasecmpz(mode, "disabled", arglen)) {
char save = mode[arglen];
long v;
((char *)mode)[arglen] = '\0';
if (!kstrtol(mode, 0, &v)) {
- ret = nouveau_clock_ustate_update(clk, v);
+ ret = nvkm_clk_ustate_update(clk, v);
if (ret < 0)
ret = 1;
}
@@ -418,53 +416,53 @@ nouveau_clock_nstate(struct nouveau_clock *clk, const char *mode, int arglen)
}
int
-nouveau_clock_ustate(struct nouveau_clock *clk, int req, int pwr)
+nvkm_clk_ustate(struct nvkm_clk *clk, int req, int pwr)
{
- int ret = nouveau_clock_ustate_update(clk, req);
+ int ret = nvkm_clk_ustate_update(clk, req);
if (ret >= 0) {
if (ret -= 2, pwr) clk->ustate_ac = ret;
else clk->ustate_dc = ret;
- return nouveau_pstate_calc(clk, true);
+ return nvkm_pstate_calc(clk, true);
}
return ret;
}
int
-nouveau_clock_astate(struct nouveau_clock *clk, int req, int rel)
+nvkm_clk_astate(struct nvkm_clk *clk, int req, int rel, bool wait)
{
if (!rel) clk->astate = req;
if ( rel) clk->astate += rel;
clk->astate = min(clk->astate, clk->state_nr - 1);
clk->astate = max(clk->astate, 0);
- return nouveau_pstate_calc(clk, true);
+ return nvkm_pstate_calc(clk, wait);
}
int
-nouveau_clock_tstate(struct nouveau_clock *clk, int req, int rel)
+nvkm_clk_tstate(struct nvkm_clk *clk, int req, int rel)
{
if (!rel) clk->tstate = req;
if ( rel) clk->tstate += rel;
clk->tstate = min(clk->tstate, 0);
clk->tstate = max(clk->tstate, -(clk->state_nr - 1));
- return nouveau_pstate_calc(clk, true);
+ return nvkm_pstate_calc(clk, true);
}
int
-nouveau_clock_dstate(struct nouveau_clock *clk, int req, int rel)
+nvkm_clk_dstate(struct nvkm_clk *clk, int req, int rel)
{
if (!rel) clk->dstate = req;
if ( rel) clk->dstate += rel;
clk->dstate = min(clk->dstate, clk->state_nr - 1);
clk->dstate = max(clk->dstate, 0);
- return nouveau_pstate_calc(clk, true);
+ return nvkm_pstate_calc(clk, true);
}
static int
-nouveau_clock_pwrsrc(struct nvkm_notify *notify)
+nvkm_clk_pwrsrc(struct nvkm_notify *notify)
{
- struct nouveau_clock *clk =
+ struct nvkm_clk *clk =
container_of(notify, typeof(*clk), pwrsrc_ntfy);
- nouveau_pstate_calc(clk, false);
+ nvkm_pstate_calc(clk, false);
return NVKM_NOTIFY_DROP;
}
@@ -473,21 +471,21 @@ nouveau_clock_pwrsrc(struct nvkm_notify *notify)
*****************************************************************************/
int
-_nouveau_clock_fini(struct nouveau_object *object, bool suspend)
+_nvkm_clk_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_clock *clk = (void *)object;
+ struct nvkm_clk *clk = (void *)object;
nvkm_notify_put(&clk->pwrsrc_ntfy);
- return nouveau_subdev_fini(&clk->base, suspend);
+ return nvkm_subdev_fini(&clk->base, suspend);
}
int
-_nouveau_clock_init(struct nouveau_object *object)
+_nvkm_clk_init(struct nvkm_object *object)
{
- struct nouveau_clock *clk = (void *)object;
- struct nouveau_clocks *clock = clk->domains;
+ struct nvkm_clk *clk = (void *)object;
+ struct nvkm_domain *clock = clk->domains;
int ret;
- ret = nouveau_subdev_init(&clk->base);
+ ret = nvkm_subdev_init(&clk->base);
if (ret)
return ret;
@@ -505,47 +503,44 @@ _nouveau_clock_init(struct nouveau_object *object)
clock++;
}
- nouveau_pstate_info(clk, &clk->bstate);
+ nvkm_pstate_info(clk, &clk->bstate);
clk->astate = clk->state_nr - 1;
clk->tstate = 0;
clk->dstate = 0;
clk->pstate = -1;
- nouveau_pstate_calc(clk, true);
+ nvkm_pstate_calc(clk, true);
return 0;
}
void
-_nouveau_clock_dtor(struct nouveau_object *object)
+_nvkm_clk_dtor(struct nvkm_object *object)
{
- struct nouveau_clock *clk = (void *)object;
- struct nouveau_pstate *pstate, *temp;
+ struct nvkm_clk *clk = (void *)object;
+ struct nvkm_pstate *pstate, *temp;
nvkm_notify_fini(&clk->pwrsrc_ntfy);
list_for_each_entry_safe(pstate, temp, &clk->states, head) {
- nouveau_pstate_del(pstate);
+ nvkm_pstate_del(pstate);
}
- nouveau_subdev_destroy(&clk->base);
+ nvkm_subdev_destroy(&clk->base);
}
int
-nouveau_clock_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- struct nouveau_clocks *clocks,
- struct nouveau_pstate *pstates, int nb_pstates,
- bool allow_reclock,
- int length, void **object)
+nvkm_clk_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, struct nvkm_domain *clocks,
+ struct nvkm_pstate *pstates, int nb_pstates,
+ bool allow_reclock, int length, void **object)
{
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_clock *clk;
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_clk *clk;
int ret, idx, arglen;
const char *mode;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "CLK",
- "clock", length, object);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "CLK",
+ "clock", length, object);
clk = *object;
if (ret)
return ret;
@@ -555,7 +550,7 @@ nouveau_clock_create_(struct nouveau_object *parent,
clk->ustate_ac = -1;
clk->ustate_dc = -1;
- INIT_WORK(&clk->work, nouveau_pstate_work);
+ INIT_WORK(&clk->work, nvkm_pstate_work);
init_waitqueue_head(&clk->wait);
atomic_set(&clk->waiting, 0);
@@ -563,7 +558,7 @@ nouveau_clock_create_(struct nouveau_object *parent,
if (!pstates) {
idx = 0;
do {
- ret = nouveau_pstate_new(clk, idx++);
+ ret = nvkm_pstate_new(clk, idx++);
} while (ret == 0);
} else {
for (idx = 0; idx < nb_pstates; idx++)
@@ -573,25 +568,24 @@ nouveau_clock_create_(struct nouveau_object *parent,
clk->allow_reclock = allow_reclock;
- ret = nvkm_notify_init(NULL, &device->event, nouveau_clock_pwrsrc, true,
+ ret = nvkm_notify_init(NULL, &device->event, nvkm_clk_pwrsrc, true,
NULL, 0, 0, &clk->pwrsrc_ntfy);
if (ret)
return ret;
- mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen);
+ mode = nvkm_stropt(device->cfgopt, "NvClkMode", &arglen);
if (mode) {
- clk->ustate_ac = nouveau_clock_nstate(clk, mode, arglen);
- clk->ustate_dc = nouveau_clock_nstate(clk, mode, arglen);
+ clk->ustate_ac = nvkm_clk_nstate(clk, mode, arglen);
+ clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen);
}
- mode = nouveau_stropt(device->cfgopt, "NvClkModeAC", &arglen);
+ mode = nvkm_stropt(device->cfgopt, "NvClkModeAC", &arglen);
if (mode)
- clk->ustate_ac = nouveau_clock_nstate(clk, mode, arglen);
+ clk->ustate_ac = nvkm_clk_nstate(clk, mode, arglen);
- mode = nouveau_stropt(device->cfgopt, "NvClkModeDC", &arglen);
+ mode = nvkm_stropt(device->cfgopt, "NvClkModeDC", &arglen);
if (mode)
- clk->ustate_dc = nouveau_clock_nstate(clk, mode, arglen);
-
+ clk->ustate_dc = nvkm_clk_nstate(clk, mode, arglen);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
index b0b7c1437f10..4c90b9769d64 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
@@ -21,11 +21,10 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include "nv50.h"
-static struct nouveau_clocks
-nv84_domains[] = {
+static struct nvkm_domain
+g84_domains[] = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href , 0xff },
{ nv_clk_src_core , 0xff, 0, "core", 1000 },
@@ -35,14 +34,14 @@ nv84_domains[] = {
{ nv_clk_src_max }
};
-struct nouveau_oclass *
-nv84_clock_oclass = &(struct nv50_clock_oclass) {
- .base.handle = NV_SUBDEV(CLOCK, 0x84),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass *
+g84_clk_oclass = &(struct nv50_clk_oclass) {
+ .base.handle = NV_SUBDEV(CLK, 0x84),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
- .domains = nv84_domains,
+ .domains = g84_domains,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
index 1234abaab2db..3d7330d54b02 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c
@@ -21,15 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include <subdev/clk.h>
+#include "pll.h"
-#include <subdev/clock.h>
+#include <core/device.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
#include <subdev/timer.h>
-#include "pll.h"
-
-struct nvc0_clock_info {
+struct gf100_clk_info {
u32 freq;
u32 ssel;
u32 mdiv;
@@ -38,17 +38,17 @@ struct nvc0_clock_info {
u32 coef;
};
-struct nvc0_clock_priv {
- struct nouveau_clock base;
- struct nvc0_clock_info eng[16];
+struct gf100_clk_priv {
+ struct nvkm_clk base;
+ struct gf100_clk_info eng[16];
};
-static u32 read_div(struct nvc0_clock_priv *, int, u32, u32);
+static u32 read_div(struct gf100_clk_priv *, int, u32, u32);
static u32
-read_vco(struct nvc0_clock_priv *priv, u32 dsrc)
+read_vco(struct gf100_clk_priv *priv, u32 dsrc)
{
- struct nouveau_clock *clk = &priv->base;
+ struct nvkm_clk *clk = &priv->base;
u32 ssrc = nv_rd32(priv, dsrc);
if (!(ssrc & 0x00000100))
return clk->read(clk, nv_clk_src_sppll0);
@@ -56,9 +56,9 @@ read_vco(struct nvc0_clock_priv *priv, u32 dsrc)
}
static u32
-read_pll(struct nvc0_clock_priv *priv, u32 pll)
+read_pll(struct gf100_clk_priv *priv, u32 pll)
{
- struct nouveau_clock *clk = &priv->base;
+ struct nvkm_clk *clk = &priv->base;
u32 ctrl = nv_rd32(priv, pll + 0x00);
u32 coef = nv_rd32(priv, pll + 0x04);
u32 P = (coef & 0x003f0000) >> 16;
@@ -95,7 +95,7 @@ read_pll(struct nvc0_clock_priv *priv, u32 pll)
}
static u32
-read_div(struct nvc0_clock_priv *priv, int doff, u32 dsrc, u32 dctl)
+read_div(struct gf100_clk_priv *priv, int doff, u32 dsrc, u32 dctl)
{
u32 ssrc = nv_rd32(priv, dsrc + (doff * 4));
u32 sctl = nv_rd32(priv, dctl + (doff * 4));
@@ -121,7 +121,7 @@ read_div(struct nvc0_clock_priv *priv, int doff, u32 dsrc, u32 dctl)
}
static u32
-read_clk(struct nvc0_clock_priv *priv, int clk)
+read_clk(struct gf100_clk_priv *priv, int clk)
{
u32 sctl = nv_rd32(priv, 0x137250 + (clk * 4));
u32 ssel = nv_rd32(priv, 0x137100);
@@ -145,10 +145,10 @@ read_clk(struct nvc0_clock_priv *priv, int clk)
}
static int
-nvc0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
+gf100_clk_read(struct nvkm_clk *clk, enum nv_clk_src src)
{
- struct nouveau_device *device = nv_device(clk);
- struct nvc0_clock_priv *priv = (void *)clk;
+ struct nvkm_device *device = nv_device(clk);
+ struct gf100_clk_priv *priv = (void *)clk;
switch (src) {
case nv_clk_src_crystal:
@@ -196,7 +196,7 @@ nvc0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
}
static u32
-calc_div(struct nvc0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
+calc_div(struct gf100_clk_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
{
u32 div = min((ref * 2) / freq, (u32)65);
if (div < 2)
@@ -207,7 +207,7 @@ calc_div(struct nvc0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
}
static u32
-calc_src(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
+calc_src(struct gf100_clk_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
{
u32 sclk;
@@ -236,9 +236,9 @@ calc_src(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
}
static u32
-calc_pll(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *coef)
+calc_pll(struct gf100_clk_priv *priv, int clk, u32 freq, u32 *coef)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll limits;
int N, M, P, ret;
@@ -250,7 +250,7 @@ calc_pll(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *coef)
if (!limits.refclk)
return 0;
- ret = nva3_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P);
+ ret = gt215_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P);
if (ret <= 0)
return 0;
@@ -259,10 +259,10 @@ calc_pll(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *coef)
}
static int
-calc_clk(struct nvc0_clock_priv *priv,
- struct nouveau_cstate *cstate, int clk, int dom)
+calc_clk(struct gf100_clk_priv *priv,
+ struct nvkm_cstate *cstate, int clk, int dom)
{
- struct nvc0_clock_info *info = &priv->eng[clk];
+ struct gf100_clk_info *info = &priv->eng[clk];
u32 freq = cstate->domain[dom];
u32 src0, div0, div1D, div1P = 0;
u32 clk0, clk1 = 0;
@@ -311,9 +311,9 @@ calc_clk(struct nvc0_clock_priv *priv,
}
static int
-nvc0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
+gf100_clk_calc(struct nvkm_clk *clk, struct nvkm_cstate *cstate)
{
- struct nvc0_clock_priv *priv = (void *)clk;
+ struct gf100_clk_priv *priv = (void *)clk;
int ret;
if ((ret = calc_clk(priv, cstate, 0x00, nv_clk_src_gpc)) ||
@@ -330,9 +330,9 @@ nvc0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
}
static void
-nvc0_clock_prog_0(struct nvc0_clock_priv *priv, int clk)
+gf100_clk_prog_0(struct gf100_clk_priv *priv, int clk)
{
- struct nvc0_clock_info *info = &priv->eng[clk];
+ struct gf100_clk_info *info = &priv->eng[clk];
if (clk < 7 && !info->ssel) {
nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv);
nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc);
@@ -340,16 +340,16 @@ nvc0_clock_prog_0(struct nvc0_clock_priv *priv, int clk)
}
static void
-nvc0_clock_prog_1(struct nvc0_clock_priv *priv, int clk)
+gf100_clk_prog_1(struct gf100_clk_priv *priv, int clk)
{
nv_mask(priv, 0x137100, (1 << clk), 0x00000000);
nv_wait(priv, 0x137100, (1 << clk), 0x00000000);
}
static void
-nvc0_clock_prog_2(struct nvc0_clock_priv *priv, int clk)
+gf100_clk_prog_2(struct gf100_clk_priv *priv, int clk)
{
- struct nvc0_clock_info *info = &priv->eng[clk];
+ struct gf100_clk_info *info = &priv->eng[clk];
const u32 addr = 0x137000 + (clk * 0x20);
if (clk <= 7) {
nv_mask(priv, addr + 0x00, 0x00000004, 0x00000000);
@@ -364,9 +364,9 @@ nvc0_clock_prog_2(struct nvc0_clock_priv *priv, int clk)
}
static void
-nvc0_clock_prog_3(struct nvc0_clock_priv *priv, int clk)
+gf100_clk_prog_3(struct gf100_clk_priv *priv, int clk)
{
- struct nvc0_clock_info *info = &priv->eng[clk];
+ struct gf100_clk_info *info = &priv->eng[clk];
if (info->ssel) {
nv_mask(priv, 0x137100, (1 << clk), info->ssel);
nv_wait(priv, 0x137100, (1 << clk), info->ssel);
@@ -374,24 +374,24 @@ nvc0_clock_prog_3(struct nvc0_clock_priv *priv, int clk)
}
static void
-nvc0_clock_prog_4(struct nvc0_clock_priv *priv, int clk)
+gf100_clk_prog_4(struct gf100_clk_priv *priv, int clk)
{
- struct nvc0_clock_info *info = &priv->eng[clk];
+ struct gf100_clk_info *info = &priv->eng[clk];
nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv);
}
static int
-nvc0_clock_prog(struct nouveau_clock *clk)
+gf100_clk_prog(struct nvkm_clk *clk)
{
- struct nvc0_clock_priv *priv = (void *)clk;
+ struct gf100_clk_priv *priv = (void *)clk;
struct {
- void (*exec)(struct nvc0_clock_priv *, int);
+ void (*exec)(struct gf100_clk_priv *, int);
} stage[] = {
- { nvc0_clock_prog_0 }, /* div programming */
- { nvc0_clock_prog_1 }, /* select div mode */
- { nvc0_clock_prog_2 }, /* (maybe) program pll */
- { nvc0_clock_prog_3 }, /* (maybe) select pll mode */
- { nvc0_clock_prog_4 }, /* final divider */
+ { gf100_clk_prog_0 }, /* div programming */
+ { gf100_clk_prog_1 }, /* select div mode */
+ { gf100_clk_prog_2 }, /* (maybe) program pll */
+ { gf100_clk_prog_3 }, /* (maybe) select pll mode */
+ { gf100_clk_prog_4 }, /* final divider */
};
int i, j;
@@ -407,14 +407,14 @@ nvc0_clock_prog(struct nouveau_clock *clk)
}
static void
-nvc0_clock_tidy(struct nouveau_clock *clk)
+gf100_clk_tidy(struct nvkm_clk *clk)
{
- struct nvc0_clock_priv *priv = (void *)clk;
+ struct gf100_clk_priv *priv = (void *)clk;
memset(priv->eng, 0x00, sizeof(priv->eng));
}
-static struct nouveau_clocks
-nvc0_domain[] = {
+static struct nvkm_domain
+gf100_domain[] = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href , 0xff },
{ nv_clk_src_hubk06 , 0x00 },
@@ -430,33 +430,33 @@ nvc0_domain[] = {
};
static int
-nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_clock_priv *priv;
+ struct gf100_clk_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, NULL, 0,
- false, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, gf100_domain,
+ NULL, 0, false, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.read = nvc0_clock_read;
- priv->base.calc = nvc0_clock_calc;
- priv->base.prog = nvc0_clock_prog;
- priv->base.tidy = nvc0_clock_tidy;
+ priv->base.read = gf100_clk_read;
+ priv->base.calc = gf100_clk_calc;
+ priv->base.prog = gf100_clk_prog;
+ priv->base.tidy = gf100_clk_tidy;
return 0;
}
-struct nouveau_oclass
-nvc0_clock_oclass = {
- .handle = NV_SUBDEV(CLOCK, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass
+gf100_clk_oclass = {
+ .handle = NV_SUBDEV(CLK, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
index 7eccad57512e..e9b2310bdfbb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c
@@ -21,15 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include <subdev/clk.h>
+#include "pll.h"
-#include <subdev/clock.h>
+#include <core/device.h>
#include <subdev/timer.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include "pll.h"
-
-struct nve0_clock_info {
+struct gk104_clk_info {
u32 freq;
u32 ssel;
u32 mdiv;
@@ -38,16 +38,16 @@ struct nve0_clock_info {
u32 coef;
};
-struct nve0_clock_priv {
- struct nouveau_clock base;
- struct nve0_clock_info eng[16];
+struct gk104_clk_priv {
+ struct nvkm_clk base;
+ struct gk104_clk_info eng[16];
};
-static u32 read_div(struct nve0_clock_priv *, int, u32, u32);
-static u32 read_pll(struct nve0_clock_priv *, u32);
+static u32 read_div(struct gk104_clk_priv *, int, u32, u32);
+static u32 read_pll(struct gk104_clk_priv *, u32);
static u32
-read_vco(struct nve0_clock_priv *priv, u32 dsrc)
+read_vco(struct gk104_clk_priv *priv, u32 dsrc)
{
u32 ssrc = nv_rd32(priv, dsrc);
if (!(ssrc & 0x00000100))
@@ -56,7 +56,7 @@ read_vco(struct nve0_clock_priv *priv, u32 dsrc)
}
static u32
-read_pll(struct nve0_clock_priv *priv, u32 pll)
+read_pll(struct gk104_clk_priv *priv, u32 pll)
{
u32 ctrl = nv_rd32(priv, pll + 0x00);
u32 coef = nv_rd32(priv, pll + 0x04);
@@ -101,7 +101,7 @@ read_pll(struct nve0_clock_priv *priv, u32 pll)
}
static u32
-read_div(struct nve0_clock_priv *priv, int doff, u32 dsrc, u32 dctl)
+read_div(struct gk104_clk_priv *priv, int doff, u32 dsrc, u32 dctl)
{
u32 ssrc = nv_rd32(priv, dsrc + (doff * 4));
u32 sctl = nv_rd32(priv, dctl + (doff * 4));
@@ -127,7 +127,7 @@ read_div(struct nve0_clock_priv *priv, int doff, u32 dsrc, u32 dctl)
}
static u32
-read_mem(struct nve0_clock_priv *priv)
+read_mem(struct gk104_clk_priv *priv)
{
switch (nv_rd32(priv, 0x1373f4) & 0x0000000f) {
case 1: return read_pll(priv, 0x132020);
@@ -138,7 +138,7 @@ read_mem(struct nve0_clock_priv *priv)
}
static u32
-read_clk(struct nve0_clock_priv *priv, int clk)
+read_clk(struct gk104_clk_priv *priv, int clk)
{
u32 sctl = nv_rd32(priv, 0x137250 + (clk * 4));
u32 sclk, sdiv;
@@ -181,10 +181,10 @@ read_clk(struct nve0_clock_priv *priv, int clk)
}
static int
-nve0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
+gk104_clk_read(struct nvkm_clk *clk, enum nv_clk_src src)
{
- struct nouveau_device *device = nv_device(clk);
- struct nve0_clock_priv *priv = (void *)clk;
+ struct nvkm_device *device = nv_device(clk);
+ struct gk104_clk_priv *priv = (void *)clk;
switch (src) {
case nv_clk_src_crystal:
@@ -214,7 +214,7 @@ nve0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
}
static u32
-calc_div(struct nve0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
+calc_div(struct gk104_clk_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
{
u32 div = min((ref * 2) / freq, (u32)65);
if (div < 2)
@@ -225,7 +225,7 @@ calc_div(struct nve0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv)
}
static u32
-calc_src(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
+calc_src(struct gk104_clk_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
{
u32 sclk;
@@ -254,9 +254,9 @@ calc_src(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
}
static u32
-calc_pll(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *coef)
+calc_pll(struct gk104_clk_priv *priv, int clk, u32 freq, u32 *coef)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll limits;
int N, M, P, ret;
@@ -268,7 +268,7 @@ calc_pll(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *coef)
if (!limits.refclk)
return 0;
- ret = nva3_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P);
+ ret = gt215_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P);
if (ret <= 0)
return 0;
@@ -277,10 +277,10 @@ calc_pll(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *coef)
}
static int
-calc_clk(struct nve0_clock_priv *priv,
- struct nouveau_cstate *cstate, int clk, int dom)
+calc_clk(struct gk104_clk_priv *priv,
+ struct nvkm_cstate *cstate, int clk, int dom)
{
- struct nve0_clock_info *info = &priv->eng[clk];
+ struct gk104_clk_info *info = &priv->eng[clk];
u32 freq = cstate->domain[dom];
u32 src0, div0, div1D, div1P = 0;
u32 clk0, clk1 = 0;
@@ -329,9 +329,9 @@ calc_clk(struct nve0_clock_priv *priv,
}
static int
-nve0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
+gk104_clk_calc(struct nvkm_clk *clk, struct nvkm_cstate *cstate)
{
- struct nve0_clock_priv *priv = (void *)clk;
+ struct gk104_clk_priv *priv = (void *)clk;
int ret;
if ((ret = calc_clk(priv, cstate, 0x00, nv_clk_src_gpc)) ||
@@ -347,9 +347,9 @@ nve0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
}
static void
-nve0_clock_prog_0(struct nve0_clock_priv *priv, int clk)
+gk104_clk_prog_0(struct gk104_clk_priv *priv, int clk)
{
- struct nve0_clock_info *info = &priv->eng[clk];
+ struct gk104_clk_info *info = &priv->eng[clk];
if (!info->ssel) {
nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x8000003f, info->ddiv);
nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc);
@@ -357,22 +357,22 @@ nve0_clock_prog_0(struct nve0_clock_priv *priv, int clk)
}
static void
-nve0_clock_prog_1_0(struct nve0_clock_priv *priv, int clk)
+gk104_clk_prog_1_0(struct gk104_clk_priv *priv, int clk)
{
nv_mask(priv, 0x137100, (1 << clk), 0x00000000);
nv_wait(priv, 0x137100, (1 << clk), 0x00000000);
}
static void
-nve0_clock_prog_1_1(struct nve0_clock_priv *priv, int clk)
+gk104_clk_prog_1_1(struct gk104_clk_priv *priv, int clk)
{
nv_mask(priv, 0x137160 + (clk * 0x04), 0x00000100, 0x00000000);
}
static void
-nve0_clock_prog_2(struct nve0_clock_priv *priv, int clk)
+gk104_clk_prog_2(struct gk104_clk_priv *priv, int clk)
{
- struct nve0_clock_info *info = &priv->eng[clk];
+ struct gk104_clk_info *info = &priv->eng[clk];
const u32 addr = 0x137000 + (clk * 0x20);
nv_mask(priv, addr + 0x00, 0x00000004, 0x00000000);
nv_mask(priv, addr + 0x00, 0x00000001, 0x00000000);
@@ -385,9 +385,9 @@ nve0_clock_prog_2(struct nve0_clock_priv *priv, int clk)
}
static void
-nve0_clock_prog_3(struct nve0_clock_priv *priv, int clk)
+gk104_clk_prog_3(struct gk104_clk_priv *priv, int clk)
{
- struct nve0_clock_info *info = &priv->eng[clk];
+ struct gk104_clk_info *info = &priv->eng[clk];
if (info->ssel)
nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f00, info->mdiv);
else
@@ -395,9 +395,9 @@ nve0_clock_prog_3(struct nve0_clock_priv *priv, int clk)
}
static void
-nve0_clock_prog_4_0(struct nve0_clock_priv *priv, int clk)
+gk104_clk_prog_4_0(struct gk104_clk_priv *priv, int clk)
{
- struct nve0_clock_info *info = &priv->eng[clk];
+ struct gk104_clk_info *info = &priv->eng[clk];
if (info->ssel) {
nv_mask(priv, 0x137100, (1 << clk), info->ssel);
nv_wait(priv, 0x137100, (1 << clk), info->ssel);
@@ -405,9 +405,9 @@ nve0_clock_prog_4_0(struct nve0_clock_priv *priv, int clk)
}
static void
-nve0_clock_prog_4_1(struct nve0_clock_priv *priv, int clk)
+gk104_clk_prog_4_1(struct gk104_clk_priv *priv, int clk)
{
- struct nve0_clock_info *info = &priv->eng[clk];
+ struct gk104_clk_info *info = &priv->eng[clk];
if (info->ssel) {
nv_mask(priv, 0x137160 + (clk * 0x04), 0x40000000, 0x40000000);
nv_mask(priv, 0x137160 + (clk * 0x04), 0x00000100, 0x00000100);
@@ -415,20 +415,20 @@ nve0_clock_prog_4_1(struct nve0_clock_priv *priv, int clk)
}
static int
-nve0_clock_prog(struct nouveau_clock *clk)
+gk104_clk_prog(struct nvkm_clk *clk)
{
- struct nve0_clock_priv *priv = (void *)clk;
+ struct gk104_clk_priv *priv = (void *)clk;
struct {
u32 mask;
- void (*exec)(struct nve0_clock_priv *, int);
+ void (*exec)(struct gk104_clk_priv *, int);
} stage[] = {
- { 0x007f, nve0_clock_prog_0 }, /* div programming */
- { 0x007f, nve0_clock_prog_1_0 }, /* select div mode */
- { 0xff80, nve0_clock_prog_1_1 },
- { 0x00ff, nve0_clock_prog_2 }, /* (maybe) program pll */
- { 0xff80, nve0_clock_prog_3 }, /* final divider */
- { 0x007f, nve0_clock_prog_4_0 }, /* (maybe) select pll mode */
- { 0xff80, nve0_clock_prog_4_1 },
+ { 0x007f, gk104_clk_prog_0 }, /* div programming */
+ { 0x007f, gk104_clk_prog_1_0 }, /* select div mode */
+ { 0xff80, gk104_clk_prog_1_1 },
+ { 0x00ff, gk104_clk_prog_2 }, /* (maybe) program pll */
+ { 0xff80, gk104_clk_prog_3 }, /* final divider */
+ { 0x007f, gk104_clk_prog_4_0 }, /* (maybe) select pll mode */
+ { 0xff80, gk104_clk_prog_4_1 },
};
int i, j;
@@ -446,14 +446,14 @@ nve0_clock_prog(struct nouveau_clock *clk)
}
static void
-nve0_clock_tidy(struct nouveau_clock *clk)
+gk104_clk_tidy(struct nvkm_clk *clk)
{
- struct nve0_clock_priv *priv = (void *)clk;
+ struct gk104_clk_priv *priv = (void *)clk;
memset(priv->eng, 0x00, sizeof(priv->eng));
}
-static struct nouveau_clocks
-nve0_domain[] = {
+static struct nvkm_domain
+gk104_domain[] = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href , 0xff },
{ nv_clk_src_gpc , 0x00, NVKM_CLK_DOM_FLAG_CORE, "core", 2000 },
@@ -468,33 +468,33 @@ nve0_domain[] = {
};
static int
-nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nve0_clock_priv *priv;
+ struct gk104_clk_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, NULL, 0,
- true, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, gk104_domain,
+ NULL, 0, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.read = nve0_clock_read;
- priv->base.calc = nve0_clock_calc;
- priv->base.prog = nve0_clock_prog;
- priv->base.tidy = nve0_clock_tidy;
+ priv->base.read = gk104_clk_read;
+ priv->base.calc = gk104_clk_calc;
+ priv->base.prog = gk104_clk_prog;
+ priv->base.tidy = gk104_clk_tidy;
return 0;
}
-struct nouveau_oclass
-nve0_clock_oclass = {
- .handle = NV_SUBDEV(CLOCK, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass
+gk104_clk_oclass = {
+ .handle = NV_SUBDEV(CLK, 0xe0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
index fb4fad374bdd..65c532742b08 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
@@ -22,6 +22,14 @@
* Shamelessly ripped off from ChromeOS's gk20a/clk_pllg.c
*
*/
+#include <subdev/clk.h>
+#include <subdev/timer.h>
+
+#include <core/device.h>
+
+#ifdef __KERNEL__
+#include <nouveau_platform.h>
+#endif
#define MHZ (1000 * 1000)
@@ -87,13 +95,6 @@
#define GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_MASK \
(0x1 << GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_SHIFT)
-#include <subdev/clock.h>
-#include <subdev/timer.h>
-
-#ifdef __KERNEL__
-#include <nouveau_platform.h>
-#endif
-
static const u8 pl_to_div[] = {
/* PL: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 */
/* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32,
@@ -116,16 +117,16 @@ static const struct gk20a_clk_pllg_params gk20a_pllg_params = {
.min_pl = 1, .max_pl = 32,
};
-struct gk20a_clock_priv {
- struct nouveau_clock base;
+struct gk20a_clk_priv {
+ struct nvkm_clk base;
const struct gk20a_clk_pllg_params *params;
u32 m, n, pl;
u32 parent_rate;
};
-#define to_gk20a_clock(base) container_of(base, struct gk20a_clock_priv, base)
+#define to_gk20a_clk(base) container_of(base, struct gk20a_clk_priv, base)
static void
-gk20a_pllg_read_mnp(struct gk20a_clock_priv *priv)
+gk20a_pllg_read_mnp(struct gk20a_clk_priv *priv)
{
u32 val;
@@ -136,7 +137,7 @@ gk20a_pllg_read_mnp(struct gk20a_clock_priv *priv)
}
static u32
-gk20a_pllg_calc_rate(struct gk20a_clock_priv *priv)
+gk20a_pllg_calc_rate(struct gk20a_clk_priv *priv)
{
u32 rate;
u32 divider;
@@ -149,7 +150,7 @@ gk20a_pllg_calc_rate(struct gk20a_clock_priv *priv)
}
static int
-gk20a_pllg_calc_mnp(struct gk20a_clock_priv *priv, unsigned long rate)
+gk20a_pllg_calc_mnp(struct gk20a_clk_priv *priv, unsigned long rate)
{
u32 target_clk_f, ref_clk_f, target_freq;
u32 min_vco_f, max_vco_f;
@@ -260,12 +261,11 @@ found_match:
nv_debug(priv, "actual target freq %d MHz, M %d, N %d, PL %d(div%d)\n",
target_freq, priv->m, priv->n, priv->pl, pl_to_div[priv->pl]);
-
return 0;
}
static int
-gk20a_pllg_slide(struct gk20a_clock_priv *priv, u32 n)
+gk20a_pllg_slide(struct gk20a_clk_priv *priv, u32 n)
{
u32 val;
int ramp_timeout;
@@ -322,21 +322,21 @@ gk20a_pllg_slide(struct gk20a_clock_priv *priv, u32 n)
}
static void
-_gk20a_pllg_enable(struct gk20a_clock_priv *priv)
+_gk20a_pllg_enable(struct gk20a_clk_priv *priv)
{
nv_mask(priv, GPCPLL_CFG, GPCPLL_CFG_ENABLE, GPCPLL_CFG_ENABLE);
nv_rd32(priv, GPCPLL_CFG);
}
static void
-_gk20a_pllg_disable(struct gk20a_clock_priv *priv)
+_gk20a_pllg_disable(struct gk20a_clk_priv *priv)
{
nv_mask(priv, GPCPLL_CFG, GPCPLL_CFG_ENABLE, 0);
nv_rd32(priv, GPCPLL_CFG);
}
static int
-_gk20a_pllg_program_mnp(struct gk20a_clock_priv *priv, bool allow_slide)
+_gk20a_pllg_program_mnp(struct gk20a_clk_priv *priv, bool allow_slide)
{
u32 val, cfg;
u32 m_old, pl_old, n_lo;
@@ -402,8 +402,8 @@ _gk20a_pllg_program_mnp(struct gk20a_clock_priv *priv, bool allow_slide)
nv_wr32(priv, GPCPLL_CFG, val);
}
- if (!nouveau_timer_wait_eq(priv, 300000, GPCPLL_CFG, GPCPLL_CFG_LOCK,
- GPCPLL_CFG_LOCK)) {
+ if (!nvkm_timer_wait_eq(priv, 300000, GPCPLL_CFG, GPCPLL_CFG_LOCK,
+ GPCPLL_CFG_LOCK)) {
nv_error(priv, "%s: timeout waiting for pllg lock\n", __func__);
return -ETIMEDOUT;
}
@@ -422,7 +422,7 @@ _gk20a_pllg_program_mnp(struct gk20a_clock_priv *priv, bool allow_slide)
}
static int
-gk20a_pllg_program_mnp(struct gk20a_clock_priv *priv)
+gk20a_pllg_program_mnp(struct gk20a_clk_priv *priv)
{
int err;
@@ -434,7 +434,7 @@ gk20a_pllg_program_mnp(struct gk20a_clock_priv *priv)
}
static void
-gk20a_pllg_disable(struct gk20a_clock_priv *priv)
+gk20a_pllg_disable(struct gk20a_clk_priv *priv)
{
u32 val;
@@ -458,14 +458,14 @@ gk20a_pllg_disable(struct gk20a_clock_priv *priv)
#define GK20A_CLK_GPC_MDIV 1000
-static struct nouveau_clocks
+static struct nvkm_domain
gk20a_domains[] = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV },
{ nv_clk_src_max }
};
-static struct nouveau_pstate
+static struct nvkm_pstate
gk20a_pstates[] = {
{
.base = {
@@ -560,9 +560,9 @@ gk20a_pstates[] = {
};
static int
-gk20a_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
+gk20a_clk_read(struct nvkm_clk *clk, enum nv_clk_src src)
{
- struct gk20a_clock_priv *priv = (void *)clk;
+ struct gk20a_clk_priv *priv = (void *)clk;
switch (src) {
case nv_clk_src_crystal:
@@ -577,34 +577,34 @@ gk20a_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
}
static int
-gk20a_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
+gk20a_clk_calc(struct nvkm_clk *clk, struct nvkm_cstate *cstate)
{
- struct gk20a_clock_priv *priv = (void *)clk;
+ struct gk20a_clk_priv *priv = (void *)clk;
return gk20a_pllg_calc_mnp(priv, cstate->domain[nv_clk_src_gpc] *
GK20A_CLK_GPC_MDIV);
}
static int
-gk20a_clock_prog(struct nouveau_clock *clk)
+gk20a_clk_prog(struct nvkm_clk *clk)
{
- struct gk20a_clock_priv *priv = (void *)clk;
+ struct gk20a_clk_priv *priv = (void *)clk;
return gk20a_pllg_program_mnp(priv);
}
static void
-gk20a_clock_tidy(struct nouveau_clock *clk)
+gk20a_clk_tidy(struct nvkm_clk *clk)
{
}
static int
-gk20a_clock_fini(struct nouveau_object *object, bool suspend)
+gk20a_clk_fini(struct nvkm_object *object, bool suspend)
{
- struct gk20a_clock_priv *priv = (void *)object;
+ struct gk20a_clk_priv *priv = (void *)object;
int ret;
- ret = nouveau_clock_fini(&priv->base, false);
+ ret = nvkm_clk_fini(&priv->base, false);
gk20a_pllg_disable(priv);
@@ -612,18 +612,18 @@ gk20a_clock_fini(struct nouveau_object *object, bool suspend)
}
static int
-gk20a_clock_init(struct nouveau_object *object)
+gk20a_clk_init(struct nvkm_object *object)
{
- struct gk20a_clock_priv *priv = (void *)object;
+ struct gk20a_clk_priv *priv = (void *)object;
int ret;
nv_mask(priv, GPC2CLK_OUT, GPC2CLK_OUT_INIT_MASK, GPC2CLK_OUT_INIT_VAL);
- ret = nouveau_clock_init(&priv->base);
+ ret = nvkm_clk_init(&priv->base);
if (ret)
return ret;
- ret = gk20a_clock_prog(&priv->base);
+ ret = gk20a_clk_prog(&priv->base);
if (ret) {
nv_error(priv, "cannot initialize clock\n");
return ret;
@@ -633,11 +633,11 @@ gk20a_clock_init(struct nouveau_object *object)
}
static int
-gk20a_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk20a_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct gk20a_clock_priv *priv;
+ struct gk20a_clk_priv *priv;
struct nouveau_platform_device *plat;
int ret;
int i;
@@ -648,8 +648,9 @@ gk20a_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
gk20a_pstates[i].pstate = i + 1;
}
- ret = nouveau_clock_create(parent, engine, oclass, gk20a_domains,
- gk20a_pstates, ARRAY_SIZE(gk20a_pstates), true, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, gk20a_domains,
+ gk20a_pstates, ARRAY_SIZE(gk20a_pstates),
+ true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -660,21 +661,20 @@ gk20a_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->parent_rate = clk_get_rate(plat->gpu->clk);
nv_info(priv, "parent clock rate: %d Mhz\n", priv->parent_rate / MHZ);
- priv->base.read = gk20a_clock_read;
- priv->base.calc = gk20a_clock_calc;
- priv->base.prog = gk20a_clock_prog;
- priv->base.tidy = gk20a_clock_tidy;
-
+ priv->base.read = gk20a_clk_read;
+ priv->base.calc = gk20a_clk_calc;
+ priv->base.prog = gk20a_clk_prog;
+ priv->base.tidy = gk20a_clk_tidy;
return 0;
}
-struct nouveau_oclass
-gk20a_clock_oclass = {
- .handle = NV_SUBDEV(CLOCK, 0xea),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = gk20a_clock_ctor,
- .dtor = _nouveau_subdev_dtor,
- .init = gk20a_clock_init,
- .fini = gk20a_clock_fini,
+struct nvkm_oclass
+gk20a_clk_oclass = {
+ .handle = NV_SUBDEV(CLK, 0xea),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk20a_clk_ctor,
+ .dtor = _nvkm_subdev_dtor,
+ .init = gk20a_clk_init,
+ .fini = gk20a_clk_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
index 07ad01247675..822d32a28d6e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
@@ -22,26 +22,25 @@
* Authors: Ben Skeggs
* Roy Spliet
*/
+#include "gt215.h"
+#include "pll.h"
+#include <core/device.h>
#include <engine/fifo.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
#include <subdev/timer.h>
-#include "pll.h"
-
-#include "nva3.h"
-
-struct nva3_clock_priv {
- struct nouveau_clock base;
- struct nva3_clock_info eng[nv_clk_src_max];
+struct gt215_clk_priv {
+ struct nvkm_clk base;
+ struct gt215_clk_info eng[nv_clk_src_max];
};
-static u32 read_clk(struct nva3_clock_priv *, int, bool);
-static u32 read_pll(struct nva3_clock_priv *, int, u32);
+static u32 read_clk(struct gt215_clk_priv *, int, bool);
+static u32 read_pll(struct gt215_clk_priv *, int, u32);
static u32
-read_vco(struct nva3_clock_priv *priv, int clk)
+read_vco(struct gt215_clk_priv *priv, int clk)
{
u32 sctl = nv_rd32(priv, 0x4120 + (clk * 4));
@@ -58,7 +57,7 @@ read_vco(struct nva3_clock_priv *priv, int clk)
}
static u32
-read_clk(struct nva3_clock_priv *priv, int clk, bool ignore_en)
+read_clk(struct gt215_clk_priv *priv, int clk, bool ignore_en)
{
u32 sctl, sdiv, sclk;
@@ -104,7 +103,7 @@ read_clk(struct nva3_clock_priv *priv, int clk, bool ignore_en)
}
static u32
-read_pll(struct nva3_clock_priv *priv, int clk, u32 pll)
+read_pll(struct gt215_clk_priv *priv, int clk, u32 pll)
{
u32 ctrl = nv_rd32(priv, pll + 0);
u32 sclk = 0, P = 1, N = 1, M = 1;
@@ -130,13 +129,14 @@ read_pll(struct nva3_clock_priv *priv, int clk, u32 pll)
if (M * P)
return sclk * N / (M * P);
+
return 0;
}
static int
-nva3_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
+gt215_clk_read(struct nvkm_clk *clk, enum nv_clk_src src)
{
- struct nva3_clock_priv *priv = (void *)clk;
+ struct gt215_clk_priv *priv = (void *)clk;
u32 hsrc;
switch (src) {
@@ -176,10 +176,10 @@ nva3_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
}
int
-nva3_clk_info(struct nouveau_clock *clock, int clk, u32 khz,
- struct nva3_clock_info *info)
+gt215_clk_info(struct nvkm_clk *clock, int clk, u32 khz,
+ struct gt215_clk_info *info)
{
- struct nva3_clock_priv *priv = (void *)clock;
+ struct gt215_clk_priv *priv = (void *)clock;
u32 oclk, sclk, sdiv, diff;
info->clk = 0;
@@ -223,11 +223,11 @@ nva3_clk_info(struct nouveau_clock *clock, int clk, u32 khz,
}
int
-nva3_pll_info(struct nouveau_clock *clock, int clk, u32 pll, u32 khz,
- struct nva3_clock_info *info)
+gt215_pll_info(struct nvkm_clk *clock, int clk, u32 pll, u32 khz,
+ struct gt215_clk_info *info)
{
- struct nouveau_bios *bios = nouveau_bios(clock);
- struct nva3_clock_priv *priv = (void *)clock;
+ struct nvkm_bios *bios = nvkm_bios(clock);
+ struct gt215_clk_priv *priv = (void *)clock;
struct nvbios_pll limits;
int P, N, M, diff;
int ret;
@@ -236,7 +236,7 @@ nva3_pll_info(struct nouveau_clock *clock, int clk, u32 pll, u32 khz,
/* If we can get a within [-2, 3) MHz of a divider, we'll disable the
* PLL and use the divider instead. */
- ret = nva3_clk_info(clock, clk, khz, info);
+ ret = gt215_clk_info(clock, clk, khz, info);
diff = khz - ret;
if (!pll || (diff >= -2000 && diff < 3000)) {
goto out;
@@ -247,38 +247,37 @@ nva3_pll_info(struct nouveau_clock *clock, int clk, u32 pll, u32 khz,
if (ret)
return ret;
- ret = nva3_clk_info(clock, clk - 0x10, limits.refclk, info);
+ ret = gt215_clk_info(clock, clk - 0x10, limits.refclk, info);
if (ret != limits.refclk)
return -EINVAL;
- ret = nva3_pll_calc(nv_subdev(priv), &limits, khz, &N, NULL, &M, &P);
+ ret = gt215_pll_calc(nv_subdev(priv), &limits, khz, &N, NULL, &M, &P);
if (ret >= 0) {
info->pll = (P << 16) | (N << 8) | M;
}
out:
info->fb_delay = max(((khz + 7566) / 15133), (u32) 18);
-
return ret ? ret : -ERANGE;
}
static int
-calc_clk(struct nva3_clock_priv *priv, struct nouveau_cstate *cstate,
+calc_clk(struct gt215_clk_priv *priv, struct nvkm_cstate *cstate,
int clk, u32 pll, int idx)
{
- int ret = nva3_pll_info(&priv->base, clk, pll, cstate->domain[idx],
- &priv->eng[idx]);
+ int ret = gt215_pll_info(&priv->base, clk, pll, cstate->domain[idx],
+ &priv->eng[idx]);
if (ret >= 0)
return 0;
return ret;
}
static int
-calc_host(struct nva3_clock_priv *priv, struct nouveau_cstate *cstate)
+calc_host(struct gt215_clk_priv *priv, struct nvkm_cstate *cstate)
{
int ret = 0;
u32 kHz = cstate->domain[nv_clk_src_host];
- struct nva3_clock_info *info = &priv->eng[nv_clk_src_host];
+ struct gt215_clk_info *info = &priv->eng[nv_clk_src_host];
if (kHz == 277000) {
info->clk = 0;
@@ -288,16 +287,17 @@ calc_host(struct nva3_clock_priv *priv, struct nouveau_cstate *cstate)
info->host_out = NVA3_HOST_CLK;
- ret = nva3_clk_info(&priv->base, 0x1d, kHz, info);
+ ret = gt215_clk_info(&priv->base, 0x1d, kHz, info);
if (ret >= 0)
return 0;
+
return ret;
}
int
-nva3_clock_pre(struct nouveau_clock *clk, unsigned long *flags)
+gt215_clk_pre(struct nvkm_clk *clk, unsigned long *flags)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(clk);
+ struct nvkm_fifo *pfifo = nvkm_fifo(clk);
/* halt and idle execution engines */
nv_mask(clk, 0x020060, 0x00070000, 0x00000000);
@@ -318,9 +318,9 @@ nva3_clock_pre(struct nouveau_clock *clk, unsigned long *flags)
}
void
-nva3_clock_post(struct nouveau_clock *clk, unsigned long *flags)
+gt215_clk_post(struct nvkm_clk *clk, unsigned long *flags)
{
- struct nouveau_fifo *pfifo = nouveau_fifo(clk);
+ struct nvkm_fifo *pfifo = nvkm_fifo(clk);
if (pfifo && flags)
pfifo->start(pfifo, flags);
@@ -330,16 +330,16 @@ nva3_clock_post(struct nouveau_clock *clk, unsigned long *flags)
}
static void
-disable_clk_src(struct nva3_clock_priv *priv, u32 src)
+disable_clk_src(struct gt215_clk_priv *priv, u32 src)
{
nv_mask(priv, src, 0x00000100, 0x00000000);
nv_mask(priv, src, 0x00000001, 0x00000000);
}
static void
-prog_pll(struct nva3_clock_priv *priv, int clk, u32 pll, int idx)
+prog_pll(struct gt215_clk_priv *priv, int clk, u32 pll, int idx)
{
- struct nva3_clock_info *info = &priv->eng[idx];
+ struct gt215_clk_info *info = &priv->eng[idx];
const u32 src0 = 0x004120 + (clk * 4);
const u32 src1 = 0x004160 + (clk * 4);
const u32 ctrl = pll + 0;
@@ -377,16 +377,16 @@ prog_pll(struct nva3_clock_priv *priv, int clk, u32 pll, int idx)
}
static void
-prog_clk(struct nva3_clock_priv *priv, int clk, int idx)
+prog_clk(struct gt215_clk_priv *priv, int clk, int idx)
{
- struct nva3_clock_info *info = &priv->eng[idx];
+ struct gt215_clk_info *info = &priv->eng[idx];
nv_mask(priv, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | info->clk);
}
static void
-prog_host(struct nva3_clock_priv *priv)
+prog_host(struct gt215_clk_priv *priv)
{
- struct nva3_clock_info *info = &priv->eng[nv_clk_src_host];
+ struct gt215_clk_info *info = &priv->eng[nv_clk_src_host];
u32 hsrc = (nv_rd32(priv, 0xc040));
switch (info->host_out) {
@@ -411,9 +411,9 @@ prog_host(struct nva3_clock_priv *priv)
}
static void
-prog_core(struct nva3_clock_priv *priv, int idx)
+prog_core(struct gt215_clk_priv *priv, int idx)
{
- struct nva3_clock_info *info = &priv->eng[idx];
+ struct gt215_clk_info *info = &priv->eng[idx];
u32 fb_delay = nv_rd32(priv, 0x10002c);
if (fb_delay < info->fb_delay)
@@ -426,10 +426,10 @@ prog_core(struct nva3_clock_priv *priv, int idx)
}
static int
-nva3_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
+gt215_clk_calc(struct nvkm_clk *clk, struct nvkm_cstate *cstate)
{
- struct nva3_clock_priv *priv = (void *)clk;
- struct nva3_clock_info *core = &priv->eng[nv_clk_src_core];
+ struct gt215_clk_priv *priv = (void *)clk;
+ struct gt215_clk_info *core = &priv->eng[nv_clk_src_core];
int ret;
if ((ret = calc_clk(priv, cstate, 0x10, 0x4200, nv_clk_src_core)) ||
@@ -442,9 +442,9 @@ nva3_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
/* XXX: Should be reading the highest bit in the VBIOS clock to decide
* whether to use a PLL or not... but using a PLL defeats the purpose */
if (core->pll) {
- ret = nva3_clk_info(clk, 0x10,
- cstate->domain[nv_clk_src_core_intm],
- &priv->eng[nv_clk_src_core_intm]);
+ ret = gt215_clk_info(clk, 0x10,
+ cstate->domain[nv_clk_src_core_intm],
+ &priv->eng[nv_clk_src_core_intm]);
if (ret < 0)
return ret;
}
@@ -453,15 +453,15 @@ nva3_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
}
static int
-nva3_clock_prog(struct nouveau_clock *clk)
+gt215_clk_prog(struct nvkm_clk *clk)
{
- struct nva3_clock_priv *priv = (void *)clk;
- struct nva3_clock_info *core = &priv->eng[nv_clk_src_core];
+ struct gt215_clk_priv *priv = (void *)clk;
+ struct gt215_clk_info *core = &priv->eng[nv_clk_src_core];
int ret = 0;
unsigned long flags;
unsigned long *f = &flags;
- ret = nva3_clock_pre(clk, f);
+ ret = gt215_clk_pre(clk, f);
if (ret)
goto out;
@@ -478,18 +478,17 @@ out:
if (ret == -EBUSY)
f = NULL;
- nva3_clock_post(clk, f);
-
+ gt215_clk_post(clk, f);
return ret;
}
static void
-nva3_clock_tidy(struct nouveau_clock *clk)
+gt215_clk_tidy(struct nvkm_clk *clk)
{
}
-static struct nouveau_clocks
-nva3_domain[] = {
+static struct nvkm_domain
+gt215_domain[] = {
{ nv_clk_src_crystal , 0xff },
{ nv_clk_src_core , 0x00, 0, "core", 1000 },
{ nv_clk_src_shader , 0x01, 0, "shader", 1000 },
@@ -502,33 +501,33 @@ nva3_domain[] = {
};
static int
-nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gt215_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nva3_clock_priv *priv;
+ struct gt215_clk_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, NULL, 0,
- true, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, gt215_domain,
+ NULL, 0, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.read = nva3_clock_read;
- priv->base.calc = nva3_clock_calc;
- priv->base.prog = nva3_clock_prog;
- priv->base.tidy = nva3_clock_tidy;
+ priv->base.read = gt215_clk_read;
+ priv->base.calc = gt215_clk_calc;
+ priv->base.prog = gt215_clk_prog;
+ priv->base.tidy = gt215_clk_tidy;
return 0;
}
-struct nouveau_oclass
-nva3_clock_oclass = {
- .handle = NV_SUBDEV(CLOCK, 0xa3),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass
+gt215_clk_oclass = {
+ .handle = NV_SUBDEV(CLK, 0xa3),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gt215_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.h b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.h
new file mode 100644
index 000000000000..b447d9cd4d37
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.h
@@ -0,0 +1,18 @@
+#ifndef __NVKM_CLK_NVA3_H__
+#define __NVKM_CLK_NVA3_H__
+#include <subdev/clk.h>
+
+struct gt215_clk_info {
+ u32 clk;
+ u32 pll;
+ enum {
+ NVA3_HOST_277,
+ NVA3_HOST_CLK,
+ } host_out;
+ u32 fb_delay;
+};
+
+int gt215_pll_info(struct nvkm_clk *, int, u32, u32, struct gt215_clk_info *);
+int gt215_clk_pre(struct nvkm_clk *clk, unsigned long *flags);
+void gt215_clk_post(struct nvkm_clk *clk, unsigned long *flags);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/mcp77.c
index 54aeab8005a0..c54417b146c7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/mcp77.c
@@ -21,18 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "gt215.h"
+#include "pll.h"
-#include <engine/fifo.h>
+#include <core/device.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
#include <subdev/timer.h>
-#include <subdev/clock.h>
-
-#include "nva3.h"
-#include "pll.h"
-struct nvaa_clock_priv {
- struct nouveau_clock base;
+struct mcp77_clk_priv {
+ struct nvkm_clk base;
enum nv_clk_src csrc, ssrc, vsrc;
u32 cctrl, sctrl;
u32 ccoef, scoef;
@@ -41,13 +39,13 @@ struct nvaa_clock_priv {
};
static u32
-read_div(struct nouveau_clock *clk)
+read_div(struct nvkm_clk *clk)
{
return nv_rd32(clk, 0x004600);
}
static u32
-read_pll(struct nouveau_clock *clk, u32 base)
+read_pll(struct nvkm_clk *clk, u32 base)
{
u32 ctrl = nv_rd32(clk, base + 0);
u32 coef = nv_rd32(clk, base + 4);
@@ -78,9 +76,9 @@ read_pll(struct nouveau_clock *clk, u32 base)
}
static int
-nvaa_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
+mcp77_clk_read(struct nvkm_clk *clk, enum nv_clk_src src)
{
- struct nvaa_clock_priv *priv = (void *)clk;
+ struct mcp77_clk_priv *priv = (void *)clk;
u32 mast = nv_rd32(clk, 0x00c054);
u32 P = 0;
@@ -160,12 +158,12 @@ nvaa_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
}
static u32
-calc_pll(struct nvaa_clock_priv *priv, u32 reg,
+calc_pll(struct mcp77_clk_priv *priv, u32 reg,
u32 clock, int *N, int *M, int *P)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll pll;
- struct nouveau_clock *clk = &priv->base;
+ struct nvkm_clk *clk = &priv->base;
int ret;
ret = nvbios_pll_parse(bios, reg, &pll);
@@ -199,9 +197,9 @@ calc_P(u32 src, u32 target, int *div)
}
static int
-nvaa_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
+mcp77_clk_calc(struct nvkm_clk *clk, struct nvkm_cstate *cstate)
{
- struct nvaa_clock_priv *priv = (void *)clk;
+ struct mcp77_clk_priv *priv = (void *)clk;
const int shader = cstate->domain[nv_clk_src_shader];
const int core = cstate->domain[nv_clk_src_core];
const int vdec = cstate->domain[nv_clk_src_vdec];
@@ -216,8 +214,7 @@ nvaa_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
/* Calculate clock * 2, so shader clock can use it too */
clock = calc_pll(priv, 0x4028, (core << 1), &N, &M, &P1);
- if (abs(core - out) <=
- abs(core - (clock >> 1))) {
+ if (abs(core - out) <= abs(core - (clock >> 1))) {
priv->csrc = nv_clk_src_hclkm4;
priv->cctrl = divs << 16;
} else {
@@ -242,9 +239,8 @@ nvaa_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
priv->ssrc = nv_clk_src_href;
} else {
clock = calc_pll(priv, 0x4020, shader, &N, &M, &P1);
- if (priv->csrc == nv_clk_src_core) {
+ if (priv->csrc == nv_clk_src_core)
out = calc_P((core << 1), shader, &divs);
- }
if (abs(shader - out) <=
abs(shader - clock) &&
@@ -261,8 +257,7 @@ nvaa_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
/* vclk */
out = calc_P(core, vdec, &divs);
clock = calc_P(500000, vdec, &P1);
- if(abs(vdec - out) <=
- abs(vdec - clock)) {
+ if(abs(vdec - out) <= abs(vdec - clock)) {
priv->vsrc = nv_clk_src_cclk;
priv->vdiv = divs << 16;
} else {
@@ -297,15 +292,15 @@ nvaa_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
}
static int
-nvaa_clock_prog(struct nouveau_clock *clk)
+mcp77_clk_prog(struct nvkm_clk *clk)
{
- struct nvaa_clock_priv *priv = (void *)clk;
+ struct mcp77_clk_priv *priv = (void *)clk;
u32 pllmask = 0, mast;
unsigned long flags;
unsigned long *f = &flags;
int ret = 0;
- ret = nva3_clock_pre(clk, f);
+ ret = gt215_clk_pre(clk, f);
if (ret)
goto out;
@@ -382,18 +377,17 @@ out:
if (ret == -EBUSY)
f = NULL;
- nva3_clock_post(clk, f);
-
+ gt215_clk_post(clk, f);
return ret;
}
static void
-nvaa_clock_tidy(struct nouveau_clock *clk)
+mcp77_clk_tidy(struct nvkm_clk *clk)
{
}
-static struct nouveau_clocks
-nvaa_domains[] = {
+static struct nvkm_domain
+mcp77_domains[] = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href , 0xff },
{ nv_clk_src_core , 0xff, 0, "core", 1000 },
@@ -403,33 +397,33 @@ nvaa_domains[] = {
};
static int
-nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+mcp77_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvaa_clock_priv *priv;
+ struct mcp77_clk_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, NULL,
- 0, true, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, mcp77_domains,
+ NULL, 0, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.read = nvaa_clock_read;
- priv->base.calc = nvaa_clock_calc;
- priv->base.prog = nvaa_clock_prog;
- priv->base.tidy = nvaa_clock_tidy;
+ priv->base.read = mcp77_clk_read;
+ priv->base.calc = mcp77_clk_calc;
+ priv->base.prog = mcp77_clk_prog;
+ priv->base.tidy = mcp77_clk_tidy;
return 0;
}
-struct nouveau_oclass *
-nvaa_clock_oclass = &(struct nouveau_oclass) {
- .handle = NV_SUBDEV(CLOCK, 0xaa),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvaa_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass *
+mcp77_clk_oclass = &(struct nvkm_oclass) {
+ .handle = NV_SUBDEV(CLK, 0xaa),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = mcp77_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv04.c
index 4c48232686be..63dbbb575228 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv04.c
@@ -21,21 +21,20 @@
*
* Authors: Ben Skeggs
*/
+#include <subdev/clk.h>
+#include "pll.h"
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include <subdev/clock.h>
#include <subdev/devinit/nv04.h>
-#include "pll.h"
-
-struct nv04_clock_priv {
- struct nouveau_clock base;
+struct nv04_clk_priv {
+ struct nvkm_clk base;
};
int
-nv04_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
- int clk, struct nouveau_pll_vals *pv)
+nv04_clk_pll_calc(struct nvkm_clk *clock, struct nvbios_pll *info,
+ int clk, struct nvkm_pll_vals *pv)
{
int N1, M1, N2, M2, P;
int ret = nv04_pll_calc(nv_subdev(clock), info, clk, &N1, &M1, &N2, &M2, &P);
@@ -51,11 +50,10 @@ nv04_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
}
int
-nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1,
- struct nouveau_pll_vals *pv)
+nv04_clk_pll_prog(struct nvkm_clk *clk, u32 reg1, struct nvkm_pll_vals *pv)
{
- struct nouveau_devinit *devinit = nouveau_devinit(clk);
- int cv = nouveau_bios(clk)->version.chip;
+ struct nvkm_devinit *devinit = nvkm_devinit(clk);
+ int cv = nvkm_bios(clk)->version.chip;
if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
cv >= 0x40) {
@@ -69,37 +67,37 @@ nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1,
return 0;
}
-static struct nouveau_clocks
+static struct nvkm_domain
nv04_domain[] = {
{ nv_clk_src_max }
};
static int
-nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv04_clock_priv *priv;
+ struct nv04_clk_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, NULL, 0,
- false, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, nv04_domain,
+ NULL, 0, false, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.pll_calc = nv04_clock_pll_calc;
- priv->base.pll_prog = nv04_clock_pll_prog;
+ priv->base.pll_calc = nv04_clk_pll_calc;
+ priv->base.pll_prog = nv04_clk_pll_prog;
return 0;
}
-struct nouveau_oclass
-nv04_clock_oclass = {
- .handle = NV_SUBDEV(CLOCK, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass
+nv04_clk_oclass = {
+ .handle = NV_SUBDEV(CLK, 0x04),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv04_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv40.c
index 08368fe97029..ed838130c89d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv40.c
@@ -21,22 +21,22 @@
*
* Authors: Ben Skeggs
*/
+#include <subdev/clk.h>
+#include "pll.h"
-#include <subdev/clock.h>
+#include <core/device.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include "pll.h"
-
-struct nv40_clock_priv {
- struct nouveau_clock base;
+struct nv40_clk_priv {
+ struct nvkm_clk base;
u32 ctrl;
u32 npll_ctrl;
u32 npll_coef;
u32 spll;
};
-static struct nouveau_clocks
+static struct nvkm_domain
nv40_domain[] = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href , 0xff },
@@ -47,7 +47,7 @@ nv40_domain[] = {
};
static u32
-read_pll_1(struct nv40_clock_priv *priv, u32 reg)
+read_pll_1(struct nv40_clk_priv *priv, u32 reg)
{
u32 ctrl = nv_rd32(priv, reg + 0x00);
int P = (ctrl & 0x00070000) >> 16;
@@ -62,7 +62,7 @@ read_pll_1(struct nv40_clock_priv *priv, u32 reg)
}
static u32
-read_pll_2(struct nv40_clock_priv *priv, u32 reg)
+read_pll_2(struct nv40_clk_priv *priv, u32 reg)
{
u32 ctrl = nv_rd32(priv, reg + 0x00);
u32 coef = nv_rd32(priv, reg + 0x04);
@@ -87,7 +87,7 @@ read_pll_2(struct nv40_clock_priv *priv, u32 reg)
}
static u32
-read_clk(struct nv40_clock_priv *priv, u32 src)
+read_clk(struct nv40_clk_priv *priv, u32 src)
{
switch (src) {
case 3:
@@ -102,9 +102,9 @@ read_clk(struct nv40_clock_priv *priv, u32 src)
}
static int
-nv40_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
+nv40_clk_read(struct nvkm_clk *clk, enum nv_clk_src src)
{
- struct nv40_clock_priv *priv = (void *)clk;
+ struct nv40_clk_priv *priv = (void *)clk;
u32 mast = nv_rd32(priv, 0x00c040);
switch (src) {
@@ -127,10 +127,10 @@ nv40_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
}
static int
-nv40_clock_calc_pll(struct nv40_clock_priv *priv, u32 reg, u32 clk,
- int *N1, int *M1, int *N2, int *M2, int *log2P)
+nv40_clk_calc_pll(struct nv40_clk_priv *priv, u32 reg, u32 clk,
+ int *N1, int *M1, int *N2, int *M2, int *log2P)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll pll;
int ret;
@@ -144,21 +144,22 @@ nv40_clock_calc_pll(struct nv40_clock_priv *priv, u32 reg, u32 clk,
ret = nv04_pll_calc(nv_subdev(priv), &pll, clk, N1, M1, N2, M2, log2P);
if (ret == 0)
return -ERANGE;
+
return ret;
}
static int
-nv40_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
+nv40_clk_calc(struct nvkm_clk *clk, struct nvkm_cstate *cstate)
{
- struct nv40_clock_priv *priv = (void *)clk;
+ struct nv40_clk_priv *priv = (void *)clk;
int gclk = cstate->domain[nv_clk_src_core];
int sclk = cstate->domain[nv_clk_src_shader];
int N1, M1, N2, M2, log2P;
int ret;
/* core/geometric clock */
- ret = nv40_clock_calc_pll(priv, 0x004000, gclk,
- &N1, &M1, &N2, &M2, &log2P);
+ ret = nv40_clk_calc_pll(priv, 0x004000, gclk,
+ &N1, &M1, &N2, &M2, &log2P);
if (ret < 0)
return ret;
@@ -172,8 +173,8 @@ nv40_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
/* use the second pll for shader/rop clock, if it differs from core */
if (sclk && sclk != gclk) {
- ret = nv40_clock_calc_pll(priv, 0x004008, sclk,
- &N1, &M1, NULL, NULL, &log2P);
+ ret = nv40_clk_calc_pll(priv, 0x004008, sclk,
+ &N1, &M1, NULL, NULL, &log2P);
if (ret < 0)
return ret;
@@ -188,9 +189,9 @@ nv40_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
}
static int
-nv40_clock_prog(struct nouveau_clock *clk)
+nv40_clk_prog(struct nvkm_clk *clk)
{
- struct nv40_clock_priv *priv = (void *)clk;
+ struct nv40_clk_priv *priv = (void *)clk;
nv_mask(priv, 0x00c040, 0x00000333, 0x00000000);
nv_wr32(priv, 0x004004, priv->npll_coef);
nv_mask(priv, 0x004000, 0xc0070100, priv->npll_ctrl);
@@ -201,40 +202,40 @@ nv40_clock_prog(struct nouveau_clock *clk)
}
static void
-nv40_clock_tidy(struct nouveau_clock *clk)
+nv40_clk_tidy(struct nvkm_clk *clk)
{
}
static int
-nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv40_clock_priv *priv;
+ struct nv40_clk_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, NULL, 0,
- true, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, nv40_domain,
+ NULL, 0, true, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- priv->base.pll_calc = nv04_clock_pll_calc;
- priv->base.pll_prog = nv04_clock_pll_prog;
- priv->base.read = nv40_clock_read;
- priv->base.calc = nv40_clock_calc;
- priv->base.prog = nv40_clock_prog;
- priv->base.tidy = nv40_clock_tidy;
+ priv->base.pll_calc = nv04_clk_pll_calc;
+ priv->base.pll_prog = nv04_clk_pll_prog;
+ priv->base.read = nv40_clk_read;
+ priv->base.calc = nv40_clk_calc;
+ priv->base.prog = nv40_clk_prog;
+ priv->base.tidy = nv40_clk_tidy;
return 0;
}
-struct nouveau_oclass
-nv40_clock_oclass = {
- .handle = NV_SUBDEV(CLOCK, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv40_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass
+nv40_clk_oclass = {
+ .handle = NV_SUBDEV(CLK, 0x40),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv40_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
index 5070ebc260f8..9b4ffd6347ce 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c
@@ -21,16 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
-#include <subdev/bios.h>
-#include <subdev/bios/pll.h>
-
#include "nv50.h"
#include "pll.h"
#include "seq.h"
+#include <core/device.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+
static u32
-read_div(struct nv50_clock_priv *priv)
+read_div(struct nv50_clk_priv *priv)
{
switch (nv_device(priv)->chipset) {
case 0x50: /* it exists, but only has bit 31, not the dividers.. */
@@ -49,9 +49,9 @@ read_div(struct nv50_clock_priv *priv)
}
static u32
-read_pll_src(struct nv50_clock_priv *priv, u32 base)
+read_pll_src(struct nv50_clk_priv *priv, u32 base)
{
- struct nouveau_clock *clk = &priv->base;
+ struct nvkm_clk *clk = &priv->base;
u32 coef, ref = clk->read(clk, nv_clk_src_crystal);
u32 rsel = nv_rd32(priv, 0x00e18c);
int P, N, M, id;
@@ -116,13 +116,14 @@ read_pll_src(struct nv50_clock_priv *priv, u32 base)
if (M)
return (ref * N / M) >> P;
+
return 0;
}
static u32
-read_pll_ref(struct nv50_clock_priv *priv, u32 base)
+read_pll_ref(struct nv50_clk_priv *priv, u32 base)
{
- struct nouveau_clock *clk = &priv->base;
+ struct nvkm_clk *clk = &priv->base;
u32 src, mast = nv_rd32(priv, 0x00c040);
switch (base) {
@@ -147,13 +148,14 @@ read_pll_ref(struct nv50_clock_priv *priv, u32 base)
if (src)
return clk->read(clk, nv_clk_src_href);
+
return read_pll_src(priv, base);
}
static u32
-read_pll(struct nv50_clock_priv *priv, u32 base)
+read_pll(struct nv50_clk_priv *priv, u32 base)
{
- struct nouveau_clock *clk = &priv->base;
+ struct nvkm_clk *clk = &priv->base;
u32 mast = nv_rd32(priv, 0x00c040);
u32 ctrl = nv_rd32(priv, base + 0);
u32 coef = nv_rd32(priv, base + 4);
@@ -162,7 +164,7 @@ read_pll(struct nv50_clock_priv *priv, u32 base)
int N1, N2, M1, M2;
if (base == 0x004028 && (mast & 0x00100000)) {
- /* wtf, appears to only disable post-divider on nva0 */
+ /* wtf, appears to only disable post-divider on gt200 */
if (nv_device(priv)->chipset != 0xa0)
return clk->read(clk, nv_clk_src_dom6);
}
@@ -185,9 +187,9 @@ read_pll(struct nv50_clock_priv *priv, u32 base)
}
static int
-nv50_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
+nv50_clk_read(struct nvkm_clk *clk, enum nv_clk_src src)
{
- struct nv50_clock_priv *priv = (void *)clk;
+ struct nv50_clk_priv *priv = (void *)clk;
u32 mast = nv_rd32(priv, 0x00c040);
u32 P = 0;
@@ -316,9 +318,9 @@ nv50_clock_read(struct nouveau_clock *clk, enum nv_clk_src src)
}
static u32
-calc_pll(struct nv50_clock_priv *priv, u32 reg, u32 clk, int *N, int *M, int *P)
+calc_pll(struct nv50_clk_priv *priv, u32 reg, u32 clk, int *N, int *M, int *P)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll pll;
int ret;
@@ -359,10 +361,10 @@ clk_same(u32 a, u32 b)
}
static int
-nv50_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
+nv50_clk_calc(struct nvkm_clk *clk, struct nvkm_cstate *cstate)
{
- struct nv50_clock_priv *priv = (void *)clk;
- struct nv50_clock_hwsq *hwsq = &priv->hwsq;
+ struct nv50_clk_priv *priv = (void *)clk;
+ struct nv50_clk_hwsq *hwsq = &priv->hwsq;
const int shader = cstate->domain[nv_clk_src_shader];
const int core = cstate->domain[nv_clk_src_core];
const int vdec = cstate->domain[nv_clk_src_vdec];
@@ -484,30 +486,30 @@ nv50_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate)
}
static int
-nv50_clock_prog(struct nouveau_clock *clk)
+nv50_clk_prog(struct nvkm_clk *clk)
{
- struct nv50_clock_priv *priv = (void *)clk;
+ struct nv50_clk_priv *priv = (void *)clk;
return clk_exec(&priv->hwsq, true);
}
static void
-nv50_clock_tidy(struct nouveau_clock *clk)
+nv50_clk_tidy(struct nvkm_clk *clk)
{
- struct nv50_clock_priv *priv = (void *)clk;
+ struct nv50_clk_priv *priv = (void *)clk;
clk_exec(&priv->hwsq, false);
}
int
-nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv50_clock_oclass *pclass = (void *)oclass;
- struct nv50_clock_priv *priv;
+ struct nv50_clk_oclass *pclass = (void *)oclass;
+ struct nv50_clk_priv *priv;
int ret;
- ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
- NULL, 0, false, &priv);
+ ret = nvkm_clk_create(parent, engine, oclass, pclass->domains,
+ NULL, 0, false, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -529,14 +531,14 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
priv->hwsq.r_mast = hwsq_reg(0x00c040);
- priv->base.read = nv50_clock_read;
- priv->base.calc = nv50_clock_calc;
- priv->base.prog = nv50_clock_prog;
- priv->base.tidy = nv50_clock_tidy;
+ priv->base.read = nv50_clk_read;
+ priv->base.calc = nv50_clk_calc;
+ priv->base.prog = nv50_clk_prog;
+ priv->base.tidy = nv50_clk_tidy;
return 0;
}
-static struct nouveau_clocks
+static struct nvkm_domain
nv50_domains[] = {
{ nv_clk_src_crystal, 0xff },
{ nv_clk_src_href , 0xff },
@@ -546,14 +548,14 @@ nv50_domains[] = {
{ nv_clk_src_max }
};
-struct nouveau_oclass *
-nv50_clock_oclass = &(struct nv50_clock_oclass) {
- .base.handle = NV_SUBDEV(CLOCK, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_clock_ctor,
- .dtor = _nouveau_clock_dtor,
- .init = _nouveau_clock_init,
- .fini = _nouveau_clock_fini,
+struct nvkm_oclass *
+nv50_clk_oclass = &(struct nv50_clk_oclass) {
+ .base.handle = NV_SUBDEV(CLK, 0x50),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_clk_ctor,
+ .dtor = _nvkm_clk_dtor,
+ .init = _nvkm_clk_init,
+ .fini = _nvkm_clk_fini,
},
.domains = nv50_domains,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.h
new file mode 100644
index 000000000000..0ead76a32f10
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.h
@@ -0,0 +1,28 @@
+#ifndef __NVKM_CLK_NV50_H__
+#define __NVKM_CLK_NV50_H__
+#include <subdev/bus/hwsq.h>
+#include <subdev/clk.h>
+
+struct nv50_clk_hwsq {
+ struct hwsq base;
+ struct hwsq_reg r_fifo;
+ struct hwsq_reg r_spll[2];
+ struct hwsq_reg r_nvpll[2];
+ struct hwsq_reg r_divs;
+ struct hwsq_reg r_mast;
+};
+
+struct nv50_clk_priv {
+ struct nvkm_clk base;
+ struct nv50_clk_hwsq hwsq;
+};
+
+int nv50_clk_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+
+struct nv50_clk_oclass {
+ struct nvkm_oclass base;
+ struct nvkm_domain *domains;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/pll.h b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/pll.h
new file mode 100644
index 000000000000..44020a30dee8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/pll.h
@@ -0,0 +1,11 @@
+#ifndef __NVKM_PLL_H__
+#define __NVKM_PLL_H__
+#include <core/os.h>
+struct nvkm_subdev;
+struct nvbios_pll;
+
+int nv04_pll_calc(struct nvkm_subdev *, struct nvbios_pll *, u32 freq,
+ int *N1, int *M1, int *N2, int *M2, int *P);
+int gt215_pll_calc(struct nvkm_subdev *, struct nvbios_pll *, u32 freq,
+ int *N, int *fN, int *M, int *P);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/pllgt215.c
index 8eca457c2814..783a3e78d632 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/pllgt215.c
@@ -21,16 +21,14 @@
*
* Authors: Ben Skeggs
*/
+#include "pll.h"
-#include <subdev/clock.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include "pll.h"
-
int
-nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
- u32 freq, int *pN, int *pfN, int *pM, int *P)
+gt215_pll_calc(struct nvkm_subdev *subdev, struct nvbios_pll *info,
+ u32 freq, int *pN, int *pfN, int *pM, int *P)
{
u32 best_err = ~0, err;
int M, lM, hM, N, fN;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/pllnv04.c
index b47d543ab2e3..f2292895a1a8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/pllnv04.c
@@ -20,14 +20,13 @@
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+#include "pll.h"
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
-#include "pll.h"
-
static int
-getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
+getMNP_single(struct nvkm_subdev *subdev, struct nvbios_pll *info, int clk,
int *pN, int *pM, int *pP)
{
/* Find M, N and P for a single stage PLL
@@ -38,7 +37,7 @@ getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
* "clk" parameter in kHz
* returns calculated clock
*/
- struct nouveau_bios *bios = nouveau_bios(subdev);
+ struct nvkm_bios *bios = nvkm_bios(subdev);
int minvco = info->vco1.min_freq, maxvco = info->vco1.max_freq;
int minM = info->vco1.min_m, maxM = info->vco1.max_m;
int minN = info->vco1.min_n, maxN = info->vco1.max_n;
@@ -126,7 +125,7 @@ getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
}
static int
-getMNP_double(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
+getMNP_double(struct nvkm_subdev *subdev, struct nvbios_pll *info, int clk,
int *pN1, int *pM1, int *pN2, int *pM2, int *pP)
{
/* Find M, N and P for a two stage PLL
@@ -137,7 +136,7 @@ getMNP_double(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
* "clk" parameter in kHz
* returns calculated clock
*/
- int chip_version = nouveau_bios(subdev)->version.chip;
+ int chip_version = nvkm_bios(subdev)->version.chip;
int minvco1 = info->vco1.min_freq, maxvco1 = info->vco1.max_freq;
int minvco2 = info->vco2.min_freq, maxvco2 = info->vco2.max_freq;
int minU1 = info->vco1.min_inputfreq, minU2 = info->vco2.min_inputfreq;
@@ -225,7 +224,7 @@ getMNP_double(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
}
int
-nv04_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info, u32 freq,
+nv04_pll_calc(struct nvkm_subdev *subdev, struct nvbios_pll *info, u32 freq,
int *N1, int *M1, int *N2, int *M2, int *P)
{
int ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/seq.h
index fb33f06ebd59..d717e8b8f679 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/seq.h
@@ -1,7 +1,5 @@
#ifndef __NVKM_CLK_SEQ_H__
#define __NVKM_CLK_SEQ_H__
-
-#include <subdev/bus.h>
#include <subdev/bus/hwsq.h>
#define clk_init(s,p) hwsq_init(&(s)->base, (p))
@@ -13,5 +11,4 @@
#define clk_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
#define clk_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
#define clk_nsec(s,n) hwsq_nsec(&(s)->base, (n))
-
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild
new file mode 100644
index 000000000000..793e73d16dac
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild
@@ -0,0 +1,14 @@
+nvkm-y += nvkm/subdev/devinit/base.o
+nvkm-y += nvkm/subdev/devinit/nv04.o
+nvkm-y += nvkm/subdev/devinit/nv05.o
+nvkm-y += nvkm/subdev/devinit/nv10.o
+nvkm-y += nvkm/subdev/devinit/nv1a.o
+nvkm-y += nvkm/subdev/devinit/nv20.o
+nvkm-y += nvkm/subdev/devinit/nv50.o
+nvkm-y += nvkm/subdev/devinit/g84.o
+nvkm-y += nvkm/subdev/devinit/g98.o
+nvkm-y += nvkm/subdev/devinit/gt215.o
+nvkm-y += nvkm/subdev/devinit/mcp89.o
+nvkm-y += nvkm/subdev/devinit/gf100.o
+nvkm-y += nvkm/subdev/devinit/gm107.o
+nvkm-y += nvkm/subdev/devinit/gm204.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
index 0e45cee82463..b0d7c5f40db1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
@@ -21,17 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
+#include <core/device.h>
#include <core/option.h>
-
#include <subdev/vga.h>
-#include "priv.h"
-
int
-_nouveau_devinit_fini(struct nouveau_object *object, bool suspend)
+_nvkm_devinit_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_devinit *devinit = (void *)object;
+ struct nvkm_devinit *devinit = (void *)object;
/* force full reinit on resume */
if (suspend)
@@ -40,17 +39,17 @@ _nouveau_devinit_fini(struct nouveau_object *object, bool suspend)
/* unlock the extended vga crtc regs */
nv_lockvgac(devinit, false);
- return nouveau_subdev_fini(&devinit->base, suspend);
+ return nvkm_subdev_fini(&devinit->base, suspend);
}
int
-_nouveau_devinit_init(struct nouveau_object *object)
+_nvkm_devinit_init(struct nvkm_object *object)
{
- struct nouveau_devinit_impl *impl = (void *)object->oclass;
- struct nouveau_devinit *devinit = (void *)object;
+ struct nvkm_devinit_impl *impl = (void *)object->oclass;
+ struct nvkm_devinit *devinit = (void *)object;
int ret;
- ret = nouveau_subdev_init(&devinit->base);
+ ret = nvkm_subdev_init(&devinit->base);
if (ret)
return ret;
@@ -64,34 +63,32 @@ _nouveau_devinit_init(struct nouveau_object *object)
}
void
-_nouveau_devinit_dtor(struct nouveau_object *object)
+_nvkm_devinit_dtor(struct nvkm_object *object)
{
- struct nouveau_devinit *devinit = (void *)object;
+ struct nvkm_devinit *devinit = (void *)object;
/* lock crtc regs */
nv_lockvgac(devinit, true);
- nouveau_subdev_destroy(&devinit->base);
+ nvkm_subdev_destroy(&devinit->base);
}
int
-nouveau_devinit_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int size, void **pobject)
+nvkm_devinit_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int size, void **pobject)
{
- struct nouveau_devinit_impl *impl = (void *)oclass;
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_devinit *devinit;
+ struct nvkm_devinit_impl *impl = (void *)oclass;
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_devinit *devinit;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "DEVINIT",
- "init", size, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "DEVINIT",
+ "init", size, pobject);
devinit = *pobject;
if (ret)
return ret;
- devinit->post = nouveau_boolopt(device->cfgopt, "NvForcePost", false);
+ devinit->post = nvkm_boolopt(device->cfgopt, "NvForcePost", false);
devinit->meminit = impl->meminit;
devinit->pll_set = impl->pll_set;
devinit->mmio = impl->mmio;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h
index 6103484fea72..36684c3f9e9c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h
@@ -23,9 +23,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include <core/device.h>
-
#include <subdev/fb/regsnv04.h>
#define NV04_PFB_DEBUG_0 0x00100080
@@ -48,7 +46,7 @@
# define NV10_PFB_REFCTRL_VALID_1 (1 << 31)
static inline struct io_mapping *
-fbmem_init(struct nouveau_device *dev)
+fbmem_init(struct nvkm_device *dev)
{
return io_mapping_create_wc(nv_device_resource_start(dev, 1),
nv_device_resource_len(dev, 1));
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c
index a7c80ded77cd..ca776ce75f4f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g84.c
@@ -21,11 +21,13 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+
static u64
-nv84_devinit_disable(struct nouveau_devinit *devinit)
+g84_devinit_disable(struct nvkm_devinit *devinit)
{
struct nv50_devinit_priv *priv = (void *)devinit;
u32 r001540 = nv_rd32(priv, 0x001540);
@@ -36,7 +38,7 @@ nv84_devinit_disable(struct nouveau_devinit *devinit)
disable |= (1ULL << NVDEV_ENGINE_MPEG);
disable |= (1ULL << NVDEV_ENGINE_VP);
disable |= (1ULL << NVDEV_ENGINE_BSP);
- disable |= (1ULL << NVDEV_ENGINE_CRYPT);
+ disable |= (1ULL << NVDEV_ENGINE_CIPHER);
}
if (!(r00154c & 0x00000004))
@@ -44,21 +46,21 @@ nv84_devinit_disable(struct nouveau_devinit *devinit)
if (!(r00154c & 0x00000020))
disable |= (1ULL << NVDEV_ENGINE_BSP);
if (!(r00154c & 0x00000040))
- disable |= (1ULL << NVDEV_ENGINE_CRYPT);
+ disable |= (1ULL << NVDEV_ENGINE_CIPHER);
return disable;
}
-struct nouveau_oclass *
-nv84_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+g84_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x84),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
.pll_set = nv50_devinit_pll_set,
- .disable = nv84_devinit_disable,
+ .disable = g84_devinit_disable,
.post = nvbios_init,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c
index a773253a17f6..d29bacee65ee 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/g98.c
@@ -21,11 +21,13 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+
static u64
-nv98_devinit_disable(struct nouveau_devinit *devinit)
+g98_devinit_disable(struct nvkm_devinit *devinit)
{
struct nv50_devinit_priv *priv = (void *)devinit;
u32 r001540 = nv_rd32(priv, 0x001540);
@@ -33,31 +35,31 @@ nv98_devinit_disable(struct nouveau_devinit *devinit)
u64 disable = 0ULL;
if (!(r001540 & 0x40000000)) {
- disable |= (1ULL << NVDEV_ENGINE_VP);
- disable |= (1ULL << NVDEV_ENGINE_BSP);
- disable |= (1ULL << NVDEV_ENGINE_PPP);
+ disable |= (1ULL << NVDEV_ENGINE_MSPDEC);
+ disable |= (1ULL << NVDEV_ENGINE_MSVLD);
+ disable |= (1ULL << NVDEV_ENGINE_MSPPP);
}
if (!(r00154c & 0x00000004))
disable |= (1ULL << NVDEV_ENGINE_DISP);
if (!(r00154c & 0x00000020))
- disable |= (1ULL << NVDEV_ENGINE_BSP);
+ disable |= (1ULL << NVDEV_ENGINE_MSVLD);
if (!(r00154c & 0x00000040))
- disable |= (1ULL << NVDEV_ENGINE_CRYPT);
+ disable |= (1ULL << NVDEV_ENGINE_SEC);
return disable;
}
-struct nouveau_oclass *
-nv98_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+g98_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x98),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
.pll_set = nv50_devinit_pll_set,
- .disable = nv98_devinit_disable,
+ .disable = g98_devinit_disable,
.post = nvbios_init,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
index 80bd7f5eda3d..e8778c67578e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
@@ -21,14 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+#include <subdev/bios/pll.h>
+#include <subdev/clk/pll.h>
+
int
-nvc0_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+gf100_devinit_pll_set(struct nvkm_devinit *devinit, u32 type, u32 freq)
{
struct nv50_devinit_priv *priv = (void *)devinit;
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll info;
int N, fN, M, P;
int ret;
@@ -37,7 +41,7 @@ nvc0_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
if (ret)
return ret;
- ret = nva3_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
+ ret = gt215_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
if (ret < 0)
return ret;
@@ -60,7 +64,7 @@ nvc0_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
}
static u64
-nvc0_devinit_disable(struct nouveau_devinit *devinit)
+gf100_devinit_disable(struct nvkm_devinit *devinit)
{
struct nv50_devinit_priv *priv = (void *)devinit;
u32 r022500 = nv_rd32(priv, 0x022500);
@@ -70,50 +74,51 @@ nvc0_devinit_disable(struct nouveau_devinit *devinit)
disable |= (1ULL << NVDEV_ENGINE_DISP);
if (r022500 & 0x00000002) {
- disable |= (1ULL << NVDEV_ENGINE_VP);
- disable |= (1ULL << NVDEV_ENGINE_PPP);
+ disable |= (1ULL << NVDEV_ENGINE_MSPDEC);
+ disable |= (1ULL << NVDEV_ENGINE_MSPPP);
}
if (r022500 & 0x00000004)
- disable |= (1ULL << NVDEV_ENGINE_BSP);
+ disable |= (1ULL << NVDEV_ENGINE_MSVLD);
if (r022500 & 0x00000008)
- disable |= (1ULL << NVDEV_ENGINE_VENC);
+ disable |= (1ULL << NVDEV_ENGINE_MSENC);
if (r022500 & 0x00000100)
- disable |= (1ULL << NVDEV_ENGINE_COPY0);
+ disable |= (1ULL << NVDEV_ENGINE_CE0);
if (r022500 & 0x00000200)
- disable |= (1ULL << NVDEV_ENGINE_COPY1);
+ disable |= (1ULL << NVDEV_ENGINE_CE1);
return disable;
}
static int
-nvc0_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_devinit_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_devinit_priv *priv;
int ret;
- ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ ret = nvkm_devinit_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
if (nv_rd32(priv, 0x022500) & 0x00000001)
priv->base.post = true;
+
return 0;
}
-struct nouveau_oclass *
-nvc0_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+gf100_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_devinit_ctor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
- .pll_set = nvc0_devinit_pll_set,
- .disable = nvc0_devinit_disable,
+ .pll_set = gf100_devinit_pll_set,
+ .disable = gf100_devinit_disable,
.post = nvbios_init,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
index 4ba43d6a1ec8..b345a53e881d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
@@ -21,11 +21,13 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+
u64
-gm107_devinit_disable(struct nouveau_devinit *devinit)
+gm107_devinit_disable(struct nvkm_devinit *devinit)
{
struct nv50_devinit_priv *priv = (void *)devinit;
u32 r021c00 = nv_rd32(priv, 0x021c00);
@@ -33,25 +35,25 @@ gm107_devinit_disable(struct nouveau_devinit *devinit)
u64 disable = 0ULL;
if (r021c00 & 0x00000001)
- disable |= (1ULL << NVDEV_ENGINE_COPY0);
+ disable |= (1ULL << NVDEV_ENGINE_CE0);
if (r021c00 & 0x00000004)
- disable |= (1ULL << NVDEV_ENGINE_COPY2);
+ disable |= (1ULL << NVDEV_ENGINE_CE2);
if (r021c04 & 0x00000001)
disable |= (1ULL << NVDEV_ENGINE_DISP);
return disable;
}
-struct nouveau_oclass *
-gm107_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+gm107_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x07),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
- .pll_set = nvc0_devinit_pll_set,
+ .pll_set = gf100_devinit_pll_set,
.disable = gm107_devinit_disable,
.post = nvbios_init,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c
index e44a86662a2a..535172c5f1ad 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c
@@ -21,17 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/pmu.h>
-#include "nv50.h"
-
static void
pmu_code(struct nv50_devinit_priv *priv, u32 pmu, u32 img, u32 len, bool sec)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
int i;
nv_wr32(priv, 0x10a180, 0x01000000 | (sec ? 0x10000000 : 0) | pmu);
@@ -50,7 +49,7 @@ pmu_code(struct nv50_devinit_priv *priv, u32 pmu, u32 img, u32 len, bool sec)
static void
pmu_data(struct nv50_devinit_priv *priv, u32 pmu, u32 img, u32 len)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
int i;
nv_wr32(priv, 0x10a1c0, 0x01000000 | pmu);
@@ -78,7 +77,7 @@ static int
pmu_load(struct nv50_devinit_priv *priv, u8 type, bool post,
u32 *init_addr_pmu, u32 *args_addr_pmu)
{
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pmuR pmu;
if (!nvbios_pmuRm(bios, type, &pmu)) {
@@ -103,10 +102,10 @@ pmu_load(struct nv50_devinit_priv *priv, u8 type, bool post,
}
static int
-gm204_devinit_post(struct nouveau_subdev *subdev, bool post)
+gm204_devinit_post(struct nvkm_subdev *subdev, bool post)
{
- struct nv50_devinit_priv *priv = (void *)nouveau_devinit(subdev);
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nv50_devinit_priv *priv = (void *)nvkm_devinit(subdev);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct bit_entry bit_I;
u32 init, args;
int ret;
@@ -158,16 +157,16 @@ gm204_devinit_post(struct nouveau_subdev *subdev, bool post)
return pmu_load(priv, 0x01, post, NULL, NULL);
}
-struct nouveau_oclass *
-gm204_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+gm204_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x07),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
- .pll_set = nvc0_devinit_pll_set,
+ .pll_set = gf100_devinit_pll_set,
.disable = gm107_devinit_disable,
.post = gm204_devinit_post,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gt215.c
index b9cd9e53f760..6a3e8d4efed7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gt215.c
@@ -21,14 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+#include <subdev/bios/pll.h>
+#include <subdev/clk/pll.h>
+
int
-nva3_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+gt215_devinit_pll_set(struct nvkm_devinit *devinit, u32 type, u32 freq)
{
struct nv50_devinit_priv *priv = (void *)devinit;
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll info;
int N, fN, M, P;
int ret;
@@ -37,7 +41,7 @@ nva3_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
if (ret)
return ret;
- ret = nva3_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
+ ret = gt215_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
if (ret < 0)
return ret;
@@ -59,7 +63,7 @@ nva3_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
}
static u64
-nva3_devinit_disable(struct nouveau_devinit *devinit)
+gt215_devinit_disable(struct nvkm_devinit *devinit)
{
struct nv50_devinit_priv *priv = (void *)devinit;
u32 r001540 = nv_rd32(priv, 0x001540);
@@ -67,22 +71,22 @@ nva3_devinit_disable(struct nouveau_devinit *devinit)
u64 disable = 0ULL;
if (!(r001540 & 0x40000000)) {
- disable |= (1ULL << NVDEV_ENGINE_VP);
- disable |= (1ULL << NVDEV_ENGINE_PPP);
+ disable |= (1ULL << NVDEV_ENGINE_MSPDEC);
+ disable |= (1ULL << NVDEV_ENGINE_MSPPP);
}
if (!(r00154c & 0x00000004))
disable |= (1ULL << NVDEV_ENGINE_DISP);
if (!(r00154c & 0x00000020))
- disable |= (1ULL << NVDEV_ENGINE_BSP);
+ disable |= (1ULL << NVDEV_ENGINE_MSVLD);
if (!(r00154c & 0x00000200))
- disable |= (1ULL << NVDEV_ENGINE_COPY0);
+ disable |= (1ULL << NVDEV_ENGINE_CE0);
return disable;
}
static u32
-nva3_devinit_mmio_part[] = {
+gt215_devinit_mmio_part[] = {
0x100720, 0x1008bc, 4,
0x100a20, 0x100adc, 4,
0x100d80, 0x100ddc, 4,
@@ -95,10 +99,10 @@ nva3_devinit_mmio_part[] = {
};
static u32
-nva3_devinit_mmio(struct nouveau_devinit *devinit, u32 addr)
+gt215_devinit_mmio(struct nvkm_devinit *devinit, u32 addr)
{
struct nv50_devinit_priv *priv = (void *)devinit;
- u32 *mmio = nva3_devinit_mmio_part;
+ u32 *mmio = gt215_devinit_mmio_part;
/* the init tables on some boards have INIT_RAM_RESTRICT_ZM_REG_GROUP
* instructions which touch registers that may not even exist on
@@ -130,17 +134,17 @@ nva3_devinit_mmio(struct nouveau_devinit *devinit, u32 addr)
return addr;
}
-struct nouveau_oclass *
-nva3_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+gt215_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0xa3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
- .pll_set = nva3_devinit_pll_set,
- .disable = nva3_devinit_disable,
- .mmio = nva3_devinit_mmio,
+ .pll_set = gt215_devinit_pll_set,
+ .disable = gt215_devinit_disable,
+ .mmio = gt215_devinit_mmio,
.post = nvbios_init,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c
index 3729846a8e5c..55cf48bbca1c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/mcp89.c
@@ -21,11 +21,13 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+
static u64
-nvaf_devinit_disable(struct nouveau_devinit *devinit)
+mcp89_devinit_disable(struct nvkm_devinit *devinit)
{
struct nv50_devinit_priv *priv = (void *)devinit;
u32 r001540 = nv_rd32(priv, 0x001540);
@@ -33,32 +35,32 @@ nvaf_devinit_disable(struct nouveau_devinit *devinit)
u64 disable = 0;
if (!(r001540 & 0x40000000)) {
- disable |= (1ULL << NVDEV_ENGINE_VP);
- disable |= (1ULL << NVDEV_ENGINE_PPP);
+ disable |= (1ULL << NVDEV_ENGINE_MSPDEC);
+ disable |= (1ULL << NVDEV_ENGINE_MSPPP);
}
if (!(r00154c & 0x00000004))
disable |= (1ULL << NVDEV_ENGINE_DISP);
if (!(r00154c & 0x00000020))
- disable |= (1ULL << NVDEV_ENGINE_BSP);
+ disable |= (1ULL << NVDEV_ENGINE_MSVLD);
if (!(r00154c & 0x00000040))
disable |= (1ULL << NVDEV_ENGINE_VIC);
if (!(r00154c & 0x00000200))
- disable |= (1ULL << NVDEV_ENGINE_COPY0);
+ disable |= (1ULL << NVDEV_ENGINE_CE0);
return disable;
}
-struct nouveau_oclass *
-nvaf_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+mcp89_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0xaf),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
- .pll_set = nva3_devinit_pll_set,
- .disable = nvaf_devinit_disable,
+ .pll_set = gt215_devinit_pll_set,
+ .disable = mcp89_devinit_disable,
.post = nvbios_init,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c
index 65651c50f6ea..03a0da834244 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c
@@ -23,14 +23,17 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
+#include "nv04.h"
+#include "fbmem.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+#include <subdev/bios/pll.h>
+#include <subdev/clk/pll.h>
#include <subdev/vga.h>
-#include "fbmem.h"
-#include "nv04.h"
-
static void
-nv04_devinit_meminit(struct nouveau_devinit *devinit)
+nv04_devinit_meminit(struct nvkm_devinit *devinit)
{
struct nv04_devinit_priv *priv = (void *)devinit;
u32 patt = 0xdeadbeef;
@@ -136,10 +139,10 @@ powerctrl_1_shift(int chip_version, int reg)
}
void
-setPLL_single(struct nouveau_devinit *devinit, u32 reg,
- struct nouveau_pll_vals *pv)
+setPLL_single(struct nvkm_devinit *devinit, u32 reg,
+ struct nvkm_pll_vals *pv)
{
- int chip_version = nouveau_bios(devinit)->version.chip;
+ int chip_version = nvkm_bios(devinit)->version.chip;
uint32_t oldpll = nv_rd32(devinit, reg);
int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
@@ -190,10 +193,10 @@ new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
}
void
-setPLL_double_highregs(struct nouveau_devinit *devinit, u32 reg1,
- struct nouveau_pll_vals *pv)
+setPLL_double_highregs(struct nvkm_devinit *devinit, u32 reg1,
+ struct nvkm_pll_vals *pv)
{
- int chip_version = nouveau_bios(devinit)->version.chip;
+ int chip_version = nvkm_bios(devinit)->version.chip;
bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
uint32_t reg2 = reg1 + ((reg1 == 0x680520) ? 0x5c : 0x70);
uint32_t oldpll1 = nv_rd32(devinit, reg1);
@@ -267,8 +270,8 @@ setPLL_double_highregs(struct nouveau_devinit *devinit, u32 reg1,
}
void
-setPLL_double_lowregs(struct nouveau_devinit *devinit, u32 NMNMreg,
- struct nouveau_pll_vals *pv)
+setPLL_double_lowregs(struct nvkm_devinit *devinit, u32 NMNMreg,
+ struct nvkm_pll_vals *pv)
{
/* When setting PLLs, there is a merry game of disabling and enabling
* various bits of hardware during the process. This function is a
@@ -301,7 +304,7 @@ setPLL_double_lowregs(struct nouveau_devinit *devinit, u32 NMNMreg,
struct nvbios_pll info;
uint8_t Pval2;
- if (nvbios_pll_parse(nouveau_bios(devinit), Preg, &info))
+ if (nvbios_pll_parse(nvkm_bios(devinit), Preg, &info))
return;
Pval2 = pv->log2P + info.bias_p;
@@ -347,10 +350,10 @@ setPLL_double_lowregs(struct nouveau_devinit *devinit, u32 NMNMreg,
}
int
-nv04_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+nv04_devinit_pll_set(struct nvkm_devinit *devinit, u32 type, u32 freq)
{
- struct nouveau_bios *bios = nouveau_bios(devinit);
- struct nouveau_pll_vals pv;
+ struct nvkm_bios *bios = nvkm_bios(devinit);
+ struct nvkm_pll_vals pv;
struct nvbios_pll info;
int cv = bios->version.chip;
int N1, M1, N2, M2, P;
@@ -361,7 +364,7 @@ nv04_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
return ret;
ret = nv04_pll_calc(nv_subdev(devinit), &info, freq,
- &N1, &M1, &N2, &M2, &P);
+ &N1, &M1, &N2, &M2, &P);
if (!ret)
return -EINVAL;
@@ -385,7 +388,7 @@ nv04_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
}
int
-nv04_devinit_fini(struct nouveau_object *object, bool suspend)
+nv04_devinit_fini(struct nvkm_object *object, bool suspend)
{
struct nv04_devinit_priv *priv = (void *)object;
int ret;
@@ -393,7 +396,7 @@ nv04_devinit_fini(struct nouveau_object *object, bool suspend)
/* make i2c busses accessible */
nv_mask(priv, 0x000200, 0x00000001, 0x00000001);
- ret = nouveau_devinit_fini(&priv->base, suspend);
+ ret = nvkm_devinit_fini(&priv->base, suspend);
if (ret)
return ret;
@@ -401,12 +404,11 @@ nv04_devinit_fini(struct nouveau_object *object, bool suspend)
if (priv->owner < 0)
priv->owner = nv_rdvgaowner(priv);
nv_wrvgaowner(priv, 0);
-
return 0;
}
int
-nv04_devinit_init(struct nouveau_object *object)
+nv04_devinit_init(struct nvkm_object *object)
{
struct nv04_devinit_priv *priv = (void *)object;
@@ -422,29 +424,29 @@ nv04_devinit_init(struct nouveau_object *object)
}
}
- return nouveau_devinit_init(&priv->base);
+ return nvkm_devinit_init(&priv->base);
}
void
-nv04_devinit_dtor(struct nouveau_object *object)
+nv04_devinit_dtor(struct nvkm_object *object)
{
struct nv04_devinit_priv *priv = (void *)object;
/* restore vga owner saved at first init */
nv_wrvgaowner(priv, priv->owner);
- nouveau_devinit_destroy(&priv->base);
+ nvkm_devinit_destroy(&priv->base);
}
int
-nv04_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_devinit_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_devinit_priv *priv;
int ret;
- ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ ret = nvkm_devinit_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -453,10 +455,10 @@ nv04_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv04_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+nv04_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_devinit_ctor,
.dtor = nv04_devinit_dtor,
.init = nv04_devinit_init,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.h
new file mode 100644
index 000000000000..14a51a9ff7d0
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.h
@@ -0,0 +1,22 @@
+#ifndef __NVKM_DEVINIT_NV04_H__
+#define __NVKM_DEVINIT_NV04_H__
+#include "priv.h"
+struct nvkm_pll_vals;
+
+struct nv04_devinit_priv {
+ struct nvkm_devinit base;
+ u8 owner;
+};
+
+int nv04_devinit_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv04_devinit_dtor(struct nvkm_object *);
+int nv04_devinit_init(struct nvkm_object *);
+int nv04_devinit_fini(struct nvkm_object *, bool);
+int nv04_devinit_pll_set(struct nvkm_devinit *, u32, u32);
+
+void setPLL_single(struct nvkm_devinit *, u32, struct nvkm_pll_vals *);
+void setPLL_double_highregs(struct nvkm_devinit *, u32, struct nvkm_pll_vals *);
+void setPLL_double_lowregs(struct nvkm_devinit *, u32, struct nvkm_pll_vals *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv05.c
index a2007a3efc4d..def8649216c2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv05.c
@@ -23,16 +23,16 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
+#include "nv04.h"
+#include "fbmem.h"
#include <subdev/bios.h>
#include <subdev/bios/bmp.h>
+#include <subdev/bios/init.h>
#include <subdev/vga.h>
-#include "fbmem.h"
-#include "nv04.h"
-
static void
-nv05_devinit_meminit(struct nouveau_devinit *devinit)
+nv05_devinit_meminit(struct nvkm_devinit *devinit)
{
static const u8 default_config_tab[][2] = {
{ 0x24, 0x00 },
@@ -45,7 +45,7 @@ nv05_devinit_meminit(struct nouveau_devinit *devinit)
{ 0x00, 0x00 }
};
struct nv04_devinit_priv *priv = (void *)devinit;
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct io_mapping *fb;
u32 patt = 0xdeadbeef;
u16 data;
@@ -125,10 +125,10 @@ out:
fbmem_fini(fb);
}
-struct nouveau_oclass *
-nv05_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+nv05_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x05),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_devinit_ctor,
.dtor = nv04_devinit_dtor,
.init = nv04_devinit_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv10.c
index 178b46f79b50..7aabc1bf0640 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv10.c
@@ -23,14 +23,14 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
-#include <subdev/vga.h>
-
-#include "fbmem.h"
#include "nv04.h"
+#include "fbmem.h"
+
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
static void
-nv10_devinit_meminit(struct nouveau_devinit *devinit)
+nv10_devinit_meminit(struct nvkm_devinit *devinit)
{
struct nv04_devinit_priv *priv = (void *)devinit;
static const int mem_width[] = { 0x10, 0x00, 0x20 };
@@ -96,10 +96,10 @@ amount_found:
fbmem_fini(fb);
}
-struct nouveau_oclass *
-nv10_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+nv10_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x10),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_devinit_ctor,
.dtor = nv04_devinit_dtor,
.init = nv04_devinit_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv1a.c
index 995dd97af3e9..9f36fff5a1c3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv1a.c
@@ -21,13 +21,15 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-struct nouveau_oclass *
-nv1a_devinit_oclass = &(struct nouveau_devinit_impl) {
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+
+struct nvkm_oclass *
+nv1a_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x1a),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_devinit_ctor,
.dtor = nv04_devinit_dtor,
.init = nv04_devinit_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv20.c
index 915089fb46f7..02fcfd921c42 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv20.c
@@ -23,15 +23,17 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
#include "fbmem.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+
static void
-nv20_devinit_meminit(struct nouveau_devinit *devinit)
+nv20_devinit_meminit(struct nvkm_devinit *devinit)
{
struct nv04_devinit_priv *priv = (void *)devinit;
- struct nouveau_device *device = nv_device(priv);
+ struct nvkm_device *device = nv_device(priv);
uint32_t mask = (device->chipset >= 0x25 ? 0x300 : 0x900);
uint32_t amount, off;
struct io_mapping *fb;
@@ -60,10 +62,10 @@ nv20_devinit_meminit(struct nouveau_devinit *devinit)
fbmem_fini(fb);
}
-struct nouveau_oclass *
-nv20_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+nv20_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x20),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_devinit_ctor,
.dtor = nv04_devinit_dtor,
.init = nv04_devinit_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c
index 968334d1dca4..26b7cb13e167 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c
@@ -21,21 +21,22 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/disp.h>
#include <subdev/bios/init.h>
+#include <subdev/bios/pll.h>
+#include <subdev/clk/pll.h>
#include <subdev/ibus.h>
#include <subdev/vga.h>
-#include "nv50.h"
-
int
-nv50_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+nv50_devinit_pll_set(struct nvkm_devinit *devinit, u32 type, u32 freq)
{
struct nv50_devinit_priv *priv = (void *)devinit;
- struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvkm_bios *bios = nvkm_bios(priv);
struct nvbios_pll info;
int N1, M1, N2, M2, P;
int ret;
@@ -76,7 +77,7 @@ nv50_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
}
static u64
-nv50_devinit_disable(struct nouveau_devinit *devinit)
+nv50_devinit_disable(struct nvkm_devinit *devinit)
{
struct nv50_devinit_priv *priv = (void *)devinit;
u32 r001540 = nv_rd32(priv, 0x001540);
@@ -89,10 +90,10 @@ nv50_devinit_disable(struct nouveau_devinit *devinit)
}
int
-nv50_devinit_init(struct nouveau_object *object)
+nv50_devinit_init(struct nvkm_object *object)
{
- struct nouveau_bios *bios = nouveau_bios(object);
- struct nouveau_ibus *ibus = nouveau_ibus(object);
+ struct nvkm_bios *bios = nvkm_bios(object);
+ struct nvkm_ibus *ibus = nvkm_ibus(object);
struct nv50_devinit_priv *priv = (void *)object;
struct nvbios_outp info;
struct dcb_output outp;
@@ -114,7 +115,7 @@ nv50_devinit_init(struct nouveau_object *object)
if (priv->base.post && ibus)
nv_ofuncs(ibus)->init(nv_object(ibus));
- ret = nouveau_devinit_init(&priv->base);
+ ret = nvkm_devinit_init(&priv->base);
if (ret)
return ret;
@@ -124,7 +125,7 @@ nv50_devinit_init(struct nouveau_object *object)
*/
while (priv->base.post && dcb_outp_parse(bios, i, &ver, &hdr, &outp)) {
if (nvbios_outp_match(bios, outp.hasht, outp.hashm,
- &ver, &hdr, &cnt, &len, &info)) {
+ &ver, &hdr, &cnt, &len, &info)) {
struct nvbios_init init = {
.subdev = nv_subdev(priv),
.bios = bios,
@@ -143,14 +144,14 @@ nv50_devinit_init(struct nouveau_object *object)
}
int
-nv50_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_devinit_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_devinit_priv *priv;
int ret;
- ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+ ret = nvkm_devinit_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -158,14 +159,14 @@ nv50_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv50_devinit_oclass = &(struct nouveau_devinit_impl) {
+struct nvkm_oclass *
+nv50_devinit_oclass = &(struct nvkm_devinit_impl) {
.base.handle = NV_SUBDEV(DEVINIT, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_devinit_ctor,
- .dtor = _nouveau_devinit_dtor,
+ .dtor = _nvkm_devinit_dtor,
.init = nv50_devinit_init,
- .fini = _nouveau_devinit_fini,
+ .fini = _nvkm_devinit_fini,
},
.pll_set = nv50_devinit_pll_set,
.disable = nv50_devinit_disable,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h
new file mode 100644
index 000000000000..b882b65ff3cd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h
@@ -0,0 +1,21 @@
+#ifndef __NVKM_DEVINIT_NV50_H__
+#define __NVKM_DEVINIT_NV50_H__
+#include "priv.h"
+
+struct nv50_devinit_priv {
+ struct nvkm_devinit base;
+ u32 r001540;
+};
+
+int nv50_devinit_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+int nv50_devinit_init(struct nvkm_object *);
+int nv50_devinit_pll_set(struct nvkm_devinit *, u32, u32);
+
+int gt215_devinit_pll_set(struct nvkm_devinit *, u32, u32);
+
+int gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32);
+
+u64 gm107_devinit_disable(struct nvkm_devinit *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/priv.h
new file mode 100644
index 000000000000..bb51a95d8012
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/priv.h
@@ -0,0 +1,34 @@
+#ifndef __NVKM_DEVINIT_PRIV_H__
+#define __NVKM_DEVINIT_PRIV_H__
+#include <subdev/devinit.h>
+
+struct nvkm_devinit_impl {
+ struct nvkm_oclass base;
+ void (*meminit)(struct nvkm_devinit *);
+ int (*pll_set)(struct nvkm_devinit *, u32 type, u32 freq);
+ u64 (*disable)(struct nvkm_devinit *);
+ u32 (*mmio)(struct nvkm_devinit *, u32);
+ int (*post)(struct nvkm_subdev *, bool);
+};
+
+#define nvkm_devinit_create(p,e,o,d) \
+ nvkm_devinit_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_devinit_destroy(p) ({ \
+ struct nvkm_devinit *d = (p); \
+ _nvkm_devinit_dtor(nv_object(d)); \
+})
+#define nvkm_devinit_init(p) ({ \
+ struct nvkm_devinit *d = (p); \
+ _nvkm_devinit_init(nv_object(d)); \
+})
+#define nvkm_devinit_fini(p,s) ({ \
+ struct nvkm_devinit *d = (p); \
+ _nvkm_devinit_fini(nv_object(d), (s)); \
+})
+
+int nvkm_devinit_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_devinit_dtor(struct nvkm_object *);
+int _nvkm_devinit_init(struct nvkm_object *);
+int _nvkm_devinit_fini(struct nvkm_object *, bool suspend);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
new file mode 100644
index 000000000000..904d601e8a50
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
@@ -0,0 +1,45 @@
+nvkm-y += nvkm/subdev/fb/base.o
+nvkm-y += nvkm/subdev/fb/nv04.o
+nvkm-y += nvkm/subdev/fb/nv10.o
+nvkm-y += nvkm/subdev/fb/nv1a.o
+nvkm-y += nvkm/subdev/fb/nv20.o
+nvkm-y += nvkm/subdev/fb/nv25.o
+nvkm-y += nvkm/subdev/fb/nv30.o
+nvkm-y += nvkm/subdev/fb/nv35.o
+nvkm-y += nvkm/subdev/fb/nv36.o
+nvkm-y += nvkm/subdev/fb/nv40.o
+nvkm-y += nvkm/subdev/fb/nv41.o
+nvkm-y += nvkm/subdev/fb/nv44.o
+nvkm-y += nvkm/subdev/fb/nv46.o
+nvkm-y += nvkm/subdev/fb/nv47.o
+nvkm-y += nvkm/subdev/fb/nv49.o
+nvkm-y += nvkm/subdev/fb/nv4e.o
+nvkm-y += nvkm/subdev/fb/nv50.o
+nvkm-y += nvkm/subdev/fb/g84.o
+nvkm-y += nvkm/subdev/fb/gt215.o
+nvkm-y += nvkm/subdev/fb/mcp77.o
+nvkm-y += nvkm/subdev/fb/mcp89.o
+nvkm-y += nvkm/subdev/fb/gf100.o
+nvkm-y += nvkm/subdev/fb/gk104.o
+nvkm-y += nvkm/subdev/fb/gk20a.o
+nvkm-y += nvkm/subdev/fb/gm107.o
+nvkm-y += nvkm/subdev/fb/ramnv04.o
+nvkm-y += nvkm/subdev/fb/ramnv10.o
+nvkm-y += nvkm/subdev/fb/ramnv1a.o
+nvkm-y += nvkm/subdev/fb/ramnv20.o
+nvkm-y += nvkm/subdev/fb/ramnv40.o
+nvkm-y += nvkm/subdev/fb/ramnv41.o
+nvkm-y += nvkm/subdev/fb/ramnv44.o
+nvkm-y += nvkm/subdev/fb/ramnv49.o
+nvkm-y += nvkm/subdev/fb/ramnv4e.o
+nvkm-y += nvkm/subdev/fb/ramnv50.o
+nvkm-y += nvkm/subdev/fb/ramgt215.o
+nvkm-y += nvkm/subdev/fb/rammcp77.o
+nvkm-y += nvkm/subdev/fb/ramgf100.o
+nvkm-y += nvkm/subdev/fb/ramgk104.o
+nvkm-y += nvkm/subdev/fb/ramgk20a.o
+nvkm-y += nvkm/subdev/fb/ramgm107.o
+nvkm-y += nvkm/subdev/fb/sddr2.o
+nvkm-y += nvkm/subdev/fb/sddr3.o
+nvkm-y += nvkm/subdev/fb/gddr3.o
+nvkm-y += nvkm/subdev/fb/gddr5.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
index c866148c440f..16589fa613cd 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
@@ -21,14 +21,13 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/bios.h>
#include <subdev/bios/M0203.h>
-#include "priv.h"
-
int
-nouveau_fb_bios_memtype(struct nouveau_bios *bios)
+nvkm_fb_bios_memtype(struct nvkm_bios *bios)
{
const u8 ramcfg = (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2;
struct nvbios_M0203E M0203E;
@@ -51,25 +50,25 @@ nouveau_fb_bios_memtype(struct nouveau_bios *bios)
}
int
-_nouveau_fb_fini(struct nouveau_object *object, bool suspend)
+_nvkm_fb_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_fb *pfb = (void *)object;
+ struct nvkm_fb *pfb = (void *)object;
int ret;
ret = nv_ofuncs(pfb->ram)->fini(nv_object(pfb->ram), suspend);
if (ret && suspend)
return ret;
- return nouveau_subdev_fini(&pfb->base, suspend);
+ return nvkm_subdev_fini(&pfb->base, suspend);
}
int
-_nouveau_fb_init(struct nouveau_object *object)
+_nvkm_fb_init(struct nvkm_object *object)
{
- struct nouveau_fb *pfb = (void *)object;
+ struct nvkm_fb *pfb = (void *)object;
int ret, i;
- ret = nouveau_subdev_init(&pfb->base);
+ ret = nvkm_subdev_init(&pfb->base);
if (ret)
return ret;
@@ -84,25 +83,25 @@ _nouveau_fb_init(struct nouveau_object *object)
}
void
-_nouveau_fb_dtor(struct nouveau_object *object)
+_nvkm_fb_dtor(struct nvkm_object *object)
{
- struct nouveau_fb *pfb = (void *)object;
+ struct nvkm_fb *pfb = (void *)object;
int i;
for (i = 0; i < pfb->tile.regions; i++)
pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
- nouveau_mm_fini(&pfb->tags);
- nouveau_mm_fini(&pfb->vram);
+ nvkm_mm_fini(&pfb->tags);
+ nvkm_mm_fini(&pfb->vram);
- nouveau_object_ref(NULL, (struct nouveau_object **)&pfb->ram);
- nouveau_subdev_destroy(&pfb->base);
+ nvkm_object_ref(NULL, (struct nvkm_object **)&pfb->ram);
+ nvkm_subdev_destroy(&pfb->base);
}
int
-nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+nvkm_fb_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_fb_impl *impl = (void *)oclass;
+ struct nvkm_fb_impl *impl = (void *)oclass;
static const char *name[] = {
[NV_MEM_TYPE_UNKNOWN] = "unknown",
[NV_MEM_TYPE_STOLEN ] = "stolen system memory",
@@ -116,38 +115,35 @@ nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
[NV_MEM_TYPE_GDDR4 ] = "GDDR4",
[NV_MEM_TYPE_GDDR5 ] = "GDDR5",
};
- struct nouveau_object *ram;
- struct nouveau_fb *pfb;
+ struct nvkm_object *ram;
+ struct nvkm_fb *pfb;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PFB", "fb",
- length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "PFB", "fb",
+ length, pobject);
pfb = *pobject;
if (ret)
return ret;
pfb->memtype_valid = impl->memtype;
- ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb),
- impl->ram, NULL, 0, &ram);
+ ret = nvkm_object_ctor(nv_object(pfb), NULL, impl->ram, NULL, 0, &ram);
if (ret) {
nv_fatal(pfb, "error detecting memory configuration!!\n");
return ret;
}
- atomic_dec(&ram->parent->refcount);
- atomic_dec(&ram->engine->refcount);
pfb->ram = (void *)ram;
- if (!nouveau_mm_initialised(&pfb->vram)) {
- ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram->size >> 12, 1);
+ if (!nvkm_mm_initialised(&pfb->vram)) {
+ ret = nvkm_mm_init(&pfb->vram, 0, pfb->ram->size >> 12, 1);
if (ret)
return ret;
}
- if (!nouveau_mm_initialised(&pfb->tags)) {
- ret = nouveau_mm_init(&pfb->tags, 0, pfb->ram->tags ?
- ++pfb->ram->tags : 0, 1);
+ if (!nvkm_mm_initialised(&pfb->tags)) {
+ ret = nvkm_mm_init(&pfb->tags, 0, pfb->ram->tags ?
+ ++pfb->ram->tags : 0, 1);
if (ret)
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c
index cf0e767d3833..6c968d1e98b3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/g84.c
@@ -21,17 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
-struct nouveau_oclass *
-nv84_fb_oclass = &(struct nv50_fb_impl) {
+struct nvkm_oclass *
+g84_fb_oclass = &(struct nv50_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x84),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_fb_ctor,
.dtor = nv50_fb_dtor,
.init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
.base.ram = &nv50_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index d85a25d027ee..15b462ae33cb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -22,8 +22,6 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
* Roy Spliet <rspliet@eclipso.eu>
*/
-
-#include <subdev/bios.h>
#include "priv.h"
struct ramxlat {
@@ -70,7 +68,7 @@ ramgddr3_wr_lo[] = {
};
int
-nouveau_gddr3_calc(struct nouveau_ram *ram)
+nvkm_gddr3_calc(struct nvkm_ram *ram)
{
int CL, WR, CWL, DLL = 0, ODT = 0, hi;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
index 7fbbe05d5c60..f6f9eee1dcd0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
@@ -21,8 +21,6 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
-#include <subdev/bios.h>
#include "priv.h"
/* binary driver only executes this path if the condition (a) is true
@@ -34,7 +32,7 @@
#define NOTE00(a) 1
int
-nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts)
+nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
{
int pd, lf, xd, vh, vr, vo, l3;
int WL, CL, WR, at[2], dt, ds;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
index 32f28dc73ef2..d51aa0237baf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
@@ -21,22 +21,23 @@
*
* Authors: Ben Skeggs
*/
+#include "gf100.h"
-#include "nvc0.h"
+#include <core/device.h>
-extern const u8 nvc0_pte_storage_type_map[256];
+extern const u8 gf100_pte_storage_type_map[256];
bool
-nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
+gf100_fb_memtype_valid(struct nvkm_fb *pfb, u32 tile_flags)
{
u8 memtype = (tile_flags & 0x0000ff00) >> 8;
- return likely((nvc0_pte_storage_type_map[memtype] != 0xff));
+ return likely((gf100_pte_storage_type_map[memtype] != 0xff));
}
static void
-nvc0_fb_intr(struct nouveau_subdev *subdev)
+gf100_fb_intr(struct nvkm_subdev *subdev)
{
- struct nvc0_fb_priv *priv = (void *)subdev;
+ struct gf100_fb_priv *priv = (void *)subdev;
u32 intr = nv_rd32(priv, 0x000100);
if (intr & 0x08000000) {
nv_debug(priv, "PFFB intr\n");
@@ -49,26 +50,27 @@ nvc0_fb_intr(struct nouveau_subdev *subdev)
}
int
-nvc0_fb_init(struct nouveau_object *object)
+gf100_fb_init(struct nvkm_object *object)
{
- struct nvc0_fb_priv *priv = (void *)object;
+ struct gf100_fb_priv *priv = (void *)object;
int ret;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
if (priv->r100c10_page)
nv_wr32(priv, 0x100c10, priv->r100c10 >> 8);
+
nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
return 0;
}
void
-nvc0_fb_dtor(struct nouveau_object *object)
+gf100_fb_dtor(struct nvkm_object *object)
{
- struct nouveau_device *device = nv_device(object);
- struct nvc0_fb_priv *priv = (void *)object;
+ struct nvkm_device *device = nv_device(object);
+ struct gf100_fb_priv *priv = (void *)object;
if (priv->r100c10_page) {
dma_unmap_page(nv_device_base(device), priv->r100c10, PAGE_SIZE,
@@ -76,19 +78,19 @@ nvc0_fb_dtor(struct nouveau_object *object)
__free_page(priv->r100c10_page);
}
- nouveau_fb_destroy(&priv->base);
+ nvkm_fb_destroy(&priv->base);
}
int
-nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_fb_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_device *device = nv_device(parent);
- struct nvc0_fb_priv *priv;
+ struct nvkm_device *device = nv_device(parent);
+ struct gf100_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nvkm_fb_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -102,19 +104,19 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return -EFAULT;
}
- nv_subdev(priv)->intr = nvc0_fb_intr;
+ nv_subdev(priv)->intr = gf100_fb_intr;
return 0;
}
-struct nouveau_oclass *
-nvc0_fb_oclass = &(struct nouveau_fb_impl) {
+struct nvkm_oclass *
+gf100_fb_oclass = &(struct nvkm_fb_impl) {
.base.handle = NV_SUBDEV(FB, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_fb_ctor,
- .dtor = nvc0_fb_dtor,
- .init = nvc0_fb_init,
- .fini = _nouveau_fb_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_fb_ctor,
+ .dtor = gf100_fb_dtor,
+ .init = gf100_fb_init,
+ .fini = _nvkm_fb_fini,
},
- .memtype = nvc0_fb_memtype_valid,
- .ram = &nvc0_ram_oclass,
+ .memtype = gf100_fb_memtype_valid,
+ .ram = &gf100_ram_oclass,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h
new file mode 100644
index 000000000000..0af4da259471
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h
@@ -0,0 +1,28 @@
+#ifndef __NVKM_RAM_NVC0_H__
+#define __NVKM_RAM_NVC0_H__
+#include "priv.h"
+#include "nv50.h"
+
+struct gf100_fb_priv {
+ struct nvkm_fb base;
+ struct page *r100c10_page;
+ dma_addr_t r100c10;
+};
+
+int gf100_fb_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void gf100_fb_dtor(struct nvkm_object *);
+int gf100_fb_init(struct nvkm_object *);
+bool gf100_fb_memtype_valid(struct nvkm_fb *, u32);
+
+#define gf100_ram_create(p,e,o,m,d) \
+ gf100_ram_create_((p), (e), (o), (m), sizeof(**d), (void **)d)
+int gf100_ram_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u32, int, void **);
+int gf100_ram_get(struct nvkm_fb *, u64, u32, u32, u32,
+ struct nvkm_mem **);
+void gf100_ram_put(struct nvkm_fb *, struct nvkm_mem **);
+
+int gk104_ram_init(struct nvkm_object*);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
index 595db50cfef3..1c08317665bb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
@@ -21,18 +21,17 @@
*
* Authors: Ben Skeggs
*/
+#include "gf100.h"
-#include "nvc0.h"
-
-struct nouveau_oclass *
-nve0_fb_oclass = &(struct nouveau_fb_impl) {
+struct nvkm_oclass *
+gk104_fb_oclass = &(struct nvkm_fb_impl) {
.base.handle = NV_SUBDEV(FB, 0xe0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_fb_ctor,
- .dtor = nvc0_fb_dtor,
- .init = nvc0_fb_init,
- .fini = _nouveau_fb_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_fb_ctor,
+ .dtor = gf100_fb_dtor,
+ .init = gf100_fb_init,
+ .fini = _nvkm_fb_fini,
},
- .memtype = nvc0_fb_memtype_valid,
- .ram = &nve0_ram_oclass,
+ .memtype = gf100_fb_memtype_valid,
+ .ram = &gk104_ram_oclass,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c
index fde42e4d1b56..6762847c05e8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c
@@ -19,20 +19,19 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-
-#include "nvc0.h"
+#include "gf100.h"
struct gk20a_fb_priv {
- struct nouveau_fb base;
+ struct nvkm_fb base;
};
static int
-gk20a_fb_init(struct nouveau_object *object)
+gk20a_fb_init(struct nvkm_object *object)
{
struct gk20a_fb_priv *priv = (void *)object;
int ret;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
@@ -41,14 +40,14 @@ gk20a_fb_init(struct nouveau_object *object)
}
static int
-gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk20a_fb_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct gk20a_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nvkm_fb_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -56,15 +55,15 @@ gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-gk20a_fb_oclass = &(struct nouveau_fb_impl) {
+struct nvkm_oclass *
+gk20a_fb_oclass = &(struct nvkm_fb_impl) {
.base.handle = NV_SUBDEV(FB, 0xea),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gk20a_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = gk20a_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
- .memtype = nvc0_fb_memtype_valid,
+ .memtype = gf100_fb_memtype_valid,
.ram = &gk20a_ram_oclass,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c
index c4840aedc2dc..843f9356b360 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c
@@ -21,18 +21,17 @@
*
* Authors: Ben Skeggs
*/
+#include "gf100.h"
-#include "nvc0.h"
-
-struct nouveau_oclass *
-gm107_fb_oclass = &(struct nouveau_fb_impl) {
+struct nvkm_oclass *
+gm107_fb_oclass = &(struct nvkm_fb_impl) {
.base.handle = NV_SUBDEV(FB, 0x07),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_fb_ctor,
- .dtor = nvc0_fb_dtor,
- .init = nvc0_fb_init,
- .fini = _nouveau_fb_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_fb_ctor,
+ .dtor = gf100_fb_dtor,
+ .init = gf100_fb_init,
+ .fini = _nvkm_fb_fini,
},
- .memtype = nvc0_fb_memtype_valid,
+ .memtype = gf100_fb_memtype_valid,
.ram = &gm107_ram_oclass,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c
index dab6e1c63d48..dd9b8a0a3c8e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c
@@ -21,19 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
-struct nouveau_oclass *
-nva3_fb_oclass = &(struct nv50_fb_impl) {
+struct nvkm_oclass *
+gt215_fb_oclass = &(struct nv50_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0xa3),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_fb_ctor,
.dtor = nv50_fb_dtor,
.init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nva3_ram_oclass,
+ .base.ram = &gt215_ram_oclass,
.trap = 0x000d0fff,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/mcp77.c
index cba8e6818035..7be4a47ef4ad 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/mcp77.c
@@ -21,19 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
-struct nouveau_oclass *
-nvaa_fb_oclass = &(struct nv50_fb_impl) {
+struct nvkm_oclass *
+mcp77_fb_oclass = &(struct nv50_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0xaa),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_fb_ctor,
.dtor = nv50_fb_dtor,
.init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nvaa_ram_oclass,
+ .base.ram = &mcp77_ram_oclass,
.trap = 0x001d07ff,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/mcp89.c
index 5423faa2c09b..2d00656faef5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/mcp89.c
@@ -21,19 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
-struct nouveau_oclass *
-nvaf_fb_oclass = &(struct nv50_fb_impl) {
+struct nvkm_oclass *
+mcp89_fb_oclass = &(struct nv50_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0xaf),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_fb_ctor,
.dtor = nv50_fb_dtor,
.init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
- .base.ram = &nvaa_ram_oclass,
+ .base.ram = &mcp77_ram_oclass,
.trap = 0x089d1fff,
}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c
index 8309fe33fe84..c063dec7d03a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.c
@@ -21,13 +21,11 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-
-#define NV04_PFB_CFG0 0x00100200
+#include "regsnv04.h"
bool
-nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
+nv04_fb_memtype_valid(struct nvkm_fb *pfb, u32 tile_flags)
{
if (!(tile_flags & 0xff00))
return true;
@@ -36,12 +34,12 @@ nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
}
static int
-nv04_fb_init(struct nouveau_object *object)
+nv04_fb_init(struct nvkm_object *object)
{
struct nv04_fb_priv *priv = (void *)object;
int ret;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
@@ -54,15 +52,15 @@ nv04_fb_init(struct nouveau_object *object)
}
int
-nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_fb_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_fb_impl *impl = (void *)oclass;
struct nv04_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nvkm_fb_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -75,14 +73,14 @@ nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv04_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x04),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv04_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv04_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.h
new file mode 100644
index 000000000000..caa0d03aaacc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv04.h
@@ -0,0 +1,53 @@
+#ifndef __NVKM_FB_NV04_H__
+#define __NVKM_FB_NV04_H__
+#include "priv.h"
+
+struct nv04_fb_priv {
+ struct nvkm_fb base;
+};
+
+int nv04_fb_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+
+struct nv04_fb_impl {
+ struct nvkm_fb_impl base;
+ struct {
+ int regions;
+ void (*init)(struct nvkm_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nvkm_fb_tile *);
+ void (*comp)(struct nvkm_fb *, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *);
+ void (*fini)(struct nvkm_fb *, int i,
+ struct nvkm_fb_tile *);
+ void (*prog)(struct nvkm_fb *, int i,
+ struct nvkm_fb_tile *);
+ } tile;
+};
+
+void nv10_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nvkm_fb_tile *);
+void nv10_fb_tile_fini(struct nvkm_fb *, int i, struct nvkm_fb_tile *);
+void nv10_fb_tile_prog(struct nvkm_fb *, int, struct nvkm_fb_tile *);
+
+void nv20_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nvkm_fb_tile *);
+void nv20_fb_tile_fini(struct nvkm_fb *, int i, struct nvkm_fb_tile *);
+void nv20_fb_tile_prog(struct nvkm_fb *, int, struct nvkm_fb_tile *);
+
+int nv30_fb_init(struct nvkm_object *);
+void nv30_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nvkm_fb_tile *);
+
+void nv40_fb_tile_comp(struct nvkm_fb *, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *);
+
+int nv41_fb_init(struct nvkm_object *);
+void nv41_fb_tile_prog(struct nvkm_fb *, int, struct nvkm_fb_tile *);
+
+int nv44_fb_init(struct nvkm_object *);
+void nv44_fb_tile_prog(struct nvkm_fb *, int, struct nvkm_fb_tile *);
+
+void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size,
+ u32 pitch, u32 flags, struct nvkm_fb_tile *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c
index ffb7ec6d97aa..f3530e4a6760 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv10.c
@@ -23,12 +23,11 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
void
-nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
- u32 flags, struct nouveau_fb_tile *tile)
+nv10_fb_tile_init(struct nvkm_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nvkm_fb_tile *tile)
{
tile->addr = 0x80000000 | addr;
tile->limit = max(1u, addr + size) - 1;
@@ -36,7 +35,7 @@ nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
}
void
-nv10_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+nv10_fb_tile_fini(struct nvkm_fb *pfb, int i, struct nvkm_fb_tile *tile)
{
tile->addr = 0;
tile->limit = 0;
@@ -45,7 +44,7 @@ nv10_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
}
void
-nv10_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+nv10_fb_tile_prog(struct nvkm_fb *pfb, int i, struct nvkm_fb_tile *tile)
{
nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
@@ -53,14 +52,14 @@ nv10_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
nv_rd32(pfb, 0x100240 + (i * 0x10));
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv10_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x10),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
- .init = _nouveau_fb_init,
- .fini = _nouveau_fb_fini,
+ .dtor = _nvkm_fb_dtor,
+ .init = _nvkm_fb_init,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv10_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c
index 265d1253624a..83bcb73caf0a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv1a.c
@@ -23,17 +23,16 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
-struct nouveau_oclass *
+struct nvkm_oclass *
nv1a_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x1a),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
- .init = _nouveau_fb_init,
- .fini = _nouveau_fb_fini,
+ .dtor = _nvkm_fb_dtor,
+ .init = _nvkm_fb_init,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv1a_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c
index 2209ade63339..e37084b8d05e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv20.c
@@ -23,12 +23,11 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
void
-nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
- u32 flags, struct nouveau_fb_tile *tile)
+nv20_fb_tile_init(struct nvkm_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nvkm_fb_tile *tile)
{
tile->addr = 0x00000001 | addr;
tile->limit = max(1u, addr + size) - 1;
@@ -40,12 +39,12 @@ nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
}
static void
-nv20_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *tile)
+nv20_fb_tile_comp(struct nvkm_fb *pfb, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
- if (!nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+ if (!nvkm_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!(flags & 2)) tile->zcomp = 0x00000000; /* Z16 */
else tile->zcomp = 0x04000000; /* Z24S8 */
tile->zcomp |= tile->tag->offset;
@@ -57,17 +56,17 @@ nv20_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
void
-nv20_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+nv20_fb_tile_fini(struct nvkm_fb *pfb, int i, struct nvkm_fb_tile *tile)
{
tile->addr = 0;
tile->limit = 0;
tile->pitch = 0;
tile->zcomp = 0;
- nouveau_mm_free(&pfb->tags, &tile->tag);
+ nvkm_mm_free(&pfb->tags, &tile->tag);
}
void
-nv20_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+nv20_fb_tile_prog(struct nvkm_fb *pfb, int i, struct nvkm_fb_tile *tile)
{
nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
@@ -76,14 +75,14 @@ nv20_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
nv_wr32(pfb, 0x100300 + (i * 0x04), tile->zcomp);
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv20_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x20),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
- .init = _nouveau_fb_init,
- .fini = _nouveau_fb_fini,
+ .dtor = _nvkm_fb_dtor,
+ .init = _nvkm_fb_init,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c
index e2a66c355c50..bc9f54f38fba 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv25.c
@@ -23,16 +23,15 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
static void
-nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *tile)
+nv25_fb_tile_comp(struct nvkm_fb *pfb, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
- if (!nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+ if (!nvkm_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (!(flags & 2)) tile->zcomp = 0x00100000; /* Z16 */
else tile->zcomp = 0x00200000; /* Z24S8 */
tile->zcomp |= tile->tag->offset;
@@ -42,14 +41,14 @@ nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv25_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x25),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
- .init = _nouveau_fb_init,
- .fini = _nouveau_fb_fini,
+ .dtor = _nvkm_fb_dtor,
+ .init = _nvkm_fb_init,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c
index cbec402ba5b9..09ebb9477e00 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv30.c
@@ -23,12 +23,13 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
+#include <core/device.h>
+
void
-nv30_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
- u32 flags, struct nouveau_fb_tile *tile)
+nv30_fb_tile_init(struct nvkm_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nvkm_fb_tile *tile)
{
/* for performance, select alternate bank offset for zeta */
if (!(flags & 4)) {
@@ -46,12 +47,12 @@ nv30_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
}
static void
-nv30_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *tile)
+nv30_fb_tile_comp(struct nvkm_fb *pfb, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
- if (!nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+ if (!nvkm_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x01000000; /* Z16 */
else tile->zcomp |= 0x02000000; /* Z24S8 */
tile->zcomp |= ((tile->tag->offset ) >> 6);
@@ -65,7 +66,7 @@ nv30_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
static int
calc_bias(struct nv04_fb_priv *priv, int k, int i, int j)
{
- struct nouveau_device *device = nv_device(priv);
+ struct nvkm_device *device = nv_device(priv);
int b = (device->chipset > 0x30 ?
nv_rd32(priv, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) :
0) & 0xf;
@@ -88,13 +89,13 @@ calc_ref(struct nv04_fb_priv *priv, int l, int k, int i)
}
int
-nv30_fb_init(struct nouveau_object *object)
+nv30_fb_init(struct nvkm_object *object)
{
- struct nouveau_device *device = nv_device(object);
+ struct nvkm_device *device = nv_device(object);
struct nv04_fb_priv *priv = (void *)object;
int ret, i, j;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
@@ -120,14 +121,14 @@ nv30_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv30_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x30),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv30_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c
index b2cf8c69fb2e..c01dc1839ea4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv35.c
@@ -23,16 +23,15 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
static void
-nv35_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *tile)
+nv35_fb_tile_comp(struct nvkm_fb *pfb, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
- if (!nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+ if (!nvkm_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x04000000; /* Z16 */
else tile->zcomp |= 0x08000000; /* Z24S8 */
tile->zcomp |= ((tile->tag->offset ) >> 6);
@@ -43,14 +42,14 @@ nv35_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv35_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x35),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv30_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c
index b4cdae2a3b2f..cad75a1cef22 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv36.c
@@ -23,16 +23,15 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
static void
-nv36_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *tile)
+nv36_fb_tile_comp(struct nvkm_fb *pfb, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x40);
u32 tags = round_up(tiles / pfb->ram->parts, 0x40);
- if (!nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+ if (!nvkm_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
if (flags & 2) tile->zcomp |= 0x10000000; /* Z16 */
else tile->zcomp |= 0x20000000; /* Z24S8 */
tile->zcomp |= ((tile->tag->offset ) >> 6);
@@ -43,14 +42,14 @@ nv36_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv36_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x36),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv30_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv20_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c
index 52814258c212..dbe5c1910c2c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.c
@@ -23,17 +23,16 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
void
-nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
- struct nouveau_fb_tile *tile)
+nv40_fb_tile_comp(struct nvkm_fb *pfb, int i, u32 size, u32 flags,
+ struct nvkm_fb_tile *tile)
{
u32 tiles = DIV_ROUND_UP(size, 0x80);
u32 tags = round_up(tiles / pfb->ram->parts, 0x100);
if ( (flags & 2) &&
- !nouveau_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
+ !nvkm_mm_head(&pfb->tags, 0, 1, tags, tags, 1, &tile->tag)) {
tile->zcomp = 0x28000000; /* Z24S8_SPLIT_GRAD */
tile->zcomp |= ((tile->tag->offset ) >> 8);
tile->zcomp |= ((tile->tag->offset + tags - 1) >> 8) << 13;
@@ -44,12 +43,12 @@ nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
}
static int
-nv40_fb_init(struct nouveau_object *object)
+nv40_fb_init(struct nvkm_object *object)
{
struct nv04_fb_priv *priv = (void *)object;
int ret;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
@@ -57,14 +56,14 @@ nv40_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv40_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x40),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv40_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv40_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.h
new file mode 100644
index 000000000000..602182661820
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv40.h
@@ -0,0 +1,14 @@
+#ifndef __NVKM_FB_NV40_H__
+#define __NVKM_FB_NV40_H__
+#include "priv.h"
+
+struct nv40_ram {
+ struct nvkm_ram base;
+ u32 ctrl;
+ u32 coef;
+};
+
+int nv40_ram_calc(struct nvkm_fb *, u32);
+int nv40_ram_prog(struct nvkm_fb *);
+void nv40_ram_tidy(struct nvkm_fb *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c
index b239a8615599..d9e1a40a2955 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv41.c
@@ -23,11 +23,10 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
void
-nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+nv41_fb_tile_prog(struct nvkm_fb *pfb, int i, struct nvkm_fb_tile *tile)
{
nv_wr32(pfb, 0x100604 + (i * 0x10), tile->limit);
nv_wr32(pfb, 0x100608 + (i * 0x10), tile->pitch);
@@ -37,12 +36,12 @@ nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
}
int
-nv41_fb_init(struct nouveau_object *object)
+nv41_fb_init(struct nvkm_object *object)
{
struct nv04_fb_priv *priv = (void *)object;
int ret;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
@@ -50,14 +49,14 @@ nv41_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv41_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x41),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv41_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv41_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c
index d8478208a681..20b97c83c4af 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv44.c
@@ -23,12 +23,11 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
static void
-nv44_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
- u32 flags, struct nouveau_fb_tile *tile)
+nv44_fb_tile_init(struct nvkm_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nvkm_fb_tile *tile)
{
tile->addr = 0x00000001; /* mode = vram */
tile->addr |= addr;
@@ -37,7 +36,7 @@ nv44_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
}
void
-nv44_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+nv44_fb_tile_prog(struct nvkm_fb *pfb, int i, struct nvkm_fb_tile *tile)
{
nv_wr32(pfb, 0x100604 + (i * 0x10), tile->limit);
nv_wr32(pfb, 0x100608 + (i * 0x10), tile->pitch);
@@ -46,12 +45,12 @@ nv44_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
}
int
-nv44_fb_init(struct nouveau_object *object)
+nv44_fb_init(struct nvkm_object *object)
{
struct nv04_fb_priv *priv = (void *)object;
int ret;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
@@ -60,14 +59,14 @@ nv44_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv44_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x44),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv44_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv44_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c
index a5b77514d35b..5bfac38cdf24 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv46.c
@@ -23,12 +23,11 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
void
-nv46_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
- u32 flags, struct nouveau_fb_tile *tile)
+nv46_fb_tile_init(struct nvkm_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+ u32 flags, struct nvkm_fb_tile *tile)
{
/* for performance, select alternate bank offset for zeta */
if (!(flags & 4)) tile->addr = (0 << 3);
@@ -40,14 +39,14 @@ nv46_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
tile->pitch = pitch;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv46_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x46),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv44_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv44_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c
index 3bea142376bc..d3b3988d1d49 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv47.c
@@ -23,17 +23,16 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
-struct nouveau_oclass *
+struct nvkm_oclass *
nv47_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x47),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv41_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv41_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c
index 666cbd5d47f5..236e36c5054e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv49.c
@@ -23,17 +23,16 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
-struct nouveau_oclass *
+struct nvkm_oclass *
nv49_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x49),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv41_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv49_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c
index 42e64f364ec1..1352b6a73fb0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv4e.c
@@ -23,17 +23,16 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "nv04.h"
-struct nouveau_oclass *
+struct nvkm_oclass *
nv4e_fb_oclass = &(struct nv04_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x4e),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_fb_ctor,
- .dtor = _nouveau_fb_dtor,
+ .dtor = _nvkm_fb_dtor,
.init = nv44_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv04_fb_memtype_valid,
.base.ram = &nv4e_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
index 4150b0d10af8..0480ce52aa06 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
@@ -21,15 +21,12 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
#include <core/client.h>
-#include <core/enum.h>
+#include <core/device.h>
#include <core/engctx.h>
-#include <core/object.h>
-
-#include <subdev/bios.h>
-
-#include "nv50.h"
+#include <core/enum.h>
int
nv50_fb_memtype[0x80] = {
@@ -44,12 +41,12 @@ nv50_fb_memtype[0x80] = {
};
bool
-nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype)
+nv50_fb_memtype_valid(struct nvkm_fb *pfb, u32 memtype)
{
return nv50_fb_memtype[(memtype & 0xff00) >> 8] != 0;
}
-static const struct nouveau_enum vm_dispatch_subclients[] = {
+static const struct nvkm_enum vm_dispatch_subclients[] = {
{ 0x00000000, "GRCTX", NULL },
{ 0x00000001, "NOTIFY", NULL },
{ 0x00000002, "QUERY", NULL },
@@ -60,14 +57,14 @@ static const struct nouveau_enum vm_dispatch_subclients[] = {
{}
};
-static const struct nouveau_enum vm_ccache_subclients[] = {
+static const struct nvkm_enum vm_ccache_subclients[] = {
{ 0x00000000, "CB", NULL },
{ 0x00000001, "TIC", NULL },
{ 0x00000002, "TSC", NULL },
{}
};
-static const struct nouveau_enum vm_prop_subclients[] = {
+static const struct nvkm_enum vm_prop_subclients[] = {
{ 0x00000000, "RT0", NULL },
{ 0x00000001, "RT1", NULL },
{ 0x00000002, "RT2", NULL },
@@ -84,24 +81,24 @@ static const struct nouveau_enum vm_prop_subclients[] = {
{}
};
-static const struct nouveau_enum vm_pfifo_subclients[] = {
+static const struct nvkm_enum vm_pfifo_subclients[] = {
{ 0x00000000, "PUSHBUF", NULL },
{ 0x00000001, "SEMAPHORE", NULL },
{}
};
-static const struct nouveau_enum vm_bar_subclients[] = {
+static const struct nvkm_enum vm_bar_subclients[] = {
{ 0x00000000, "FB", NULL },
{ 0x00000001, "IN", NULL },
{}
};
-static const struct nouveau_enum vm_client[] = {
+static const struct nvkm_enum vm_client[] = {
{ 0x00000000, "STRMOUT", NULL },
{ 0x00000003, "DISPATCH", vm_dispatch_subclients },
{ 0x00000004, "PFIFO_WRITE", NULL },
{ 0x00000005, "CCACHE", vm_ccache_subclients },
- { 0x00000006, "PPPP", NULL },
+ { 0x00000006, "PMSPPP", NULL },
{ 0x00000007, "CLIPID", NULL },
{ 0x00000008, "PFIFO_READ", NULL },
{ 0x00000009, "VFETCH", NULL },
@@ -115,24 +112,24 @@ static const struct nouveau_enum vm_client[] = {
{}
};
-static const struct nouveau_enum vm_engine[] = {
+static const struct nvkm_enum vm_engine[] = {
{ 0x00000000, "PGRAPH", NULL, NVDEV_ENGINE_GR },
{ 0x00000001, "PVP", NULL, NVDEV_ENGINE_VP },
{ 0x00000004, "PEEPHOLE", NULL },
{ 0x00000005, "PFIFO", vm_pfifo_subclients, NVDEV_ENGINE_FIFO },
{ 0x00000006, "BAR", vm_bar_subclients },
- { 0x00000008, "PPPP", NULL, NVDEV_ENGINE_PPP },
+ { 0x00000008, "PMSPPP", NULL, NVDEV_ENGINE_MSPPP },
{ 0x00000008, "PMPEG", NULL, NVDEV_ENGINE_MPEG },
{ 0x00000009, "PBSP", NULL, NVDEV_ENGINE_BSP },
- { 0x0000000a, "PCRYPT", NULL, NVDEV_ENGINE_CRYPT },
+ { 0x0000000a, "PCRYPT", NULL, NVDEV_ENGINE_CIPHER },
{ 0x0000000b, "PCOUNTER", NULL },
{ 0x0000000c, "SEMAPHORE_BG", NULL },
- { 0x0000000d, "PCOPY", NULL, NVDEV_ENGINE_COPY0 },
+ { 0x0000000d, "PCE0", NULL, NVDEV_ENGINE_CE0 },
{ 0x0000000e, "PDAEMON", NULL },
{}
};
-static const struct nouveau_enum vm_fault[] = {
+static const struct nvkm_enum vm_fault[] = {
{ 0x00000000, "PT_NOT_PRESENT", NULL },
{ 0x00000001, "PT_TOO_SHORT", NULL },
{ 0x00000002, "PAGE_NOT_PRESENT", NULL },
@@ -146,13 +143,13 @@ static const struct nouveau_enum vm_fault[] = {
};
static void
-nv50_fb_intr(struct nouveau_subdev *subdev)
+nv50_fb_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_device *device = nv_device(subdev);
- struct nouveau_engine *engine;
+ struct nvkm_device *device = nv_device(subdev);
+ struct nvkm_engine *engine;
struct nv50_fb_priv *priv = (void *)subdev;
- const struct nouveau_enum *en, *cl;
- struct nouveau_object *engctx = NULL;
+ const struct nvkm_enum *en, *cl;
+ struct nvkm_object *engctx = NULL;
u32 trap[6], idx, chan;
u8 st0, st1, st2, st3;
int i;
@@ -183,14 +180,21 @@ nv50_fb_intr(struct nouveau_subdev *subdev)
}
chan = (trap[2] << 16) | trap[1];
- en = nouveau_enum_find(vm_engine, st0);
+ en = nvkm_enum_find(vm_engine, st0);
if (en && en->data2) {
- const struct nouveau_enum *orig_en = en;
+ const struct nvkm_enum *orig_en = en;
while (en->name && en->value == st0 && en->data2) {
- engine = nouveau_engine(subdev, en->data2);
+ engine = nvkm_engine(subdev, en->data2);
+ /*XXX: clean this up */
+ if (!engine && en->data2 == NVDEV_ENGINE_BSP)
+ engine = nvkm_engine(subdev, NVDEV_ENGINE_MSVLD);
+ if (!engine && en->data2 == NVDEV_ENGINE_CIPHER)
+ engine = nvkm_engine(subdev, NVDEV_ENGINE_SEC);
+ if (!engine && en->data2 == NVDEV_ENGINE_VP)
+ engine = nvkm_engine(subdev, NVDEV_ENGINE_MSPDEC);
if (engine) {
- engctx = nouveau_engctx_get(engine, chan);
+ engctx = nvkm_engctx_get(engine, chan);
if (engctx)
break;
}
@@ -203,23 +207,23 @@ nv50_fb_intr(struct nouveau_subdev *subdev)
nv_error(priv, "trapped %s at 0x%02x%04x%04x on channel 0x%08x [%s] ",
(trap[5] & 0x00000100) ? "read" : "write",
trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, chan,
- nouveau_client_name(engctx));
+ nvkm_client_name(engctx));
- nouveau_engctx_put(engctx);
+ nvkm_engctx_put(engctx);
if (en)
pr_cont("%s/", en->name);
else
pr_cont("%02x/", st0);
- cl = nouveau_enum_find(vm_client, st2);
+ cl = nvkm_enum_find(vm_client, st2);
if (cl)
pr_cont("%s/", cl->name);
else
pr_cont("%02x/", st2);
- if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3);
- else if (en && en->data) cl = nouveau_enum_find(en->data, st3);
+ if (cl && cl->data) cl = nvkm_enum_find(cl->data, st3);
+ else if (en && en->data) cl = nvkm_enum_find(en->data, st3);
else cl = NULL;
if (cl)
pr_cont("%s", cl->name);
@@ -227,7 +231,7 @@ nv50_fb_intr(struct nouveau_subdev *subdev)
pr_cont("%02x", st3);
pr_cont(" reason: ");
- en = nouveau_enum_find(vm_fault, st1);
+ en = nvkm_enum_find(vm_fault, st1);
if (en)
pr_cont("%s\n", en->name);
else
@@ -235,15 +239,15 @@ nv50_fb_intr(struct nouveau_subdev *subdev)
}
int
-nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_fb_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_device *device = nv_device(parent);
+ struct nvkm_device *device = nv_device(parent);
struct nv50_fb_priv *priv;
int ret;
- ret = nouveau_fb_create(parent, engine, oclass, &priv);
+ ret = nvkm_fb_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -264,9 +268,9 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
void
-nv50_fb_dtor(struct nouveau_object *object)
+nv50_fb_dtor(struct nvkm_object *object)
{
- struct nouveau_device *device = nv_device(object);
+ struct nvkm_device *device = nv_device(object);
struct nv50_fb_priv *priv = (void *)object;
if (priv->r100c08_page) {
@@ -275,17 +279,17 @@ nv50_fb_dtor(struct nouveau_object *object)
__free_page(priv->r100c08_page);
}
- nouveau_fb_destroy(&priv->base);
+ nvkm_fb_destroy(&priv->base);
}
int
-nv50_fb_init(struct nouveau_object *object)
+nv50_fb_init(struct nvkm_object *object)
{
struct nv50_fb_impl *impl = (void *)object->oclass;
struct nv50_fb_priv *priv = (void *)object;
int ret;
- ret = nouveau_fb_init(&priv->base);
+ ret = nvkm_fb_init(&priv->base);
if (ret)
return ret;
@@ -301,14 +305,14 @@ nv50_fb_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
nv50_fb_oclass = &(struct nv50_fb_impl) {
.base.base.handle = NV_SUBDEV(FB, 0x50),
- .base.base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_fb_ctor,
.dtor = nv50_fb_dtor,
.init = nv50_fb_init,
- .fini = _nouveau_fb_fini,
+ .fini = _nvkm_fb_fini,
},
.base.memtype = nv50_fb_memtype_valid,
.base.ram = &nv50_ram_oclass,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h
new file mode 100644
index 000000000000..f3cde3f1f511
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.h
@@ -0,0 +1,31 @@
+#ifndef __NVKM_FB_NV50_H__
+#define __NVKM_FB_NV50_H__
+#include "priv.h"
+
+struct nv50_fb_priv {
+ struct nvkm_fb base;
+ struct page *r100c08_page;
+ dma_addr_t r100c08;
+};
+
+int nv50_fb_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv50_fb_dtor(struct nvkm_object *);
+int nv50_fb_init(struct nvkm_object *);
+
+struct nv50_fb_impl {
+ struct nvkm_fb_impl base;
+ u32 trap;
+};
+
+#define nv50_ram_create(p,e,o,d) \
+ nv50_ram_create_((p), (e), (o), sizeof(**d), (void **)d)
+int nv50_ram_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+int nv50_ram_get(struct nvkm_fb *, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nvkm_mem **);
+void nv50_ram_put(struct nvkm_fb *, struct nvkm_mem **);
+void __nv50_ram_put(struct nvkm_fb *, struct nvkm_mem *);
+extern int nv50_fb_memtype[0x80];
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
new file mode 100644
index 000000000000..d82da02daa1f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
@@ -0,0 +1,74 @@
+#ifndef __NVKM_FB_PRIV_H__
+#define __NVKM_FB_PRIV_H__
+#include <subdev/fb.h>
+struct nvkm_bios;
+
+#define nvkm_ram_create(p,e,o,d) \
+ nvkm_object_create_((p), (e), (o), 0, sizeof(**d), (void **)d)
+#define nvkm_ram_destroy(p) \
+ nvkm_object_destroy(&(p)->base)
+#define nvkm_ram_init(p) \
+ nvkm_object_init(&(p)->base)
+#define nvkm_ram_fini(p,s) \
+ nvkm_object_fini(&(p)->base, (s))
+
+#define nvkm_ram_create_(p,e,o,s,d) \
+ nvkm_object_create_((p), (e), (o), 0, (s), (void **)d)
+#define _nvkm_ram_dtor nvkm_object_destroy
+#define _nvkm_ram_init nvkm_object_init
+#define _nvkm_ram_fini nvkm_object_fini
+
+extern struct nvkm_oclass nv04_ram_oclass;
+extern struct nvkm_oclass nv10_ram_oclass;
+extern struct nvkm_oclass nv1a_ram_oclass;
+extern struct nvkm_oclass nv20_ram_oclass;
+extern struct nvkm_oclass nv40_ram_oclass;
+extern struct nvkm_oclass nv41_ram_oclass;
+extern struct nvkm_oclass nv44_ram_oclass;
+extern struct nvkm_oclass nv49_ram_oclass;
+extern struct nvkm_oclass nv4e_ram_oclass;
+extern struct nvkm_oclass nv50_ram_oclass;
+extern struct nvkm_oclass gt215_ram_oclass;
+extern struct nvkm_oclass mcp77_ram_oclass;
+extern struct nvkm_oclass gf100_ram_oclass;
+extern struct nvkm_oclass gk104_ram_oclass;
+extern struct nvkm_oclass gk20a_ram_oclass;
+extern struct nvkm_oclass gm107_ram_oclass;
+
+int nvkm_sddr2_calc(struct nvkm_ram *ram);
+int nvkm_sddr3_calc(struct nvkm_ram *ram);
+int nvkm_gddr3_calc(struct nvkm_ram *ram);
+int nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts);
+
+#define nvkm_fb_create(p,e,c,d) \
+ nvkm_fb_create_((p), (e), (c), sizeof(**d), (void **)d)
+#define nvkm_fb_destroy(p) ({ \
+ struct nvkm_fb *pfb = (p); \
+ _nvkm_fb_dtor(nv_object(pfb)); \
+})
+#define nvkm_fb_init(p) ({ \
+ struct nvkm_fb *pfb = (p); \
+ _nvkm_fb_init(nv_object(pfb)); \
+})
+#define nvkm_fb_fini(p,s) ({ \
+ struct nvkm_fb *pfb = (p); \
+ _nvkm_fb_fini(nv_object(pfb), (s)); \
+})
+
+int nvkm_fb_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_fb_dtor(struct nvkm_object *);
+int _nvkm_fb_init(struct nvkm_object *);
+int _nvkm_fb_fini(struct nvkm_object *, bool);
+
+struct nvkm_fb_impl {
+ struct nvkm_oclass base;
+ struct nvkm_oclass *ram;
+ bool (*memtype)(struct nvkm_fb *, u32);
+};
+
+bool nv04_fb_memtype_valid(struct nvkm_fb *, u32 memtype);
+bool nv50_fb_memtype_valid(struct nvkm_fb *, u32 memtype);
+
+int nvkm_fb_bios_memtype(struct nvkm_bios *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
index 0ac7256443bb..f343682b1387 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
@@ -1,11 +1,10 @@
#ifndef __NVKM_FBRAM_FUC_H__
#define __NVKM_FBRAM_FUC_H__
-
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
struct ramfuc {
- struct nouveau_memx *memx;
- struct nouveau_fb *pfb;
+ struct nvkm_memx *memx;
+ struct nvkm_fb *pfb;
int sequence;
};
@@ -55,12 +54,12 @@ ramfuc_reg(u32 addr)
}
static inline int
-ramfuc_init(struct ramfuc *ram, struct nouveau_fb *pfb)
+ramfuc_init(struct ramfuc *ram, struct nvkm_fb *pfb)
{
- struct nouveau_pwr *ppwr = nouveau_pwr(pfb);
+ struct nvkm_pmu *pmu = nvkm_pmu(pfb);
int ret;
- ret = nouveau_memx_init(ppwr, &ram->memx);
+ ret = nvkm_memx_init(pmu, &ram->memx);
if (ret)
return ret;
@@ -74,7 +73,7 @@ ramfuc_exec(struct ramfuc *ram, bool exec)
{
int ret = 0;
if (ram->pfb) {
- ret = nouveau_memx_fini(&ram->memx, exec);
+ ret = nvkm_memx_fini(&ram->memx, exec);
ram->pfb = NULL;
}
return ret;
@@ -97,10 +96,8 @@ ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data)
reg->data = data;
for (mask = reg->mask; mask > 0; mask = (mask & ~1) >> 1) {
- if (mask & 1) {
- nouveau_memx_wr32(ram->memx, reg->addr+off, reg->data);
- }
-
+ if (mask & 1)
+ nvkm_memx_wr32(ram->memx, reg->addr+off, reg->data);
off += reg->stride;
}
}
@@ -125,45 +122,45 @@ ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data)
static inline void
ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec)
{
- nouveau_memx_wait(ram->memx, addr, mask, data, nsec);
+ nvkm_memx_wait(ram->memx, addr, mask, data, nsec);
}
static inline void
ramfuc_nsec(struct ramfuc *ram, u32 nsec)
{
- nouveau_memx_nsec(ram->memx, nsec);
+ nvkm_memx_nsec(ram->memx, nsec);
}
static inline void
ramfuc_wait_vblank(struct ramfuc *ram)
{
- nouveau_memx_wait_vblank(ram->memx);
+ nvkm_memx_wait_vblank(ram->memx);
}
static inline void
ramfuc_train(struct ramfuc *ram)
{
- nouveau_memx_train(ram->memx);
+ nvkm_memx_train(ram->memx);
}
static inline int
-ramfuc_train_result(struct nouveau_fb *pfb, u32 *result, u32 rsize)
+ramfuc_train_result(struct nvkm_fb *pfb, u32 *result, u32 rsize)
{
- struct nouveau_pwr *ppwr = nouveau_pwr(pfb);
+ struct nvkm_pmu *pmu = nvkm_pmu(pfb);
- return nouveau_memx_train_result(ppwr, result, rsize);
+ return nvkm_memx_train_result(pmu, result, rsize);
}
static inline void
ramfuc_block(struct ramfuc *ram)
{
- nouveau_memx_block(ram->memx);
+ nvkm_memx_block(ram->memx);
}
static inline void
ramfuc_unblock(struct ramfuc *ram)
{
- nouveau_memx_unblock(ram->memx);
+ nvkm_memx_unblock(ram->memx);
}
#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
@@ -180,5 +177,4 @@ ramfuc_unblock(struct ramfuc *ram)
#define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
#define ram_block(s) ramfuc_block(&(s)->base)
#define ram_unblock(s) ramfuc_unblock(&(s)->base)
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
index 735cb9580abe..de9f39569943 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
@@ -21,23 +21,20 @@
*
* Authors: Ben Skeggs
*/
+#include "gf100.h"
+#include "ramfuc.h"
+#include <core/device.h>
+#include <core/option.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
#include <subdev/bios/rammap.h>
#include <subdev/bios/timing.h>
+#include <subdev/clk.h>
+#include <subdev/clk/pll.h>
#include <subdev/ltc.h>
-#include <subdev/clock.h>
-#include <subdev/clock/pll.h>
-
-#include <core/option.h>
-
-#include "ramfuc.h"
-
-#include "nvc0.h"
-
-struct nvc0_ramfuc {
+struct gf100_ramfuc {
struct ramfuc base;
struct ramfuc_reg r_0x10fe20;
@@ -100,18 +97,18 @@ struct nvc0_ramfuc {
struct ramfuc_reg r_0x13d8f4;
};
-struct nvc0_ram {
- struct nouveau_ram base;
- struct nvc0_ramfuc fuc;
+struct gf100_ram {
+ struct nvkm_ram base;
+ struct gf100_ramfuc fuc;
struct nvbios_pll refpll;
struct nvbios_pll mempll;
};
static void
-nvc0_ram_train(struct nvc0_ramfuc *fuc, u32 magic)
+gf100_ram_train(struct gf100_ramfuc *fuc, u32 magic)
{
- struct nvc0_ram *ram = container_of(fuc, typeof(*ram), fuc);
- struct nouveau_fb *pfb = nouveau_fb(ram);
+ struct gf100_ram *ram = container_of(fuc, typeof(*ram), fuc);
+ struct nvkm_fb *pfb = nvkm_fb(ram);
u32 part = nv_rd32(pfb, 0x022438), i;
u32 mask = nv_rd32(pfb, 0x022554);
u32 addr = 0x110974;
@@ -127,12 +124,12 @@ nvc0_ram_train(struct nvc0_ramfuc *fuc, u32 magic)
}
static int
-nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
+gf100_ram_calc(struct nvkm_fb *pfb, u32 freq)
{
- struct nouveau_clock *clk = nouveau_clock(pfb);
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nvc0_ram *ram = (void *)pfb->ram;
- struct nvc0_ramfuc *fuc = &ram->fuc;
+ struct nvkm_clk *clk = nvkm_clk(pfb);
+ struct nvkm_bios *bios = nvkm_bios(pfb);
+ struct gf100_ram *ram = (void *)pfb->ram;
+ struct gf100_ramfuc *fuc = &ram->fuc;
struct nvbios_ramcfg cfg;
u8 ver, cnt, len, strap;
struct {
@@ -146,7 +143,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* lookup memory config data relevant to the target frequency */
rammap.data = nvbios_rammapEm(bios, freq / 1000, &ver, &rammap.size,
- &cnt, &ramcfg.size, &cfg);
+ &cnt, &ramcfg.size, &cfg);
if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) {
nv_error(pfb, "invalid/missing rammap entry\n");
return -EINVAL;
@@ -169,7 +166,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
strap = nv_ro08(bios, ramcfg.data + 0x01);
if (strap != 0xff) {
timing.data = nvbios_timingEe(bios, strap, &ver, &timing.size,
- &cnt, &len);
+ &cnt, &len);
if (!timing.data || ver != 0x10 || timing.size < 0x19) {
nv_error(pfb, "invalid/missing timing entry\n");
return -EINVAL;
@@ -213,8 +210,8 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
if (mode == 1 && from == 0) {
/* calculate refpll */
- ret = nva3_pll_calc(nv_subdev(pfb), &ram->refpll,
- ram->mempll.refclk, &N1, NULL, &M1, &P);
+ ret = gt215_pll_calc(nv_subdev(pfb), &ram->refpll,
+ ram->mempll.refclk, &N1, NULL, &M1, &P);
if (ret <= 0) {
nv_error(pfb, "unable to calc refpll\n");
return ret ? ret : -ERANGE;
@@ -228,8 +225,8 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000);
/* calculate mempll */
- ret = nva3_pll_calc(nv_subdev(pfb), &ram->mempll, freq,
- &N1, NULL, &M1, &P);
+ ret = gt215_pll_calc(nv_subdev(pfb), &ram->mempll, freq,
+ &N1, NULL, &M1, &P);
if (ret <= 0) {
nv_error(pfb, "unable to calc refpll\n");
return ret ? ret : -ERANGE;
@@ -277,7 +274,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_wr32(fuc, 0x10f210, 0x00000000);
ram_nsec(fuc, 1000);
if (mode == 0)
- nvc0_ram_train(fuc, 0x000c1001);
+ gf100_ram_train(fuc, 0x000c1001);
ram_wr32(fuc, 0x10f310, 0x00000001);
ram_nsec(fuc, 1000);
ram_wr32(fuc, 0x10f090, 0x00000061);
@@ -325,8 +322,8 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_wr32(fuc, 0x10f348, 0x00700008);
ram_wr32(fuc, 0x61c140, 0x19240000);
ram_wr32(fuc, 0x10f830, 0x00300017);
- nvc0_ram_train(fuc, 0x80021001);
- nvc0_ram_train(fuc, 0x80081001);
+ gf100_ram_train(fuc, 0x80021001);
+ gf100_ram_train(fuc, 0x80081001);
ram_wr32(fuc, 0x10f340, 0x00500004);
ram_nsec(fuc, 1000);
ram_wr32(fuc, 0x10f830, 0x01300017);
@@ -379,7 +376,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_wr32(fuc, 0x13d8f4, 0x00000000);
ram_wr32(fuc, 0x61c140, 0x09a40000);
- nvc0_ram_train(fuc, 0x800e1008);
+ gf100_ram_train(fuc, 0x800e1008);
ram_nsec(fuc, 1000);
ram_wr32(fuc, 0x10f800, 0x00001804);
@@ -392,7 +389,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_wr32(fuc, 0x10f9b0, 0x05313f41);
ram_wr32(fuc, 0x10f9b4, 0x00002f50);
- nvc0_ram_train(fuc, 0x010c1001);
+ gf100_ram_train(fuc, 0x010c1001);
}
ram_mask(fuc, 0x10f200, 0x00000800, 0x00000800);
@@ -400,34 +397,35 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq)
if (mode == 0)
ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
+
return 0;
}
static int
-nvc0_ram_prog(struct nouveau_fb *pfb)
+gf100_ram_prog(struct nvkm_fb *pfb)
{
- struct nouveau_device *device = nv_device(pfb);
- struct nvc0_ram *ram = (void *)pfb->ram;
- struct nvc0_ramfuc *fuc = &ram->fuc;
- ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
+ struct nvkm_device *device = nv_device(pfb);
+ struct gf100_ram *ram = (void *)pfb->ram;
+ struct gf100_ramfuc *fuc = &ram->fuc;
+ ram_exec(fuc, nvkm_boolopt(device->cfgopt, "NvMemExec", true));
return 0;
}
static void
-nvc0_ram_tidy(struct nouveau_fb *pfb)
+gf100_ram_tidy(struct nvkm_fb *pfb)
{
- struct nvc0_ram *ram = (void *)pfb->ram;
- struct nvc0_ramfuc *fuc = &ram->fuc;
+ struct gf100_ram *ram = (void *)pfb->ram;
+ struct gf100_ramfuc *fuc = &ram->fuc;
ram_exec(fuc, false);
}
-extern const u8 nvc0_pte_storage_type_map[256];
+extern const u8 gf100_pte_storage_type_map[256];
void
-nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+gf100_ram_put(struct nvkm_fb *pfb, struct nvkm_mem **pmem)
{
- struct nouveau_ltc *ltc = nouveau_ltc(pfb);
- struct nouveau_mem *mem = *pmem;
+ struct nvkm_ltc *ltc = nvkm_ltc(pfb);
+ struct nvkm_mem *mem = *pmem;
*pmem = NULL;
if (unlikely(mem == NULL))
@@ -443,15 +441,15 @@ nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
}
int
-nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **pmem)
+gf100_ram_get(struct nvkm_fb *pfb, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nvkm_mem **pmem)
{
- struct nouveau_mm *mm = &pfb->vram;
- struct nouveau_mm_node *r;
- struct nouveau_mem *mem;
+ struct nvkm_mm *mm = &pfb->vram;
+ struct nvkm_mm_node *r;
+ struct nvkm_mem *mem;
int type = (memtype & 0x0ff);
int back = (memtype & 0x800);
- const bool comp = nvc0_pte_storage_type_map[type] != type;
+ const bool comp = gf100_pte_storage_type_map[type] != type;
int ret;
size >>= 12;
@@ -469,7 +467,7 @@ nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
mutex_lock(&pfb->base.mutex);
if (comp) {
- struct nouveau_ltc *ltc = nouveau_ltc(pfb);
+ struct nvkm_ltc *ltc = nvkm_ltc(pfb);
/* compression only works with lpages */
if (align == (1 << (17 - 12))) {
@@ -478,15 +476,15 @@ nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
}
if (unlikely(!mem->tag))
- type = nvc0_pte_storage_type_map[type];
+ type = gf100_pte_storage_type_map[type];
}
mem->memtype = type;
do {
if (back)
- ret = nouveau_mm_tail(mm, 0, 1, size, ncmin, align, &r);
+ ret = nvkm_mm_tail(mm, 0, 1, size, ncmin, align, &r);
else
- ret = nouveau_mm_head(mm, 0, 1, size, ncmin, align, &r);
+ ret = nvkm_mm_head(mm, 0, 1, size, ncmin, align, &r);
if (ret) {
mutex_unlock(&pfb->base.mutex);
pfb->ram->put(pfb, &mem);
@@ -498,20 +496,20 @@ nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
} while (size);
mutex_unlock(&pfb->base.mutex);
- r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+ r = list_first_entry(&mem->regions, struct nvkm_mm_node, rl_entry);
mem->offset = (u64)r->offset << 12;
*pmem = mem;
return 0;
}
int
-nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u32 maskaddr, int size,
- void **pobject)
+gf100_ram_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u32 maskaddr, int size,
+ void **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nouveau_ram *ram;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_bios *bios = nvkm_bios(pfb);
+ struct nvkm_ram *ram;
const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
u32 parts = nv_rd32(pfb, 0x022438);
@@ -521,7 +519,7 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
bool uniform = true;
int ret, part;
- ret = nouveau_ram_create_(parent, engine, oclass, size, pobject);
+ ret = nvkm_ram_create_(parent, engine, oclass, size, pobject);
ram = *pobject;
if (ret)
return ret;
@@ -529,7 +527,7 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
nv_debug(pfb, "0x100800: 0x%08x\n", nv_rd32(pfb, 0x100800));
nv_debug(pfb, "parts 0x%08x mask 0x%08x\n", parts, pmask);
- ram->type = nouveau_fb_bios_memtype(bios);
+ ram->type = nvkm_fb_bios_memtype(bios);
ram->ranks = (nv_rd32(pfb, 0x10f200) & 0x00000004) ? 2 : 1;
/* read amount of vram attached to each memory controller */
@@ -551,11 +549,11 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
if (uniform) {
offset = rsvd_head;
length = (ram->size >> 12) - rsvd_head - rsvd_tail;
- ret = nouveau_mm_init(&pfb->vram, offset, length, 1);
+ ret = nvkm_mm_init(&pfb->vram, offset, length, 1);
} else {
/* otherwise, address lowest common amount from 0GiB */
- ret = nouveau_mm_init(&pfb->vram, rsvd_head,
- (bsize << 8) * parts - rsvd_head, 1);
+ ret = nvkm_mm_init(&pfb->vram, rsvd_head,
+ (bsize << 8) * parts - rsvd_head, 1);
if (ret)
return ret;
@@ -563,27 +561,27 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
offset = (0x0200000000ULL >> 12) + (bsize << 8);
length = (ram->size >> 12) - ((bsize * parts) << 8) - rsvd_tail;
- ret = nouveau_mm_init(&pfb->vram, offset, length, 1);
+ ret = nvkm_mm_init(&pfb->vram, offset, length, 1);
if (ret)
- nouveau_mm_fini(&pfb->vram);
+ nvkm_mm_fini(&pfb->vram);
}
if (ret)
return ret;
- ram->get = nvc0_ram_get;
- ram->put = nvc0_ram_put;
+ ram->get = gf100_ram_get;
+ ram->put = gf100_ram_put;
return 0;
}
static int
-nvc0_ram_init(struct nouveau_object *object)
+gf100_ram_init(struct nvkm_object *object)
{
- struct nouveau_fb *pfb = (void *)object->parent;
- struct nvc0_ram *ram = (void *)object;
+ struct nvkm_fb *pfb = (void *)object->parent;
+ struct gf100_ram *ram = (void *)object;
int ret, i;
- ret = nouveau_ram_init(&ram->base);
+ ret = nvkm_ram_init(&ram->base);
if (ret)
return ret;
@@ -624,15 +622,15 @@ nvc0_ram_init(struct nouveau_object *object)
}
static int
-nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nvc0_ram *ram;
+ struct nvkm_bios *bios = nvkm_bios(parent);
+ struct gf100_ram *ram;
int ret;
- ret = nvc0_ram_create(parent, engine, oclass, 0x022554, &ram);
+ ret = gf100_ram_create(parent, engine, oclass, 0x022554, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -651,9 +649,9 @@ nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
switch (ram->base.type) {
case NV_MEM_TYPE_GDDR5:
- ram->base.calc = nvc0_ram_calc;
- ram->base.prog = nvc0_ram_prog;
- ram->base.tidy = nvc0_ram_tidy;
+ ram->base.calc = gf100_ram_calc;
+ ram->base.prog = gf100_ram_prog;
+ ram->base.tidy = gf100_ram_tidy;
break;
default:
nv_warn(ram, "reclocking of this ram type unsupported\n");
@@ -721,13 +719,13 @@ nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
-nvc0_ram_oclass = {
+struct nvkm_oclass
+gf100_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = nvc0_ram_init,
- .fini = _nouveau_ram_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_ram_ctor,
+ .dtor = _nvkm_ram_dtor,
+ .init = gf100_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
index 6bae474abb44..1ef15c3e6a81 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
@@ -21,29 +21,23 @@
*
* Authors: Ben Skeggs
*/
+#include "ramfuc.h"
+#include "gf100.h"
-#include <subdev/gpio.h>
-
+#include <core/device.h>
+#include <core/option.h>
#include <subdev/bios.h>
-#include <subdev/bios/pll.h>
#include <subdev/bios/init.h>
-#include <subdev/bios/rammap.h>
-#include <subdev/bios/timing.h>
#include <subdev/bios/M0205.h>
#include <subdev/bios/M0209.h>
+#include <subdev/bios/pll.h>
+#include <subdev/bios/rammap.h>
+#include <subdev/bios/timing.h>
+#include <subdev/clk.h>
+#include <subdev/clk/pll.h>
+#include <subdev/gpio.h>
-#include <subdev/clock.h>
-#include <subdev/clock/pll.h>
-
-#include <subdev/timer.h>
-
-#include <core/option.h>
-
-#include "nvc0.h"
-
-#include "ramfuc.h"
-
-struct nve0_ramfuc {
+struct gk104_ramfuc {
struct ramfuc base;
struct nvbios_pll refpll;
@@ -124,9 +118,9 @@ struct nve0_ramfuc {
struct ramfuc_reg r_0x100750;
};
-struct nve0_ram {
- struct nouveau_ram base;
- struct nve0_ramfuc fuc;
+struct gk104_ram {
+ struct nvkm_ram base;
+ struct gk104_ramfuc fuc;
struct list_head cfg;
u32 parts;
@@ -144,9 +138,9 @@ struct nve0_ram {
* GDDR5
******************************************************************************/
static void
-nve0_ram_train(struct nve0_ramfuc *fuc, u32 mask, u32 data)
+gk104_ram_train(struct gk104_ramfuc *fuc, u32 mask, u32 data)
{
- struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
+ struct gk104_ram *ram = container_of(fuc, typeof(*ram), fuc);
u32 addr = 0x110974, i;
ram_mask(fuc, 0x10f910, mask, data);
@@ -160,9 +154,9 @@ nve0_ram_train(struct nve0_ramfuc *fuc, u32 mask, u32 data)
}
static void
-r1373f4_init(struct nve0_ramfuc *fuc)
+r1373f4_init(struct gk104_ramfuc *fuc)
{
- struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
+ struct gk104_ram *ram = container_of(fuc, typeof(*ram), fuc);
const u32 mcoef = ((--ram->P2 << 28) | (ram->N2 << 8) | ram->M2);
const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
const u32 runk0 = ram->fN1 << 16;
@@ -210,10 +204,10 @@ r1373f4_init(struct nve0_ramfuc *fuc)
}
static void
-r1373f4_fini(struct nve0_ramfuc *fuc)
+r1373f4_fini(struct gk104_ramfuc *fuc)
{
- struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc);
- struct nouveau_ram_data *next = ram->base.next;
+ struct gk104_ram *ram = container_of(fuc, typeof(*ram), fuc);
+ struct nvkm_ram_data *next = ram->base.next;
u8 v0 = next->bios.ramcfg_11_03_c0;
u8 v1 = next->bios.ramcfg_11_03_30;
u32 tmp;
@@ -232,10 +226,10 @@ r1373f4_fini(struct nve0_ramfuc *fuc)
}
static void
-nve0_ram_nuts(struct nve0_ram *ram, struct ramfuc_reg *reg,
- u32 _mask, u32 _data, u32 _copy)
+gk104_ram_nuts(struct gk104_ram *ram, struct ramfuc_reg *reg,
+ u32 _mask, u32 _data, u32 _copy)
{
- struct nve0_fb_priv *priv = (void *)nouveau_fb(ram);
+ struct gk104_fb_priv *priv = (void *)nvkm_fb(ram);
struct ramfuc *fuc = &ram->fuc.base;
u32 addr = 0x110000 + (reg->addr & 0xfff);
u32 mask = _mask | _copy;
@@ -246,19 +240,19 @@ nve0_ram_nuts(struct nve0_ram *ram, struct ramfuc_reg *reg,
if (ram->pnuts & (1 << i)) {
u32 prev = nv_rd32(priv, addr);
u32 next = (prev & ~mask) | data;
- nouveau_memx_wr32(fuc->memx, addr, next);
+ nvkm_memx_wr32(fuc->memx, addr, next);
}
}
}
#define ram_nuts(s,r,m,d,c) \
- nve0_ram_nuts((s), &(s)->fuc.r_##r, (m), (d), (c))
+ gk104_ram_nuts((s), &(s)->fuc.r_##r, (m), (d), (c))
static int
-nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
+gk104_ram_calc_gddr5(struct nvkm_fb *pfb, u32 freq)
{
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
- struct nouveau_ram_data *next = ram->base.next;
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct gk104_ramfuc *fuc = &ram->fuc;
+ struct nvkm_ram_data *next = ram->base.next;
int vc = !next->bios.ramcfg_11_02_08;
int mv = !next->bios.ramcfg_11_02_04;
u32 mask, data;
@@ -283,7 +277,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000);
- nve0_ram_train(fuc, 0x01020000, 0x000c0000);
+ gk104_ram_train(fuc, 0x01020000, 0x000c0000);
ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
ram_nsec(fuc, 1000);
@@ -588,7 +582,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
if (next->bios.ramcfg_11_08_10 && (ram->mode == 2) /*XXX*/) {
u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000);
- nve0_ram_train(fuc, 0xbc0e0000, 0xa4010000); /*XXX*/
+ gk104_ram_train(fuc, 0xbc0e0000, 0xa4010000); /*XXX*/
ram_nsec(fuc, 1000);
ram_wr32(fuc, 0x10f294, temp);
}
@@ -643,7 +637,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
} else {
data = 0xa40e0000;
}
- nve0_ram_train(fuc, 0xbc0f0000, data);
+ gk104_ram_train(fuc, 0xbc0f0000, data);
if (1) /* XXX: not always? */
ram_nsec(fuc, 1000);
@@ -661,7 +655,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
}
if (next->bios.ramcfg_11_07_02)
- nve0_ram_train(fuc, 0x80020000, 0x01000000);
+ gk104_ram_train(fuc, 0x80020000, 0x01000000);
ram_unblock(fuc);
ram_wr32(fuc, 0x62c000, 0x0f0f0f00);
@@ -680,14 +674,14 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq)
******************************************************************************/
static int
-nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
+gk104_ram_calc_sddr3(struct nvkm_fb *pfb, u32 freq)
{
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct gk104_ramfuc *fuc = &ram->fuc;
const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1);
const u32 runk0 = ram->fN1 << 16;
const u32 runk1 = ram->fN1;
- struct nouveau_ram_data *next = ram->base.next;
+ struct nvkm_ram_data *next = ram->base.next;
int vc = !next->bios.ramcfg_11_02_08;
int mv = !next->bios.ramcfg_11_02_04;
u32 mask, data;
@@ -932,11 +926,10 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq)
******************************************************************************/
static int
-nve0_ram_calc_data(struct nouveau_fb *pfb, u32 khz,
- struct nouveau_ram_data *data)
+gk104_ram_calc_data(struct nvkm_fb *pfb, u32 khz, struct nvkm_ram_data *data)
{
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nouveau_ram_data *cfg;
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct nvkm_ram_data *cfg;
u32 mhz = khz / 1000;
list_for_each_entry(cfg, &ram->cfg, head) {
@@ -953,10 +946,10 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 khz,
}
static int
-nve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
+gk104_ram_calc_xits(struct nvkm_fb *pfb, struct nvkm_ram_data *next)
{
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct gk104_ramfuc *fuc = &ram->fuc;
int refclk, i;
int ret;
@@ -980,8 +973,8 @@ nve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
refclk = fuc->mempll.refclk;
/* calculate refpll coefficients */
- ret = nva3_pll_calc(nv_subdev(pfb), &fuc->refpll, refclk, &ram->N1,
- &ram->fN1, &ram->M1, &ram->P1);
+ ret = gt215_pll_calc(nv_subdev(pfb), &fuc->refpll, refclk, &ram->N1,
+ &ram->fN1, &ram->M1, &ram->P1);
fuc->mempll.refclk = ret;
if (ret <= 0) {
nv_error(pfb, "unable to calc refpll\n");
@@ -997,8 +990,8 @@ nve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
fuc->mempll.min_p = 1;
fuc->mempll.max_p = 2;
- ret = nva3_pll_calc(nv_subdev(pfb), &fuc->mempll, next->freq,
- &ram->N2, NULL, &ram->M2, &ram->P2);
+ ret = gt215_pll_calc(nv_subdev(pfb), &fuc->mempll, next->freq,
+ &ram->N2, NULL, &ram->M2, &ram->P2);
if (ret <= 0) {
nv_error(pfb, "unable to calc mempll\n");
return -EINVAL;
@@ -1013,14 +1006,14 @@ nve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
switch (ram->base.type) {
case NV_MEM_TYPE_DDR3:
- ret = nouveau_sddr3_calc(&ram->base);
+ ret = nvkm_sddr3_calc(&ram->base);
if (ret == 0)
- ret = nve0_ram_calc_sddr3(pfb, next->freq);
+ ret = gk104_ram_calc_sddr3(pfb, next->freq);
break;
case NV_MEM_TYPE_GDDR5:
- ret = nouveau_gddr5_calc(&ram->base, ram->pnuts != 0);
+ ret = nvkm_gddr5_calc(&ram->base, ram->pnuts != 0);
if (ret == 0)
- ret = nve0_ram_calc_gddr5(pfb, next->freq);
+ ret = gk104_ram_calc_gddr5(pfb, next->freq);
break;
default:
ret = -ENOSYS;
@@ -1031,21 +1024,21 @@ nve0_ram_calc_xits(struct nouveau_fb *pfb, struct nouveau_ram_data *next)
}
static int
-nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
+gk104_ram_calc(struct nvkm_fb *pfb, u32 freq)
{
- struct nouveau_clock *clk = nouveau_clock(pfb);
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nouveau_ram_data *xits = &ram->base.xition;
- struct nouveau_ram_data *copy;
+ struct nvkm_clk *clk = nvkm_clk(pfb);
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct nvkm_ram_data *xits = &ram->base.xition;
+ struct nvkm_ram_data *copy;
int ret;
if (ram->base.next == NULL) {
- ret = nve0_ram_calc_data(pfb, clk->read(clk, nv_clk_src_mem),
- &ram->base.former);
+ ret = gk104_ram_calc_data(pfb, clk->read(clk, nv_clk_src_mem),
+ &ram->base.former);
if (ret)
return ret;
- ret = nve0_ram_calc_data(pfb, freq, &ram->base.target);
+ ret = gk104_ram_calc_data(pfb, freq, &ram->base.target);
if (ret)
return ret;
@@ -1069,14 +1062,14 @@ nve0_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram->base.next = &ram->base.target;
}
- return nve0_ram_calc_xits(pfb, ram->base.next);
+ return gk104_ram_calc_xits(pfb, ram->base.next);
}
static void
-nve0_ram_prog_0(struct nouveau_fb *pfb, u32 freq)
+gk104_ram_prog_0(struct nvkm_fb *pfb, u32 freq)
{
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nouveau_ram_data *cfg;
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct nvkm_ram_data *cfg;
u32 mhz = freq / 1000;
u32 mask, data;
@@ -1149,35 +1142,35 @@ nve0_ram_prog_0(struct nouveau_fb *pfb, u32 freq)
}
static int
-nve0_ram_prog(struct nouveau_fb *pfb)
+gk104_ram_prog(struct nvkm_fb *pfb)
{
- struct nouveau_device *device = nv_device(pfb);
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
- struct nouveau_ram_data *next = ram->base.next;
+ struct nvkm_device *device = nv_device(pfb);
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct gk104_ramfuc *fuc = &ram->fuc;
+ struct nvkm_ram_data *next = ram->base.next;
- if (!nouveau_boolopt(device->cfgopt, "NvMemExec", true)) {
+ if (!nvkm_boolopt(device->cfgopt, "NvMemExec", true)) {
ram_exec(fuc, false);
return (ram->base.next == &ram->base.xition);
}
- nve0_ram_prog_0(pfb, 1000);
+ gk104_ram_prog_0(pfb, 1000);
ram_exec(fuc, true);
- nve0_ram_prog_0(pfb, next->freq);
+ gk104_ram_prog_0(pfb, next->freq);
return (ram->base.next == &ram->base.xition);
}
static void
-nve0_ram_tidy(struct nouveau_fb *pfb)
+gk104_ram_tidy(struct nvkm_fb *pfb)
{
- struct nve0_ram *ram = (void *)pfb->ram;
- struct nve0_ramfuc *fuc = &ram->fuc;
+ struct gk104_ram *ram = (void *)pfb->ram;
+ struct gk104_ramfuc *fuc = &ram->fuc;
ram->base.next = NULL;
ram_exec(fuc, false);
}
-struct nve0_ram_train {
+struct gk104_ram_train {
u16 mask;
struct nvbios_M0209S remap;
struct nvbios_M0209S type00;
@@ -1190,10 +1183,10 @@ struct nve0_ram_train {
};
static int
-nve0_ram_train_type(struct nouveau_fb *pfb, int i, u8 ramcfg,
- struct nve0_ram_train *train)
+gk104_ram_train_type(struct nvkm_fb *pfb, int i, u8 ramcfg,
+ struct gk104_ram_train *train)
{
- struct nouveau_bios *bios = nouveau_bios(pfb);
+ struct nvkm_bios *bios = nvkm_bios(pfb);
struct nvbios_M0205E M0205E;
struct nvbios_M0205S M0205S;
struct nvbios_M0209E M0209E;
@@ -1251,7 +1244,7 @@ nve0_ram_train_type(struct nouveau_fb *pfb, int i, u8 ramcfg,
}
static int
-nve0_ram_train_init_0(struct nouveau_fb *pfb, struct nve0_ram_train *train)
+gk104_ram_train_init_0(struct nvkm_fb *pfb, struct gk104_ram_train *train)
{
int i, j;
@@ -1285,15 +1278,15 @@ nve0_ram_train_init_0(struct nouveau_fb *pfb, struct nve0_ram_train *train)
}
static int
-nve0_ram_train_init(struct nouveau_fb *pfb)
+gk104_ram_train_init(struct nvkm_fb *pfb)
{
u8 ramcfg = nvbios_ramcfg_index(nv_subdev(pfb));
- struct nve0_ram_train *train;
+ struct gk104_ram_train *train;
int ret = -ENOMEM, i;
if ((train = kzalloc(sizeof(*train), GFP_KERNEL))) {
for (i = 0; i < 0x100; i++) {
- ret = nve0_ram_train_type(pfb, i, ramcfg, train);
+ ret = gk104_ram_train_type(pfb, i, ramcfg, train);
if (ret && ret != -ENOENT)
break;
}
@@ -1301,7 +1294,7 @@ nve0_ram_train_init(struct nouveau_fb *pfb)
switch (pfb->ram->type) {
case NV_MEM_TYPE_GDDR5:
- ret = nve0_ram_train_init_0(pfb, train);
+ ret = gk104_ram_train_init_0(pfb, train);
break;
default:
ret = 0;
@@ -1313,16 +1306,16 @@ nve0_ram_train_init(struct nouveau_fb *pfb)
}
int
-nve0_ram_init(struct nouveau_object *object)
+gk104_ram_init(struct nvkm_object *object)
{
- struct nouveau_fb *pfb = (void *)object->parent;
- struct nve0_ram *ram = (void *)object;
- struct nouveau_bios *bios = nouveau_bios(pfb);
+ struct nvkm_fb *pfb = (void *)object->parent;
+ struct gk104_ram *ram = (void *)object;
+ struct nvkm_bios *bios = nvkm_bios(pfb);
u8 ver, hdr, cnt, len, snr, ssz;
u32 data, save;
int ret, i;
- ret = nouveau_ram_init(&ram->base);
+ ret = nvkm_ram_init(&ram->base);
if (ret)
return ret;
@@ -1360,15 +1353,15 @@ nve0_ram_init(struct nouveau_object *object)
nv_wr32(pfb, 0x10ecc0, 0xffffffff);
nv_mask(pfb, 0x10f160, 0x00000010, 0x00000010);
- return nve0_ram_train_init(pfb);
+ return gk104_ram_train_init(pfb);
}
static int
-nve0_ram_ctor_data(struct nve0_ram *ram, u8 ramcfg, int i)
+gk104_ram_ctor_data(struct gk104_ram *ram, u8 ramcfg, int i)
{
- struct nouveau_fb *pfb = (void *)nv_object(ram)->parent;
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nouveau_ram_data *cfg;
+ struct nvkm_fb *pfb = (void *)nv_object(ram)->parent;
+ struct nvkm_bios *bios = nvkm_bios(pfb);
+ struct nvkm_ram_data *cfg;
struct nvbios_ramcfg *d = &ram->diff;
struct nvbios_ramcfg *p, *n;
u8 ver, hdr, cnt, len;
@@ -1434,33 +1427,33 @@ done:
}
static void
-nve0_ram_dtor(struct nouveau_object *object)
+gk104_ram_dtor(struct nvkm_object *object)
{
- struct nve0_ram *ram = (void *)object;
- struct nouveau_ram_data *cfg, *tmp;
+ struct gk104_ram *ram = (void *)object;
+ struct nvkm_ram_data *cfg, *tmp;
list_for_each_entry_safe(cfg, tmp, &ram->cfg, head) {
kfree(cfg);
}
- nouveau_ram_destroy(&ram->base);
+ nvkm_ram_destroy(&ram->base);
}
static int
-nve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nouveau_gpio *gpio = nouveau_gpio(pfb);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_bios *bios = nvkm_bios(pfb);
+ struct nvkm_gpio *gpio = nvkm_gpio(pfb);
struct dcb_gpio_func func;
- struct nve0_ram *ram;
+ struct gk104_ram *ram;
int ret, i;
u8 ramcfg = nvbios_ramcfg_index(nv_subdev(pfb));
u32 tmp;
- ret = nvc0_ram_create(parent, engine, oclass, 0x022554, &ram);
+ ret = gf100_ram_create(parent, engine, oclass, 0x022554, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -1470,9 +1463,9 @@ nve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
switch (ram->base.type) {
case NV_MEM_TYPE_DDR3:
case NV_MEM_TYPE_GDDR5:
- ram->base.calc = nve0_ram_calc;
- ram->base.prog = nve0_ram_prog;
- ram->base.tidy = nve0_ram_tidy;
+ ram->base.calc = gk104_ram_calc;
+ ram->base.prog = gk104_ram_prog;
+ ram->base.tidy = gk104_ram_tidy;
break;
default:
nv_warn(pfb, "reclocking of this RAM type is unsupported\n");
@@ -1510,7 +1503,7 @@ nve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
* need to treat this condition as a "don't touch" indicator.
*/
for (i = 0; !ret; i++) {
- ret = nve0_ram_ctor_data(ram, ramcfg, i);
+ ret = gk104_ram_ctor_data(ram, ramcfg, i);
if (ret && ret != -ENOENT) {
nv_error(pfb, "failed to parse ramcfg data\n");
return ret;
@@ -1634,13 +1627,13 @@ nve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
-nve0_ram_oclass = {
+struct nvkm_oclass
+gk104_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_ram_ctor,
- .dtor = nve0_ram_dtor,
- .init = nve0_ram_init,
- .fini = _nouveau_ram_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_ram_ctor,
+ .dtor = gk104_ram_dtor,
+ .init = gk104_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk20a.c
index 4d77d75e4673..5f30db140b47 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk20a.c
@@ -19,20 +19,19 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-
#include "priv.h"
-#include <subdev/fb.h>
+#include <core/device.h>
struct gk20a_mem {
- struct nouveau_mem base;
+ struct nvkm_mem base;
void *cpuaddr;
dma_addr_t handle;
};
#define to_gk20a_mem(m) container_of(m, struct gk20a_mem, base)
static void
-gk20a_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+gk20a_ram_put(struct nvkm_fb *pfb, struct nvkm_mem **pmem)
{
struct device *dev = nv_device_base(nv_device(pfb));
struct gk20a_mem *mem = to_gk20a_mem(*pmem);
@@ -50,8 +49,8 @@ gk20a_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
}
static int
-gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **pmem)
+gk20a_ram_get(struct nvkm_fb *pfb, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nvkm_mem **pmem)
{
struct device *dev = nv_device_base(nv_device(pfb));
struct gk20a_mem *mem;
@@ -116,19 +115,18 @@ gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
mem->base.pages[i] = mem->handle + (PAGE_SIZE * i);
mem->base.offset = (u64)mem->base.pages[0];
-
return 0;
}
static int
-gk20a_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 datasize,
- struct nouveau_object **pobject)
+gk20a_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 datasize,
+ struct nvkm_object **pobject)
{
- struct nouveau_ram *ram;
+ struct nvkm_ram *ram;
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -137,16 +135,15 @@ gk20a_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
ram->get = gk20a_ram_get;
ram->put = gk20a_ram_put;
-
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gk20a_ram_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gk20a_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramgm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c
index 4c6363595c79..a298b39f55c5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramgm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgm107.c
@@ -21,22 +21,21 @@
*
* Authors: Ben Skeggs
*/
-
-#include "nvc0.h"
+#include "gf100.h"
struct gm107_ram {
- struct nouveau_ram base;
+ struct nvkm_ram base;
};
static int
-gm107_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gm107_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct gm107_ram *ram;
int ret;
- ret = nvc0_ram_create(parent, engine, oclass, 0x021c14, &ram);
+ ret = gf100_ram_create(parent, engine, oclass, 0x021c14, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -44,13 +43,13 @@ gm107_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gm107_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm107_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = nve0_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = gk104_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 3b38a538845d..24176401b49b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -23,32 +23,22 @@
* Roy Spliet <rspliet@eclipso.eu>
*/
+#include "ramfuc.h"
+#include "nv50.h"
+
+#include <core/device.h>
+#include <core/option.h>
#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/pll.h>
-#include <subdev/bios/rammap.h>
#include <subdev/bios/M0205.h>
+#include <subdev/bios/rammap.h>
#include <subdev/bios/timing.h>
-
-#include <subdev/clock/nva3.h>
-#include <subdev/clock/pll.h>
-
+#include <subdev/clk/gt215.h>
#include <subdev/gpio.h>
-#include <subdev/timer.h>
-
-#include <engine/fifo.h>
-
-#include <core/option.h>
-
-#include "ramfuc.h"
-
-#include "nv50.h"
-
/* XXX: Remove when memx gains GPIO support */
extern int nv50_gpio_location(int line, u32 *reg, u32 *shift);
-struct nva3_ramfuc {
+struct gt215_ramfuc {
struct ramfuc base;
struct ramfuc_reg r_0x001610;
struct ramfuc_reg r_0x001700;
@@ -89,7 +79,7 @@ struct nva3_ramfuc {
struct ramfuc_reg r_gpioFBVREF;
};
-struct nva3_ltrain {
+struct gt215_ltrain {
enum {
NVA3_TRAIN_UNKNOWN,
NVA3_TRAIN_UNSUPPORTED,
@@ -100,17 +90,17 @@ struct nva3_ltrain {
u32 r_100720;
u32 r_1111e0;
u32 r_111400;
- struct nouveau_mem *mem;
+ struct nvkm_mem *mem;
};
-struct nva3_ram {
- struct nouveau_ram base;
- struct nva3_ramfuc fuc;
- struct nva3_ltrain ltrain;
+struct gt215_ram {
+ struct nvkm_ram base;
+ struct gt215_ramfuc fuc;
+ struct gt215_ltrain ltrain;
};
void
-nva3_link_train_calc(u32 *vals, struct nva3_ltrain *train)
+gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
{
int i, lo, hi;
u8 median[8], bins[4] = {0, 0, 0, 0}, bin = 0, qty = 0;
@@ -164,14 +154,14 @@ nva3_link_train_calc(u32 *vals, struct nva3_ltrain *train)
* Link training for (at least) DDR3
*/
int
-nva3_link_train(struct nouveau_fb *pfb)
+gt215_link_train(struct nvkm_fb *pfb)
{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nouveau_clock *clk = nouveau_clock(pfb);
- struct nva3_ltrain *train = &ram->ltrain;
- struct nouveau_device *device = nv_device(pfb);
- struct nva3_ramfuc *fuc = &ram->fuc;
+ struct nvkm_bios *bios = nvkm_bios(pfb);
+ struct gt215_ram *ram = (void *)pfb->ram;
+ struct nvkm_clk *clk = nvkm_clk(pfb);
+ struct gt215_ltrain *train = &ram->ltrain;
+ struct nvkm_device *device = nv_device(pfb);
+ struct gt215_ramfuc *fuc = &ram->fuc;
u32 *result, r1700;
int ret, i;
struct nvbios_M0205T M0205T = { 0 };
@@ -180,7 +170,7 @@ nva3_link_train(struct nouveau_fb *pfb)
unsigned long flags;
unsigned long *f = &flags;
- if (nouveau_boolopt(device->cfgopt, "NvMemExec", true) != true)
+ if (nvkm_boolopt(device->cfgopt, "NvMemExec", true) != true)
return -ENOSYS;
/* XXX: Multiple partitions? */
@@ -197,7 +187,7 @@ nva3_link_train(struct nouveau_fb *pfb)
clk_current = clk->read(clk, nv_clk_src_mem);
- ret = nva3_clock_pre(clk, f);
+ ret = gt215_clk_pre(clk, f);
if (ret)
goto out;
@@ -252,12 +242,12 @@ nva3_link_train(struct nouveau_fb *pfb)
nv_mask(pfb, 0x616308, 0x10, 0x10);
nv_mask(pfb, 0x616b08, 0x10, 0x10);
- nva3_clock_post(clk, f);
+ gt215_clk_post(clk, f);
ram_train_result(pfb, result, 64);
for (i = 0; i < 64; i++)
nv_debug(pfb, "Train: %08x", result[i]);
- nva3_link_train_calc(result, train);
+ gt215_link_train_calc(result, train);
nv_debug(pfb, "Train: %08x %08x %08x", train->r_100720,
train->r_1111e0, train->r_111400);
@@ -274,12 +264,12 @@ out:
train->state = NVA3_TRAIN_UNSUPPORTED;
- nva3_clock_post(clk, f);
+ gt215_clk_post(clk, f);
return ret;
}
int
-nva3_link_train_init(struct nouveau_fb *pfb)
+gt215_link_train_init(struct nvkm_fb *pfb)
{
static const u32 pattern[16] = {
0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee,
@@ -287,10 +277,10 @@ nva3_link_train_init(struct nouveau_fb *pfb)
0x33333333, 0x55555555, 0x77777777, 0x66666666,
0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb,
};
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nva3_ltrain *train = &ram->ltrain;
- struct nouveau_mem *mem;
+ struct nvkm_bios *bios = nvkm_bios(pfb);
+ struct gt215_ram *ram = (void *)pfb->ram;
+ struct gt215_ltrain *train = &ram->ltrain;
+ struct nvkm_mem *mem;
struct nvbios_M0205E M0205E;
u8 ver, hdr, cnt, len;
u32 r001700;
@@ -340,14 +330,13 @@ nva3_link_train_init(struct nouveau_fb *pfb)
train->r_100720 = nv_rd32(pfb, 0x100720);
train->r_1111e0 = nv_rd32(pfb, 0x1111e0);
train->r_111400 = nv_rd32(pfb, 0x111400);
-
return 0;
}
void
-nva3_link_train_fini(struct nouveau_fb *pfb)
+gt215_link_train_fini(struct nvkm_fb *pfb)
{
- struct nva3_ram *ram = (void *)pfb->ram;
+ struct gt215_ram *ram = (void *)pfb->ram;
if (ram->ltrain.mem)
pfb->ram->put(pfb, &ram->ltrain.mem);
@@ -358,9 +347,9 @@ nva3_link_train_fini(struct nouveau_fb *pfb)
*/
#define T(t) cfg->timing_10_##t
static int
-nva3_ram_timing_calc(struct nouveau_fb *pfb, u32 *timing)
+gt215_ram_timing_calc(struct nvkm_fb *pfb, u32 *timing)
{
- struct nva3_ram *ram = (void *)pfb->ram;
+ struct gt215_ram *ram = (void *)pfb->ram;
struct nvbios_ramcfg *cfg = &ram->base.target.bios;
int tUNK_base, tUNK_40_0, prevCL;
u32 cur2, cur3, cur7, cur8;
@@ -433,7 +422,7 @@ nva3_ram_timing_calc(struct nouveau_fb *pfb, u32 *timing)
#undef T
static void
-nouveau_sddr2_dll_reset(struct nva3_ramfuc *fuc)
+nvkm_sddr2_dll_reset(struct gt215_ramfuc *fuc)
{
ram_mask(fuc, mr[0], 0x100, 0x100);
ram_nsec(fuc, 1000);
@@ -442,7 +431,7 @@ nouveau_sddr2_dll_reset(struct nva3_ramfuc *fuc)
}
static void
-nouveau_sddr3_dll_disable(struct nva3_ramfuc *fuc, u32 *mr)
+nvkm_sddr3_dll_disable(struct gt215_ramfuc *fuc, u32 *mr)
{
u32 mr1_old = ram_rd32(fuc, mr[1]);
@@ -454,7 +443,7 @@ nouveau_sddr3_dll_disable(struct nva3_ramfuc *fuc, u32 *mr)
}
static void
-nouveau_gddr3_dll_disable(struct nva3_ramfuc *fuc, u32 *mr)
+nvkm_gddr3_dll_disable(struct gt215_ramfuc *fuc, u32 *mr)
{
u32 mr1_old = ram_rd32(fuc, mr[1]);
@@ -465,7 +454,7 @@ nouveau_gddr3_dll_disable(struct nva3_ramfuc *fuc, u32 *mr)
}
static void
-nva3_ram_lock_pll(struct nva3_ramfuc *fuc, struct nva3_clock_info *mclk)
+gt215_ram_lock_pll(struct gt215_ramfuc *fuc, struct gt215_clk_info *mclk)
{
ram_wr32(fuc, 0x004004, mclk->pll);
ram_mask(fuc, 0x004000, 0x00000001, 0x00000001);
@@ -475,9 +464,9 @@ nva3_ram_lock_pll(struct nva3_ramfuc *fuc, struct nva3_clock_info *mclk)
}
static void
-nva3_ram_fbvref(struct nva3_ramfuc *fuc, u32 val)
+gt215_ram_fbvref(struct gt215_ramfuc *fuc, u32 val)
{
- struct nouveau_gpio *gpio = nouveau_gpio(fuc->base.pfb);
+ struct nvkm_gpio *gpio = nvkm_gpio(fuc->base.pfb);
struct dcb_gpio_func func;
u32 reg, sh, gpio_val;
int ret;
@@ -498,14 +487,14 @@ nva3_ram_fbvref(struct nva3_ramfuc *fuc, u32 val)
}
static int
-nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
+gt215_ram_calc(struct nvkm_fb *pfb, u32 freq)
{
- struct nouveau_bios *bios = nouveau_bios(pfb);
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nva3_ramfuc *fuc = &ram->fuc;
- struct nva3_ltrain *train = &ram->ltrain;
- struct nva3_clock_info mclk;
- struct nouveau_ram_data *next;
+ struct nvkm_bios *bios = nvkm_bios(pfb);
+ struct gt215_ram *ram = (void *)pfb->ram;
+ struct gt215_ramfuc *fuc = &ram->fuc;
+ struct gt215_ltrain *train = &ram->ltrain;
+ struct gt215_clk_info mclk;
+ struct nvkm_ram_data *next;
u8 ver, hdr, cnt, len, strap;
u32 data;
u32 r004018, r100760, r100da0, r111100, ctrl;
@@ -519,12 +508,12 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram->base.next = next;
if (ram->ltrain.state == NVA3_TRAIN_ONCE)
- nva3_link_train(pfb);
+ gt215_link_train(pfb);
/* lookup memory config data relevant to the target frequency */
i = 0;
data = nvbios_rammapEm(bios, freq / 1000, &ver, &hdr, &cnt, &len,
- &next->bios);
+ &next->bios);
if (!data || ver != 0x10 || hdr < 0x05) {
nv_error(pfb, "invalid/missing rammap entry\n");
return -EINVAL;
@@ -555,13 +544,13 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
}
}
- ret = nva3_pll_info(nouveau_clock(pfb), 0x12, 0x4000, freq, &mclk);
+ ret = gt215_pll_info(nvkm_clk(pfb), 0x12, 0x4000, freq, &mclk);
if (ret < 0) {
nv_error(pfb, "failed mclk calculation\n");
return ret;
}
- nva3_ram_timing_calc(pfb, timing);
+ gt215_ram_timing_calc(pfb, timing);
ret = ram_init(fuc, pfb);
if (ret)
@@ -574,13 +563,13 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
switch (ram->base.type) {
case NV_MEM_TYPE_DDR2:
- ret = nouveau_sddr2_calc(&ram->base);
+ ret = nvkm_sddr2_calc(&ram->base);
break;
case NV_MEM_TYPE_DDR3:
- ret = nouveau_sddr3_calc(&ram->base);
+ ret = nvkm_sddr3_calc(&ram->base);
break;
case NV_MEM_TYPE_GDDR3:
- ret = nouveau_gddr3_calc(&ram->base);
+ ret = nvkm_gddr3_calc(&ram->base);
break;
default:
ret = -ENOSYS;
@@ -621,7 +610,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* If switching from non-pll to pll, lock before disabling FB */
if (mclk.pll && !pll2pll) {
ram_mask(fuc, 0x004128, 0x003f3141, mclk.clk | 0x00000101);
- nva3_ram_lock_pll(fuc, &mclk);
+ gt215_ram_lock_pll(fuc, &mclk);
}
/* Start with disabling some CRTCs and PFIFO? */
@@ -643,15 +632,15 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
/* If we're disabling the DLL, do it now */
switch (next->bios.ramcfg_10_DLLoff * ram->base.type) {
case NV_MEM_TYPE_DDR3:
- nouveau_sddr3_dll_disable(fuc, ram->base.mr);
+ nvkm_sddr3_dll_disable(fuc, ram->base.mr);
break;
case NV_MEM_TYPE_GDDR3:
- nouveau_gddr3_dll_disable(fuc, ram->base.mr);
+ nvkm_gddr3_dll_disable(fuc, ram->base.mr);
break;
}
if (fuc->r_gpioFBVREF.addr && next->bios.timing_10_ODT)
- nva3_ram_fbvref(fuc, 0);
+ gt215_ram_fbvref(fuc, 0);
/* Brace RAM for impact */
ram_wr32(fuc, 0x1002d4, 0x00000001);
@@ -678,7 +667,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x004000, 0x00000008, 0x00000008);
ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000);
ram_wr32(fuc, 0x004018, 0x00001000);
- nva3_ram_lock_pll(fuc, &mclk);
+ gt215_ram_lock_pll(fuc, &mclk);
}
if (mclk.pll) {
@@ -818,11 +807,11 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
ram_mask(fuc, 0x111100, 0xffffffff, r111100);
if (fuc->r_gpioFBVREF.addr && !next->bios.timing_10_ODT)
- nva3_ram_fbvref(fuc, 1);
+ gt215_ram_fbvref(fuc, 1);
/* Reset DLL */
if (!next->bios.ramcfg_10_DLLoff)
- nouveau_sddr2_dll_reset(fuc);
+ nvkm_sddr2_dll_reset(fuc);
if (ram->base.type == NV_MEM_TYPE_GDDR3) {
ram_nsec(fuc, 31000);
@@ -866,12 +855,12 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
}
static int
-nva3_ram_prog(struct nouveau_fb *pfb)
+gt215_ram_prog(struct nvkm_fb *pfb)
{
- struct nouveau_device *device = nv_device(pfb);
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nva3_ramfuc *fuc = &ram->fuc;
- bool exec = nouveau_boolopt(device->cfgopt, "NvMemExec", true);
+ struct nvkm_device *device = nv_device(pfb);
+ struct gt215_ram *ram = (void *)pfb->ram;
+ struct gt215_ramfuc *fuc = &ram->fuc;
+ bool exec = nvkm_boolopt(device->cfgopt, "NvMemExec", true);
if (exec) {
nv_mask(pfb, 0x001534, 0x2, 0x2);
@@ -891,49 +880,48 @@ nva3_ram_prog(struct nouveau_fb *pfb)
}
static void
-nva3_ram_tidy(struct nouveau_fb *pfb)
+gt215_ram_tidy(struct nvkm_fb *pfb)
{
- struct nva3_ram *ram = (void *)pfb->ram;
- struct nva3_ramfuc *fuc = &ram->fuc;
+ struct gt215_ram *ram = (void *)pfb->ram;
+ struct gt215_ramfuc *fuc = &ram->fuc;
ram_exec(fuc, false);
}
static int
-nva3_ram_init(struct nouveau_object *object)
+gt215_ram_init(struct nvkm_object *object)
{
- struct nouveau_fb *pfb = (void *)object->parent;
- struct nva3_ram *ram = (void *)object;
+ struct nvkm_fb *pfb = (void *)object->parent;
+ struct gt215_ram *ram = (void *)object;
int ret;
- ret = nouveau_ram_init(&ram->base);
+ ret = nvkm_ram_init(&ram->base);
if (ret)
return ret;
- nva3_link_train_init(pfb);
-
+ gt215_link_train_init(pfb);
return 0;
}
static int
-nva3_ram_fini(struct nouveau_object *object, bool suspend)
+gt215_ram_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_fb *pfb = (void *)object->parent;
+ struct nvkm_fb *pfb = (void *)object->parent;
if (!suspend)
- nva3_link_train_fini(pfb);
+ gt215_link_train_fini(pfb);
return 0;
}
static int
-nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 datasize,
- struct nouveau_object **pobject)
+gt215_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 datasize,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_gpio *gpio = nouveau_gpio(pfb);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_gpio *gpio = nvkm_gpio(pfb);
struct dcb_gpio_func func;
- struct nva3_ram *ram;
+ struct gt215_ram *ram;
int ret, i;
u32 reg, shift;
@@ -946,9 +934,9 @@ nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
case NV_MEM_TYPE_DDR2:
case NV_MEM_TYPE_DDR3:
case NV_MEM_TYPE_GDDR3:
- ram->base.calc = nva3_ram_calc;
- ram->base.prog = nva3_ram_prog;
- ram->base.tidy = nva3_ram_tidy;
+ ram->base.calc = gt215_ram_calc;
+ ram->base.prog = gt215_ram_prog;
+ ram->base.tidy = gt215_ram_tidy;
break;
default:
nv_warn(ram, "reclocking of this ram type unsupported\n");
@@ -1013,12 +1001,12 @@ nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
-nva3_ram_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = nva3_ram_init,
- .fini = nva3_ram_fini,
+struct nvkm_oclass
+gt215_ram_oclass = {
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gt215_ram_ctor,
+ .dtor = _nvkm_ram_dtor,
+ .init = gt215_ram_init,
+ .fini = gt215_ram_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c
index 033a8e999497..abc18e89a97c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c
@@ -21,26 +21,25 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
-struct nvaa_ram_priv {
- struct nouveau_ram base;
+struct mcp77_ram_priv {
+ struct nvkm_ram base;
u64 poller_base;
};
static int
-nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 datasize,
- struct nouveau_object **pobject)
+mcp77_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 datasize,
+ struct nvkm_object **pobject)
{
u32 rsvd_head = ( 256 * 1024); /* vga memory */
u32 rsvd_tail = (1024 * 1024); /* vbios etc */
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nvaa_ram_priv *priv;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct mcp77_ram_priv *priv;
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &priv);
+ ret = nvkm_ram_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -52,9 +51,9 @@ nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
rsvd_tail += 0x1000;
priv->poller_base = priv->base.size - rsvd_tail;
- ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12,
- (priv->base.size - (rsvd_head + rsvd_tail)) >> 12,
- 1);
+ ret = nvkm_mm_init(&pfb->vram, rsvd_head >> 12,
+ (priv->base.size - (rsvd_head + rsvd_tail)) >> 12,
+ 1);
if (ret)
return ret;
@@ -64,14 +63,14 @@ nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
static int
-nvaa_ram_init(struct nouveau_object *object)
+mcp77_ram_init(struct nvkm_object *object)
{
- struct nouveau_fb *pfb = nouveau_fb(object);
- struct nvaa_ram_priv *priv = (void *)object;
+ struct nvkm_fb *pfb = nvkm_fb(object);
+ struct mcp77_ram_priv *priv = (void *)object;
int ret;
u64 dniso, hostnb, flush;
- ret = nouveau_ram_init(&priv->base);
+ ret = nvkm_ram_init(&priv->base);
if (ret)
return ret;
@@ -88,16 +87,15 @@ nvaa_ram_init(struct nouveau_object *object)
nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002);
nv_wr32(pfb, 0x100c24, flush);
nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000);
-
return 0;
}
-struct nouveau_oclass
-nvaa_ram_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvaa_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = nvaa_ram_init,
- .fini = _nouveau_ram_fini,
+struct nvkm_oclass
+mcp77_ram_oclass = {
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = mcp77_ram_ctor,
+ .dtor = _nvkm_ram_dtor,
+ .init = mcp77_ram_init,
+ .fini = _nvkm_ram_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c
index 1972268d1410..855de1617229 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv04.c
@@ -21,22 +21,20 @@
*
* Authors: Ben Skeggs
*/
-
-#include <subdev/fb/regsnv04.h>
-
#include "priv.h"
+#include "regsnv04.h"
static int
-nv04_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_ram *ram;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_ram *ram;
u32 boot0 = nv_rd32(pfb, NV04_PFB_BOOT_0);
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -65,16 +63,17 @@ nv04_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
ram->type = NV_MEM_TYPE_SGRAM;
else
ram->type = NV_MEM_TYPE_SDRAM;
+
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv04_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c
index 8311f3774edf..3b8a1eda5b64 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv10.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
static int
-nv10_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv10_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_ram *ram;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_ram *ram;
u32 cfg0 = nv_rd32(pfb, 0x100200);
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -48,14 +47,13 @@ nv10_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-
-struct nouveau_oclass
+struct nvkm_oclass
nv10_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv10_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
index d0caddfb9db0..fbae05db4ffd 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
@@ -21,16 +21,17 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
+#include <core/device.h>
+
static int
-nv1a_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv1a_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_ram *ram;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_ram *ram;
struct pci_dev *bridge;
u32 mem, mib;
int ret;
@@ -41,7 +42,7 @@ nv1a_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return -ENODEV;
}
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -59,13 +60,13 @@ nv1a_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv1a_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv1a_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c
index fdc11bba226d..d9e7187bd235 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv20.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
static int
-nv20_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv20_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_ram *ram;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_ram *ram;
u32 pbus1218 = nv_rd32(pfb, 0x001218);
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -51,13 +50,13 @@ nv20_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv20_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv20_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c
index 7648beb11199..3d31fa45c1a6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c
@@ -21,23 +21,20 @@
*
* Authors: Ben Skeggs
*/
+#include "nv40.h"
+#include <core/device.h>
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
-#include <subdev/bios/pll.h>
#include <subdev/bios/init.h>
-#include <subdev/clock.h>
-#include <subdev/clock/pll.h>
+#include <subdev/bios/pll.h>
+#include <subdev/clk/pll.h>
#include <subdev/timer.h>
-#include <engine/fifo.h>
-
-#include "nv40.h"
-
int
-nv40_ram_calc(struct nouveau_fb *pfb, u32 freq)
+nv40_ram_calc(struct nvkm_fb *pfb, u32 freq)
{
- struct nouveau_bios *bios = nouveau_bios(pfb);
+ struct nvkm_bios *bios = nvkm_bios(pfb);
struct nv40_ram *ram = (void *)pfb->ram;
struct nvbios_pll pll;
int N1, M1, N2, M2;
@@ -68,9 +65,9 @@ nv40_ram_calc(struct nouveau_fb *pfb, u32 freq)
}
int
-nv40_ram_prog(struct nouveau_fb *pfb)
+nv40_ram_prog(struct nvkm_fb *pfb)
{
- struct nouveau_bios *bios = nouveau_bios(pfb);
+ struct nvkm_bios *bios = nvkm_bios(pfb);
struct nv40_ram *ram = (void *)pfb->ram;
struct bit_entry M;
u32 crtc_mask = 0;
@@ -167,21 +164,21 @@ nv40_ram_prog(struct nouveau_fb *pfb)
}
void
-nv40_ram_tidy(struct nouveau_fb *pfb)
+nv40_ram_tidy(struct nvkm_fb *pfb)
{
}
static int
-nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
struct nv40_ram *ram;
u32 pbus1218 = nv_rd32(pfb, 0x001218);
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -203,13 +200,13 @@ nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
}
-struct nouveau_oclass
+struct nvkm_oclass
nv40_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv40_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c
index d64498a4d9ee..33c612b1355f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv41.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv40.h"
static int
-nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv41_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
struct nv40_ram *ram;
u32 pfb474 = nv_rd32(pfb, 0x100474);
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -55,13 +54,13 @@ nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv41_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv41_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c
index 089acac810c5..f575a7246403 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv44.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv40.h"
static int
-nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv44_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
struct nv40_ram *ram;
u32 pfb474 = nv_rd32(pfb, 0x100474);
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -53,13 +52,13 @@ nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv44_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv44_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c
index baa013afa57b..51b44cdb2732 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv49.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv40.h"
static int
-nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv49_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
struct nv40_ram *ram;
u32 pfb914 = nv_rd32(pfb, 0x100914);
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -55,13 +54,13 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv49_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv49_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c
index 63a6aab86028..f3ed1c60d730 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv4e.c
@@ -21,19 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
static int
-nv4e_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv4e_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_ram *ram;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_ram *ram;
int ret;
- ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ ret = nvkm_ram_create(parent, engine, oclass, &ram);
*pobject = nv_object(ram);
if (ret)
return ret;
@@ -43,13 +42,13 @@ nv4e_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv4e_ram_oclass = {
.handle = 0,
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv4e_ram_create,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 64a983c96625..d2c81dd635dc 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -21,21 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "nv50.h"
+#include "ramseq.h"
+#include <core/device.h>
+#include <core/option.h>
#include <subdev/bios.h>
-#include <subdev/bios/bit.h>
-#include <subdev/bios/pll.h>
#include <subdev/bios/perf.h>
+#include <subdev/bios/pll.h>
#include <subdev/bios/timing.h>
-#include <subdev/clock/pll.h>
-#include <subdev/fb.h>
-
-#include <core/option.h>
-#include <core/mm.h>
-
-#include "ramseq.h"
-
-#include "nv50.h"
+#include <subdev/clk/pll.h>
struct nv50_ramseq {
struct hwsq base;
@@ -56,16 +51,16 @@ struct nv50_ramseq {
};
struct nv50_ram {
- struct nouveau_ram base;
+ struct nvkm_ram base;
struct nv50_ramseq hwsq;
};
#define QFX5800NVA0 1
static int
-nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
+nv50_ram_calc(struct nvkm_fb *pfb, u32 freq)
{
- struct nouveau_bios *bios = nouveau_bios(pfb);
+ struct nvkm_bios *bios = nvkm_bios(pfb);
struct nv50_ram *ram = (void *)pfb->ram;
struct nv50_ramseq *hwsq = &ram->hwsq;
struct nvbios_perfE perfE;
@@ -82,7 +77,7 @@ nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
i = 0;
do {
ramcfg.data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt,
- &ramcfg.size, &perfE);
+ &ramcfg.size, &perfE);
if (!ramcfg.data || (ver < 0x25 || ver >= 0x40) ||
(ramcfg.size < 2)) {
nv_error(pfb, "invalid/missing perftab entry\n");
@@ -103,7 +98,7 @@ nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
strap = nv_ro08(bios, ramcfg.data + 0x01);
if (strap != 0xff) {
timing.data = nvbios_timingEe(bios, strap, &ver, &hdr,
- &cnt, &len);
+ &cnt, &len);
if (!timing.data || ver != 0x10 || hdr < 0x12) {
nv_error(pfb, "invalid/missing timing entry "
"%02x %04x %02x %02x\n",
@@ -136,7 +131,7 @@ nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
mpll.vco2.max_freq = 0;
if (ret == 0) {
ret = nv04_pll_calc(nv_subdev(pfb), &mpll, freq,
- &N1, &M1, &N2, &M2, &P);
+ &N1, &M1, &N2, &M2, &P);
if (ret == 0)
ret = -EINVAL;
}
@@ -205,18 +200,18 @@ nv50_ram_calc(struct nouveau_fb *pfb, u32 freq)
}
static int
-nv50_ram_prog(struct nouveau_fb *pfb)
+nv50_ram_prog(struct nvkm_fb *pfb)
{
- struct nouveau_device *device = nv_device(pfb);
+ struct nvkm_device *device = nv_device(pfb);
struct nv50_ram *ram = (void *)pfb->ram;
struct nv50_ramseq *hwsq = &ram->hwsq;
- ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
+ ram_exec(hwsq, nvkm_boolopt(device->cfgopt, "NvMemExec", true));
return 0;
}
static void
-nv50_ram_tidy(struct nouveau_fb *pfb)
+nv50_ram_tidy(struct nvkm_fb *pfb)
{
struct nv50_ram *ram = (void *)pfb->ram;
struct nv50_ramseq *hwsq = &ram->hwsq;
@@ -224,24 +219,24 @@ nv50_ram_tidy(struct nouveau_fb *pfb)
}
void
-__nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem)
+__nv50_ram_put(struct nvkm_fb *pfb, struct nvkm_mem *mem)
{
- struct nouveau_mm_node *this;
+ struct nvkm_mm_node *this;
while (!list_empty(&mem->regions)) {
this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
list_del(&this->rl_entry);
- nouveau_mm_free(&pfb->vram, &this);
+ nvkm_mm_free(&pfb->vram, &this);
}
- nouveau_mm_free(&pfb->tags, &mem->tag);
+ nvkm_mm_free(&pfb->tags, &mem->tag);
}
void
-nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+nv50_ram_put(struct nvkm_fb *pfb, struct nvkm_mem **pmem)
{
- struct nouveau_mem *mem = *pmem;
+ struct nvkm_mem *mem = *pmem;
*pmem = NULL;
if (unlikely(mem == NULL))
@@ -255,13 +250,13 @@ nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
}
int
-nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
- u32 memtype, struct nouveau_mem **pmem)
+nv50_ram_get(struct nvkm_fb *pfb, u64 size, u32 align, u32 ncmin,
+ u32 memtype, struct nvkm_mem **pmem)
{
- struct nouveau_mm *heap = &pfb->vram;
- struct nouveau_mm *tags = &pfb->tags;
- struct nouveau_mm_node *r;
- struct nouveau_mem *mem;
+ struct nvkm_mm *heap = &pfb->vram;
+ struct nvkm_mm *tags = &pfb->tags;
+ struct nvkm_mm_node *r;
+ struct nvkm_mem *mem;
int comp = (memtype & 0x300) >> 8;
int type = (memtype & 0x07f);
int back = (memtype & 0x800);
@@ -280,7 +275,7 @@ nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
if (align == 16) {
int n = (max >> 4) * comp;
- ret = nouveau_mm_head(tags, 0, 1, n, n, 1, &mem->tag);
+ ret = nvkm_mm_head(tags, 0, 1, n, n, 1, &mem->tag);
if (ret)
mem->tag = NULL;
}
@@ -296,9 +291,9 @@ nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
type = nv50_fb_memtype[type];
do {
if (back)
- ret = nouveau_mm_tail(heap, 0, type, max, min, align, &r);
+ ret = nvkm_mm_tail(heap, 0, type, max, min, align, &r);
else
- ret = nouveau_mm_head(heap, 0, type, max, min, align, &r);
+ ret = nvkm_mm_head(heap, 0, type, max, min, align, &r);
if (ret) {
mutex_unlock(&pfb->base.mutex);
pfb->ram->put(pfb, &mem);
@@ -310,14 +305,14 @@ nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
} while (max);
mutex_unlock(&pfb->base.mutex);
- r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+ r = list_first_entry(&mem->regions, struct nvkm_mm_node, rl_entry);
mem->offset = (u64)r->offset << 12;
*pmem = mem;
return 0;
}
static u32
-nv50_fb_vram_rblock(struct nouveau_fb *pfb, struct nouveau_ram *ram)
+nv50_fb_vram_rblock(struct nvkm_fb *pfb, struct nvkm_ram *ram)
{
int colbits, rowbitsa, rowbitsb, banks;
u64 rowsize, predicted;
@@ -326,8 +321,8 @@ nv50_fb_vram_rblock(struct nouveau_fb *pfb, struct nouveau_ram *ram)
r0 = nv_rd32(pfb, 0x100200);
r4 = nv_rd32(pfb, 0x100204);
rt = nv_rd32(pfb, 0x100250);
- nv_debug(pfb, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt,
- nv_rd32(pfb, 0x001540));
+ nv_debug(pfb, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ r0, r4, rt, nv_rd32(pfb, 0x001540));
colbits = (r4 & 0x0000f000) >> 12;
rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
@@ -353,17 +348,17 @@ nv50_fb_vram_rblock(struct nouveau_fb *pfb, struct nouveau_ram *ram)
}
int
-nv50_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+nv50_ram_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_ram *ram;
+ struct nvkm_bios *bios = nvkm_bios(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_ram *ram;
int ret;
- ret = nouveau_ram_create_(parent, engine, oclass, length, pobject);
+ ret = nvkm_ram_create_(parent, engine, oclass, length, pobject);
ram = *pobject;
if (ret)
return ret;
@@ -377,7 +372,7 @@ nv50_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
switch (nv_rd32(pfb, 0x100714) & 0x00000007) {
case 0: ram->type = NV_MEM_TYPE_DDR1; break;
case 1:
- if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
+ if (nvkm_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
ram->type = NV_MEM_TYPE_DDR3;
else
ram->type = NV_MEM_TYPE_DDR2;
@@ -389,9 +384,9 @@ nv50_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
break;
}
- ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) -
- (rsvd_head + rsvd_tail),
- nv50_fb_vram_rblock(pfb, ram) >> 12);
+ ret = nvkm_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) -
+ (rsvd_head + rsvd_tail),
+ nv50_fb_vram_rblock(pfb, ram) >> 12);
if (ret)
return ret;
@@ -403,9 +398,9 @@ nv50_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine,
}
static int
-nv50_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 datasize,
- struct nouveau_object **pobject)
+nv50_ram_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 datasize,
+ struct nvkm_object **pobject)
{
struct nv50_ram *ram;
int ret, i;
@@ -459,12 +454,12 @@ nv50_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv50_ram_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_ram_ctor,
- .dtor = _nouveau_ram_dtor,
- .init = _nouveau_ram_init,
- .fini = _nouveau_ram_fini,
+ .dtor = _nvkm_ram_dtor,
+ .init = _nvkm_ram_init,
+ .fini = _nvkm_ram_fini,
}
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
index 571077e39071..0f1f97ccd5f6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
@@ -1,7 +1,5 @@
#ifndef __NVKM_FBRAM_SEQ_H__
#define __NVKM_FBRAM_SEQ_H__
-
-#include <subdev/bus.h>
#include <subdev/bus/hwsq.h>
#define ram_init(s,p) hwsq_init(&(s)->base, (p))
@@ -14,5 +12,4 @@
#define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
#define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
#define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n))
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb/regsnv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/regsnv04.h
index 0f7fc0c52ab2..1f865f61504e 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb/regsnv04.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/regsnv04.h
@@ -1,5 +1,5 @@
-#ifndef __NOUVEAU_FB_REGS_04_H__
-#define __NOUVEAU_FB_REGS_04_H__
+#ifndef __NVKM_FB_REGS_04_H__
+#define __NVKM_FB_REGS_04_H__
#define NV04_PFB_BOOT_0 0x00100000
# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003
@@ -17,5 +17,6 @@
# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028
# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100
# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000
+#define NV04_PFB_CFG0 0x00100200
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
index 252575f3aa29..afab42df28d4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
@@ -22,7 +22,6 @@
* Authors: Roy Spliet <rspliet@eclipso.eu>
* Ben Skeggs
*/
-
#include "priv.h"
struct ramxlat {
@@ -58,7 +57,7 @@ ramddr2_wr[] = {
};
int
-nouveau_sddr2_calc(struct nouveau_ram *ram)
+nvkm_sddr2_calc(struct nvkm_ram *ram)
{
int CL, WR, DLL = 0, ODT = 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
index a2dca4869e52..10844355c3f3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
@@ -22,7 +22,6 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
* Roy Spliet <rspliet@eclipso.eu>
*/
-
#include "priv.h"
struct ramxlat {
@@ -67,7 +66,7 @@ ramddr3_cwl[] = {
};
int
-nouveau_sddr3_calc(struct nouveau_ram *ram)
+nvkm_sddr3_calc(struct nvkm_ram *ram)
{
int CWL, CL, WR, DLL = 0, ODT = 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/Kbuild
new file mode 100644
index 000000000000..f3d4e6e131b6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/Kbuild
@@ -0,0 +1,4 @@
+nvkm-y += nvkm/subdev/fuse/base.o
+nvkm-y += nvkm/subdev/fuse/nv50.o
+nvkm-y += nvkm/subdev/fuse/gf100.o
+nvkm-y += nvkm/subdev/fuse/gm107.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fuse/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c
index 9e8e92127715..b7b7193bbce7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fuse/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c
@@ -21,34 +21,31 @@
*
* Authors: Martin Peres
*/
-
#include <subdev/fuse.h>
int
-_nouveau_fuse_init(struct nouveau_object *object)
+_nvkm_fuse_init(struct nvkm_object *object)
{
- struct nouveau_fuse *fuse = (void *)object;
- return nouveau_subdev_init(&fuse->base);
+ struct nvkm_fuse *fuse = (void *)object;
+ return nvkm_subdev_init(&fuse->base);
}
void
-_nouveau_fuse_dtor(struct nouveau_object *object)
+_nvkm_fuse_dtor(struct nvkm_object *object)
{
- struct nouveau_fuse *fuse = (void *)object;
- nouveau_subdev_destroy(&fuse->base);
+ struct nvkm_fuse *fuse = (void *)object;
+ nvkm_subdev_destroy(&fuse->base);
}
int
-nouveau_fuse_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+nvkm_fuse_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_fuse *fuse;
+ struct nvkm_fuse *fuse;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "FUSE",
- "fuse", length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "FUSE",
+ "fuse", length, pobject);
fuse = *pobject;
-
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fuse/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/gf100.c
index 5ed03f54b3d4..393ef3a0faaf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fuse/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/gf100.c
@@ -21,63 +21,58 @@
*
* Authors: Martin Peres
*/
-
#include "priv.h"
struct gf100_fuse_priv {
- struct nouveau_fuse base;
+ struct nvkm_fuse base;
spinlock_t fuse_enable_lock;
};
static u32
-gf100_fuse_rd32(struct nouveau_object *object, u64 addr)
+gf100_fuse_rd32(struct nvkm_object *object, u64 addr)
{
struct gf100_fuse_priv *priv = (void *)object;
unsigned long flags;
u32 fuse_enable, unk, val;
+ /* racy if another part of nvkm start writing to these regs */
spin_lock_irqsave(&priv->fuse_enable_lock, flags);
-
- /* racy if another part of nouveau start writing to these regs */
fuse_enable = nv_mask(priv, 0x22400, 0x800, 0x800);
unk = nv_mask(priv, 0x21000, 0x1, 0x1);
val = nv_rd32(priv, 0x21100 + addr);
nv_wr32(priv, 0x21000, unk);
nv_wr32(priv, 0x22400, fuse_enable);
-
spin_unlock_irqrestore(&priv->fuse_enable_lock, flags);
-
return val;
}
static int
-gf100_fuse_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_fuse_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct gf100_fuse_priv *priv;
int ret;
- ret = nouveau_fuse_create(parent, engine, oclass, &priv);
+ ret = nvkm_fuse_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
spin_lock_init(&priv->fuse_enable_lock);
-
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gf100_fuse_oclass = {
.handle = NV_SUBDEV(FUSE, 0xC0),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gf100_fuse_ctor,
- .dtor = _nouveau_fuse_dtor,
- .init = _nouveau_fuse_init,
- .fini = _nouveau_fuse_fini,
+ .dtor = _nvkm_fuse_dtor,
+ .init = _nvkm_fuse_init,
+ .fini = _nvkm_fuse_fini,
.rd32 = gf100_fuse_rd32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fuse/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/gm107.c
index 4f1a636c6538..ba19158a5912 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fuse/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/gm107.c
@@ -21,31 +21,29 @@
*
* Authors: Martin Peres
*/
-
#include "priv.h"
struct gm107_fuse_priv {
- struct nouveau_fuse base;
+ struct nvkm_fuse base;
};
static u32
-gm107_fuse_rd32(struct nouveau_object *object, u64 addr)
+gm107_fuse_rd32(struct nvkm_object *object, u64 addr)
{
struct gf100_fuse_priv *priv = (void *)object;
-
return nv_rd32(priv, 0x21100 + addr);
}
static int
-gm107_fuse_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gm107_fuse_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct gm107_fuse_priv *priv;
int ret;
- ret = nouveau_fuse_create(parent, engine, oclass, &priv);
+ ret = nvkm_fuse_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -53,14 +51,14 @@ gm107_fuse_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gm107_fuse_oclass = {
.handle = NV_SUBDEV(FUSE, 0x117),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm107_fuse_ctor,
- .dtor = _nouveau_fuse_dtor,
- .init = _nouveau_fuse_init,
- .fini = _nouveau_fuse_fini,
+ .dtor = _nvkm_fuse_dtor,
+ .init = _nvkm_fuse_init,
+ .fini = _nvkm_fuse_fini,
.rd32 = gm107_fuse_rd32,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fuse/g80.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/nv50.c
index a374ade485be..0d2afc426100 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fuse/g80.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/nv50.c
@@ -21,61 +21,56 @@
*
* Authors: Martin Peres
*/
-
#include "priv.h"
-struct g80_fuse_priv {
- struct nouveau_fuse base;
+struct nv50_fuse_priv {
+ struct nvkm_fuse base;
spinlock_t fuse_enable_lock;
};
static u32
-g80_fuse_rd32(struct nouveau_object *object, u64 addr)
+nv50_fuse_rd32(struct nvkm_object *object, u64 addr)
{
- struct g80_fuse_priv *priv = (void *)object;
+ struct nv50_fuse_priv *priv = (void *)object;
unsigned long flags;
u32 fuse_enable, val;
+ /* racy if another part of nvkm start writing to this reg */
spin_lock_irqsave(&priv->fuse_enable_lock, flags);
-
- /* racy if another part of nouveau start writing to this reg */
fuse_enable = nv_mask(priv, 0x1084, 0x800, 0x800);
val = nv_rd32(priv, 0x21000 + addr);
nv_wr32(priv, 0x1084, fuse_enable);
-
spin_unlock_irqrestore(&priv->fuse_enable_lock, flags);
-
return val;
}
static int
-g80_fuse_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_fuse_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct g80_fuse_priv *priv;
+ struct nv50_fuse_priv *priv;
int ret;
- ret = nouveau_fuse_create(parent, engine, oclass, &priv);
+ ret = nvkm_fuse_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
spin_lock_init(&priv->fuse_enable_lock);
-
return 0;
}
-struct nouveau_oclass
-g80_fuse_oclass = {
+struct nvkm_oclass
+nv50_fuse_oclass = {
.handle = NV_SUBDEV(FUSE, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = g80_fuse_ctor,
- .dtor = _nouveau_fuse_dtor,
- .init = _nouveau_fuse_init,
- .fini = _nouveau_fuse_fini,
- .rd32 = g80_fuse_rd32,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_fuse_ctor,
+ .dtor = _nvkm_fuse_dtor,
+ .init = _nvkm_fuse_init,
+ .fini = _nvkm_fuse_fini,
+ .rd32 = nv50_fuse_rd32,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/priv.h
new file mode 100644
index 000000000000..7e050f789384
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/priv.h
@@ -0,0 +1,7 @@
+#ifndef __NVKM_FUSE_PRIV_H__
+#define __NVKM_FUSE_PRIV_H__
+#include <subdev/fuse.h>
+
+int _nvkm_fuse_init(struct nvkm_object *object);
+void _nvkm_fuse_dtor(struct nvkm_object *object);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild
new file mode 100644
index 000000000000..ea42a9ed1821
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/Kbuild
@@ -0,0 +1,6 @@
+nvkm-y += nvkm/subdev/gpio/base.o
+nvkm-y += nvkm/subdev/gpio/nv10.o
+nvkm-y += nvkm/subdev/gpio/nv50.o
+nvkm-y += nvkm/subdev/gpio/g94.o
+nvkm-y += nvkm/subdev/gpio/gf110.o
+nvkm-y += nvkm/subdev/gpio/gk104.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
index 7ad99b763f4c..dea58161ba46 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
@@ -21,32 +21,30 @@
*
* Authors: Ben Skeggs
*/
-
-#include <subdev/bios.h>
-#include <subdev/bios/gpio.h>
-
#include "priv.h"
+#include <core/device.h>
+#include <core/notify.h>
+
static int
-nouveau_gpio_drive(struct nouveau_gpio *gpio,
- int idx, int line, int dir, int out)
+nvkm_gpio_drive(struct nvkm_gpio *gpio, int idx, int line, int dir, int out)
{
- const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
return impl->drive ? impl->drive(gpio, line, dir, out) : -ENODEV;
}
static int
-nouveau_gpio_sense(struct nouveau_gpio *gpio, int idx, int line)
+nvkm_gpio_sense(struct nvkm_gpio *gpio, int idx, int line)
{
- const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
return impl->sense ? impl->sense(gpio, line) : -ENODEV;
}
static int
-nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line,
- struct dcb_gpio_func *func)
+nvkm_gpio_find(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line,
+ struct dcb_gpio_func *func)
{
- struct nouveau_bios *bios = nouveau_bios(gpio);
+ struct nvkm_bios *bios = nvkm_bios(gpio);
u8 ver, len;
u16 data;
@@ -74,30 +72,30 @@ nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line,
}
static int
-nouveau_gpio_set(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, int state)
+nvkm_gpio_set(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line, int state)
{
struct dcb_gpio_func func;
int ret;
- ret = nouveau_gpio_find(gpio, idx, tag, line, &func);
+ ret = nvkm_gpio_find(gpio, idx, tag, line, &func);
if (ret == 0) {
int dir = !!(func.log[state] & 0x02);
int out = !!(func.log[state] & 0x01);
- ret = nouveau_gpio_drive(gpio, idx, func.line, dir, out);
+ ret = nvkm_gpio_drive(gpio, idx, func.line, dir, out);
}
return ret;
}
static int
-nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line)
+nvkm_gpio_get(struct nvkm_gpio *gpio, int idx, u8 tag, u8 line)
{
struct dcb_gpio_func func;
int ret;
- ret = nouveau_gpio_find(gpio, idx, tag, line, &func);
+ ret = nvkm_gpio_find(gpio, idx, tag, line, &func);
if (ret == 0) {
- ret = nouveau_gpio_sense(gpio, idx, func.line);
+ ret = nvkm_gpio_sense(gpio, idx, func.line);
if (ret >= 0)
ret = (ret == (func.log[1] & 1));
}
@@ -106,24 +104,24 @@ nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line)
}
static void
-nouveau_gpio_intr_fini(struct nvkm_event *event, int type, int index)
+nvkm_gpio_intr_fini(struct nvkm_event *event, int type, int index)
{
- struct nouveau_gpio *gpio = container_of(event, typeof(*gpio), event);
- const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ struct nvkm_gpio *gpio = container_of(event, typeof(*gpio), event);
+ const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
impl->intr_mask(gpio, type, 1 << index, 0);
}
static void
-nouveau_gpio_intr_init(struct nvkm_event *event, int type, int index)
+nvkm_gpio_intr_init(struct nvkm_event *event, int type, int index)
{
- struct nouveau_gpio *gpio = container_of(event, typeof(*gpio), event);
- const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ struct nvkm_gpio *gpio = container_of(event, typeof(*gpio), event);
+ const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
impl->intr_mask(gpio, type, 1 << index, 1 << index);
}
static int
-nouveau_gpio_intr_ctor(struct nouveau_object *object, void *data, u32 size,
- struct nvkm_notify *notify)
+nvkm_gpio_intr_ctor(struct nvkm_object *object, void *data, u32 size,
+ struct nvkm_notify *notify)
{
struct nvkm_gpio_ntfy_req *req = data;
if (!WARN_ON(size != sizeof(*req))) {
@@ -136,10 +134,10 @@ nouveau_gpio_intr_ctor(struct nouveau_object *object, void *data, u32 size,
}
static void
-nouveau_gpio_intr(struct nouveau_subdev *subdev)
+nvkm_gpio_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_gpio *gpio = nouveau_gpio(subdev);
- const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
+ struct nvkm_gpio *gpio = nvkm_gpio(subdev);
+ const struct nvkm_gpio_impl *impl = (void *)nv_object(gpio)->oclass;
u32 hi, lo, i;
impl->intr_stat(gpio, &hi, &lo);
@@ -154,23 +152,23 @@ nouveau_gpio_intr(struct nouveau_subdev *subdev)
}
static const struct nvkm_event_func
-nouveau_gpio_intr_func = {
- .ctor = nouveau_gpio_intr_ctor,
- .init = nouveau_gpio_intr_init,
- .fini = nouveau_gpio_intr_fini,
+nvkm_gpio_intr_func = {
+ .ctor = nvkm_gpio_intr_ctor,
+ .init = nvkm_gpio_intr_init,
+ .fini = nvkm_gpio_intr_fini,
};
int
-_nouveau_gpio_fini(struct nouveau_object *object, bool suspend)
+_nvkm_gpio_fini(struct nvkm_object *object, bool suspend)
{
- const struct nouveau_gpio_impl *impl = (void *)object->oclass;
- struct nouveau_gpio *gpio = nouveau_gpio(object);
+ const struct nvkm_gpio_impl *impl = (void *)object->oclass;
+ struct nvkm_gpio *gpio = nvkm_gpio(object);
u32 mask = (1 << impl->lines) - 1;
impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0);
impl->intr_stat(gpio, &mask, &mask);
- return nouveau_subdev_fini(&gpio->base, suspend);
+ return nvkm_subdev_fini(&gpio->base, suspend);
}
static struct dmi_system_id gpio_reset_ids[] = {
@@ -185,12 +183,12 @@ static struct dmi_system_id gpio_reset_ids[] = {
};
int
-_nouveau_gpio_init(struct nouveau_object *object)
+_nvkm_gpio_init(struct nvkm_object *object)
{
- struct nouveau_gpio *gpio = nouveau_gpio(object);
+ struct nvkm_gpio *gpio = nvkm_gpio(object);
int ret;
- ret = nouveau_subdev_init(&gpio->base);
+ ret = nvkm_subdev_init(&gpio->base);
if (ret)
return ret;
@@ -201,52 +199,50 @@ _nouveau_gpio_init(struct nouveau_object *object)
}
void
-_nouveau_gpio_dtor(struct nouveau_object *object)
+_nvkm_gpio_dtor(struct nvkm_object *object)
{
- struct nouveau_gpio *gpio = (void *)object;
+ struct nvkm_gpio *gpio = (void *)object;
nvkm_event_fini(&gpio->event);
- nouveau_subdev_destroy(&gpio->base);
+ nvkm_subdev_destroy(&gpio->base);
}
int
-nouveau_gpio_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int length, void **pobject)
+nvkm_gpio_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- const struct nouveau_gpio_impl *impl = (void *)oclass;
- struct nouveau_gpio *gpio;
+ const struct nvkm_gpio_impl *impl = (void *)oclass;
+ struct nvkm_gpio *gpio;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "GPIO", "gpio",
- length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "GPIO",
+ "gpio", length, pobject);
gpio = *pobject;
if (ret)
return ret;
- gpio->find = nouveau_gpio_find;
- gpio->set = nouveau_gpio_set;
- gpio->get = nouveau_gpio_get;
+ gpio->find = nvkm_gpio_find;
+ gpio->set = nvkm_gpio_set;
+ gpio->get = nvkm_gpio_get;
gpio->reset = impl->reset;
- ret = nvkm_event_init(&nouveau_gpio_intr_func, 2, impl->lines,
+ ret = nvkm_event_init(&nvkm_gpio_intr_func, 2, impl->lines,
&gpio->event);
if (ret)
return ret;
- nv_subdev(gpio)->intr = nouveau_gpio_intr;
+ nv_subdev(gpio)->intr = nvkm_gpio_intr;
return 0;
}
int
-_nouveau_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+_nvkm_gpio_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_gpio *gpio;
+ struct nvkm_gpio *gpio;
int ret;
- ret = nouveau_gpio_create(parent, engine, oclass, &gpio);
+ ret = nvkm_gpio_create(parent, engine, oclass, &gpio);
*pobject = nv_object(gpio);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c
index cae404ccadac..12b3e01fca8e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/g94.c
@@ -21,11 +21,10 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
void
-nv94_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
+g94_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
u32 intr0 = nv_rd32(gpio, 0x00e054);
u32 intr1 = nv_rd32(gpio, 0x00e074);
@@ -38,7 +37,7 @@ nv94_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
}
void
-nv94_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
+g94_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
u32 inte0 = nv_rd32(gpio, 0x00e050);
u32 inte1 = nv_rd32(gpio, 0x00e070);
@@ -56,18 +55,18 @@ nv94_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x00e070, inte1);
}
-struct nouveau_oclass *
-nv94_gpio_oclass = &(struct nouveau_gpio_impl) {
+struct nvkm_oclass *
+g94_gpio_oclass = &(struct nvkm_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0x94),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_gpio_ctor,
- .dtor = _nouveau_gpio_dtor,
- .init = _nouveau_gpio_init,
- .fini = _nouveau_gpio_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_gpio_ctor,
+ .dtor = _nvkm_gpio_dtor,
+ .init = _nvkm_gpio_init,
+ .fini = _nvkm_gpio_fini,
},
.lines = 32,
- .intr_stat = nv94_gpio_intr_stat,
- .intr_mask = nv94_gpio_intr_mask,
+ .intr_stat = g94_gpio_intr_stat,
+ .intr_mask = g94_gpio_intr_mask,
.drive = nv50_gpio_drive,
.sense = nv50_gpio_sense,
.reset = nv50_gpio_reset,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf110.c
index 480d6d2af770..2c3bb255d1f8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gf110.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
void
-nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match)
+gf110_gpio_reset(struct nvkm_gpio *gpio, u8 match)
{
- struct nouveau_bios *bios = nouveau_bios(gpio);
+ struct nvkm_bios *bios = nvkm_bios(gpio);
u8 ver, len;
u16 entry;
int ent = -1;
@@ -53,7 +52,7 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match)
}
int
-nvd0_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
+gf110_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
{
u32 data = ((dir ^ 1) << 13) | (out << 12);
nv_mask(gpio, 0x00d610 + (line * 4), 0x00003000, data);
@@ -62,24 +61,24 @@ nvd0_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
}
int
-nvd0_gpio_sense(struct nouveau_gpio *gpio, int line)
+gf110_gpio_sense(struct nvkm_gpio *gpio, int line)
{
return !!(nv_rd32(gpio, 0x00d610 + (line * 4)) & 0x00004000);
}
-struct nouveau_oclass *
-nvd0_gpio_oclass = &(struct nouveau_gpio_impl) {
+struct nvkm_oclass *
+gf110_gpio_oclass = &(struct nvkm_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0xd0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_gpio_ctor,
- .dtor = _nouveau_gpio_dtor,
- .init = _nouveau_gpio_init,
- .fini = _nouveau_gpio_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_gpio_ctor,
+ .dtor = _nvkm_gpio_dtor,
+ .init = _nvkm_gpio_init,
+ .fini = _nvkm_gpio_fini,
},
.lines = 32,
- .intr_stat = nv94_gpio_intr_stat,
- .intr_mask = nv94_gpio_intr_mask,
- .drive = nvd0_gpio_drive,
- .sense = nvd0_gpio_sense,
- .reset = nvd0_gpio_reset,
+ .intr_stat = g94_gpio_intr_stat,
+ .intr_mask = g94_gpio_intr_mask,
+ .drive = gf110_gpio_drive,
+ .sense = gf110_gpio_sense,
+ .reset = gf110_gpio_reset,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c
index e1145b48c76c..42fd2faaaa4f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c
@@ -21,11 +21,10 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
static void
-nve0_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
+gk104_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
u32 intr0 = nv_rd32(gpio, 0x00dc00);
u32 intr1 = nv_rd32(gpio, 0x00dc80);
@@ -38,7 +37,7 @@ nve0_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
}
void
-nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
+gk104_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
u32 inte0 = nv_rd32(gpio, 0x00dc08);
u32 inte1 = nv_rd32(gpio, 0x00dc88);
@@ -56,19 +55,19 @@ nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x00dc88, inte1);
}
-struct nouveau_oclass *
-nve0_gpio_oclass = &(struct nouveau_gpio_impl) {
+struct nvkm_oclass *
+gk104_gpio_oclass = &(struct nvkm_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0xe0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_gpio_ctor,
- .dtor = _nouveau_gpio_dtor,
- .init = _nouveau_gpio_init,
- .fini = _nouveau_gpio_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_gpio_ctor,
+ .dtor = _nvkm_gpio_dtor,
+ .init = _nvkm_gpio_init,
+ .fini = _nvkm_gpio_fini,
},
.lines = 32,
- .intr_stat = nve0_gpio_intr_stat,
- .intr_mask = nve0_gpio_intr_mask,
- .drive = nvd0_gpio_drive,
- .sense = nvd0_gpio_sense,
- .reset = nvd0_gpio_reset,
+ .intr_stat = gk104_gpio_intr_stat,
+ .intr_mask = gk104_gpio_intr_mask,
+ .drive = gf110_gpio_drive,
+ .sense = gf110_gpio_sense,
+ .reset = gf110_gpio_reset,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c
index 27ad23eaf185..2b295154247e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv10.c
@@ -23,11 +23,10 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-
#include "priv.h"
static int
-nv10_gpio_sense(struct nouveau_gpio *gpio, int line)
+nv10_gpio_sense(struct nvkm_gpio *gpio, int line)
{
if (line < 2) {
line = line * 16;
@@ -49,7 +48,7 @@ nv10_gpio_sense(struct nouveau_gpio *gpio, int line)
}
static int
-nv10_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
+nv10_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
{
u32 reg, mask, data;
@@ -79,7 +78,7 @@ nv10_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
}
static void
-nv10_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
+nv10_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
u32 intr = nv_rd32(gpio, 0x001104);
u32 stat = nv_rd32(gpio, 0x001144) & intr;
@@ -89,7 +88,7 @@ nv10_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
}
static void
-nv10_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
+nv10_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
u32 inte = nv_rd32(gpio, 0x001144);
if (type & NVKM_GPIO_LO)
@@ -99,14 +98,14 @@ nv10_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x001144, inte);
}
-struct nouveau_oclass *
-nv10_gpio_oclass = &(struct nouveau_gpio_impl) {
+struct nvkm_oclass *
+nv10_gpio_oclass = &(struct nvkm_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0x10),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_gpio_ctor,
- .dtor = _nouveau_gpio_dtor,
- .init = _nouveau_gpio_init,
- .fini = _nouveau_gpio_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_gpio_ctor,
+ .dtor = _nvkm_gpio_dtor,
+ .init = _nvkm_gpio_init,
+ .fini = _nvkm_gpio_fini,
},
.lines = 16,
.intr_stat = nv10_gpio_intr_stat,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
index 2e30d5a62d6e..6a031035bd27 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
void
-nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match)
+nv50_gpio_reset(struct nvkm_gpio *gpio, u8 match)
{
- struct nouveau_bios *bios = nouveau_bios(gpio);
+ struct nvkm_bios *bios = nvkm_bios(gpio);
u8 ver, len;
u16 entry;
int ent = -1;
@@ -68,7 +67,7 @@ nv50_gpio_location(int line, u32 *reg, u32 *shift)
}
int
-nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
+nv50_gpio_drive(struct nvkm_gpio *gpio, int line, int dir, int out)
{
u32 reg, shift;
@@ -80,7 +79,7 @@ nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out)
}
int
-nv50_gpio_sense(struct nouveau_gpio *gpio, int line)
+nv50_gpio_sense(struct nvkm_gpio *gpio, int line)
{
u32 reg, shift;
@@ -91,7 +90,7 @@ nv50_gpio_sense(struct nouveau_gpio *gpio, int line)
}
static void
-nv50_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
+nv50_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
{
u32 intr = nv_rd32(gpio, 0x00e054);
u32 stat = nv_rd32(gpio, 0x00e050) & intr;
@@ -101,7 +100,7 @@ nv50_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo)
}
static void
-nv50_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
+nv50_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
u32 inte = nv_rd32(gpio, 0x00e050);
if (type & NVKM_GPIO_LO)
@@ -111,14 +110,14 @@ nv50_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data)
nv_wr32(gpio, 0x00e050, inte);
}
-struct nouveau_oclass *
-nv50_gpio_oclass = &(struct nouveau_gpio_impl) {
+struct nvkm_oclass *
+nv50_gpio_oclass = &(struct nvkm_gpio_impl) {
.base.handle = NV_SUBDEV(GPIO, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_gpio_ctor,
- .dtor = _nouveau_gpio_dtor,
- .init = _nouveau_gpio_init,
- .fini = _nouveau_gpio_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_gpio_ctor,
+ .dtor = _nvkm_gpio_dtor,
+ .init = _nvkm_gpio_init,
+ .fini = _nvkm_gpio_fini,
},
.lines = 16,
.intr_stat = nv50_gpio_intr_stat,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h
new file mode 100644
index 000000000000..382f8d44e140
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/priv.h
@@ -0,0 +1,64 @@
+#ifndef __NVKM_GPIO_PRIV_H__
+#define __NVKM_GPIO_PRIV_H__
+#include <subdev/gpio.h>
+
+#define nvkm_gpio_create(p,e,o,d) \
+ nvkm_gpio_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_gpio_destroy(p) ({ \
+ struct nvkm_gpio *gpio = (p); \
+ _nvkm_gpio_dtor(nv_object(gpio)); \
+})
+#define nvkm_gpio_init(p) ({ \
+ struct nvkm_gpio *gpio = (p); \
+ _nvkm_gpio_init(nv_object(gpio)); \
+})
+#define nvkm_gpio_fini(p,s) ({ \
+ struct nvkm_gpio *gpio = (p); \
+ _nvkm_gpio_fini(nv_object(gpio), (s)); \
+})
+
+int nvkm_gpio_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+int _nvkm_gpio_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void _nvkm_gpio_dtor(struct nvkm_object *);
+int _nvkm_gpio_init(struct nvkm_object *);
+int _nvkm_gpio_fini(struct nvkm_object *, bool);
+
+struct nvkm_gpio_impl {
+ struct nvkm_oclass base;
+ int lines;
+
+ /* read and ack pending interrupts, returning only data
+ * for lines that have not been masked off, while still
+ * performing the ack for anything that was pending.
+ */
+ void (*intr_stat)(struct nvkm_gpio *, u32 *, u32 *);
+
+ /* mask on/off interrupts for hi/lo transitions on a
+ * given set of gpio lines
+ */
+ void (*intr_mask)(struct nvkm_gpio *, u32, u32, u32);
+
+ /* configure gpio direction and output value */
+ int (*drive)(struct nvkm_gpio *, int line, int dir, int out);
+
+ /* sense current state of given gpio line */
+ int (*sense)(struct nvkm_gpio *, int line);
+
+ /*XXX*/
+ void (*reset)(struct nvkm_gpio *, u8);
+};
+
+void nv50_gpio_reset(struct nvkm_gpio *, u8);
+int nv50_gpio_drive(struct nvkm_gpio *, int, int, int);
+int nv50_gpio_sense(struct nvkm_gpio *, int);
+
+void g94_gpio_intr_stat(struct nvkm_gpio *, u32 *, u32 *);
+void g94_gpio_intr_mask(struct nvkm_gpio *, u32, u32, u32);
+
+void gf110_gpio_reset(struct nvkm_gpio *, u8);
+int gf110_gpio_drive(struct nvkm_gpio *, int, int, int);
+int gf110_gpio_sense(struct nvkm_gpio *, int);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
new file mode 100644
index 000000000000..d68307409980
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
@@ -0,0 +1,16 @@
+nvkm-y += nvkm/subdev/i2c/base.o
+nvkm-y += nvkm/subdev/i2c/anx9805.o
+nvkm-y += nvkm/subdev/i2c/aux.o
+nvkm-y += nvkm/subdev/i2c/bit.o
+nvkm-y += nvkm/subdev/i2c/pad.o
+nvkm-y += nvkm/subdev/i2c/padnv04.o
+nvkm-y += nvkm/subdev/i2c/padg94.o
+nvkm-y += nvkm/subdev/i2c/padgm204.o
+nvkm-y += nvkm/subdev/i2c/nv04.o
+nvkm-y += nvkm/subdev/i2c/nv4e.o
+nvkm-y += nvkm/subdev/i2c/nv50.o
+nvkm-y += nvkm/subdev/i2c/g94.o
+nvkm-y += nvkm/subdev/i2c/gf110.o
+nvkm-y += nvkm/subdev/i2c/gf117.o
+nvkm-y += nvkm/subdev/i2c/gk104.o
+nvkm-y += nvkm/subdev/i2c/gm204.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c
index 2c2731a6cf91..d17dd1cf3c34 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include "port.h"
struct anx9805_i2c_port {
- struct nouveau_i2c_port base;
+ struct nvkm_i2c_port base;
u32 addr;
u32 ctrl;
};
static int
-anx9805_train(struct nouveau_i2c_port *port, int link_nr, int link_bw, bool enh)
+anx9805_train(struct nvkm_i2c_port *port, int link_nr, int link_bw, bool enh)
{
struct anx9805_i2c_port *chan = (void *)port;
- struct nouveau_i2c_port *mast = (void *)nv_object(chan)->parent;
+ struct nvkm_i2c_port *mast = (void *)nv_object(chan)->parent;
u8 tmp, i;
DBG("ANX9805 train %d 0x%02x %d\n", link_nr, link_bw, enh);
@@ -62,11 +61,11 @@ anx9805_train(struct nouveau_i2c_port *port, int link_nr, int link_bw, bool enh)
}
static int
-anx9805_aux(struct nouveau_i2c_port *port, bool retry,
+anx9805_aux(struct nvkm_i2c_port *port, bool retry,
u8 type, u32 addr, u8 *data, u8 size)
{
struct anx9805_i2c_port *chan = (void *)port;
- struct nouveau_i2c_port *mast = (void *)nv_object(chan)->parent;
+ struct nvkm_i2c_port *mast = (void *)nv_object(chan)->parent;
int i, ret = -ETIMEDOUT;
u8 buf[16] = {};
u8 tmp;
@@ -116,25 +115,25 @@ done:
return ret;
}
-static const struct nouveau_i2c_func
+static const struct nvkm_i2c_func
anx9805_aux_func = {
.aux = anx9805_aux,
.lnk_ctl = anx9805_train,
};
static int
-anx9805_aux_chan_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+anx9805_aux_chan_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
- struct nouveau_i2c_port *mast = (void *)parent;
+ struct nvkm_i2c_port *mast = (void *)parent;
struct anx9805_i2c_port *chan;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_aux_algo, &anx9805_aux_func,
- &chan);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_aux_algo, &anx9805_aux_func,
+ &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
@@ -156,22 +155,23 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent,
struct i2c_algo_bit_data *algo = mast->adapter.algo_data;
algo->udelay = max(algo->udelay, 40);
}
+
return 0;
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
anx9805_aux_ofuncs = {
.ctor = anx9805_aux_chan_ctor,
- .dtor = _nouveau_i2c_port_dtor,
- .init = _nouveau_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .dtor = _nvkm_i2c_port_dtor,
+ .init = _nvkm_i2c_port_init,
+ .fini = _nvkm_i2c_port_fini,
};
static int
anx9805_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct anx9805_i2c_port *port = adap->algo_data;
- struct nouveau_i2c_port *mast = (void *)nv_object(port)->parent;
+ struct nvkm_i2c_port *mast = (void *)nv_object(port)->parent;
struct i2c_msg *msg = msgs;
int ret = -ETIMEDOUT;
int i, j, cnt = num;
@@ -233,23 +233,22 @@ anx9805_i2c_algo = {
.functionality = anx9805_func
};
-static const struct nouveau_i2c_func
+static const struct nvkm_i2c_func
anx9805_i2c_func = {
};
static int
-anx9805_ddc_port_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+anx9805_ddc_port_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
- struct nouveau_i2c_port *mast = (void *)parent;
+ struct nvkm_i2c_port *mast = (void *)parent;
struct anx9805_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &anx9805_i2c_algo, &anx9805_i2c_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &anx9805_i2c_algo, &anx9805_i2c_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -271,19 +270,20 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent,
struct i2c_algo_bit_data *algo = mast->adapter.algo_data;
algo->udelay = max(algo->udelay, 40);
}
+
return 0;
}
-static struct nouveau_ofuncs
+static struct nvkm_ofuncs
anx9805_ddc_ofuncs = {
.ctor = anx9805_ddc_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
- .init = _nouveau_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .dtor = _nvkm_i2c_port_dtor,
+ .init = _nvkm_i2c_port_init,
+ .fini = _nvkm_i2c_port_fini,
};
-struct nouveau_oclass
-nouveau_anx9805_sclass[] = {
+struct nvkm_oclass
+nvkm_anx9805_sclass[] = {
{ .handle = NV_I2C_TYPE_EXTDDC(0x0d), .ofuncs = &anx9805_ddc_ofuncs },
{ .handle = NV_I2C_TYPE_EXTAUX(0x0d), .ofuncs = &anx9805_aux_ofuncs },
{ .handle = NV_I2C_TYPE_EXTDDC(0x0e), .ofuncs = &anx9805_ddc_ofuncs },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
index 02eb42be2e9e..1c18860f80d1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
int
-nv_rdaux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size)
+nv_rdaux(struct nvkm_i2c_port *port, u32 addr, u8 *data, u8 size)
{
- struct nouveau_i2c *i2c = nouveau_i2c(port);
+ struct nvkm_i2c *i2c = nvkm_i2c(port);
if (port->func->aux) {
int ret = i2c->acquire(port, 0);
if (ret == 0) {
@@ -40,9 +39,9 @@ nv_rdaux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size)
}
int
-nv_wraux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size)
+nv_wraux(struct nvkm_i2c_port *port, u32 addr, u8 *data, u8 size)
{
- struct nouveau_i2c *i2c = nouveau_i2c(port);
+ struct nvkm_i2c *i2c = nvkm_i2c(port);
if (port->func->aux) {
int ret = i2c->acquire(port, 0);
if (ret == 0) {
@@ -57,8 +56,8 @@ nv_wraux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size)
static int
aux_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
- struct nouveau_i2c_port *port = adap->algo_data;
- struct nouveau_i2c *i2c = nouveau_i2c(port);
+ struct nvkm_i2c_port *port = adap->algo_data;
+ struct nvkm_i2c *i2c = nvkm_i2c(port);
struct i2c_msg *msg = msgs;
int ret, mcnt = num;
@@ -108,7 +107,7 @@ aux_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
-const struct i2c_algorithm nouveau_i2c_aux_algo = {
+const struct i2c_algorithm nvkm_i2c_aux_algo = {
.master_xfer = aux_xfer,
.functionality = aux_func
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
index 0dc605db7ec8..9200f122c02c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
@@ -21,18 +21,14 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
+#include "pad.h"
+#include <core/device.h>
+#include <core/notify.h>
#include <core/option.h>
-#include <core/object.h>
-#include <core/event.h>
-
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
-#include <subdev/bios/i2c.h>
-#include <subdev/vga.h>
-
-#include "priv.h"
-#include "pad.h"
/******************************************************************************
* interface to linux i2c bit-banging algorithm
@@ -45,46 +41,46 @@
#endif
static int
-nouveau_i2c_pre_xfer(struct i2c_adapter *adap)
+nvkm_i2c_pre_xfer(struct i2c_adapter *adap)
{
struct i2c_algo_bit_data *bit = adap->algo_data;
- struct nouveau_i2c_port *port = bit->data;
- return nouveau_i2c(port)->acquire(port, bit->timeout);
+ struct nvkm_i2c_port *port = bit->data;
+ return nvkm_i2c(port)->acquire(port, bit->timeout);
}
static void
-nouveau_i2c_post_xfer(struct i2c_adapter *adap)
+nvkm_i2c_post_xfer(struct i2c_adapter *adap)
{
struct i2c_algo_bit_data *bit = adap->algo_data;
- struct nouveau_i2c_port *port = bit->data;
- return nouveau_i2c(port)->release(port);
+ struct nvkm_i2c_port *port = bit->data;
+ return nvkm_i2c(port)->release(port);
}
static void
-nouveau_i2c_setscl(void *data, int state)
+nvkm_i2c_setscl(void *data, int state)
{
- struct nouveau_i2c_port *port = data;
+ struct nvkm_i2c_port *port = data;
port->func->drive_scl(port, state);
}
static void
-nouveau_i2c_setsda(void *data, int state)
+nvkm_i2c_setsda(void *data, int state)
{
- struct nouveau_i2c_port *port = data;
+ struct nvkm_i2c_port *port = data;
port->func->drive_sda(port, state);
}
static int
-nouveau_i2c_getscl(void *data)
+nvkm_i2c_getscl(void *data)
{
- struct nouveau_i2c_port *port = data;
+ struct nvkm_i2c_port *port = data;
return port->func->sense_scl(port);
}
static int
-nouveau_i2c_getsda(void *data)
+nvkm_i2c_getsda(void *data)
{
- struct nouveau_i2c_port *port = data;
+ struct nvkm_i2c_port *port = data;
return port->func->sense_sda(port);
}
@@ -93,42 +89,41 @@ nouveau_i2c_getsda(void *data)
*****************************************************************************/
int
-_nouveau_i2c_port_fini(struct nouveau_object *object, bool suspend)
+_nvkm_i2c_port_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_i2c_port *port = (void *)object;
+ struct nvkm_i2c_port *port = (void *)object;
struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port);
nv_ofuncs(pad)->fini(nv_object(pad), suspend);
- return nouveau_object_fini(&port->base, suspend);
+ return nvkm_object_fini(&port->base, suspend);
}
void
-_nouveau_i2c_port_dtor(struct nouveau_object *object)
+_nvkm_i2c_port_dtor(struct nvkm_object *object)
{
- struct nouveau_i2c_port *port = (void *)object;
+ struct nvkm_i2c_port *port = (void *)object;
i2c_del_adapter(&port->adapter);
- nouveau_object_destroy(&port->base);
+ nvkm_object_destroy(&port->base);
}
int
-nouveau_i2c_port_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, u8 index,
- const struct i2c_algorithm *algo,
- const struct nouveau_i2c_func *func,
- int size, void **pobject)
+nvkm_i2c_port_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, u8 index,
+ const struct i2c_algorithm *algo,
+ const struct nvkm_i2c_func *func,
+ int size, void **pobject)
{
- struct nouveau_device *device = nv_device(engine);
- struct nouveau_i2c *i2c = (void *)engine;
- struct nouveau_i2c_port *port;
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_i2c *i2c = nvkm_i2c(parent);
+ struct nvkm_i2c_port *port;
int ret;
- ret = nouveau_object_create_(parent, engine, oclass, 0, size, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, 0, size, pobject);
port = *pobject;
if (ret)
return ret;
snprintf(port->adapter.name, sizeof(port->adapter.name),
- "nouveau-%s-%d", device->name, index);
+ "nvkm-%s-%d", device->name, index);
port->adapter.owner = THIS_MODULE;
port->adapter.dev.parent = nv_device_base(device);
port->index = index;
@@ -136,8 +131,8 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
port->func = func;
mutex_init(&port->mutex);
- if ( algo == &nouveau_i2c_bit_algo &&
- !nouveau_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) {
+ if ( algo == &nvkm_i2c_bit_algo &&
+ !nvkm_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) {
struct i2c_algo_bit_data *bit;
bit = kzalloc(sizeof(*bit), GFP_KERNEL);
@@ -147,12 +142,12 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
bit->udelay = 10;
bit->timeout = usecs_to_jiffies(2200);
bit->data = port;
- bit->pre_xfer = nouveau_i2c_pre_xfer;
- bit->post_xfer = nouveau_i2c_post_xfer;
- bit->setsda = nouveau_i2c_setsda;
- bit->setscl = nouveau_i2c_setscl;
- bit->getsda = nouveau_i2c_getsda;
- bit->getscl = nouveau_i2c_getscl;
+ bit->pre_xfer = nvkm_i2c_pre_xfer;
+ bit->post_xfer = nvkm_i2c_post_xfer;
+ bit->setsda = nvkm_i2c_setsda;
+ bit->setscl = nvkm_i2c_setscl;
+ bit->getsda = nvkm_i2c_getsda;
+ bit->getscl = nvkm_i2c_getscl;
port->adapter.algo_data = bit;
ret = i2c_bit_add_bus(&port->adapter);
@@ -171,11 +166,11 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
* base i2c subdev class implementation
*****************************************************************************/
-static struct nouveau_i2c_port *
-nouveau_i2c_find(struct nouveau_i2c *i2c, u8 index)
+static struct nvkm_i2c_port *
+nvkm_i2c_find(struct nvkm_i2c *i2c, u8 index)
{
- struct nouveau_bios *bios = nouveau_bios(i2c);
- struct nouveau_i2c_port *port;
+ struct nvkm_bios *bios = nvkm_bios(i2c);
+ struct nvkm_i2c_port *port;
if (index == NV_I2C_DEFAULT(0) ||
index == NV_I2C_DEFAULT(1)) {
@@ -200,10 +195,10 @@ nouveau_i2c_find(struct nouveau_i2c *i2c, u8 index)
return NULL;
}
-static struct nouveau_i2c_port *
-nouveau_i2c_find_type(struct nouveau_i2c *i2c, u16 type)
+static struct nvkm_i2c_port *
+nvkm_i2c_find_type(struct nvkm_i2c *i2c, u16 type)
{
- struct nouveau_i2c_port *port;
+ struct nvkm_i2c_port *port;
list_for_each_entry(port, &i2c->ports, head) {
if (nv_hclass(port) == type)
@@ -214,10 +209,10 @@ nouveau_i2c_find_type(struct nouveau_i2c *i2c, u16 type)
}
static void
-nouveau_i2c_release_pad(struct nouveau_i2c_port *port)
+nvkm_i2c_release_pad(struct nvkm_i2c_port *port)
{
struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port);
- struct nouveau_i2c *i2c = nouveau_i2c(port);
+ struct nvkm_i2c *i2c = nvkm_i2c(port);
if (atomic_dec_and_test(&nv_object(pad)->usecount)) {
nv_ofuncs(pad)->fini(nv_object(pad), false);
@@ -226,18 +221,18 @@ nouveau_i2c_release_pad(struct nouveau_i2c_port *port)
}
static int
-nouveau_i2c_try_acquire_pad(struct nouveau_i2c_port *port)
+nvkm_i2c_try_acquire_pad(struct nvkm_i2c_port *port)
{
struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port);
if (atomic_add_return(1, &nv_object(pad)->usecount) != 1) {
- struct nouveau_object *owner = (void *)pad->port;
+ struct nvkm_object *owner = (void *)pad->port;
do {
if (owner == (void *)port)
return 0;
owner = owner->parent;
} while(owner);
- nouveau_i2c_release_pad(port);
+ nvkm_i2c_release_pad(port);
return -EBUSY;
}
@@ -247,48 +242,48 @@ nouveau_i2c_try_acquire_pad(struct nouveau_i2c_port *port)
}
static int
-nouveau_i2c_acquire_pad(struct nouveau_i2c_port *port, unsigned long timeout)
+nvkm_i2c_acquire_pad(struct nvkm_i2c_port *port, unsigned long timeout)
{
- struct nouveau_i2c *i2c = nouveau_i2c(port);
+ struct nvkm_i2c *i2c = nvkm_i2c(port);
if (timeout) {
if (wait_event_timeout(i2c->wait,
- nouveau_i2c_try_acquire_pad(port) == 0,
+ nvkm_i2c_try_acquire_pad(port) == 0,
timeout) == 0)
return -EBUSY;
} else {
- wait_event(i2c->wait, nouveau_i2c_try_acquire_pad(port) == 0);
+ wait_event(i2c->wait, nvkm_i2c_try_acquire_pad(port) == 0);
}
return 0;
}
static void
-nouveau_i2c_release(struct nouveau_i2c_port *port)
+nvkm_i2c_release(struct nvkm_i2c_port *port)
__releases(pad->mutex)
{
- nouveau_i2c(port)->release_pad(port);
+ nvkm_i2c(port)->release_pad(port);
mutex_unlock(&port->mutex);
}
static int
-nouveau_i2c_acquire(struct nouveau_i2c_port *port, unsigned long timeout)
+nvkm_i2c_acquire(struct nvkm_i2c_port *port, unsigned long timeout)
__acquires(pad->mutex)
{
int ret;
mutex_lock(&port->mutex);
- if ((ret = nouveau_i2c(port)->acquire_pad(port, timeout)))
+ if ((ret = nvkm_i2c(port)->acquire_pad(port, timeout)))
mutex_unlock(&port->mutex);
return ret;
}
static int
-nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what,
- struct nouveau_i2c_board_info *info,
- bool (*match)(struct nouveau_i2c_port *,
- struct i2c_board_info *, void *), void *data)
+nvkm_i2c_identify(struct nvkm_i2c *i2c, int index, const char *what,
+ struct nvkm_i2c_board_info *info,
+ bool (*match)(struct nvkm_i2c_port *,
+ struct i2c_board_info *, void *), void *data)
{
- struct nouveau_i2c_port *port = nouveau_i2c_find(i2c, index);
+ struct nvkm_i2c_port *port = nvkm_i2c_find(i2c, index);
int i;
if (!port) {
@@ -327,27 +322,27 @@ nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what,
}
static void
-nouveau_i2c_intr_fini(struct nvkm_event *event, int type, int index)
+nvkm_i2c_intr_fini(struct nvkm_event *event, int type, int index)
{
- struct nouveau_i2c *i2c = container_of(event, typeof(*i2c), event);
- struct nouveau_i2c_port *port = i2c->find(i2c, index);
- const struct nouveau_i2c_impl *impl = (void *)nv_object(i2c)->oclass;
+ struct nvkm_i2c *i2c = container_of(event, typeof(*i2c), event);
+ struct nvkm_i2c_port *port = i2c->find(i2c, index);
+ const struct nvkm_i2c_impl *impl = (void *)nv_object(i2c)->oclass;
if (port && port->aux >= 0)
impl->aux_mask(i2c, type, 1 << port->aux, 0);
}
static void
-nouveau_i2c_intr_init(struct nvkm_event *event, int type, int index)
+nvkm_i2c_intr_init(struct nvkm_event *event, int type, int index)
{
- struct nouveau_i2c *i2c = container_of(event, typeof(*i2c), event);
- struct nouveau_i2c_port *port = i2c->find(i2c, index);
- const struct nouveau_i2c_impl *impl = (void *)nv_object(i2c)->oclass;
+ struct nvkm_i2c *i2c = container_of(event, typeof(*i2c), event);
+ struct nvkm_i2c_port *port = i2c->find(i2c, index);
+ const struct nvkm_i2c_impl *impl = (void *)nv_object(i2c)->oclass;
if (port && port->aux >= 0)
impl->aux_mask(i2c, type, 1 << port->aux, 1 << port->aux);
}
static int
-nouveau_i2c_intr_ctor(struct nouveau_object *object, void *data, u32 size,
+nvkm_i2c_intr_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
struct nvkm_i2c_ntfy_req *req = data;
@@ -361,11 +356,11 @@ nouveau_i2c_intr_ctor(struct nouveau_object *object, void *data, u32 size,
}
static void
-nouveau_i2c_intr(struct nouveau_subdev *subdev)
+nvkm_i2c_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_i2c_impl *impl = (void *)nv_oclass(subdev);
- struct nouveau_i2c *i2c = nouveau_i2c(subdev);
- struct nouveau_i2c_port *port;
+ struct nvkm_i2c_impl *impl = (void *)nv_oclass(subdev);
+ struct nvkm_i2c *i2c = nvkm_i2c(subdev);
+ struct nvkm_i2c_port *port;
u32 hi, lo, rq, tx, e;
if (impl->aux_stat) {
@@ -393,18 +388,18 @@ nouveau_i2c_intr(struct nouveau_subdev *subdev)
}
static const struct nvkm_event_func
-nouveau_i2c_intr_func = {
- .ctor = nouveau_i2c_intr_ctor,
- .init = nouveau_i2c_intr_init,
- .fini = nouveau_i2c_intr_fini,
+nvkm_i2c_intr_func = {
+ .ctor = nvkm_i2c_intr_ctor,
+ .init = nvkm_i2c_intr_init,
+ .fini = nvkm_i2c_intr_fini,
};
int
-_nouveau_i2c_fini(struct nouveau_object *object, bool suspend)
+_nvkm_i2c_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_i2c_impl *impl = (void *)nv_oclass(object);
- struct nouveau_i2c *i2c = (void *)object;
- struct nouveau_i2c_port *port;
+ struct nvkm_i2c_impl *impl = (void *)nv_oclass(object);
+ struct nvkm_i2c *i2c = (void *)object;
+ struct nvkm_i2c_port *port;
u32 mask;
int ret;
@@ -419,7 +414,7 @@ _nouveau_i2c_fini(struct nouveau_object *object, bool suspend)
impl->aux_stat(i2c, &mask, &mask, &mask, &mask);
}
- return nouveau_subdev_fini(&i2c->base, suspend);
+ return nvkm_subdev_fini(&i2c->base, suspend);
fail:
list_for_each_entry_continue_reverse(port, &i2c->ports, head) {
nv_ofuncs(port)->init(nv_object(port));
@@ -429,13 +424,13 @@ fail:
}
int
-_nouveau_i2c_init(struct nouveau_object *object)
+_nvkm_i2c_init(struct nvkm_object *object)
{
- struct nouveau_i2c *i2c = (void *)object;
- struct nouveau_i2c_port *port;
+ struct nvkm_i2c *i2c = (void *)object;
+ struct nvkm_i2c_port *port;
int ret;
- ret = nouveau_subdev_init(&i2c->base);
+ ret = nvkm_subdev_init(&i2c->base);
if (ret == 0) {
list_for_each_entry(port, &i2c->ports, head) {
ret = nv_ofuncs(port)->init(nv_object(port));
@@ -454,33 +449,33 @@ fail:
}
void
-_nouveau_i2c_dtor(struct nouveau_object *object)
+_nvkm_i2c_dtor(struct nvkm_object *object)
{
- struct nouveau_i2c *i2c = (void *)object;
- struct nouveau_i2c_port *port, *temp;
+ struct nvkm_i2c *i2c = (void *)object;
+ struct nvkm_i2c_port *port, *temp;
nvkm_event_fini(&i2c->event);
list_for_each_entry_safe(port, temp, &i2c->ports, head) {
- nouveau_object_ref(NULL, (struct nouveau_object **)&port);
+ nvkm_object_ref(NULL, (struct nvkm_object **)&port);
}
- nouveau_subdev_destroy(&i2c->base);
+ nvkm_subdev_destroy(&i2c->base);
}
-static struct nouveau_oclass *
-nouveau_i2c_extdev_sclass[] = {
- nouveau_anx9805_sclass,
+static struct nvkm_oclass *
+nvkm_i2c_extdev_sclass[] = {
+ nvkm_anx9805_sclass,
};
static void
-nouveau_i2c_create_port(struct nouveau_i2c *i2c, int index, u8 type,
- struct dcb_i2c_entry *info)
+nvkm_i2c_create_port(struct nvkm_i2c *i2c, int index, u8 type,
+ struct dcb_i2c_entry *info)
{
- const struct nouveau_i2c_impl *impl = (void *)nv_oclass(i2c);
- struct nouveau_oclass *oclass;
- struct nouveau_object *parent;
- struct nouveau_object *object;
+ const struct nvkm_i2c_impl *impl = (void *)nv_oclass(i2c);
+ struct nvkm_oclass *oclass;
+ struct nvkm_object *parent;
+ struct nvkm_object *object;
int ret, pad;
if (info->share != DCB_I2C_UNUSED) {
@@ -494,8 +489,8 @@ nouveau_i2c_create_port(struct nouveau_i2c *i2c, int index, u8 type,
oclass = impl->pad_x;
}
- ret = nouveau_object_ctor(NULL, nv_object(i2c), oclass, NULL, pad,
- &parent);
+ ret = nvkm_object_ctor(nv_object(i2c), NULL, oclass,
+ NULL, pad, &parent);
if (ret < 0)
return;
@@ -503,44 +498,40 @@ nouveau_i2c_create_port(struct nouveau_i2c *i2c, int index, u8 type,
do {
ret = -EINVAL;
if (oclass->handle == type) {
- ret = nouveau_object_ctor(parent, nv_object(i2c),
- oclass, info, index,
- &object);
+ ret = nvkm_object_ctor(parent, NULL, oclass,
+ info, index, &object);
}
} while (ret && (++oclass)->handle);
- nouveau_object_ref(NULL, &parent);
+ nvkm_object_ref(NULL, &parent);
}
int
-nouveau_i2c_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int length, void **pobject)
+nvkm_i2c_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nouveau_i2c *i2c;
- struct nouveau_object *object;
+ struct nvkm_bios *bios = nvkm_bios(parent);
+ struct nvkm_i2c *i2c;
+ struct nvkm_object *object;
struct dcb_i2c_entry info;
int ret, i, j, index = -1;
struct dcb_output outp;
u8 ver, hdr;
u32 data;
- ret = nouveau_subdev_create(parent, engine, oclass, 0,
- "I2C", "i2c", &i2c);
+ ret = nvkm_subdev_create(parent, engine, oclass, 0, "I2C", "i2c", &i2c);
*pobject = nv_object(i2c);
if (ret)
return ret;
- nv_subdev(i2c)->intr = nouveau_i2c_intr;
- i2c->find = nouveau_i2c_find;
- i2c->find_type = nouveau_i2c_find_type;
- i2c->acquire_pad = nouveau_i2c_acquire_pad;
- i2c->release_pad = nouveau_i2c_release_pad;
- i2c->acquire = nouveau_i2c_acquire;
- i2c->release = nouveau_i2c_release;
- i2c->identify = nouveau_i2c_identify;
+ nv_subdev(i2c)->intr = nvkm_i2c_intr;
+ i2c->find = nvkm_i2c_find;
+ i2c->find_type = nvkm_i2c_find_type;
+ i2c->acquire_pad = nvkm_i2c_acquire_pad;
+ i2c->release_pad = nvkm_i2c_release_pad;
+ i2c->acquire = nvkm_i2c_acquire;
+ i2c->release = nvkm_i2c_release;
+ i2c->identify = nvkm_i2c_identify;
init_waitqueue_head(&i2c->wait);
INIT_LIST_HEAD(&i2c->ports);
@@ -549,23 +540,21 @@ nouveau_i2c_create_(struct nouveau_object *parent,
case DCB_I2C_NV04_BIT:
case DCB_I2C_NV4E_BIT:
case DCB_I2C_NVIO_BIT:
- nouveau_i2c_create_port(i2c, NV_I2C_PORT(index),
- info.type, &info);
+ nvkm_i2c_create_port(i2c, NV_I2C_PORT(index),
+ info.type, &info);
break;
case DCB_I2C_NVIO_AUX:
- nouveau_i2c_create_port(i2c, NV_I2C_AUX(index),
- info.type, &info);
+ nvkm_i2c_create_port(i2c, NV_I2C_AUX(index),
+ info.type, &info);
break;
case DCB_I2C_PMGR:
if (info.drive != DCB_I2C_UNUSED) {
- nouveau_i2c_create_port(i2c, NV_I2C_PORT(index),
- DCB_I2C_NVIO_BIT,
- &info);
+ nvkm_i2c_create_port(i2c, NV_I2C_PORT(index),
+ DCB_I2C_NVIO_BIT, &info);
}
if (info.auxch != DCB_I2C_UNUSED) {
- nouveau_i2c_create_port(i2c, NV_I2C_AUX(index),
- DCB_I2C_NVIO_AUX,
- &info);
+ nvkm_i2c_create_port(i2c, NV_I2C_AUX(index),
+ DCB_I2C_NVIO_AUX, &info);
}
break;
case DCB_I2C_UNUSED:
@@ -597,20 +586,19 @@ nouveau_i2c_create_(struct nouveau_object *parent,
ret = -ENODEV;
j = -1;
- while (ret && ++j < ARRAY_SIZE(nouveau_i2c_extdev_sclass)) {
+ while (ret && ++j < ARRAY_SIZE(nvkm_i2c_extdev_sclass)) {
parent = nv_object(i2c->find(i2c, outp.i2c_index));
- oclass = nouveau_i2c_extdev_sclass[j];
+ oclass = nvkm_i2c_extdev_sclass[j];
do {
if (oclass->handle != info.type)
continue;
- ret = nouveau_object_ctor(parent, *pobject,
- oclass, NULL,
- index++, &object);
+ ret = nvkm_object_ctor(parent, NULL, oclass,
+ NULL, index++, &object);
} while (ret && (++oclass)->handle);
}
}
- ret = nvkm_event_init(&nouveau_i2c_intr_func, 4, index, &i2c->event);
+ ret = nvkm_event_init(&nvkm_i2c_intr_func, 4, index, &i2c->event);
if (ret)
return ret;
@@ -618,14 +606,14 @@ nouveau_i2c_create_(struct nouveau_object *parent,
}
int
-_nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+_nvkm_i2c_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_i2c *i2c;
+ struct nvkm_i2c *i2c;
int ret;
- ret = nouveau_i2c_create(parent, engine, oclass, &i2c);
+ ret = nvkm_i2c_create(parent, engine, oclass, &i2c);
*pobject = nv_object(i2c);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bit.c
index 813ffc96e864..861a453d2a67 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bit.c
@@ -21,7 +21,6 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
#ifdef CONFIG_NOUVEAU_I2C_INTERNAL
@@ -30,37 +29,37 @@
#define T_HOLD 5000
static inline void
-i2c_drive_scl(struct nouveau_i2c_port *port, int state)
+i2c_drive_scl(struct nvkm_i2c_port *port, int state)
{
port->func->drive_scl(port, state);
}
static inline void
-i2c_drive_sda(struct nouveau_i2c_port *port, int state)
+i2c_drive_sda(struct nvkm_i2c_port *port, int state)
{
port->func->drive_sda(port, state);
}
static inline int
-i2c_sense_scl(struct nouveau_i2c_port *port)
+i2c_sense_scl(struct nvkm_i2c_port *port)
{
return port->func->sense_scl(port);
}
static inline int
-i2c_sense_sda(struct nouveau_i2c_port *port)
+i2c_sense_sda(struct nvkm_i2c_port *port)
{
return port->func->sense_sda(port);
}
static void
-i2c_delay(struct nouveau_i2c_port *port, u32 nsec)
+i2c_delay(struct nvkm_i2c_port *port, u32 nsec)
{
udelay((nsec + 500) / 1000);
}
static bool
-i2c_raise_scl(struct nouveau_i2c_port *port)
+i2c_raise_scl(struct nvkm_i2c_port *port)
{
u32 timeout = T_TIMEOUT / T_RISEFALL;
@@ -73,7 +72,7 @@ i2c_raise_scl(struct nouveau_i2c_port *port)
}
static int
-i2c_start(struct nouveau_i2c_port *port)
+i2c_start(struct nvkm_i2c_port *port)
{
int ret = 0;
@@ -93,7 +92,7 @@ i2c_start(struct nouveau_i2c_port *port)
}
static void
-i2c_stop(struct nouveau_i2c_port *port)
+i2c_stop(struct nvkm_i2c_port *port)
{
i2c_drive_scl(port, 0);
i2c_drive_sda(port, 0);
@@ -106,7 +105,7 @@ i2c_stop(struct nouveau_i2c_port *port)
}
static int
-i2c_bitw(struct nouveau_i2c_port *port, int sda)
+i2c_bitw(struct nvkm_i2c_port *port, int sda)
{
i2c_drive_sda(port, sda);
i2c_delay(port, T_RISEFALL);
@@ -121,7 +120,7 @@ i2c_bitw(struct nouveau_i2c_port *port, int sda)
}
static int
-i2c_bitr(struct nouveau_i2c_port *port)
+i2c_bitr(struct nvkm_i2c_port *port)
{
int sda;
@@ -140,7 +139,7 @@ i2c_bitr(struct nouveau_i2c_port *port)
}
static int
-i2c_get_byte(struct nouveau_i2c_port *port, u8 *byte, bool last)
+i2c_get_byte(struct nvkm_i2c_port *port, u8 *byte, bool last)
{
int i, bit;
@@ -156,7 +155,7 @@ i2c_get_byte(struct nouveau_i2c_port *port, u8 *byte, bool last)
}
static int
-i2c_put_byte(struct nouveau_i2c_port *port, u8 byte)
+i2c_put_byte(struct nvkm_i2c_port *port, u8 byte)
{
int i, ret;
for (i = 7; i >= 0; i--) {
@@ -172,7 +171,7 @@ i2c_put_byte(struct nouveau_i2c_port *port, u8 byte)
}
static int
-i2c_addr(struct nouveau_i2c_port *port, struct i2c_msg *msg)
+i2c_addr(struct nvkm_i2c_port *port, struct i2c_msg *msg)
{
u32 addr = msg->addr << 1;
if (msg->flags & I2C_M_RD)
@@ -183,11 +182,11 @@ i2c_addr(struct nouveau_i2c_port *port, struct i2c_msg *msg)
static int
i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
- struct nouveau_i2c_port *port = adap->algo_data;
+ struct nvkm_i2c_port *port = adap->algo_data;
struct i2c_msg *msg = msgs;
int ret = 0, mcnt = num;
- ret = nouveau_i2c(port)->acquire(port, nsecs_to_jiffies(T_TIMEOUT));
+ ret = nvkm_i2c(port)->acquire(port, nsecs_to_jiffies(T_TIMEOUT));
if (ret)
return ret;
@@ -211,7 +210,7 @@ i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
}
i2c_stop(port);
- nouveau_i2c(port)->release(port);
+ nvkm_i2c(port)->release(port);
return (ret < 0) ? ret : num;
}
#else
@@ -228,7 +227,7 @@ i2c_bit_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
-const struct i2c_algorithm nouveau_i2c_bit_algo = {
+const struct i2c_algorithm nvkm_i2c_bit_algo = {
.master_xfer = i2c_bit_xfer,
.functionality = i2c_bit_func
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/g94.c
index e383ee81f4d2..2a2dd47b9835 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/g94.c
@@ -21,11 +21,10 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
void
-nv94_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
+g94_aux_stat(struct nvkm_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
{
u32 intr = nv_rd32(i2c, 0x00e06c);
u32 stat = nv_rd32(i2c, 0x00e068) & intr, i;
@@ -39,7 +38,7 @@ nv94_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
}
void
-nv94_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data)
+g94_aux_mask(struct nvkm_i2c *i2c, u32 type, u32 mask, u32 data)
{
u32 temp = nv_rd32(i2c, 0x00e068), i;
for (i = 0; i < 8; i++) {
@@ -58,13 +57,13 @@ nv94_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data)
#define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args)
static void
-auxch_fini(struct nouveau_i2c *aux, int ch)
+auxch_fini(struct nvkm_i2c *aux, int ch)
{
nv_mask(aux, 0x00e4e4 + (ch * 0x50), 0x00310000, 0x00000000);
}
static int
-auxch_init(struct nouveau_i2c *aux, int ch)
+auxch_init(struct nvkm_i2c *aux, int ch)
{
const u32 unksel = 1; /* nfi which to use, or if it matters.. */
const u32 ureq = unksel ? 0x00100000 : 0x00200000;
@@ -99,10 +98,10 @@ auxch_init(struct nouveau_i2c *aux, int ch)
}
int
-nv94_aux(struct nouveau_i2c_port *base, bool retry,
+g94_aux(struct nvkm_i2c_port *base, bool retry,
u8 type, u32 addr, u8 *data, u8 size)
{
- struct nouveau_i2c *aux = nouveau_i2c(base);
+ struct nvkm_i2c *aux = nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
u32 ctrl, stat, timeout, retries;
u32 xbuf[4] = {};
@@ -185,8 +184,8 @@ out:
return ret < 0 ? ret : (stat & 0x000f0000) >> 16;
}
-static const struct nouveau_i2c_func
-nv94_i2c_func = {
+static const struct nvkm_i2c_func
+g94_i2c_func = {
.drive_scl = nv50_i2c_drive_scl,
.drive_sda = nv50_i2c_drive_sda,
.sense_scl = nv50_i2c_sense_scl,
@@ -194,17 +193,16 @@ nv94_i2c_func = {
};
static int
-nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+g94_i2c_port_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct dcb_i2c_entry *info = data;
struct nv50_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_bit_algo, &nv94_i2c_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_bit_algo, &g94_i2c_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -217,23 +215,22 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-static const struct nouveau_i2c_func
-nv94_aux_func = {
- .aux = nv94_aux,
+static const struct nvkm_i2c_func
+g94_aux_func = {
+ .aux = g94_aux,
};
int
-nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+g94_aux_port_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct dcb_i2c_entry *info = data;
struct nv50_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_aux_algo, &nv94_aux_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_aux_algo, &g94_aux_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -243,40 +240,40 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-static struct nouveau_oclass
-nv94_i2c_sclass[] = {
+static struct nvkm_oclass
+g94_i2c_sclass[] = {
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv94_i2c_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g94_i2c_port_ctor,
+ .dtor = _nvkm_i2c_port_dtor,
.init = nv50_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .fini = _nvkm_i2c_port_fini,
},
},
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv94_aux_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
- .init = _nouveau_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g94_aux_port_ctor,
+ .dtor = _nvkm_i2c_port_dtor,
+ .init = _nvkm_i2c_port_init,
+ .fini = _nvkm_i2c_port_fini,
},
},
{}
};
-struct nouveau_oclass *
-nv94_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+g94_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0x94),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
- .sclass = nv94_i2c_sclass,
+ .sclass = g94_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
- .pad_s = &nv94_i2c_pad_oclass,
+ .pad_s = &g94_i2c_pad_oclass,
.aux = 4,
- .aux_stat = nv94_aux_stat,
- .aux_mask = nv94_aux_mask,
+ .aux_stat = g94_aux_stat,
+ .aux_mask = g94_aux_mask,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gf110.c
index fd99380502ec..4d4ac6638140 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gf110.c
@@ -21,45 +21,43 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
static int
-nvd0_i2c_sense_scl(struct nouveau_i2c_port *base)
+gf110_i2c_sense_scl(struct nvkm_i2c_port *base)
{
- struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv50_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
return !!(nv_rd32(priv, port->addr) & 0x00000010);
}
static int
-nvd0_i2c_sense_sda(struct nouveau_i2c_port *base)
+gf110_i2c_sense_sda(struct nvkm_i2c_port *base)
{
- struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv50_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
return !!(nv_rd32(priv, port->addr) & 0x00000020);
}
-static const struct nouveau_i2c_func
-nvd0_i2c_func = {
+static const struct nvkm_i2c_func
+gf110_i2c_func = {
.drive_scl = nv50_i2c_drive_scl,
.drive_sda = nv50_i2c_drive_sda,
- .sense_scl = nvd0_i2c_sense_scl,
- .sense_sda = nvd0_i2c_sense_sda,
+ .sense_scl = gf110_i2c_sense_scl,
+ .sense_sda = gf110_i2c_sense_sda,
};
int
-nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+gf110_i2c_port_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct dcb_i2c_entry *info = data;
struct nv50_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_bit_algo, &nvd0_i2c_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_bit_algo, &gf110_i2c_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -69,40 +67,40 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
-nvd0_i2c_sclass[] = {
+struct nvkm_oclass
+gf110_i2c_sclass[] = {
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvd0_i2c_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf110_i2c_port_ctor,
+ .dtor = _nvkm_i2c_port_dtor,
.init = nv50_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .fini = _nvkm_i2c_port_fini,
},
},
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv94_aux_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
- .init = _nouveau_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g94_aux_port_ctor,
+ .dtor = _nvkm_i2c_port_dtor,
+ .init = _nvkm_i2c_port_init,
+ .fini = _nvkm_i2c_port_fini,
},
},
{}
};
-struct nouveau_oclass *
-nvd0_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+gf110_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0xd0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
- .sclass = nvd0_i2c_sclass,
+ .sclass = gf110_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
- .pad_s = &nv94_i2c_pad_oclass,
+ .pad_s = &g94_i2c_pad_oclass,
.aux = 4,
- .aux_stat = nv94_aux_stat,
- .aux_mask = nv94_aux_mask,
+ .aux_stat = g94_aux_stat,
+ .aux_mask = g94_aux_mask,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gf117.c
index fa891c39866b..e290b40f2d13 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gf117.c
@@ -21,19 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
-struct nouveau_oclass *
-gf117_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+gf117_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0xd7),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
- .sclass = nvd0_i2c_sclass,
+ .sclass = gf110_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
.pad_s = &nv04_i2c_pad_oclass,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gk104.c
index 25fe5c2d110e..1a464903a992 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gk104.c
@@ -21,11 +21,10 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
void
-nve0_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
+gk104_aux_stat(struct nvkm_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
{
u32 intr = nv_rd32(i2c, 0x00dc60);
u32 stat = nv_rd32(i2c, 0x00dc68) & intr, i;
@@ -39,7 +38,7 @@ nve0_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
}
void
-nve0_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data)
+gk104_aux_mask(struct nvkm_i2c *i2c, u32 type, u32 mask, u32 data)
{
u32 temp = nv_rd32(i2c, 0x00dc68), i;
for (i = 0; i < 8; i++) {
@@ -54,19 +53,19 @@ nve0_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data)
nv_wr32(i2c, 0x00dc68, temp);
}
-struct nouveau_oclass *
-nve0_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+gk104_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0xe0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
- .sclass = nvd0_i2c_sclass,
+ .sclass = gf110_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
- .pad_s = &nv94_i2c_pad_oclass,
+ .pad_s = &g94_i2c_pad_oclass,
.aux = 4,
- .aux_stat = nve0_aux_stat,
- .aux_mask = nve0_aux_mask,
+ .aux_stat = gk104_aux_stat,
+ .aux_mask = gk104_aux_mask,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm204.c
index 06a2b87ccbf1..ab64237b3842 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm204.c
@@ -21,20 +21,19 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
#define AUX_DBG(fmt, args...) nv_debug(aux, "AUXCH(%d): " fmt, ch, ##args)
#define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args)
static void
-auxch_fini(struct nouveau_i2c *aux, int ch)
+auxch_fini(struct nvkm_i2c *aux, int ch)
{
nv_mask(aux, 0x00d954 + (ch * 0x50), 0x00310000, 0x00000000);
}
static int
-auxch_init(struct nouveau_i2c *aux, int ch)
+auxch_init(struct nvkm_i2c *aux, int ch)
{
const u32 unksel = 1; /* nfi which to use, or if it matters.. */
const u32 ureq = unksel ? 0x00100000 : 0x00200000;
@@ -69,10 +68,10 @@ auxch_init(struct nouveau_i2c *aux, int ch)
}
int
-gm204_aux(struct nouveau_i2c_port *base, bool retry,
+gm204_aux(struct nvkm_i2c_port *base, bool retry,
u8 type, u32 addr, u8 *data, u8 size)
{
- struct nouveau_i2c *aux = nouveau_i2c(base);
+ struct nvkm_i2c *aux = nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
u32 ctrl, stat, timeout, retries;
u32 xbuf[4] = {};
@@ -155,24 +154,23 @@ out:
return ret < 0 ? ret : (stat & 0x000f0000) >> 16;
}
-static const struct nouveau_i2c_func
+static const struct nvkm_i2c_func
gm204_aux_func = {
.aux = gm204_aux,
};
int
-gm204_aux_port_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+gm204_aux_port_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct dcb_i2c_entry *info = data;
struct nv50_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_aux_algo, &gm204_aux_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_aux_algo, &gm204_aux_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -182,40 +180,40 @@ gm204_aux_port_ctor(struct nouveau_object *parent,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gm204_i2c_sclass[] = {
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvd0_i2c_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf110_i2c_port_ctor,
+ .dtor = _nvkm_i2c_port_dtor,
.init = nv50_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .fini = _nvkm_i2c_port_fini,
},
},
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm204_aux_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
- .init = _nouveau_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .dtor = _nvkm_i2c_port_dtor,
+ .init = _nvkm_i2c_port_init,
+ .fini = _nvkm_i2c_port_fini,
},
},
{}
};
-struct nouveau_oclass *
-gm204_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+gm204_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0x24),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
.sclass = gm204_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
.pad_s = &gm204_i2c_pad_oclass,
.aux = 8,
- .aux_stat = nve0_aux_stat,
- .aux_mask = nve0_aux_mask,
+ .aux_stat = gk104_aux_stat,
+ .aux_mask = gk104_aux_mask,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv04.c
index b1725bdea967..4cdf1c489353 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv04.c
@@ -21,25 +21,24 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/vga.h>
-#include "priv.h"
-
struct nv04_i2c_priv {
- struct nouveau_i2c base;
+ struct nvkm_i2c base;
};
struct nv04_i2c_port {
- struct nouveau_i2c_port base;
+ struct nvkm_i2c_port base;
u8 drive;
u8 sense;
};
static void
-nv04_i2c_drive_scl(struct nouveau_i2c_port *base, int state)
+nv04_i2c_drive_scl(struct nvkm_i2c_port *base, int state)
{
- struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv04_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv04_i2c_port *port = (void *)base;
u8 val = nv_rdvgac(priv, 0, port->drive);
if (state) val |= 0x20;
@@ -48,9 +47,9 @@ nv04_i2c_drive_scl(struct nouveau_i2c_port *base, int state)
}
static void
-nv04_i2c_drive_sda(struct nouveau_i2c_port *base, int state)
+nv04_i2c_drive_sda(struct nvkm_i2c_port *base, int state)
{
- struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv04_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv04_i2c_port *port = (void *)base;
u8 val = nv_rdvgac(priv, 0, port->drive);
if (state) val |= 0x10;
@@ -59,22 +58,22 @@ nv04_i2c_drive_sda(struct nouveau_i2c_port *base, int state)
}
static int
-nv04_i2c_sense_scl(struct nouveau_i2c_port *base)
+nv04_i2c_sense_scl(struct nvkm_i2c_port *base)
{
- struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv04_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv04_i2c_port *port = (void *)base;
return !!(nv_rdvgac(priv, 0, port->sense) & 0x04);
}
static int
-nv04_i2c_sense_sda(struct nouveau_i2c_port *base)
+nv04_i2c_sense_sda(struct nvkm_i2c_port *base)
{
- struct nv04_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv04_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv04_i2c_port *port = (void *)base;
return !!(nv_rdvgac(priv, 0, port->sense) & 0x08);
}
-static const struct nouveau_i2c_func
+static const struct nvkm_i2c_func
nv04_i2c_func = {
.drive_scl = nv04_i2c_drive_scl,
.drive_sda = nv04_i2c_drive_sda,
@@ -83,17 +82,16 @@ nv04_i2c_func = {
};
static int
-nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+nv04_i2c_port_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct dcb_i2c_entry *info = data;
struct nv04_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_bit_algo, &nv04_i2c_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_bit_algo, &nv04_i2c_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -103,27 +101,27 @@ nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-static struct nouveau_oclass
+static struct nvkm_oclass
nv04_i2c_sclass[] = {
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NV04_BIT),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_i2c_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
- .init = _nouveau_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .dtor = _nvkm_i2c_port_dtor,
+ .init = _nvkm_i2c_port_init,
+ .fini = _nvkm_i2c_port_fini,
},
},
{}
};
-struct nouveau_oclass *
-nv04_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+nv04_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
.sclass = nv04_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv4e.c
index f16c87ce5ba1..046fe5e2ea19 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv4e.c
@@ -21,53 +21,52 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/vga.h>
-#include "priv.h"
-
struct nv4e_i2c_priv {
- struct nouveau_i2c base;
+ struct nvkm_i2c base;
};
struct nv4e_i2c_port {
- struct nouveau_i2c_port base;
+ struct nvkm_i2c_port base;
u32 addr;
};
static void
-nv4e_i2c_drive_scl(struct nouveau_i2c_port *base, int state)
+nv4e_i2c_drive_scl(struct nvkm_i2c_port *base, int state)
{
- struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv4e_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv4e_i2c_port *port = (void *)base;
nv_mask(priv, port->addr, 0x2f, state ? 0x21 : 0x01);
}
static void
-nv4e_i2c_drive_sda(struct nouveau_i2c_port *base, int state)
+nv4e_i2c_drive_sda(struct nvkm_i2c_port *base, int state)
{
- struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv4e_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv4e_i2c_port *port = (void *)base;
nv_mask(priv, port->addr, 0x1f, state ? 0x11 : 0x01);
}
static int
-nv4e_i2c_sense_scl(struct nouveau_i2c_port *base)
+nv4e_i2c_sense_scl(struct nvkm_i2c_port *base)
{
- struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv4e_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv4e_i2c_port *port = (void *)base;
return !!(nv_rd32(priv, port->addr) & 0x00040000);
}
static int
-nv4e_i2c_sense_sda(struct nouveau_i2c_port *base)
+nv4e_i2c_sense_sda(struct nvkm_i2c_port *base)
{
- struct nv4e_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv4e_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv4e_i2c_port *port = (void *)base;
return !!(nv_rd32(priv, port->addr) & 0x00080000);
}
-static const struct nouveau_i2c_func
+static const struct nvkm_i2c_func
nv4e_i2c_func = {
.drive_scl = nv4e_i2c_drive_scl,
.drive_sda = nv4e_i2c_drive_sda,
@@ -76,17 +75,16 @@ nv4e_i2c_func = {
};
static int
-nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+nv4e_i2c_port_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct dcb_i2c_entry *info = data;
struct nv4e_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_bit_algo, &nv4e_i2c_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_bit_algo, &nv4e_i2c_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -95,27 +93,27 @@ nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-static struct nouveau_oclass
+static struct nvkm_oclass
nv4e_i2c_sclass[] = {
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NV4E_BIT),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv4e_i2c_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
- .init = _nouveau_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .dtor = _nvkm_i2c_port_dtor,
+ .init = _nvkm_i2c_port_init,
+ .fini = _nvkm_i2c_port_fini,
},
},
{}
};
-struct nouveau_oclass *
-nv4e_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+nv4e_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0x4e),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
.sclass = nv4e_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv50.c
index 7b8756d4df08..fba5b26a5682 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv50.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv50.h"
void
-nv50_i2c_drive_scl(struct nouveau_i2c_port *base, int state)
+nv50_i2c_drive_scl(struct nvkm_i2c_port *base, int state)
{
- struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv50_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
if (state) port->state |= 0x01;
else port->state &= 0xfe;
@@ -35,9 +34,9 @@ nv50_i2c_drive_scl(struct nouveau_i2c_port *base, int state)
}
void
-nv50_i2c_drive_sda(struct nouveau_i2c_port *base, int state)
+nv50_i2c_drive_sda(struct nvkm_i2c_port *base, int state)
{
- struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv50_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
if (state) port->state |= 0x02;
else port->state &= 0xfd;
@@ -45,22 +44,22 @@ nv50_i2c_drive_sda(struct nouveau_i2c_port *base, int state)
}
int
-nv50_i2c_sense_scl(struct nouveau_i2c_port *base)
+nv50_i2c_sense_scl(struct nvkm_i2c_port *base)
{
- struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv50_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
return !!(nv_rd32(priv, port->addr) & 0x00000001);
}
int
-nv50_i2c_sense_sda(struct nouveau_i2c_port *base)
+nv50_i2c_sense_sda(struct nvkm_i2c_port *base)
{
- struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
+ struct nv50_i2c_priv *priv = (void *)nvkm_i2c(base);
struct nv50_i2c_port *port = (void *)base;
return !!(nv_rd32(priv, port->addr) & 0x00000002);
}
-static const struct nouveau_i2c_func
+static const struct nvkm_i2c_func
nv50_i2c_func = {
.drive_scl = nv50_i2c_drive_scl,
.drive_sda = nv50_i2c_drive_sda,
@@ -76,17 +75,16 @@ const u32 nv50_i2c_addr[] = {
const int nv50_i2c_addr_nr = ARRAY_SIZE(nv50_i2c_addr);
static int
-nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+nv50_i2c_port_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct dcb_i2c_entry *info = data;
struct nv50_i2c_port *port;
int ret;
- ret = nouveau_i2c_port_create(parent, engine, oclass, index,
- &nouveau_i2c_bit_algo, &nv50_i2c_func,
- &port);
+ ret = nvkm_i2c_port_create(parent, engine, oclass, index,
+ &nvkm_i2c_bit_algo, &nv50_i2c_func, &port);
*pobject = nv_object(port);
if (ret)
return ret;
@@ -100,35 +98,35 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
int
-nv50_i2c_port_init(struct nouveau_object *object)
+nv50_i2c_port_init(struct nvkm_object *object)
{
- struct nv50_i2c_priv *priv = (void *)object->engine;
+ struct nv50_i2c_priv *priv = (void *)nvkm_i2c(object);
struct nv50_i2c_port *port = (void *)object;
nv_wr32(priv, port->addr, port->state);
- return nouveau_i2c_port_init(&port->base);
+ return nvkm_i2c_port_init(&port->base);
}
-static struct nouveau_oclass
+static struct nvkm_oclass
nv50_i2c_sclass[] = {
{ .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_i2c_port_ctor,
- .dtor = _nouveau_i2c_port_dtor,
+ .dtor = _nvkm_i2c_port_dtor,
.init = nv50_i2c_port_init,
- .fini = _nouveau_i2c_port_fini,
+ .fini = _nvkm_i2c_port_fini,
},
},
{}
};
-struct nouveau_oclass *
-nv50_i2c_oclass = &(struct nouveau_i2c_impl) {
+struct nvkm_oclass *
+nv50_i2c_oclass = &(struct nvkm_i2c_impl) {
.base.handle = NV_SUBDEV(I2C, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_i2c_ctor,
- .dtor = _nouveau_i2c_dtor,
- .init = _nouveau_i2c_init,
- .fini = _nouveau_i2c_fini,
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_i2c_ctor,
+ .dtor = _nvkm_i2c_dtor,
+ .init = _nvkm_i2c_init,
+ .fini = _nvkm_i2c_fini,
},
.sclass = nv50_i2c_sclass,
.pad_x = &nv04_i2c_pad_oclass,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv50.h
new file mode 100644
index 000000000000..b3139e721b02
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/nv50.h
@@ -0,0 +1,32 @@
+#ifndef __NV50_I2C_H__
+#define __NV50_I2C_H__
+#include "priv.h"
+
+struct nv50_i2c_priv {
+ struct nvkm_i2c base;
+};
+
+struct nv50_i2c_port {
+ struct nvkm_i2c_port base;
+ u32 addr;
+ u32 state;
+};
+
+extern const u32 nv50_i2c_addr[];
+extern const int nv50_i2c_addr_nr;
+int nv50_i2c_port_init(struct nvkm_object *);
+int nv50_i2c_sense_scl(struct nvkm_i2c_port *);
+int nv50_i2c_sense_sda(struct nvkm_i2c_port *);
+void nv50_i2c_drive_scl(struct nvkm_i2c_port *, int state);
+void nv50_i2c_drive_sda(struct nvkm_i2c_port *, int state);
+
+int g94_aux_port_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void g94_i2c_acquire(struct nvkm_i2c_port *);
+void g94_i2c_release(struct nvkm_i2c_port *);
+
+int gf110_i2c_port_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.c
index e9e412477c12..a242eeb67829 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.c
@@ -21,35 +21,34 @@
*
* Authors: Ben Skeggs
*/
-
#include "pad.h"
int
-_nvkm_i2c_pad_fini(struct nouveau_object *object, bool suspend)
+_nvkm_i2c_pad_fini(struct nvkm_object *object, bool suspend)
{
struct nvkm_i2c_pad *pad = (void *)object;
DBG("-> NULL\n");
pad->port = NULL;
- return nouveau_object_fini(&pad->base, suspend);
+ return nvkm_object_fini(&pad->base, suspend);
}
int
-_nvkm_i2c_pad_init(struct nouveau_object *object)
+_nvkm_i2c_pad_init(struct nvkm_object *object)
{
struct nvkm_i2c_pad *pad = (void *)object;
DBG("-> PORT:%02x\n", pad->next->index);
pad->port = pad->next;
- return nouveau_object_init(&pad->base);
+ return nvkm_object_init(&pad->base);
}
int
-nvkm_i2c_pad_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int index,
+nvkm_i2c_pad_create_(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int index,
int size, void **pobject)
{
- struct nouveau_i2c *i2c = (void *)engine;
- struct nouveau_i2c_port *port;
+ struct nvkm_i2c *i2c = nvkm_i2c(parent);
+ struct nvkm_i2c_port *port;
struct nvkm_i2c_pad *pad;
int ret;
@@ -62,7 +61,7 @@ nvkm_i2c_pad_create_(struct nouveau_object *parent,
}
}
- ret = nouveau_object_create_(parent, engine, oclass, 0, size, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, 0, size, pobject);
pad = *pobject;
if (ret)
return ret;
@@ -72,9 +71,9 @@ nvkm_i2c_pad_create_(struct nouveau_object *parent,
}
int
-_nvkm_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+_nvkm_i2c_pad_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct nvkm_i2c_pad *pad;
int ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h
index 452ac10c3004..f3422cc6f8db 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h
@@ -1,20 +1,19 @@
#ifndef __NVKM_I2C_PAD_H__
#define __NVKM_I2C_PAD_H__
-
#include "priv.h"
struct nvkm_i2c_pad {
- struct nouveau_object base;
+ struct nvkm_object base;
int index;
- struct nouveau_i2c_port *port;
- struct nouveau_i2c_port *next;
+ struct nvkm_i2c_port *port;
+ struct nvkm_i2c_port *next;
};
static inline struct nvkm_i2c_pad *
-nvkm_i2c_pad(struct nouveau_i2c_port *port)
+nvkm_i2c_pad(struct nvkm_i2c_port *port)
{
- struct nouveau_object *pad = nv_object(port);
- while (pad->parent)
+ struct nvkm_object *pad = nv_object(port);
+ while (!nv_iclass(pad->parent, NV_SUBDEV_CLASS))
pad = pad->parent;
return (void *)pad;
}
@@ -34,25 +33,24 @@ nvkm_i2c_pad(struct nouveau_i2c_port *port)
_nvkm_i2c_pad_fini(nv_object(_p), (s)); \
})
-int nvkm_i2c_pad_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int index, int, void **);
+int nvkm_i2c_pad_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int index, int, void **);
-int _nvkm_i2c_pad_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-#define _nvkm_i2c_pad_dtor nouveau_object_destroy
-int _nvkm_i2c_pad_init(struct nouveau_object *);
-int _nvkm_i2c_pad_fini(struct nouveau_object *, bool);
+int _nvkm_i2c_pad_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+#define _nvkm_i2c_pad_dtor nvkm_object_destroy
+int _nvkm_i2c_pad_init(struct nvkm_object *);
+int _nvkm_i2c_pad_fini(struct nvkm_object *, bool);
#ifndef MSG
#define MSG(l,f,a...) do { \
struct nvkm_i2c_pad *_pad = (void *)pad; \
- nv_##l(nv_object(_pad)->engine, "PAD:%c:%02x: "f, \
+ nv_##l(_pad, "PAD:%c:%02x: "f, \
_pad->index >= 0x100 ? 'X' : 'S', \
_pad->index >= 0x100 ? _pad->index - 0x100 : _pad->index, ##a); \
} while(0)
#define DBG(f,a...) MSG(debug, f, ##a)
#define ERR(f,a...) MSG(error, f, ##a)
#endif
-
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c
index 0dc6753014f0..e9832f7a7e38 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padg94.c
@@ -21,28 +21,27 @@
*
* Authors: Ben Skeggs
*/
-
#include "pad.h"
-struct nv94_i2c_pad {
+struct g94_i2c_pad {
struct nvkm_i2c_pad base;
int addr;
};
static int
-nv94_i2c_pad_fini(struct nouveau_object *object, bool suspend)
+g94_i2c_pad_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_i2c *i2c = (void *)object->engine;
- struct nv94_i2c_pad *pad = (void *)object;
+ struct nvkm_i2c *i2c = (void *)nvkm_i2c(object);
+ struct g94_i2c_pad *pad = (void *)object;
nv_mask(i2c, 0x00e50c + pad->addr, 0x00000001, 0x00000001);
return nvkm_i2c_pad_fini(&pad->base, suspend);
}
static int
-nv94_i2c_pad_init(struct nouveau_object *object)
+g94_i2c_pad_init(struct nvkm_object *object)
{
- struct nouveau_i2c *i2c = (void *)object->engine;
- struct nv94_i2c_pad *pad = (void *)object;
+ struct nvkm_i2c *i2c = (void *)nvkm_i2c(object);
+ struct g94_i2c_pad *pad = (void *)object;
switch (nv_oclass(pad->base.next)->handle) {
case NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX):
@@ -59,11 +58,11 @@ nv94_i2c_pad_init(struct nouveau_object *object)
}
static int
-nv94_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+g94_i2c_pad_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
- struct nv94_i2c_pad *pad;
+ struct g94_i2c_pad *pad;
int ret;
ret = nvkm_i2c_pad_create(parent, engine, oclass, index, &pad);
@@ -75,12 +74,12 @@ nv94_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
-nv94_i2c_pad_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv94_i2c_pad_ctor,
+struct nvkm_oclass
+g94_i2c_pad_oclass = {
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g94_i2c_pad_ctor,
.dtor = _nvkm_i2c_pad_dtor,
- .init = nv94_i2c_pad_init,
- .fini = nv94_i2c_pad_fini,
+ .init = g94_i2c_pad_init,
+ .fini = g94_i2c_pad_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm204.c
index f0e6fbbaa8cd..be590405444d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm204.c
@@ -21,7 +21,6 @@
*
* Authors: Ben Skeggs
*/
-
#include "pad.h"
struct gm204_i2c_pad {
@@ -30,18 +29,18 @@ struct gm204_i2c_pad {
};
static int
-gm204_i2c_pad_fini(struct nouveau_object *object, bool suspend)
+gm204_i2c_pad_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_i2c *i2c = (void *)object->engine;
+ struct nvkm_i2c *i2c = (void *)nvkm_i2c(object);
struct gm204_i2c_pad *pad = (void *)object;
nv_mask(i2c, 0x00d97c + pad->addr, 0x00000001, 0x00000001);
return nvkm_i2c_pad_fini(&pad->base, suspend);
}
static int
-gm204_i2c_pad_init(struct nouveau_object *object)
+gm204_i2c_pad_init(struct nvkm_object *object)
{
- struct nouveau_i2c *i2c = (void *)object->engine;
+ struct nvkm_i2c *i2c = (void *)nvkm_i2c(object);
struct gm204_i2c_pad *pad = (void *)object;
switch (nv_oclass(pad->base.next)->handle) {
@@ -59,9 +58,9 @@ gm204_i2c_pad_init(struct nouveau_object *object)
}
static int
-gm204_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 index,
- struct nouveau_object **pobject)
+gm204_i2c_pad_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 index,
+ struct nvkm_object **pobject)
{
struct gm204_i2c_pad *pad;
int ret;
@@ -75,9 +74,9 @@ gm204_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gm204_i2c_pad_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm204_i2c_pad_ctor,
.dtor = _nvkm_i2c_pad_dtor,
.init = gm204_i2c_pad_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padnv04.c
index 2c4b61296dd1..22c7daaad3a0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padnv04.c
@@ -21,12 +21,11 @@
*
* Authors: Ben Skeggs
*/
-
#include "pad.h"
-struct nouveau_oclass
+struct nvkm_oclass
nv04_i2c_pad_oclass = {
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = _nvkm_i2c_pad_ctor,
.dtor = _nvkm_i2c_pad_dtor,
.init = _nvkm_i2c_pad_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/port.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/port.h
index a8ff6e077af5..586f53dad813 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/port.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/port.h
@@ -1,15 +1,13 @@
#ifndef __NVKM_I2C_PORT_H__
#define __NVKM_I2C_PORT_H__
-
#include "priv.h"
#ifndef MSG
#define MSG(l,f,a...) do { \
- struct nouveau_i2c_port *_port = (void *)port; \
- nv_##l(nv_object(_port)->engine, "PORT:%02x: "f, _port->index, ##a); \
+ struct nvkm_i2c_port *_port = (void *)port; \
+ nv_##l(_port, "PORT:%02x: "f, _port->index, ##a); \
} while(0)
#define DBG(f,a...) MSG(debug, f, ##a)
#define ERR(f,a...) MSG(error, f, ##a)
#endif
-
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/priv.h
new file mode 100644
index 000000000000..6586e1567fcf
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/priv.h
@@ -0,0 +1,87 @@
+#ifndef __NVKM_I2C_PRIV_H__
+#define __NVKM_I2C_PRIV_H__
+#include <subdev/i2c.h>
+
+extern struct nvkm_oclass nv04_i2c_pad_oclass;
+extern struct nvkm_oclass g94_i2c_pad_oclass;
+extern struct nvkm_oclass gm204_i2c_pad_oclass;
+
+#define nvkm_i2c_port_create(p,e,o,i,a,f,d) \
+ nvkm_i2c_port_create_((p), (e), (o), (i), (a), (f), \
+ sizeof(**d), (void **)d)
+#define nvkm_i2c_port_destroy(p) ({ \
+ struct nvkm_i2c_port *port = (p); \
+ _nvkm_i2c_port_dtor(nv_object(i2c)); \
+})
+#define nvkm_i2c_port_init(p) \
+ nvkm_object_init(&(p)->base)
+#define nvkm_i2c_port_fini(p,s) \
+ nvkm_object_fini(&(p)->base, (s))
+
+int nvkm_i2c_port_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, u8,
+ const struct i2c_algorithm *,
+ const struct nvkm_i2c_func *,
+ int, void **);
+void _nvkm_i2c_port_dtor(struct nvkm_object *);
+#define _nvkm_i2c_port_init nvkm_object_init
+int _nvkm_i2c_port_fini(struct nvkm_object *, bool);
+
+#define nvkm_i2c_create(p,e,o,d) \
+ nvkm_i2c_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_i2c_destroy(p) ({ \
+ struct nvkm_i2c *i2c = (p); \
+ _nvkm_i2c_dtor(nv_object(i2c)); \
+})
+#define nvkm_i2c_init(p) ({ \
+ struct nvkm_i2c *i2c = (p); \
+ _nvkm_i2c_init(nv_object(i2c)); \
+})
+#define nvkm_i2c_fini(p,s) ({ \
+ struct nvkm_i2c *i2c = (p); \
+ _nvkm_i2c_fini(nv_object(i2c), (s)); \
+})
+
+int nvkm_i2c_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+int _nvkm_i2c_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void _nvkm_i2c_dtor(struct nvkm_object *);
+int _nvkm_i2c_init(struct nvkm_object *);
+int _nvkm_i2c_fini(struct nvkm_object *, bool);
+
+extern struct nvkm_oclass nvkm_anx9805_sclass[];
+extern struct nvkm_oclass gf110_i2c_sclass[];
+
+extern const struct i2c_algorithm nvkm_i2c_bit_algo;
+extern const struct i2c_algorithm nvkm_i2c_aux_algo;
+
+struct nvkm_i2c_impl {
+ struct nvkm_oclass base;
+
+ /* supported i2c port classes */
+ struct nvkm_oclass *sclass;
+ struct nvkm_oclass *pad_x;
+ struct nvkm_oclass *pad_s;
+
+ /* number of native dp aux channels present */
+ int aux;
+
+ /* read and ack pending interrupts, returning only data
+ * for ports that have not been masked off, while still
+ * performing the ack for anything that was pending.
+ */
+ void (*aux_stat)(struct nvkm_i2c *, u32 *, u32 *, u32 *, u32 *);
+
+ /* mask on/off interrupt types for a given set of auxch
+ */
+ void (*aux_mask)(struct nvkm_i2c *, u32, u32, u32);
+};
+
+void g94_aux_stat(struct nvkm_i2c *, u32 *, u32 *, u32 *, u32 *);
+void g94_aux_mask(struct nvkm_i2c *, u32, u32, u32);
+
+void gk104_aux_stat(struct nvkm_i2c *, u32 *, u32 *, u32 *, u32 *);
+void gk104_aux_mask(struct nvkm_i2c *, u32, u32, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild
new file mode 100644
index 000000000000..a0b12d27284a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild
@@ -0,0 +1,3 @@
+nvkm-y += nvkm/subdev/ibus/gf100.o
+nvkm-y += nvkm/subdev/ibus/gk104.o
+nvkm-y += nvkm/subdev/ibus/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
index 4e977ff27e44..8e578f802f66 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ibus/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/ibus.h>
-struct nvc0_ibus_priv {
- struct nouveau_ibus base;
+struct gf100_ibus_priv {
+ struct nvkm_ibus base;
};
static void
-nvc0_ibus_intr_hub(struct nvc0_ibus_priv *priv, int i)
+gf100_ibus_intr_hub(struct gf100_ibus_priv *priv, int i)
{
u32 addr = nv_rd32(priv, 0x122120 + (i * 0x0400));
u32 data = nv_rd32(priv, 0x122124 + (i * 0x0400));
@@ -39,7 +38,7 @@ nvc0_ibus_intr_hub(struct nvc0_ibus_priv *priv, int i)
}
static void
-nvc0_ibus_intr_rop(struct nvc0_ibus_priv *priv, int i)
+gf100_ibus_intr_rop(struct gf100_ibus_priv *priv, int i)
{
u32 addr = nv_rd32(priv, 0x124120 + (i * 0x0400));
u32 data = nv_rd32(priv, 0x124124 + (i * 0x0400));
@@ -49,7 +48,7 @@ nvc0_ibus_intr_rop(struct nvc0_ibus_priv *priv, int i)
}
static void
-nvc0_ibus_intr_gpc(struct nvc0_ibus_priv *priv, int i)
+gf100_ibus_intr_gpc(struct gf100_ibus_priv *priv, int i)
{
u32 addr = nv_rd32(priv, 0x128120 + (i * 0x0400));
u32 data = nv_rd32(priv, 0x128124 + (i * 0x0400));
@@ -59,9 +58,9 @@ nvc0_ibus_intr_gpc(struct nvc0_ibus_priv *priv, int i)
}
static void
-nvc0_ibus_intr(struct nouveau_subdev *subdev)
+gf100_ibus_intr(struct nvkm_subdev *subdev)
{
- struct nvc0_ibus_priv *priv = (void *)subdev;
+ struct gf100_ibus_priv *priv = (void *)subdev;
u32 intr0 = nv_rd32(priv, 0x121c58);
u32 intr1 = nv_rd32(priv, 0x121c5c);
u32 hubnr = nv_rd32(priv, 0x121c70);
@@ -72,7 +71,7 @@ nvc0_ibus_intr(struct nouveau_subdev *subdev)
for (i = 0; (intr0 & 0x0000ff00) && i < hubnr; i++) {
u32 stat = 0x00000100 << i;
if (intr0 & stat) {
- nvc0_ibus_intr_hub(priv, i);
+ gf100_ibus_intr_hub(priv, i);
intr0 &= ~stat;
}
}
@@ -80,7 +79,7 @@ nvc0_ibus_intr(struct nouveau_subdev *subdev)
for (i = 0; (intr0 & 0xffff0000) && i < ropnr; i++) {
u32 stat = 0x00010000 << i;
if (intr0 & stat) {
- nvc0_ibus_intr_rop(priv, i);
+ gf100_ibus_intr_rop(priv, i);
intr0 &= ~stat;
}
}
@@ -88,36 +87,36 @@ nvc0_ibus_intr(struct nouveau_subdev *subdev)
for (i = 0; intr1 && i < gpcnr; i++) {
u32 stat = 0x00000001 << i;
if (intr1 & stat) {
- nvc0_ibus_intr_gpc(priv, i);
+ gf100_ibus_intr_gpc(priv, i);
intr1 &= ~stat;
}
}
}
static int
-nvc0_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_ibus_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_ibus_priv *priv;
+ struct gf100_ibus_priv *priv;
int ret;
- ret = nouveau_ibus_create(parent, engine, oclass, &priv);
+ ret = nvkm_ibus_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nv_subdev(priv)->intr = nvc0_ibus_intr;
+ nv_subdev(priv)->intr = gf100_ibus_intr;
return 0;
}
-struct nouveau_oclass
-nvc0_ibus_oclass = {
+struct nvkm_oclass
+gf100_ibus_oclass = {
.handle = NV_SUBDEV(IBUS, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_ibus_ctor,
- .dtor = _nouveau_ibus_dtor,
- .init = _nouveau_ibus_init,
- .fini = _nouveau_ibus_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_ibus_ctor,
+ .dtor = _nvkm_ibus_dtor,
+ .init = _nvkm_ibus_init,
+ .fini = _nvkm_ibus_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c
index ebef970a0645..7b6e9a6cd7b2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c
@@ -21,15 +21,14 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/ibus.h>
-struct nve0_ibus_priv {
- struct nouveau_ibus base;
+struct gk104_ibus_priv {
+ struct nvkm_ibus base;
};
static void
-nve0_ibus_intr_hub(struct nve0_ibus_priv *priv, int i)
+gk104_ibus_intr_hub(struct gk104_ibus_priv *priv, int i)
{
u32 addr = nv_rd32(priv, 0x122120 + (i * 0x0800));
u32 data = nv_rd32(priv, 0x122124 + (i * 0x0800));
@@ -39,7 +38,7 @@ nve0_ibus_intr_hub(struct nve0_ibus_priv *priv, int i)
}
static void
-nve0_ibus_intr_rop(struct nve0_ibus_priv *priv, int i)
+gk104_ibus_intr_rop(struct gk104_ibus_priv *priv, int i)
{
u32 addr = nv_rd32(priv, 0x124120 + (i * 0x0800));
u32 data = nv_rd32(priv, 0x124124 + (i * 0x0800));
@@ -49,7 +48,7 @@ nve0_ibus_intr_rop(struct nve0_ibus_priv *priv, int i)
}
static void
-nve0_ibus_intr_gpc(struct nve0_ibus_priv *priv, int i)
+gk104_ibus_intr_gpc(struct gk104_ibus_priv *priv, int i)
{
u32 addr = nv_rd32(priv, 0x128120 + (i * 0x0800));
u32 data = nv_rd32(priv, 0x128124 + (i * 0x0800));
@@ -59,9 +58,9 @@ nve0_ibus_intr_gpc(struct nve0_ibus_priv *priv, int i)
}
static void
-nve0_ibus_intr(struct nouveau_subdev *subdev)
+gk104_ibus_intr(struct nvkm_subdev *subdev)
{
- struct nve0_ibus_priv *priv = (void *)subdev;
+ struct gk104_ibus_priv *priv = (void *)subdev;
u32 intr0 = nv_rd32(priv, 0x120058);
u32 intr1 = nv_rd32(priv, 0x12005c);
u32 hubnr = nv_rd32(priv, 0x120070);
@@ -72,7 +71,7 @@ nve0_ibus_intr(struct nouveau_subdev *subdev)
for (i = 0; (intr0 & 0x0000ff00) && i < hubnr; i++) {
u32 stat = 0x00000100 << i;
if (intr0 & stat) {
- nve0_ibus_intr_hub(priv, i);
+ gk104_ibus_intr_hub(priv, i);
intr0 &= ~stat;
}
}
@@ -80,7 +79,7 @@ nve0_ibus_intr(struct nouveau_subdev *subdev)
for (i = 0; (intr0 & 0xffff0000) && i < ropnr; i++) {
u32 stat = 0x00010000 << i;
if (intr0 & stat) {
- nve0_ibus_intr_rop(priv, i);
+ gk104_ibus_intr_rop(priv, i);
intr0 &= ~stat;
}
}
@@ -88,17 +87,17 @@ nve0_ibus_intr(struct nouveau_subdev *subdev)
for (i = 0; intr1 && i < gpcnr; i++) {
u32 stat = 0x00000001 << i;
if (intr1 & stat) {
- nve0_ibus_intr_gpc(priv, i);
+ gk104_ibus_intr_gpc(priv, i);
intr1 &= ~stat;
}
}
}
static int
-nve0_ibus_init(struct nouveau_object *object)
+gk104_ibus_init(struct nvkm_object *object)
{
- struct nve0_ibus_priv *priv = (void *)object;
- int ret = nouveau_ibus_init(&priv->base);
+ struct gk104_ibus_priv *priv = (void *)object;
+ int ret = nvkm_ibus_init(&priv->base);
if (ret == 0) {
nv_mask(priv, 0x122318, 0x0003ffff, 0x00001000);
nv_mask(priv, 0x12231c, 0x0003ffff, 0x00000200);
@@ -112,29 +111,29 @@ nve0_ibus_init(struct nouveau_object *object)
}
static int
-nve0_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk104_ibus_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nve0_ibus_priv *priv;
+ struct gk104_ibus_priv *priv;
int ret;
- ret = nouveau_ibus_create(parent, engine, oclass, &priv);
+ ret = nvkm_ibus_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nv_subdev(priv)->intr = nve0_ibus_intr;
+ nv_subdev(priv)->intr = gk104_ibus_intr;
return 0;
}
-struct nouveau_oclass
-nve0_ibus_oclass = {
+struct nvkm_oclass
+gk104_ibus_oclass = {
.handle = NV_SUBDEV(IBUS, 0xe0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nve0_ibus_ctor,
- .dtor = _nouveau_ibus_dtor,
- .init = nve0_ibus_init,
- .fini = _nouveau_ibus_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk104_ibus_ctor,
+ .dtor = _nvkm_ibus_dtor,
+ .init = gk104_ibus_init,
+ .fini = _nvkm_ibus_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c
index 245f0ebaa6af..c0fdb89e74ac 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c
@@ -19,12 +19,11 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-
#include <subdev/ibus.h>
#include <subdev/timer.h>
struct gk20a_ibus_priv {
- struct nouveau_ibus base;
+ struct nvkm_ibus base;
};
static void
@@ -42,7 +41,7 @@ gk20a_ibus_init_priv_ring(struct gk20a_ibus_priv *priv)
}
static void
-gk20a_ibus_intr(struct nouveau_subdev *subdev)
+gk20a_ibus_intr(struct nvkm_subdev *subdev)
{
struct gk20a_ibus_priv *priv = (void *)subdev;
u32 status0 = nv_rd32(priv, 0x120058);
@@ -60,12 +59,12 @@ gk20a_ibus_intr(struct nouveau_subdev *subdev)
}
static int
-gk20a_ibus_init(struct nouveau_object *object)
+gk20a_ibus_init(struct nvkm_object *object)
{
struct gk20a_ibus_priv *priv = (void *)object;
int ret;
- ret = _nouveau_ibus_init(object);
+ ret = _nvkm_ibus_init(object);
if (ret)
return ret;
@@ -75,14 +74,14 @@ gk20a_ibus_init(struct nouveau_object *object)
}
static int
-gk20a_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk20a_ibus_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct gk20a_ibus_priv *priv;
int ret;
- ret = nouveau_ibus_create(parent, engine, oclass, &priv);
+ ret = nvkm_ibus_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -91,13 +90,13 @@ gk20a_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gk20a_ibus_oclass = {
.handle = NV_SUBDEV(IBUS, 0xea),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gk20a_ibus_ctor,
- .dtor = _nouveau_ibus_dtor,
+ .dtor = _nvkm_ibus_dtor,
.init = gk20a_ibus_init,
- .fini = _nouveau_ibus_fini,
+ .fini = _nvkm_ibus_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild
new file mode 100644
index 000000000000..e6f35abe7879
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/Kbuild
@@ -0,0 +1,4 @@
+nvkm-y += nvkm/subdev/instmem/base.o
+nvkm-y += nvkm/subdev/instmem/nv04.o
+nvkm-y += nvkm/subdev/instmem/nv40.o
+nvkm-y += nvkm/subdev/instmem/nv50.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
index 14706d9842ca..d16358cc6cbb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -21,38 +21,37 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
+#include <core/engine.h>
+
/******************************************************************************
* instmem object base implementation
*****************************************************************************/
void
-_nouveau_instobj_dtor(struct nouveau_object *object)
+_nvkm_instobj_dtor(struct nvkm_object *object)
{
- struct nouveau_instmem *imem = (void *)object->engine;
- struct nouveau_instobj *iobj = (void *)object;
+ struct nvkm_instmem *imem = nvkm_instmem(object);
+ struct nvkm_instobj *iobj = (void *)object;
mutex_lock(&nv_subdev(imem)->mutex);
list_del(&iobj->head);
mutex_unlock(&nv_subdev(imem)->mutex);
- return nouveau_object_destroy(&iobj->base);
+ return nvkm_object_destroy(&iobj->base);
}
int
-nouveau_instobj_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int length, void **pobject)
+nvkm_instobj_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_instmem *imem = (void *)engine;
- struct nouveau_instobj *iobj;
+ struct nvkm_instmem *imem = nvkm_instmem(parent);
+ struct nvkm_instobj *iobj;
int ret;
- ret = nouveau_object_create_(parent, engine, oclass, NV_MEMOBJ_CLASS,
- length, pobject);
+ ret = nvkm_object_create_(parent, engine, oclass, NV_MEMOBJ_CLASS,
+ length, pobject);
iobj = *pobject;
if (ret)
return ret;
@@ -68,27 +67,24 @@ nouveau_instobj_create_(struct nouveau_object *parent,
*****************************************************************************/
static int
-nouveau_instmem_alloc(struct nouveau_instmem *imem,
- struct nouveau_object *parent, u32 size, u32 align,
- struct nouveau_object **pobject)
+nvkm_instmem_alloc(struct nvkm_instmem *imem, struct nvkm_object *parent,
+ u32 size, u32 align, struct nvkm_object **pobject)
{
- struct nouveau_object *engine = nv_object(imem);
- struct nouveau_instmem_impl *impl = (void *)engine->oclass;
- struct nouveau_instobj_args args = { .size = size, .align = align };
- return nouveau_object_ctor(parent, engine, impl->instobj, &args,
- sizeof(args), pobject);
+ struct nvkm_instmem_impl *impl = (void *)imem->base.object.oclass;
+ struct nvkm_instobj_args args = { .size = size, .align = align };
+ return nvkm_object_ctor(parent, &parent->engine->subdev.object,
+ impl->instobj, &args, sizeof(args), pobject);
}
int
-_nouveau_instmem_fini(struct nouveau_object *object, bool suspend)
+_nvkm_instmem_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_instmem *imem = (void *)object;
- struct nouveau_instobj *iobj;
+ struct nvkm_instmem *imem = (void *)object;
+ struct nvkm_instobj *iobj;
int i, ret = 0;
if (suspend) {
mutex_lock(&imem->base.mutex);
-
list_for_each_entry(iobj, &imem->list, head) {
iobj->suspend = vmalloc(iobj->size);
if (!iobj->suspend) {
@@ -99,29 +95,26 @@ _nouveau_instmem_fini(struct nouveau_object *object, bool suspend)
for (i = 0; i < iobj->size; i += 4)
iobj->suspend[i / 4] = nv_ro32(iobj, i);
}
-
mutex_unlock(&imem->base.mutex);
-
if (ret)
return ret;
}
- return nouveau_subdev_fini(&imem->base, suspend);
+ return nvkm_subdev_fini(&imem->base, suspend);
}
int
-_nouveau_instmem_init(struct nouveau_object *object)
+_nvkm_instmem_init(struct nvkm_object *object)
{
- struct nouveau_instmem *imem = (void *)object;
- struct nouveau_instobj *iobj;
+ struct nvkm_instmem *imem = (void *)object;
+ struct nvkm_instobj *iobj;
int ret, i;
- ret = nouveau_subdev_init(&imem->base);
+ ret = nvkm_subdev_init(&imem->base);
if (ret)
return ret;
mutex_lock(&imem->base.mutex);
-
list_for_each_entry(iobj, &imem->list, head) {
if (iobj->suspend) {
for (i = 0; i < iobj->size; i += 4)
@@ -130,28 +123,24 @@ _nouveau_instmem_init(struct nouveau_object *object)
iobj->suspend = NULL;
}
}
-
mutex_unlock(&imem->base.mutex);
-
return 0;
}
int
-nouveau_instmem_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int length, void **pobject)
+nvkm_instmem_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_instmem *imem;
+ struct nvkm_instmem *imem;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0,
- "INSTMEM", "instmem", length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "INSTMEM",
+ "instmem", length, pobject);
imem = *pobject;
if (ret)
return ret;
INIT_LIST_HEAD(&imem->list);
- imem->alloc = nouveau_instmem_alloc;
+ imem->alloc = nvkm_instmem_alloc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
index e8b1401c59c0..80614f1b2074 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
@@ -21,56 +21,59 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
+#include <core/ramht.h>
+
/******************************************************************************
* instmem object implementation
*****************************************************************************/
static u32
-nv04_instobj_rd32(struct nouveau_object *object, u64 addr)
+nv04_instobj_rd32(struct nvkm_object *object, u64 addr)
{
+ struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object);
struct nv04_instobj_priv *node = (void *)object;
- return nv_ro32(object->engine, node->mem->offset + addr);
+ return nv_ro32(priv, node->mem->offset + addr);
}
static void
-nv04_instobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
+nv04_instobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
+ struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object);
struct nv04_instobj_priv *node = (void *)object;
- nv_wo32(object->engine, node->mem->offset + addr, data);
+ nv_wo32(priv, node->mem->offset + addr, data);
}
static void
-nv04_instobj_dtor(struct nouveau_object *object)
+nv04_instobj_dtor(struct nvkm_object *object)
{
- struct nv04_instmem_priv *priv = (void *)object->engine;
+ struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object);
struct nv04_instobj_priv *node = (void *)object;
- nouveau_mm_free(&priv->heap, &node->mem);
- nouveau_instobj_destroy(&node->base);
+ nvkm_mm_free(&priv->heap, &node->mem);
+ nvkm_instobj_destroy(&node->base);
}
static int
-nv04_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv04_instmem_priv *priv = (void *)engine;
+ struct nv04_instmem_priv *priv = (void *)nvkm_instmem(parent);
struct nv04_instobj_priv *node;
- struct nouveau_instobj_args *args = data;
+ struct nvkm_instobj_args *args = data;
int ret;
if (!args->align)
args->align = 1;
- ret = nouveau_instobj_create(parent, engine, oclass, &node);
+ ret = nvkm_instobj_create(parent, engine, oclass, &node);
*pobject = nv_object(node);
if (ret)
return ret;
- ret = nouveau_mm_head(&priv->heap, 0, 1, args->size, args->size,
- args->align, &node->mem);
+ ret = nvkm_mm_head(&priv->heap, 0, 1, args->size, args->size,
+ args->align, &node->mem);
if (ret)
return ret;
@@ -79,13 +82,13 @@ nv04_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_instobj_impl
+struct nvkm_instobj_impl
nv04_instobj_oclass = {
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_instobj_ctor,
.dtor = nv04_instobj_dtor,
- .init = _nouveau_instobj_init,
- .fini = _nouveau_instobj_fini,
+ .init = _nvkm_instobj_init,
+ .fini = _nvkm_instobj_fini,
.rd32 = nv04_instobj_rd32,
.wr32 = nv04_instobj_wr32,
},
@@ -96,40 +99,40 @@ nv04_instobj_oclass = {
*****************************************************************************/
static u32
-nv04_instmem_rd32(struct nouveau_object *object, u64 addr)
+nv04_instmem_rd32(struct nvkm_object *object, u64 addr)
{
return nv_rd32(object, 0x700000 + addr);
}
static void
-nv04_instmem_wr32(struct nouveau_object *object, u64 addr, u32 data)
+nv04_instmem_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
return nv_wr32(object, 0x700000 + addr, data);
}
void
-nv04_instmem_dtor(struct nouveau_object *object)
+nv04_instmem_dtor(struct nvkm_object *object)
{
struct nv04_instmem_priv *priv = (void *)object;
- nouveau_gpuobj_ref(NULL, &priv->ramfc);
- nouveau_gpuobj_ref(NULL, &priv->ramro);
- nouveau_ramht_ref(NULL, &priv->ramht);
- nouveau_gpuobj_ref(NULL, &priv->vbios);
- nouveau_mm_fini(&priv->heap);
+ nvkm_gpuobj_ref(NULL, &priv->ramfc);
+ nvkm_gpuobj_ref(NULL, &priv->ramro);
+ nvkm_ramht_ref(NULL, &priv->ramht);
+ nvkm_gpuobj_ref(NULL, &priv->vbios);
+ nvkm_mm_fini(&priv->heap);
if (priv->iomem)
iounmap(priv->iomem);
- nouveau_instmem_destroy(&priv->base);
+ nvkm_instmem_destroy(&priv->base);
}
static int
-nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_instmem_priv *priv;
int ret;
- ret = nouveau_instmem_create(parent, engine, oclass, &priv);
+ ret = nvkm_instmem_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -137,44 +140,44 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
/* PRAMIN aperture maps over the end of VRAM, reserve it */
priv->base.reserved = 512 * 1024;
- ret = nouveau_mm_init(&priv->heap, 0, priv->base.reserved, 1);
+ ret = nvkm_mm_init(&priv->heap, 0, priv->base.reserved, 1);
if (ret)
return ret;
/* 0x00000-0x10000: reserve for probable vbios image */
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
- &priv->vbios);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
+ &priv->vbios);
if (ret)
return ret;
/* 0x10000-0x18000: reserve for RAMHT */
- ret = nouveau_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
+ ret = nvkm_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
if (ret)
return ret;
/* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x00800, 0,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x00800, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
if (ret)
return ret;
/* 0x18800-0x18a00: reserve for RAMRO */
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x00200, 0, 0,
- &priv->ramro);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x00200, 0, 0,
+ &priv->ramro);
if (ret)
return ret;
return 0;
}
-struct nouveau_oclass *
-nv04_instmem_oclass = &(struct nouveau_instmem_impl) {
+struct nvkm_oclass *
+nv04_instmem_oclass = &(struct nvkm_instmem_impl) {
.base.handle = NV_SUBDEV(INSTMEM, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_instmem_ctor,
.dtor = nv04_instmem_dtor,
- .init = _nouveau_instmem_init,
- .fini = _nouveau_instmem_fini,
+ .init = _nvkm_instmem_init,
+ .fini = _nvkm_instmem_fini,
.rd32 = nv04_instmem_rd32,
.wr32 = nv04_instmem_wr32,
},
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h
new file mode 100644
index 000000000000..42b6c928047c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h
@@ -0,0 +1,36 @@
+#ifndef __NV04_INSTMEM_H__
+#define __NV04_INSTMEM_H__
+#include "priv.h"
+
+#include <core/mm.h>
+
+extern struct nvkm_instobj_impl nv04_instobj_oclass;
+
+struct nv04_instmem_priv {
+ struct nvkm_instmem base;
+
+ void __iomem *iomem;
+ struct nvkm_mm heap;
+
+ struct nvkm_gpuobj *vbios;
+ struct nvkm_ramht *ramht;
+ struct nvkm_gpuobj *ramro;
+ struct nvkm_gpuobj *ramfc;
+};
+
+static inline struct nv04_instmem_priv *
+nv04_instmem(void *obj)
+{
+ return (void *)nvkm_instmem(obj);
+}
+
+struct nv04_instobj_priv {
+ struct nvkm_instobj base;
+ struct nvkm_mm_node *mem;
+};
+
+void nv04_instmem_dtor(struct nvkm_object *);
+
+int nv04_instmem_alloc(struct nvkm_instmem *, struct nvkm_object *,
+ u32 size, u32 align, struct nvkm_object **pobject);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
index 8803809f9fc5..b42b8588fc0e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
@@ -21,39 +21,39 @@
*
* Authors: Ben Skeggs
*/
-
-#include <engine/graph/nv40.h>
-
#include "nv04.h"
+#include <core/ramht.h>
+#include <engine/gr/nv40.h>
+
/******************************************************************************
* instmem subdev implementation
*****************************************************************************/
static u32
-nv40_instmem_rd32(struct nouveau_object *object, u64 addr)
+nv40_instmem_rd32(struct nvkm_object *object, u64 addr)
{
struct nv04_instmem_priv *priv = (void *)object;
return ioread32_native(priv->iomem + addr);
}
static void
-nv40_instmem_wr32(struct nouveau_object *object, u64 addr, u32 data)
+nv40_instmem_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
struct nv04_instmem_priv *priv = (void *)object;
iowrite32_native(data, priv->iomem + addr);
}
static int
-nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_device *device = nv_device(parent);
+ struct nvkm_device *device = nv_device(parent);
struct nv04_instmem_priv *priv;
int ret, bar, vs;
- ret = nouveau_instmem_create(parent, engine, oclass, &priv);
+ ret = nvkm_instmem_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -73,12 +73,12 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
/* PRAMIN aperture maps over the end of vram, reserve enough space
* to fit graphics contexts for every channel, the magics come
- * from engine/graph/nv40.c
+ * from engine/gr/nv40.c
*/
vs = hweight8((nv_rd32(priv, 0x001540) & 0x0000ff00) >> 8);
if (device->chipset == 0x40) priv->base.reserved = 0x6aa0 * vs;
else if (device->chipset < 0x43) priv->base.reserved = 0x4f00 * vs;
- else if (nv44_graph_class(priv)) priv->base.reserved = 0x4980 * vs;
+ else if (nv44_gr_class(priv)) priv->base.reserved = 0x4980 * vs;
else priv->base.reserved = 0x4a40 * vs;
priv->base.reserved += 16 * 1024;
priv->base.reserved *= 32; /* per-channel */
@@ -87,49 +87,48 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.reserved = round_up(priv->base.reserved, 4096);
- ret = nouveau_mm_init(&priv->heap, 0, priv->base.reserved, 1);
+ ret = nvkm_mm_init(&priv->heap, 0, priv->base.reserved, 1);
if (ret)
return ret;
/* 0x00000-0x10000: reserve for probable vbios image */
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
- &priv->vbios);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
+ &priv->vbios);
if (ret)
return ret;
/* 0x10000-0x18000: reserve for RAMHT */
- ret = nouveau_ramht_new(nv_object(priv), NULL, 0x08000, 0,
- &priv->ramht);
+ ret = nvkm_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
if (ret)
return ret;
/* 0x18000-0x18200: reserve for RAMRO
* 0x18200-0x20000: padding
*/
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x08000, 0, 0,
- &priv->ramro);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x08000, 0, 0,
+ &priv->ramro);
if (ret)
return ret;
/* 0x20000-0x21000: reserve for RAMFC
* 0x21000-0x40000: padding and some unknown crap
*/
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
if (ret)
return ret;
return 0;
}
-struct nouveau_oclass *
-nv40_instmem_oclass = &(struct nouveau_instmem_impl) {
+struct nvkm_oclass *
+nv40_instmem_oclass = &(struct nvkm_instmem_impl) {
.base.handle = NV_SUBDEV(INSTMEM, 0x40),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv40_instmem_ctor,
.dtor = nv04_instmem_dtor,
- .init = _nouveau_instmem_init,
- .fini = _nouveau_instmem_fini,
+ .init = _nvkm_instmem_init,
+ .fini = _nvkm_instmem_fini,
.rd32 = nv40_instmem_rd32,
.wr32 = nv40_instmem_wr32,
},
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
index 7cb3b098a08d..8404143f93ee 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -21,21 +21,19 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/fb.h>
-#include <core/mm.h>
-
-#include "priv.h"
struct nv50_instmem_priv {
- struct nouveau_instmem base;
+ struct nvkm_instmem base;
spinlock_t lock;
u64 addr;
};
struct nv50_instobj_priv {
- struct nouveau_instobj base;
- struct nouveau_mem *mem;
+ struct nvkm_instobj base;
+ struct nvkm_mem *mem;
};
/******************************************************************************
@@ -43,9 +41,9 @@ struct nv50_instobj_priv {
*****************************************************************************/
static u32
-nv50_instobj_rd32(struct nouveau_object *object, u64 offset)
+nv50_instobj_rd32(struct nvkm_object *object, u64 offset)
{
- struct nv50_instmem_priv *priv = (void *)object->engine;
+ struct nv50_instmem_priv *priv = (void *)nvkm_instmem(object);
struct nv50_instobj_priv *node = (void *)object;
unsigned long flags;
u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
@@ -63,9 +61,9 @@ nv50_instobj_rd32(struct nouveau_object *object, u64 offset)
}
static void
-nv50_instobj_wr32(struct nouveau_object *object, u64 offset, u32 data)
+nv50_instobj_wr32(struct nvkm_object *object, u64 offset, u32 data)
{
- struct nv50_instmem_priv *priv = (void *)object->engine;
+ struct nv50_instmem_priv *priv = (void *)nvkm_instmem(object);
struct nv50_instobj_priv *node = (void *)object;
unsigned long flags;
u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
@@ -81,28 +79,28 @@ nv50_instobj_wr32(struct nouveau_object *object, u64 offset, u32 data)
}
static void
-nv50_instobj_dtor(struct nouveau_object *object)
+nv50_instobj_dtor(struct nvkm_object *object)
{
struct nv50_instobj_priv *node = (void *)object;
- struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nvkm_fb *pfb = nvkm_fb(object);
pfb->ram->put(pfb, &node->mem);
- nouveau_instobj_destroy(&node->base);
+ nvkm_instobj_destroy(&node->base);
}
static int
-nv50_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
- struct nouveau_instobj_args *args = data;
+ struct nvkm_fb *pfb = nvkm_fb(parent);
+ struct nvkm_instobj_args *args = data;
struct nv50_instobj_priv *node;
int ret;
args->size = max((args->size + 4095) & ~4095, (u32)4096);
args->align = max((args->align + 4095) & ~4095, (u32)4096);
- ret = nouveau_instobj_create(parent, engine, oclass, &node);
+ ret = nvkm_instobj_create(parent, engine, oclass, &node);
*pobject = nv_object(node);
if (ret)
return ret;
@@ -117,13 +115,13 @@ nv50_instobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-static struct nouveau_instobj_impl
+static struct nvkm_instobj_impl
nv50_instobj_oclass = {
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_instobj_ctor,
.dtor = nv50_instobj_dtor,
- .init = _nouveau_instobj_init,
- .fini = _nouveau_instobj_fini,
+ .init = _nvkm_instobj_init,
+ .fini = _nvkm_instobj_fini,
.rd32 = nv50_instobj_rd32,
.wr32 = nv50_instobj_wr32,
},
@@ -134,22 +132,22 @@ nv50_instobj_oclass = {
*****************************************************************************/
static int
-nv50_instmem_fini(struct nouveau_object *object, bool suspend)
+nv50_instmem_fini(struct nvkm_object *object, bool suspend)
{
struct nv50_instmem_priv *priv = (void *)object;
priv->addr = ~0ULL;
- return nouveau_instmem_fini(&priv->base, suspend);
+ return nvkm_instmem_fini(&priv->base, suspend);
}
static int
-nv50_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_instmem_priv *priv;
int ret;
- ret = nouveau_instmem_create(parent, engine, oclass, &priv);
+ ret = nvkm_instmem_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -158,13 +156,13 @@ nv50_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv50_instmem_oclass = &(struct nouveau_instmem_impl) {
+struct nvkm_oclass *
+nv50_instmem_oclass = &(struct nvkm_instmem_impl) {
.base.handle = NV_SUBDEV(INSTMEM, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_instmem_ctor,
- .dtor = _nouveau_instmem_dtor,
- .init = _nouveau_instmem_init,
+ .dtor = _nvkm_instmem_dtor,
+ .init = _nvkm_instmem_init,
.fini = nv50_instmem_fini,
},
.instobj = &nv50_instobj_oclass.base,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
new file mode 100644
index 000000000000..b10e292e5607
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
@@ -0,0 +1,54 @@
+#ifndef __NVKM_INSTMEM_PRIV_H__
+#define __NVKM_INSTMEM_PRIV_H__
+#include <subdev/instmem.h>
+
+struct nvkm_instobj_impl {
+ struct nvkm_oclass base;
+};
+
+struct nvkm_instobj_args {
+ u32 size;
+ u32 align;
+};
+
+#define nvkm_instobj_create(p,e,o,d) \
+ nvkm_instobj_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_instobj_destroy(p) ({ \
+ struct nvkm_instobj *iobj = (p); \
+ _nvkm_instobj_dtor(nv_object(iobj)); \
+})
+#define nvkm_instobj_init(p) \
+ nvkm_object_init(&(p)->base)
+#define nvkm_instobj_fini(p,s) \
+ nvkm_object_fini(&(p)->base, (s))
+
+int nvkm_instobj_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_instobj_dtor(struct nvkm_object *);
+#define _nvkm_instobj_init nvkm_object_init
+#define _nvkm_instobj_fini nvkm_object_fini
+
+struct nvkm_instmem_impl {
+ struct nvkm_oclass base;
+ struct nvkm_oclass *instobj;
+};
+
+#define nvkm_instmem_create(p,e,o,d) \
+ nvkm_instmem_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_instmem_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_instmem_init(p) ({ \
+ struct nvkm_instmem *imem = (p); \
+ _nvkm_instmem_init(nv_object(imem)); \
+})
+#define nvkm_instmem_fini(p,s) ({ \
+ struct nvkm_instmem *imem = (p); \
+ _nvkm_instmem_fini(nv_object(imem), (s)); \
+})
+
+int nvkm_instmem_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+#define _nvkm_instmem_dtor _nvkm_subdev_dtor
+int _nvkm_instmem_init(struct nvkm_object *);
+int _nvkm_instmem_fini(struct nvkm_object *, bool);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild
new file mode 100644
index 000000000000..e5df3d865f0c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild
@@ -0,0 +1,4 @@
+nvkm-y += nvkm/subdev/ltc/base.o
+nvkm-y += nvkm/subdev/ltc/gf100.o
+nvkm-y += nvkm/subdev/ltc/gk104.o
+nvkm-y += nvkm/subdev/ltc/gm107.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
index 7fa331516f84..2fb87fbfd11c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
@@ -21,17 +21,15 @@
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-
#include "priv.h"
static int
-nvkm_ltc_tags_alloc(struct nouveau_ltc *ltc, u32 n,
- struct nouveau_mm_node **pnode)
+nvkm_ltc_tags_alloc(struct nvkm_ltc *ltc, u32 n, struct nvkm_mm_node **pnode)
{
struct nvkm_ltc_priv *priv = (void *)ltc;
int ret;
- ret = nouveau_mm_head(&priv->tags, 0, 1, n, n, 1, pnode);
+ ret = nvkm_mm_head(&priv->tags, 0, 1, n, n, 1, pnode);
if (ret)
*pnode = NULL;
@@ -39,14 +37,14 @@ nvkm_ltc_tags_alloc(struct nouveau_ltc *ltc, u32 n,
}
static void
-nvkm_ltc_tags_free(struct nouveau_ltc *ltc, struct nouveau_mm_node **pnode)
+nvkm_ltc_tags_free(struct nvkm_ltc *ltc, struct nvkm_mm_node **pnode)
{
struct nvkm_ltc_priv *priv = (void *)ltc;
- nouveau_mm_free(&priv->tags, pnode);
+ nvkm_mm_free(&priv->tags, pnode);
}
static void
-nvkm_ltc_tags_clear(struct nouveau_ltc *ltc, u32 first, u32 count)
+nvkm_ltc_tags_clear(struct nvkm_ltc *ltc, u32 first, u32 count)
{
const struct nvkm_ltc_impl *impl = (void *)nv_oclass(ltc);
struct nvkm_ltc_priv *priv = (void *)ltc;
@@ -59,7 +57,7 @@ nvkm_ltc_tags_clear(struct nouveau_ltc *ltc, u32 first, u32 count)
}
static int
-nvkm_ltc_zbc_color_get(struct nouveau_ltc *ltc, int index, const u32 color[4])
+nvkm_ltc_zbc_color_get(struct nvkm_ltc *ltc, int index, const u32 color[4])
{
const struct nvkm_ltc_impl *impl = (void *)nv_oclass(ltc);
struct nvkm_ltc_priv *priv = (void *)ltc;
@@ -69,7 +67,7 @@ nvkm_ltc_zbc_color_get(struct nouveau_ltc *ltc, int index, const u32 color[4])
}
static int
-nvkm_ltc_zbc_depth_get(struct nouveau_ltc *ltc, int index, const u32 depth)
+nvkm_ltc_zbc_depth_get(struct nvkm_ltc *ltc, int index, const u32 depth)
{
const struct nvkm_ltc_impl *impl = (void *)nv_oclass(ltc);
struct nvkm_ltc_priv *priv = (void *)ltc;
@@ -79,13 +77,13 @@ nvkm_ltc_zbc_depth_get(struct nouveau_ltc *ltc, int index, const u32 depth)
}
int
-_nvkm_ltc_init(struct nouveau_object *object)
+_nvkm_ltc_init(struct nvkm_object *object)
{
const struct nvkm_ltc_impl *impl = (void *)nv_oclass(object);
struct nvkm_ltc_priv *priv = (void *)object;
int ret, i;
- ret = nouveau_subdev_init(&priv->base.base);
+ ret = nvkm_subdev_init(&priv->base.base);
if (ret)
return ret;
@@ -98,15 +96,15 @@ _nvkm_ltc_init(struct nouveau_object *object)
}
int
-nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+nvkm_ltc_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
const struct nvkm_ltc_impl *impl = (void *)oclass;
struct nvkm_ltc_priv *priv;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PLTCG",
- "l2c", length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "PLTCG",
+ "l2c", length, pobject);
priv = *pobject;
if (ret)
return ret;
@@ -119,7 +117,7 @@ nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.tags_free = nvkm_ltc_tags_free;
priv->base.tags_clear = nvkm_ltc_tags_clear;
priv->base.zbc_min = 1; /* reserve 0 for disabled */
- priv->base.zbc_max = min(impl->zbc, NOUVEAU_LTC_MAX_ZBC_CNT) - 1;
+ priv->base.zbc_max = min(impl->zbc, NVKM_LTC_MAX_ZBC_CNT) - 1;
priv->base.zbc_color_get = nvkm_ltc_zbc_color_get;
priv->base.zbc_depth_get = nvkm_ltc_zbc_depth_get;
return 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c
index 2db0977284f8..8e7cc6200d60 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c
@@ -21,12 +21,12 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
+#include <core/enum.h>
#include <subdev/fb.h>
#include <subdev/timer.h>
-#include "priv.h"
-
void
gf100_ltc_cbc_clear(struct nvkm_ltc_priv *priv, u32 start, u32 limit)
{
@@ -62,7 +62,7 @@ gf100_ltc_zbc_clear_depth(struct nvkm_ltc_priv *priv, int i, const u32 depth)
nv_wr32(priv, 0x17ea58, depth);
}
-static const struct nouveau_bitfield
+static const struct nvkm_bitfield
gf100_ltc_lts_intr_name[] = {
{ 0x00000001, "IDLE_ERROR_IQ" },
{ 0x00000002, "IDLE_ERROR_CBC" },
@@ -89,7 +89,7 @@ gf100_ltc_lts_intr(struct nvkm_ltc_priv *priv, int ltc, int lts)
if (stat) {
nv_info(priv, "LTC%d_LTS%d:", ltc, lts);
- nouveau_bitfield_print(gf100_ltc_lts_intr_name, stat);
+ nvkm_bitfield_print(gf100_ltc_lts_intr_name, stat);
pr_cont("\n");
}
@@ -97,7 +97,7 @@ gf100_ltc_lts_intr(struct nvkm_ltc_priv *priv, int ltc, int lts)
}
void
-gf100_ltc_intr(struct nouveau_subdev *subdev)
+gf100_ltc_intr(struct nvkm_subdev *subdev)
{
struct nvkm_ltc_priv *priv = (void *)subdev;
u32 mask;
@@ -112,7 +112,7 @@ gf100_ltc_intr(struct nouveau_subdev *subdev)
}
static int
-gf100_ltc_init(struct nouveau_object *object)
+gf100_ltc_init(struct nvkm_object *object)
{
struct nvkm_ltc_priv *priv = (void *)object;
u32 lpg128 = !(nv_rd32(priv, 0x100c80) & 0x00000001);
@@ -130,13 +130,13 @@ gf100_ltc_init(struct nouveau_object *object)
}
void
-gf100_ltc_dtor(struct nouveau_object *object)
+gf100_ltc_dtor(struct nvkm_object *object)
{
- struct nouveau_fb *pfb = nouveau_fb(object);
+ struct nvkm_fb *pfb = nvkm_fb(object);
struct nvkm_ltc_priv *priv = (void *)object;
- nouveau_mm_fini(&priv->tags);
- nouveau_mm_free(&pfb->vram, &priv->tag_ram);
+ nvkm_mm_fini(&priv->tags);
+ nvkm_mm_free(&pfb->vram, &priv->tag_ram);
nvkm_ltc_destroy(priv);
}
@@ -144,7 +144,7 @@ gf100_ltc_dtor(struct nouveau_object *object)
/* TODO: Figure out tag memory details and drop the over-cautious allocation.
*/
int
-gf100_ltc_init_tag_ram(struct nouveau_fb *pfb, struct nvkm_ltc_priv *priv)
+gf100_ltc_init_tag_ram(struct nvkm_fb *pfb, struct nvkm_ltc_priv *priv)
{
u32 tag_size, tag_margin, tag_align;
int ret;
@@ -170,8 +170,8 @@ gf100_ltc_init_tag_ram(struct nouveau_fb *pfb, struct nvkm_ltc_priv *priv)
tag_size += tag_align;
tag_size = (tag_size + 0xfff) >> 12; /* round up */
- ret = nouveau_mm_tail(&pfb->vram, 1, 1, tag_size, tag_size, 1,
- &priv->tag_ram);
+ ret = nvkm_mm_tail(&pfb->vram, 1, 1, tag_size, tag_size, 1,
+ &priv->tag_ram);
if (ret) {
priv->num_tags = 0;
} else {
@@ -183,16 +183,16 @@ gf100_ltc_init_tag_ram(struct nouveau_fb *pfb, struct nvkm_ltc_priv *priv)
priv->tag_base = tag_base;
}
- ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
+ ret = nvkm_mm_init(&priv->tags, 0, priv->num_tags, 1);
return ret;
}
int
-gf100_ltc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_ltc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
struct nvkm_ltc_priv *priv;
u32 parts, mask;
int ret, i;
@@ -218,10 +218,10 @@ gf100_ltc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
gf100_ltc_oclass = &(struct nvkm_ltc_impl) {
.base.handle = NV_SUBDEV(LTC, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gf100_ltc_ctor,
.dtor = gf100_ltc_dtor,
.init = gf100_ltc_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c
index b39b5d0eb8f9..d53959b5ec67 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c
@@ -21,11 +21,10 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
static int
-gk104_ltc_init(struct nouveau_object *object)
+gk104_ltc_init(struct nvkm_object *object)
{
struct nvkm_ltc_priv *priv = (void *)object;
u32 lpg128 = !(nv_rd32(priv, 0x100c80) & 0x00000001);
@@ -42,10 +41,10 @@ gk104_ltc_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
gk104_ltc_oclass = &(struct nvkm_ltc_impl) {
.base.handle = NV_SUBDEV(LTC, 0xe4),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gf100_ltc_ctor,
.dtor = gf100_ltc_dtor,
.init = gk104_ltc_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
index 89fc4238f50c..6b3f6f4ce107 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
@@ -21,12 +21,11 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
#include <subdev/fb.h>
#include <subdev/timer.h>
-#include "priv.h"
-
static void
gm107_ltc_cbc_clear(struct nvkm_ltc_priv *priv, u32 start, u32 limit)
{
@@ -75,7 +74,7 @@ gm107_ltc_lts_isr(struct nvkm_ltc_priv *priv, int ltc, int lts)
}
static void
-gm107_ltc_intr(struct nouveau_subdev *subdev)
+gm107_ltc_intr(struct nvkm_subdev *subdev)
{
struct nvkm_ltc_priv *priv = (void *)subdev;
u32 mask;
@@ -90,7 +89,7 @@ gm107_ltc_intr(struct nouveau_subdev *subdev)
}
static int
-gm107_ltc_init(struct nouveau_object *object)
+gm107_ltc_init(struct nvkm_object *object)
{
struct nvkm_ltc_priv *priv = (void *)object;
u32 lpg128 = !(nv_rd32(priv, 0x100c80) & 0x00000001);
@@ -107,11 +106,11 @@ gm107_ltc_init(struct nouveau_object *object)
}
static int
-gm107_ltc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gm107_ltc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nvkm_fb *pfb = nvkm_fb(parent);
struct nvkm_ltc_priv *priv;
u32 parts, mask;
int ret, i;
@@ -136,10 +135,10 @@ gm107_ltc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
+struct nvkm_oclass *
gm107_ltc_oclass = &(struct nvkm_ltc_impl) {
.base.handle = NV_SUBDEV(LTC, 0xff),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm107_ltc_ctor,
.dtor = gf100_ltc_dtor,
.init = gm107_ltc_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h
index 41f179d93da6..09537d7b6783 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltc/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h
@@ -1,23 +1,22 @@
#ifndef __NVKM_LTC_PRIV_H__
#define __NVKM_LTC_PRIV_H__
-
#include <subdev/ltc.h>
-#include <subdev/fb.h>
-#include <core/enum.h>
+#include <core/mm.h>
+struct nvkm_fb;
struct nvkm_ltc_priv {
- struct nouveau_ltc base;
+ struct nvkm_ltc base;
u32 ltc_nr;
u32 lts_nr;
u32 num_tags;
u32 tag_base;
- struct nouveau_mm tags;
- struct nouveau_mm_node *tag_ram;
+ struct nvkm_mm tags;
+ struct nvkm_mm_node *tag_ram;
- u32 zbc_color[NOUVEAU_LTC_MAX_ZBC_CNT][4];
- u32 zbc_depth[NOUVEAU_LTC_MAX_ZBC_CNT];
+ u32 zbc_color[NVKM_LTC_MAX_ZBC_CNT][4];
+ u32 zbc_depth[NVKM_LTC_MAX_ZBC_CNT];
};
#define nvkm_ltc_create(p,e,o,d) \
@@ -35,24 +34,24 @@ struct nvkm_ltc_priv {
_nvkm_ltc_fini(nv_object(_priv), (s)); \
})
-int nvkm_ltc_create_(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, int, void **);
+int nvkm_ltc_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
-#define _nvkm_ltc_dtor _nouveau_subdev_dtor
-int _nvkm_ltc_init(struct nouveau_object *);
-#define _nvkm_ltc_fini _nouveau_subdev_fini
+#define _nvkm_ltc_dtor _nvkm_subdev_dtor
+int _nvkm_ltc_init(struct nvkm_object *);
+#define _nvkm_ltc_fini _nvkm_subdev_fini
-int gf100_ltc_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void gf100_ltc_dtor(struct nouveau_object *);
-int gf100_ltc_init_tag_ram(struct nouveau_fb *, struct nvkm_ltc_priv *);
-int gf100_ltc_tags_alloc(struct nouveau_ltc *, u32, struct nouveau_mm_node **);
-void gf100_ltc_tags_free(struct nouveau_ltc *, struct nouveau_mm_node **);
+int gf100_ltc_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void gf100_ltc_dtor(struct nvkm_object *);
+int gf100_ltc_init_tag_ram(struct nvkm_fb *, struct nvkm_ltc_priv *);
+int gf100_ltc_tags_alloc(struct nvkm_ltc *, u32, struct nvkm_mm_node **);
+void gf100_ltc_tags_free(struct nvkm_ltc *, struct nvkm_mm_node **);
struct nvkm_ltc_impl {
- struct nouveau_oclass base;
- void (*intr)(struct nouveau_subdev *);
+ struct nvkm_oclass base;
+ void (*intr)(struct nvkm_subdev *);
void (*cbc_clear)(struct nvkm_ltc_priv *, u32 start, u32 limit);
void (*cbc_wait)(struct nvkm_ltc_priv *);
@@ -62,10 +61,9 @@ struct nvkm_ltc_impl {
void (*zbc_clear_depth)(struct nvkm_ltc_priv *, int, const u32);
};
-void gf100_ltc_intr(struct nouveau_subdev *);
+void gf100_ltc_intr(struct nvkm_subdev *);
void gf100_ltc_cbc_clear(struct nvkm_ltc_priv *, u32, u32);
void gf100_ltc_cbc_wait(struct nvkm_ltc_priv *);
void gf100_ltc_zbc_clear_color(struct nvkm_ltc_priv *, int, const u32[4]);
void gf100_ltc_zbc_clear_depth(struct nvkm_ltc_priv *, int, const u32);
-
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
new file mode 100644
index 000000000000..721643f04bb5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
@@ -0,0 +1,11 @@
+nvkm-y += nvkm/subdev/mc/base.o
+nvkm-y += nvkm/subdev/mc/nv04.o
+nvkm-y += nvkm/subdev/mc/nv40.o
+nvkm-y += nvkm/subdev/mc/nv44.o
+nvkm-y += nvkm/subdev/mc/nv4c.o
+nvkm-y += nvkm/subdev/mc/nv50.o
+nvkm-y += nvkm/subdev/mc/g94.o
+nvkm-y += nvkm/subdev/mc/g98.o
+nvkm-y += nvkm/subdev/mc/gf100.o
+nvkm-y += nvkm/subdev/mc/gf106.o
+nvkm-y += nvkm/subdev/mc/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
index ca7cee3a314a..5b051a26653e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
@@ -21,20 +21,21 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
+
+#include <core/device.h>
#include <core/option.h>
static inline void
-nouveau_mc_unk260(struct nouveau_mc *pmc, u32 data)
+nvkm_mc_unk260(struct nvkm_mc *pmc, u32 data)
{
- const struct nouveau_mc_oclass *impl = (void *)nv_oclass(pmc);
+ const struct nvkm_mc_oclass *impl = (void *)nv_oclass(pmc);
if (impl->unk260)
impl->unk260(pmc, data);
}
static inline u32
-nouveau_mc_intr_mask(struct nouveau_mc *pmc)
+nvkm_mc_intr_mask(struct nvkm_mc *pmc)
{
u32 intr = nv_rd32(pmc, 0x000100);
if (intr == 0xffffffff) /* likely fallen off the bus */
@@ -43,25 +44,25 @@ nouveau_mc_intr_mask(struct nouveau_mc *pmc)
}
static irqreturn_t
-nouveau_mc_intr(int irq, void *arg)
+nvkm_mc_intr(int irq, void *arg)
{
- struct nouveau_mc *pmc = arg;
- const struct nouveau_mc_oclass *oclass = (void *)nv_object(pmc)->oclass;
- const struct nouveau_mc_intr *map = oclass->intr;
- struct nouveau_subdev *unit;
+ struct nvkm_mc *pmc = arg;
+ const struct nvkm_mc_oclass *oclass = (void *)nv_object(pmc)->oclass;
+ const struct nvkm_mc_intr *map = oclass->intr;
+ struct nvkm_subdev *unit;
u32 intr;
nv_wr32(pmc, 0x000140, 0x00000000);
nv_rd32(pmc, 0x000140);
- intr = nouveau_mc_intr_mask(pmc);
+ intr = nvkm_mc_intr_mask(pmc);
if (pmc->use_msi)
oclass->msi_rearm(pmc);
if (intr) {
- u32 stat = intr = nouveau_mc_intr_mask(pmc);
+ u32 stat = intr = nvkm_mc_intr_mask(pmc);
while (map->stat) {
if (intr & map->stat) {
- unit = nouveau_subdev(pmc, map->unit);
+ unit = nvkm_subdev(pmc, map->unit);
if (unit && unit->intr)
unit->intr(unit);
stat &= ~map->stat;
@@ -78,18 +79,18 @@ nouveau_mc_intr(int irq, void *arg)
}
int
-_nouveau_mc_fini(struct nouveau_object *object, bool suspend)
+_nvkm_mc_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_mc *pmc = (void *)object;
+ struct nvkm_mc *pmc = (void *)object;
nv_wr32(pmc, 0x000140, 0x00000000);
- return nouveau_subdev_fini(&pmc->base, suspend);
+ return nvkm_subdev_fini(&pmc->base, suspend);
}
int
-_nouveau_mc_init(struct nouveau_object *object)
+_nvkm_mc_init(struct nvkm_object *object)
{
- struct nouveau_mc *pmc = (void *)object;
- int ret = nouveau_subdev_init(&pmc->base);
+ struct nvkm_mc *pmc = (void *)object;
+ int ret = nvkm_subdev_init(&pmc->base);
if (ret)
return ret;
nv_wr32(pmc, 0x000140, 0x00000001);
@@ -97,34 +98,34 @@ _nouveau_mc_init(struct nouveau_object *object)
}
void
-_nouveau_mc_dtor(struct nouveau_object *object)
+_nvkm_mc_dtor(struct nvkm_object *object)
{
- struct nouveau_device *device = nv_device(object);
- struct nouveau_mc *pmc = (void *)object;
+ struct nvkm_device *device = nv_device(object);
+ struct nvkm_mc *pmc = (void *)object;
free_irq(pmc->irq, pmc);
if (pmc->use_msi)
pci_disable_msi(device->pdev);
- nouveau_subdev_destroy(&pmc->base);
+ nvkm_subdev_destroy(&pmc->base);
}
int
-nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *bclass, int length, void **pobject)
+nvkm_mc_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *bclass, int length, void **pobject)
{
- const struct nouveau_mc_oclass *oclass = (void *)bclass;
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_mc *pmc;
+ const struct nvkm_mc_oclass *oclass = (void *)bclass;
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_mc *pmc;
int ret;
- ret = nouveau_subdev_create_(parent, engine, bclass, 0, "PMC",
- "master", length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, bclass, 0, "PMC",
+ "master", length, pobject);
pmc = *pobject;
if (ret)
return ret;
- pmc->unk260 = nouveau_mc_unk260;
+ pmc->unk260 = nvkm_mc_unk260;
- if (nv_device_is_pci(device))
+ if (nv_device_is_pci(device)) {
switch (device->pdev->device & 0x0ff0) {
case 0x00f0:
case 0x02e0:
@@ -138,10 +139,11 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
default:
pmc->use_msi = true;
break;
+ }
}
- pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI",
- pmc->use_msi);
+ pmc->use_msi = nvkm_boolopt(device->cfgopt, "NvMSI",
+ pmc->use_msi);
if (pmc->use_msi && oclass->msi_rearm) {
pmc->use_msi = pci_enable_msi(device->pdev) == 0;
@@ -159,9 +161,7 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
pmc->irq = ret;
- ret = request_irq(pmc->irq, nouveau_mc_intr, IRQF_SHARED, "nouveau",
- pmc);
-
+ ret = request_irq(pmc->irq, nvkm_mc_intr, IRQF_SHARED, "nvkm", pmc);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c
index 5f4541105e73..f042e7d8321d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c
@@ -21,17 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-struct nouveau_oclass *
-nv94_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+g94_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0x94),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
.intr = nv50_mc_intr,
.msi_rearm = nv40_mc_msi_rearm,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
index 3c76d9038f38..8ab7f1272a14 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
@@ -21,39 +21,38 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-static const struct nouveau_mc_intr
-nv98_mc_intr[] = {
+static const struct nvkm_mc_intr
+g98_mc_intr[] = {
{ 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */
- { 0x00000001, NVDEV_ENGINE_PPP },
+ { 0x00000001, NVDEV_ENGINE_MSPPP },
{ 0x00000100, NVDEV_ENGINE_FIFO },
{ 0x00001000, NVDEV_ENGINE_GR },
- { 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84:NVA3 */
- { 0x00008000, NVDEV_ENGINE_BSP },
- { 0x00020000, NVDEV_ENGINE_VP },
- { 0x00040000, NVDEV_SUBDEV_PWR }, /* NVA3:NVC0 */
+ { 0x00004000, NVDEV_ENGINE_SEC }, /* NV84:NVA3 */
+ { 0x00008000, NVDEV_ENGINE_MSVLD },
+ { 0x00020000, NVDEV_ENGINE_MSPDEC },
+ { 0x00040000, NVDEV_SUBDEV_PMU }, /* NVA3:NVC0 */
{ 0x00080000, NVDEV_SUBDEV_THERM }, /* NVA3:NVC0 */
{ 0x00100000, NVDEV_SUBDEV_TIMER },
{ 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */
{ 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */
- { 0x00400000, NVDEV_ENGINE_COPY0 }, /* NVA3- */
+ { 0x00400000, NVDEV_ENGINE_CE0 }, /* NVA3- */
{ 0x10000000, NVDEV_SUBDEV_BUS },
{ 0x80000000, NVDEV_ENGINE_SW },
{ 0x0042d101, NVDEV_SUBDEV_FB },
{},
};
-struct nouveau_oclass *
-nv98_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+g98_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0x98),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
- .intr = nv98_mc_intr,
+ .intr = g98_mc_intr,
.msi_rearm = nv40_mc_msi_rearm,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
index 15d41dc176ff..2425984b045e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
@@ -21,26 +21,25 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-const struct nouveau_mc_intr
-nvc0_mc_intr[] = {
+const struct nvkm_mc_intr
+gf100_mc_intr[] = {
{ 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */
- { 0x00000001, NVDEV_ENGINE_PPP },
- { 0x00000020, NVDEV_ENGINE_COPY0 },
- { 0x00000040, NVDEV_ENGINE_COPY1 },
- { 0x00000080, NVDEV_ENGINE_COPY2 },
+ { 0x00000001, NVDEV_ENGINE_MSPPP },
+ { 0x00000020, NVDEV_ENGINE_CE0 },
+ { 0x00000040, NVDEV_ENGINE_CE1 },
+ { 0x00000080, NVDEV_ENGINE_CE2 },
{ 0x00000100, NVDEV_ENGINE_FIFO },
{ 0x00001000, NVDEV_ENGINE_GR },
{ 0x00002000, NVDEV_SUBDEV_FB },
- { 0x00008000, NVDEV_ENGINE_BSP },
+ { 0x00008000, NVDEV_ENGINE_MSVLD },
{ 0x00040000, NVDEV_SUBDEV_THERM },
- { 0x00020000, NVDEV_ENGINE_VP },
+ { 0x00020000, NVDEV_ENGINE_MSPDEC },
{ 0x00100000, NVDEV_SUBDEV_TIMER },
{ 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */
{ 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */
- { 0x01000000, NVDEV_SUBDEV_PWR },
+ { 0x01000000, NVDEV_SUBDEV_PMU },
{ 0x02000000, NVDEV_SUBDEV_LTC },
{ 0x08000000, NVDEV_SUBDEV_FB },
{ 0x10000000, NVDEV_SUBDEV_BUS },
@@ -50,28 +49,28 @@ nvc0_mc_intr[] = {
};
static void
-nvc0_mc_msi_rearm(struct nouveau_mc *pmc)
+gf100_mc_msi_rearm(struct nvkm_mc *pmc)
{
struct nv04_mc_priv *priv = (void *)pmc;
nv_wr32(priv, 0x088704, 0x00000000);
}
void
-nvc0_mc_unk260(struct nouveau_mc *pmc, u32 data)
+gf100_mc_unk260(struct nvkm_mc *pmc, u32 data)
{
nv_wr32(pmc, 0x000260, data);
}
-struct nouveau_oclass *
-nvc0_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+gf100_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
- .intr = nvc0_mc_intr,
- .msi_rearm = nvc0_mc_msi_rearm,
- .unk260 = nvc0_mc_unk260,
+ .intr = gf100_mc_intr,
+ .msi_rearm = gf100_mc_msi_rearm,
+ .unk260 = gf100_mc_unk260,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c
index 68b5f61aadb5..8d2a8f457778 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c
@@ -21,19 +21,18 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-struct nouveau_oclass *
-nvc3_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+gf106_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0xc3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
- .intr = nvc0_mc_intr,
+ .intr = gf100_mc_intr,
.msi_rearm = nv40_mc_msi_rearm,
- .unk260 = nvc0_mc_unk260,
+ .unk260 = gf100_mc_unk260,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
index b8d6cb435d0a..43b27742956d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
@@ -21,18 +21,17 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-struct nouveau_oclass *
-gk20a_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+gk20a_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0xea),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
- .intr = nvc0_mc_intr,
+ .intr = gf100_mc_intr,
.msi_rearm = nv40_mc_msi_rearm,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
index 2d787e4dfefa..32713827b4dc 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
@@ -21,10 +21,9 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-const struct nouveau_mc_intr
+const struct nvkm_mc_intr
nv04_mc_intr[] = {
{ 0x00000001, NVDEV_ENGINE_MPEG }, /* NV17- MPEG/ME */
{ 0x00000100, NVDEV_ENGINE_FIFO },
@@ -40,25 +39,25 @@ nv04_mc_intr[] = {
};
int
-nv04_mc_init(struct nouveau_object *object)
+nv04_mc_init(struct nvkm_object *object)
{
struct nv04_mc_priv *priv = (void *)object;
nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */
nv_wr32(priv, 0x001850, 0x00000001); /* disable rom access */
- return nouveau_mc_init(&priv->base);
+ return nvkm_mc_init(&priv->base);
}
int
-nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_mc_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_mc_priv *priv;
int ret;
- ret = nouveau_mc_create(parent, engine, oclass, &priv);
+ ret = nvkm_mc_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -66,14 +65,14 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass *
-nv04_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+nv04_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0x04),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv04_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
.intr = nv04_mc_intr,
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h
new file mode 100644
index 000000000000..411de3d08ab6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.h
@@ -0,0 +1,20 @@
+#ifndef __NVKM_MC_NV04_H__
+#define __NVKM_MC_NV04_H__
+#include "priv.h"
+
+struct nv04_mc_priv {
+ struct nvkm_mc base;
+};
+
+int nv04_mc_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+
+extern const struct nvkm_mc_intr nv04_mc_intr[];
+int nv04_mc_init(struct nvkm_object *);
+void nv40_mc_msi_rearm(struct nvkm_mc *);
+int nv44_mc_init(struct nvkm_object *object);
+int nv50_mc_init(struct nvkm_object *);
+extern const struct nvkm_mc_intr nv50_mc_intr[];
+extern const struct nvkm_mc_intr gf100_mc_intr[];
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c
index 5b1faecfed2d..b7613059da08 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c
@@ -21,24 +21,23 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
void
-nv40_mc_msi_rearm(struct nouveau_mc *pmc)
+nv40_mc_msi_rearm(struct nvkm_mc *pmc)
{
struct nv04_mc_priv *priv = (void *)pmc;
nv_wr08(priv, 0x088068, 0xff);
}
-struct nouveau_oclass *
-nv40_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+nv40_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0x40),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv04_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
.intr = nv04_mc_intr,
.msi_rearm = nv40_mc_msi_rearm,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
index cc4d0d2d886e..2c7f7c701a2b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
@@ -21,11 +21,10 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
int
-nv44_mc_init(struct nouveau_object *object)
+nv44_mc_init(struct nvkm_object *object)
{
struct nv04_mc_priv *priv = (void *)object;
u32 tmp = nv_rd32(priv, 0x10020c);
@@ -37,17 +36,17 @@ nv44_mc_init(struct nouveau_object *object)
nv_wr32(priv, 0x001708, 0);
nv_wr32(priv, 0x00170c, tmp);
- return nouveau_mc_init(&priv->base);
+ return nvkm_mc_init(&priv->base);
}
-struct nouveau_oclass *
-nv44_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+nv44_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0x44),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv44_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
.intr = nv04_mc_intr,
.msi_rearm = nv40_mc_msi_rearm,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c
index 165401c4045c..c0aac7e20d45 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c
@@ -21,17 +21,16 @@
*
* Authors: Ilia Mirkin
*/
-
#include "nv04.h"
-struct nouveau_oclass *
-nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+nv4c_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0x4c),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv44_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
.intr = nv04_mc_intr,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
index 9ca93e2718f7..40e3019e1fde 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
@@ -21,16 +21,17 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
-const struct nouveau_mc_intr
+#include <core/device.h>
+
+const struct nvkm_mc_intr
nv50_mc_intr[] = {
{ 0x04000000, NVDEV_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */
{ 0x00000001, NVDEV_ENGINE_MPEG },
{ 0x00000100, NVDEV_ENGINE_FIFO },
{ 0x00001000, NVDEV_ENGINE_GR },
- { 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84- */
+ { 0x00004000, NVDEV_ENGINE_CIPHER }, /* NV84- */
{ 0x00008000, NVDEV_ENGINE_BSP }, /* NV84- */
{ 0x00020000, NVDEV_ENGINE_VP }, /* NV84- */
{ 0x00100000, NVDEV_SUBDEV_TIMER },
@@ -43,28 +44,28 @@ nv50_mc_intr[] = {
};
static void
-nv50_mc_msi_rearm(struct nouveau_mc *pmc)
+nv50_mc_msi_rearm(struct nvkm_mc *pmc)
{
- struct nouveau_device *device = nv_device(pmc);
+ struct nvkm_device *device = nv_device(pmc);
pci_write_config_byte(device->pdev, 0x68, 0xff);
}
int
-nv50_mc_init(struct nouveau_object *object)
+nv50_mc_init(struct nvkm_object *object)
{
struct nv04_mc_priv *priv = (void *)object;
nv_wr32(priv, 0x000200, 0xffffffff); /* everything on */
- return nouveau_mc_init(&priv->base);
+ return nvkm_mc_init(&priv->base);
}
-struct nouveau_oclass *
-nv50_mc_oclass = &(struct nouveau_mc_oclass) {
+struct nvkm_oclass *
+nv50_mc_oclass = &(struct nvkm_mc_oclass) {
.base.handle = NV_SUBDEV(MC, 0x50),
- .base.ofuncs = &(struct nouveau_ofuncs) {
+ .base.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_mc_ctor,
- .dtor = _nouveau_mc_dtor,
+ .dtor = _nvkm_mc_dtor,
.init = nv50_mc_init,
- .fini = _nouveau_mc_fini,
+ .fini = _nvkm_mc_fini,
},
.intr = nv50_mc_intr,
.msi_rearm = nv50_mc_msi_rearm,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
new file mode 100644
index 000000000000..d2cad07afd1a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
@@ -0,0 +1,36 @@
+#ifndef __NVKM_MC_PRIV_H__
+#define __NVKM_MC_PRIV_H__
+#include <subdev/mc.h>
+
+#define nvkm_mc_create(p,e,o,d) \
+ nvkm_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_mc_destroy(p) ({ \
+ struct nvkm_mc *pmc = (p); _nvkm_mc_dtor(nv_object(pmc)); \
+})
+#define nvkm_mc_init(p) ({ \
+ struct nvkm_mc *pmc = (p); _nvkm_mc_init(nv_object(pmc)); \
+})
+#define nvkm_mc_fini(p,s) ({ \
+ struct nvkm_mc *pmc = (p); _nvkm_mc_fini(nv_object(pmc), (s)); \
+})
+
+int nvkm_mc_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+void _nvkm_mc_dtor(struct nvkm_object *);
+int _nvkm_mc_init(struct nvkm_object *);
+int _nvkm_mc_fini(struct nvkm_object *, bool);
+
+struct nvkm_mc_intr {
+ u32 stat;
+ u32 unit;
+};
+
+struct nvkm_mc_oclass {
+ struct nvkm_oclass base;
+ const struct nvkm_mc_intr *intr;
+ void (*msi_rearm)(struct nvkm_mc *);
+ void (*unk260)(struct nvkm_mc *, u32);
+};
+
+void gf100_mc_unk260(struct nvkm_mc *, u32);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild
new file mode 100644
index 000000000000..012c9db687b2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/Kbuild
@@ -0,0 +1,6 @@
+nvkm-y += nvkm/subdev/mmu/base.o
+nvkm-y += nvkm/subdev/mmu/nv04.o
+nvkm-y += nvkm/subdev/mmu/nv41.o
+nvkm-y += nvkm/subdev/mmu/nv44.o
+nvkm-y += nvkm/subdev/mmu/nv50.o
+nvkm-y += nvkm/subdev/mmu/gf100.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
new file mode 100644
index 000000000000..277b6ec04e24
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include <subdev/mmu.h>
+#include <subdev/fb.h>
+
+#include <core/gpuobj.h>
+
+void
+nvkm_vm_map_at(struct nvkm_vma *vma, u64 delta, struct nvkm_mem *node)
+{
+ struct nvkm_vm *vm = vma->vm;
+ struct nvkm_mmu *mmu = vm->mmu;
+ struct nvkm_mm_node *r;
+ int big = vma->node->type != mmu->spg_shift;
+ u32 offset = vma->node->offset + (delta >> 12);
+ u32 bits = vma->node->type - 12;
+ u32 pde = (offset >> mmu->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (mmu->pgt_bits - bits);
+ u32 end, len;
+
+ delta = 0;
+ list_for_each_entry(r, &node->regions, rl_entry) {
+ u64 phys = (u64)r->offset << 12;
+ u32 num = r->length >> bits;
+
+ while (num) {
+ struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
+
+ end = (pte + num);
+ if (unlikely(end >= max))
+ end = max;
+ len = end - pte;
+
+ mmu->map(vma, pgt, node, pte, len, phys, delta);
+
+ num -= len;
+ pte += len;
+ if (unlikely(end >= max)) {
+ phys += len << (bits + 12);
+ pde++;
+ pte = 0;
+ }
+
+ delta += (u64)len << vma->node->type;
+ }
+ }
+
+ mmu->flush(vm);
+}
+
+static void
+nvkm_vm_map_sg_table(struct nvkm_vma *vma, u64 delta, u64 length,
+ struct nvkm_mem *mem)
+{
+ struct nvkm_vm *vm = vma->vm;
+ struct nvkm_mmu *mmu = vm->mmu;
+ int big = vma->node->type != mmu->spg_shift;
+ u32 offset = vma->node->offset + (delta >> 12);
+ u32 bits = vma->node->type - 12;
+ u32 num = length >> vma->node->type;
+ u32 pde = (offset >> mmu->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (mmu->pgt_bits - bits);
+ unsigned m, sglen;
+ u32 end, len;
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(mem->sg->sgl, sg, mem->sg->nents, i) {
+ struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
+ sglen = sg_dma_len(sg) >> PAGE_SHIFT;
+
+ end = pte + sglen;
+ if (unlikely(end >= max))
+ end = max;
+ len = end - pte;
+
+ for (m = 0; m < len; m++) {
+ dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
+
+ mmu->map_sg(vma, pgt, mem, pte, 1, &addr);
+ num--;
+ pte++;
+
+ if (num == 0)
+ goto finish;
+ }
+ if (unlikely(end >= max)) {
+ pde++;
+ pte = 0;
+ }
+ if (m < sglen) {
+ for (; m < sglen; m++) {
+ dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
+
+ mmu->map_sg(vma, pgt, mem, pte, 1, &addr);
+ num--;
+ pte++;
+ if (num == 0)
+ goto finish;
+ }
+ }
+
+ }
+finish:
+ mmu->flush(vm);
+}
+
+static void
+nvkm_vm_map_sg(struct nvkm_vma *vma, u64 delta, u64 length,
+ struct nvkm_mem *mem)
+{
+ struct nvkm_vm *vm = vma->vm;
+ struct nvkm_mmu *mmu = vm->mmu;
+ dma_addr_t *list = mem->pages;
+ int big = vma->node->type != mmu->spg_shift;
+ u32 offset = vma->node->offset + (delta >> 12);
+ u32 bits = vma->node->type - 12;
+ u32 num = length >> vma->node->type;
+ u32 pde = (offset >> mmu->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (mmu->pgt_bits - bits);
+ u32 end, len;
+
+ while (num) {
+ struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
+
+ end = (pte + num);
+ if (unlikely(end >= max))
+ end = max;
+ len = end - pte;
+
+ mmu->map_sg(vma, pgt, mem, pte, len, list);
+
+ num -= len;
+ pte += len;
+ list += len;
+ if (unlikely(end >= max)) {
+ pde++;
+ pte = 0;
+ }
+ }
+
+ mmu->flush(vm);
+}
+
+void
+nvkm_vm_map(struct nvkm_vma *vma, struct nvkm_mem *node)
+{
+ if (node->sg)
+ nvkm_vm_map_sg_table(vma, 0, node->size << 12, node);
+ else
+ if (node->pages)
+ nvkm_vm_map_sg(vma, 0, node->size << 12, node);
+ else
+ nvkm_vm_map_at(vma, 0, node);
+}
+
+void
+nvkm_vm_unmap_at(struct nvkm_vma *vma, u64 delta, u64 length)
+{
+ struct nvkm_vm *vm = vma->vm;
+ struct nvkm_mmu *mmu = vm->mmu;
+ int big = vma->node->type != mmu->spg_shift;
+ u32 offset = vma->node->offset + (delta >> 12);
+ u32 bits = vma->node->type - 12;
+ u32 num = length >> vma->node->type;
+ u32 pde = (offset >> mmu->pgt_bits) - vm->fpde;
+ u32 pte = (offset & ((1 << mmu->pgt_bits) - 1)) >> bits;
+ u32 max = 1 << (mmu->pgt_bits - bits);
+ u32 end, len;
+
+ while (num) {
+ struct nvkm_gpuobj *pgt = vm->pgt[pde].obj[big];
+
+ end = (pte + num);
+ if (unlikely(end >= max))
+ end = max;
+ len = end - pte;
+
+ mmu->unmap(pgt, pte, len);
+
+ num -= len;
+ pte += len;
+ if (unlikely(end >= max)) {
+ pde++;
+ pte = 0;
+ }
+ }
+
+ mmu->flush(vm);
+}
+
+void
+nvkm_vm_unmap(struct nvkm_vma *vma)
+{
+ nvkm_vm_unmap_at(vma, 0, (u64)vma->node->length << 12);
+}
+
+static void
+nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde)
+{
+ struct nvkm_mmu *mmu = vm->mmu;
+ struct nvkm_vm_pgd *vpgd;
+ struct nvkm_vm_pgt *vpgt;
+ struct nvkm_gpuobj *pgt;
+ u32 pde;
+
+ for (pde = fpde; pde <= lpde; pde++) {
+ vpgt = &vm->pgt[pde - vm->fpde];
+ if (--vpgt->refcount[big])
+ continue;
+
+ pgt = vpgt->obj[big];
+ vpgt->obj[big] = NULL;
+
+ list_for_each_entry(vpgd, &vm->pgd_list, head) {
+ mmu->map_pgt(vpgd->obj, pde, vpgt->obj);
+ }
+
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+ nvkm_gpuobj_ref(NULL, &pgt);
+ mutex_lock(&nv_subdev(mmu)->mutex);
+ }
+}
+
+static int
+nvkm_vm_map_pgt(struct nvkm_vm *vm, u32 pde, u32 type)
+{
+ struct nvkm_mmu *mmu = vm->mmu;
+ struct nvkm_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
+ struct nvkm_vm_pgd *vpgd;
+ struct nvkm_gpuobj *pgt;
+ int big = (type != mmu->spg_shift);
+ u32 pgt_size;
+ int ret;
+
+ pgt_size = (1 << (mmu->pgt_bits + 12)) >> type;
+ pgt_size *= 8;
+
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+ ret = nvkm_gpuobj_new(nv_object(vm->mmu), NULL, pgt_size, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &pgt);
+ mutex_lock(&nv_subdev(mmu)->mutex);
+ if (unlikely(ret))
+ return ret;
+
+ /* someone beat us to filling the PDE while we didn't have the lock */
+ if (unlikely(vpgt->refcount[big]++)) {
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+ nvkm_gpuobj_ref(NULL, &pgt);
+ mutex_lock(&nv_subdev(mmu)->mutex);
+ return 0;
+ }
+
+ vpgt->obj[big] = pgt;
+ list_for_each_entry(vpgd, &vm->pgd_list, head) {
+ mmu->map_pgt(vpgd->obj, pde, vpgt->obj);
+ }
+
+ return 0;
+}
+
+int
+nvkm_vm_get(struct nvkm_vm *vm, u64 size, u32 page_shift, u32 access,
+ struct nvkm_vma *vma)
+{
+ struct nvkm_mmu *mmu = vm->mmu;
+ u32 align = (1 << page_shift) >> 12;
+ u32 msize = size >> 12;
+ u32 fpde, lpde, pde;
+ int ret;
+
+ mutex_lock(&nv_subdev(mmu)->mutex);
+ ret = nvkm_mm_head(&vm->mm, 0, page_shift, msize, msize, align,
+ &vma->node);
+ if (unlikely(ret != 0)) {
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+ return ret;
+ }
+
+ fpde = (vma->node->offset >> mmu->pgt_bits);
+ lpde = (vma->node->offset + vma->node->length - 1) >> mmu->pgt_bits;
+
+ for (pde = fpde; pde <= lpde; pde++) {
+ struct nvkm_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde];
+ int big = (vma->node->type != mmu->spg_shift);
+
+ if (likely(vpgt->refcount[big])) {
+ vpgt->refcount[big]++;
+ continue;
+ }
+
+ ret = nvkm_vm_map_pgt(vm, pde, vma->node->type);
+ if (ret) {
+ if (pde != fpde)
+ nvkm_vm_unmap_pgt(vm, big, fpde, pde - 1);
+ nvkm_mm_free(&vm->mm, &vma->node);
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+ return ret;
+ }
+ }
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+
+ vma->vm = NULL;
+ nvkm_vm_ref(vm, &vma->vm, NULL);
+ vma->offset = (u64)vma->node->offset << 12;
+ vma->access = access;
+ return 0;
+}
+
+void
+nvkm_vm_put(struct nvkm_vma *vma)
+{
+ struct nvkm_vm *vm = vma->vm;
+ struct nvkm_mmu *mmu = vm->mmu;
+ u32 fpde, lpde;
+
+ if (unlikely(vma->node == NULL))
+ return;
+ fpde = (vma->node->offset >> mmu->pgt_bits);
+ lpde = (vma->node->offset + vma->node->length - 1) >> mmu->pgt_bits;
+
+ mutex_lock(&nv_subdev(mmu)->mutex);
+ nvkm_vm_unmap_pgt(vm, vma->node->type != mmu->spg_shift, fpde, lpde);
+ nvkm_mm_free(&vm->mm, &vma->node);
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+
+ nvkm_vm_ref(NULL, &vma->vm, NULL);
+}
+
+int
+nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset,
+ u32 block, struct nvkm_vm **pvm)
+{
+ struct nvkm_vm *vm;
+ u64 mm_length = (offset + length) - mm_offset;
+ int ret;
+
+ vm = kzalloc(sizeof(*vm), GFP_KERNEL);
+ if (!vm)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&vm->pgd_list);
+ vm->mmu = mmu;
+ kref_init(&vm->refcount);
+ vm->fpde = offset >> (mmu->pgt_bits + 12);
+ vm->lpde = (offset + length - 1) >> (mmu->pgt_bits + 12);
+
+ vm->pgt = vzalloc((vm->lpde - vm->fpde + 1) * sizeof(*vm->pgt));
+ if (!vm->pgt) {
+ kfree(vm);
+ return -ENOMEM;
+ }
+
+ ret = nvkm_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12,
+ block >> 12);
+ if (ret) {
+ vfree(vm->pgt);
+ kfree(vm);
+ return ret;
+ }
+
+ *pvm = vm;
+
+ return 0;
+}
+
+int
+nvkm_vm_new(struct nvkm_device *device, u64 offset, u64 length, u64 mm_offset,
+ struct nvkm_vm **pvm)
+{
+ struct nvkm_mmu *mmu = nvkm_mmu(device);
+ return mmu->create(mmu, offset, length, mm_offset, pvm);
+}
+
+static int
+nvkm_vm_link(struct nvkm_vm *vm, struct nvkm_gpuobj *pgd)
+{
+ struct nvkm_mmu *mmu = vm->mmu;
+ struct nvkm_vm_pgd *vpgd;
+ int i;
+
+ if (!pgd)
+ return 0;
+
+ vpgd = kzalloc(sizeof(*vpgd), GFP_KERNEL);
+ if (!vpgd)
+ return -ENOMEM;
+
+ nvkm_gpuobj_ref(pgd, &vpgd->obj);
+
+ mutex_lock(&nv_subdev(mmu)->mutex);
+ for (i = vm->fpde; i <= vm->lpde; i++)
+ mmu->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj);
+ list_add(&vpgd->head, &vm->pgd_list);
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+ return 0;
+}
+
+static void
+nvkm_vm_unlink(struct nvkm_vm *vm, struct nvkm_gpuobj *mpgd)
+{
+ struct nvkm_mmu *mmu = vm->mmu;
+ struct nvkm_vm_pgd *vpgd, *tmp;
+ struct nvkm_gpuobj *pgd = NULL;
+
+ if (!mpgd)
+ return;
+
+ mutex_lock(&nv_subdev(mmu)->mutex);
+ list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
+ if (vpgd->obj == mpgd) {
+ pgd = vpgd->obj;
+ list_del(&vpgd->head);
+ kfree(vpgd);
+ break;
+ }
+ }
+ mutex_unlock(&nv_subdev(mmu)->mutex);
+
+ nvkm_gpuobj_ref(NULL, &pgd);
+}
+
+static void
+nvkm_vm_del(struct kref *kref)
+{
+ struct nvkm_vm *vm = container_of(kref, typeof(*vm), refcount);
+ struct nvkm_vm_pgd *vpgd, *tmp;
+
+ list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
+ nvkm_vm_unlink(vm, vpgd->obj);
+ }
+
+ nvkm_mm_fini(&vm->mm);
+ vfree(vm->pgt);
+ kfree(vm);
+}
+
+int
+nvkm_vm_ref(struct nvkm_vm *ref, struct nvkm_vm **ptr, struct nvkm_gpuobj *pgd)
+{
+ if (ref) {
+ int ret = nvkm_vm_link(ref, pgd);
+ if (ret)
+ return ret;
+
+ kref_get(&ref->refcount);
+ }
+
+ if (*ptr) {
+ nvkm_vm_unlink(*ptr, pgd);
+ kref_put(&(*ptr)->refcount, nvkm_vm_del);
+ }
+
+ *ptr = ref;
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
index 2d0988755530..294cda37f068 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
@@ -21,25 +21,23 @@
*
* Authors: Ben Skeggs
*/
-
-#include <core/device.h>
-#include <core/gpuobj.h>
-
-#include <subdev/timer.h>
+#include <subdev/mmu.h>
+#include <subdev/bar.h>
#include <subdev/fb.h>
-#include <subdev/vm.h>
#include <subdev/ltc.h>
-#include <subdev/bar.h>
+#include <subdev/timer.h>
-struct nvc0_vmmgr_priv {
- struct nouveau_vmmgr base;
+#include <core/gpuobj.h>
+
+struct gf100_mmu_priv {
+ struct nvkm_mmu base;
};
/* Map from compressed to corresponding uncompressed storage type.
* The value 0xff represents an invalid storage type.
*/
-const u8 nvc0_pte_storage_type_map[256] =
+const u8 gf100_pte_storage_type_map[256] =
{
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, /* 0x00 */
0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -77,8 +75,7 @@ const u8 nvc0_pte_storage_type_map[256] =
static void
-nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index,
- struct nouveau_gpuobj *pgt[2])
+gf100_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 index, struct nvkm_gpuobj *pgt[2])
{
u32 pde[2] = { 0, 0 };
@@ -92,7 +89,7 @@ nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index,
}
static inline u64
-nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
+gf100_vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target)
{
phys >>= 8;
@@ -102,22 +99,20 @@ nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
phys |= ((u64)target << 32);
phys |= ((u64)memtype << 36);
-
return phys;
}
static void
-nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
- struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
+gf100_vm_map(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+ struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
{
u64 next = 1 << (vma->node->type - 8);
- phys = nvc0_vm_addr(vma, phys, mem->memtype, 0);
+ phys = gf100_vm_addr(vma, phys, mem->memtype, 0);
pte <<= 3;
if (mem->tag) {
- struct nouveau_ltc *ltc =
- nouveau_ltc(vma->vm->vmm->base.base.parent);
+ struct nvkm_ltc *ltc = nvkm_ltc(vma->vm->mmu);
u32 tag = mem->tag->offset + (delta >> 17);
phys |= (u64)tag << (32 + 12);
next |= (u64)1 << (32 + 12);
@@ -133,16 +128,16 @@ nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
static void
-nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
- struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+gf100_vm_map_sg(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+ struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5;
/* compressed storage types are invalid for system memory */
- u32 memtype = nvc0_pte_storage_type_map[mem->memtype & 0xff];
+ u32 memtype = gf100_pte_storage_type_map[mem->memtype & 0xff];
pte <<= 3;
while (cnt--) {
- u64 phys = nvc0_vm_addr(vma, *list++, memtype, target);
+ u64 phys = gf100_vm_addr(vma, *list++, memtype, target);
nv_wo32(pgt, pte + 0, lower_32_bits(phys));
nv_wo32(pgt, pte + 4, upper_32_bits(phys));
pte += 8;
@@ -150,7 +145,7 @@ nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
static void
-nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+gf100_vm_unmap(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt)
{
pte <<= 3;
while (cnt--) {
@@ -161,11 +156,11 @@ nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
static void
-nvc0_vm_flush(struct nouveau_vm *vm)
+gf100_vm_flush(struct nvkm_vm *vm)
{
- struct nvc0_vmmgr_priv *priv = (void *)vm->vmm;
- struct nouveau_bar *bar = nouveau_bar(priv);
- struct nouveau_vm_pgd *vpgd;
+ struct gf100_mmu_priv *priv = (void *)vm->mmu;
+ struct nvkm_bar *bar = nvkm_bar(priv);
+ struct nvkm_vm_pgd *vpgd;
u32 type;
bar->flush(bar);
@@ -197,21 +192,21 @@ nvc0_vm_flush(struct nouveau_vm *vm)
}
static int
-nvc0_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
- u64 mm_offset, struct nouveau_vm **pvm)
+gf100_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset,
+ struct nvkm_vm **pvm)
{
- return nouveau_vm_create(vmm, offset, length, mm_offset, 4096, pvm);
+ return nvkm_vm_create(mmu, offset, length, mm_offset, 4096, pvm);
}
static int
-nvc0_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf100_mmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvc0_vmmgr_priv *priv;
+ struct gf100_mmu_priv *priv;
int ret;
- ret = nouveau_vmmgr_create(parent, engine, oclass, "VM", "vm", &priv);
+ ret = nvkm_mmu_create(parent, engine, oclass, "VM", "vm", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -221,22 +216,22 @@ nvc0_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.pgt_bits = 27 - 12;
priv->base.spg_shift = 12;
priv->base.lpg_shift = 17;
- priv->base.create = nvc0_vm_create;
- priv->base.map_pgt = nvc0_vm_map_pgt;
- priv->base.map = nvc0_vm_map;
- priv->base.map_sg = nvc0_vm_map_sg;
- priv->base.unmap = nvc0_vm_unmap;
- priv->base.flush = nvc0_vm_flush;
+ priv->base.create = gf100_vm_create;
+ priv->base.map_pgt = gf100_vm_map_pgt;
+ priv->base.map = gf100_vm_map;
+ priv->base.map_sg = gf100_vm_map_sg;
+ priv->base.unmap = gf100_vm_unmap;
+ priv->base.flush = gf100_vm_flush;
return 0;
}
-struct nouveau_oclass
-nvc0_vmmgr_oclass = {
- .handle = NV_SUBDEV(VM, 0xc0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvc0_vmmgr_ctor,
- .dtor = _nouveau_vmmgr_dtor,
- .init = _nouveau_vmmgr_init,
- .fini = _nouveau_vmmgr_fini,
+struct nvkm_oclass
+gf100_mmu_oclass = {
+ .handle = NV_SUBDEV(MMU, 0xc0),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf100_mmu_ctor,
+ .dtor = _nvkm_mmu_dtor,
+ .init = _nvkm_mmu_init,
+ .fini = _nvkm_mmu_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c
index ed45437167f2..fe93ea2711c9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c
@@ -21,11 +21,11 @@
*
* Authors: Ben Skeggs
*/
+#include "nv04.h"
+#include <core/device.h>
#include <core/gpuobj.h>
-#include "nv04.h"
-
#define NV04_PDMA_SIZE (128 * 1024 * 1024)
#define NV04_PDMA_PAGE ( 4 * 1024)
@@ -34,8 +34,8 @@
******************************************************************************/
static void
-nv04_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
- struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+nv04_vm_map_sg(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+ struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
pte = 0x00008 + (pte * 4);
while (cnt) {
@@ -51,7 +51,7 @@ nv04_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
static void
-nv04_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+nv04_vm_unmap(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt)
{
pte = 0x00008 + (pte * 4);
while (cnt--) {
@@ -61,7 +61,7 @@ nv04_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
static void
-nv04_vm_flush(struct nouveau_vm *vm)
+nv04_vm_flush(struct nvkm_vm *vm)
{
}
@@ -70,27 +70,27 @@ nv04_vm_flush(struct nouveau_vm *vm)
******************************************************************************/
int
-nv04_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length, u64 mmstart,
- struct nouveau_vm **pvm)
+nv04_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mmstart,
+ struct nvkm_vm **pvm)
{
return -EINVAL;
}
/*******************************************************************************
- * VMMGR subdev
+ * MMU subdev
******************************************************************************/
static int
-nv04_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_mmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv04_vmmgr_priv *priv;
- struct nouveau_gpuobj *dma;
+ struct nv04_mmu_priv *priv;
+ struct nvkm_gpuobj *dma;
int ret;
- ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIGART",
- "pcigart", &priv);
+ ret = nvkm_mmu_create(parent, engine, oclass, "PCIGART",
+ "pcigart", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -105,15 +105,15 @@ nv04_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.unmap = nv04_vm_unmap;
priv->base.flush = nv04_vm_flush;
- ret = nouveau_vm_create(&priv->base, 0, NV04_PDMA_SIZE, 0, 4096,
- &priv->vm);
+ ret = nvkm_vm_create(&priv->base, 0, NV04_PDMA_SIZE, 0, 4096,
+ &priv->vm);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL,
- (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 +
- 8, 16, NVOBJ_FLAG_ZERO_ALLOC,
- &priv->vm->pgt[0].obj[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL,
+ (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 + 8,
+ 16, NVOBJ_FLAG_ZERO_ALLOC,
+ &priv->vm->pgt[0].obj[0]);
dma = priv->vm->pgt[0].obj[0];
priv->vm->pgt[0].refcount[0] = 1;
if (ret)
@@ -125,27 +125,27 @@ nv04_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
void
-nv04_vmmgr_dtor(struct nouveau_object *object)
+nv04_mmu_dtor(struct nvkm_object *object)
{
- struct nv04_vmmgr_priv *priv = (void *)object;
+ struct nv04_mmu_priv *priv = (void *)object;
if (priv->vm) {
- nouveau_gpuobj_ref(NULL, &priv->vm->pgt[0].obj[0]);
- nouveau_vm_ref(NULL, &priv->vm, NULL);
+ nvkm_gpuobj_ref(NULL, &priv->vm->pgt[0].obj[0]);
+ nvkm_vm_ref(NULL, &priv->vm, NULL);
}
if (priv->nullp) {
pci_free_consistent(nv_device(priv)->pdev, 16 * 1024,
priv->nullp, priv->null);
}
- nouveau_vmmgr_destroy(&priv->base);
+ nvkm_mmu_destroy(&priv->base);
}
-struct nouveau_oclass
-nv04_vmmgr_oclass = {
- .handle = NV_SUBDEV(VM, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv04_vmmgr_ctor,
- .dtor = nv04_vmmgr_dtor,
- .init = _nouveau_vmmgr_init,
- .fini = _nouveau_vmmgr_fini,
+struct nvkm_oclass
+nv04_mmu_oclass = {
+ .handle = NV_SUBDEV(MMU, 0x04),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv04_mmu_ctor,
+ .dtor = nv04_mmu_dtor,
+ .init = _nvkm_mmu_init,
+ .fini = _nvkm_mmu_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h
new file mode 100644
index 000000000000..7bf6f4b38f1d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.h
@@ -0,0 +1,19 @@
+#ifndef __NV04_MMU_PRIV__
+#define __NV04_MMU_PRIV__
+
+#include <subdev/mmu.h>
+
+struct nv04_mmu_priv {
+ struct nvkm_mmu base;
+ struct nvkm_vm *vm;
+ dma_addr_t null;
+ void *nullp;
+};
+
+static inline struct nv04_mmu_priv *
+nv04_mmu(void *obj)
+{
+ return (void *)nvkm_mmu(obj);
+}
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c
index 064c76262876..61ee3ab11660 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
+#include "nv04.h"
+#include <core/device.h>
#include <core/gpuobj.h>
#include <core/option.h>
-
#include <subdev/timer.h>
-#include <subdev/vm.h>
-
-#include "nv04.h"
#define NV41_GART_SIZE (512 * 1024 * 1024)
#define NV41_GART_PAGE ( 4 * 1024)
@@ -38,8 +36,8 @@
******************************************************************************/
static void
-nv41_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
- struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+nv41_vm_map_sg(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+ struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
pte = pte * 4;
while (cnt) {
@@ -55,7 +53,7 @@ nv41_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
static void
-nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+nv41_vm_unmap(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt)
{
pte = pte * 4;
while (cnt--) {
@@ -65,9 +63,9 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
static void
-nv41_vm_flush(struct nouveau_vm *vm)
+nv41_vm_flush(struct nvkm_vm *vm)
{
- struct nv04_vmmgr_priv *priv = (void *)vm->vmm;
+ struct nv04_mmu_priv *priv = (void *)vm->mmu;
mutex_lock(&nv_subdev(priv)->mutex);
nv_wr32(priv, 0x100810, 0x00000022);
@@ -80,26 +78,26 @@ nv41_vm_flush(struct nouveau_vm *vm)
}
/*******************************************************************************
- * VMMGR subdev
+ * MMU subdev
******************************************************************************/
static int
-nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv41_mmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_device *device = nv_device(parent);
- struct nv04_vmmgr_priv *priv;
+ struct nvkm_device *device = nv_device(parent);
+ struct nv04_mmu_priv *priv;
int ret;
if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
- !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
- return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
- data, size, pobject);
+ !nvkm_boolopt(device->cfgopt, "NvPCIE", true)) {
+ return nvkm_object_ctor(parent, engine, &nv04_mmu_oclass,
+ data, size, pobject);
}
- ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIEGART",
- "pciegart", &priv);
+ ret = nvkm_mmu_create(parent, engine, oclass, "PCIEGART",
+ "pciegart", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -114,15 +112,15 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.unmap = nv41_vm_unmap;
priv->base.flush = nv41_vm_flush;
- ret = nouveau_vm_create(&priv->base, 0, NV41_GART_SIZE, 0, 4096,
- &priv->vm);
+ ret = nvkm_vm_create(&priv->base, 0, NV41_GART_SIZE, 0, 4096,
+ &priv->vm);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL,
- (NV41_GART_SIZE / NV41_GART_PAGE) * 4,
- 16, NVOBJ_FLAG_ZERO_ALLOC,
- &priv->vm->pgt[0].obj[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL,
+ (NV41_GART_SIZE / NV41_GART_PAGE) * 4, 16,
+ NVOBJ_FLAG_ZERO_ALLOC,
+ &priv->vm->pgt[0].obj[0]);
priv->vm->pgt[0].refcount[0] = 1;
if (ret)
return ret;
@@ -131,13 +129,13 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
static int
-nv41_vmmgr_init(struct nouveau_object *object)
+nv41_mmu_init(struct nvkm_object *object)
{
- struct nv04_vmmgr_priv *priv = (void *)object;
- struct nouveau_gpuobj *dma = priv->vm->pgt[0].obj[0];
+ struct nv04_mmu_priv *priv = (void *)object;
+ struct nvkm_gpuobj *dma = priv->vm->pgt[0].obj[0];
int ret;
- ret = nouveau_vmmgr_init(&priv->base);
+ ret = nvkm_mmu_init(&priv->base);
if (ret)
return ret;
@@ -147,13 +145,13 @@ nv41_vmmgr_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv41_vmmgr_oclass = {
- .handle = NV_SUBDEV(VM, 0x41),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv41_vmmgr_ctor,
- .dtor = nv04_vmmgr_dtor,
- .init = nv41_vmmgr_init,
- .fini = _nouveau_vmmgr_fini,
+struct nvkm_oclass
+nv41_mmu_oclass = {
+ .handle = NV_SUBDEV(MMU, 0x41),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv41_mmu_ctor,
+ .dtor = nv04_mmu_dtor,
+ .init = nv41_mmu_init,
+ .fini = _nvkm_mmu_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c
index fae1f67d5948..b90ded1887aa 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c
@@ -21,14 +21,12 @@
*
* Authors: Ben Skeggs
*/
+#include "nv04.h"
+#include <core/device.h>
#include <core/gpuobj.h>
#include <core/option.h>
-
#include <subdev/timer.h>
-#include <subdev/vm.h>
-
-#include "nv04.h"
#define NV44_GART_SIZE (512 * 1024 * 1024)
#define NV44_GART_PAGE ( 4 * 1024)
@@ -38,7 +36,7 @@
******************************************************************************/
static void
-nv44_vm_fill(struct nouveau_gpuobj *pgt, dma_addr_t null,
+nv44_vm_fill(struct nvkm_gpuobj *pgt, dma_addr_t null,
dma_addr_t *list, u32 pte, u32 cnt)
{
u32 base = (pte << 2) & ~0x0000000f;
@@ -84,10 +82,10 @@ nv44_vm_fill(struct nouveau_gpuobj *pgt, dma_addr_t null,
}
static void
-nv44_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
- struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+nv44_vm_map_sg(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+ struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
- struct nv04_vmmgr_priv *priv = (void *)vma->vm->vmm;
+ struct nv04_mmu_priv *priv = (void *)vma->vm->mmu;
u32 tmp[4];
int i;
@@ -115,9 +113,9 @@ nv44_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
static void
-nv44_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+nv44_vm_unmap(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt)
{
- struct nv04_vmmgr_priv *priv = (void *)nouveau_vmmgr(pgt);
+ struct nv04_mmu_priv *priv = (void *)nvkm_mmu(pgt);
if (pte & 3) {
u32 max = 4 - (pte & 3);
@@ -140,9 +138,9 @@ nv44_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
static void
-nv44_vm_flush(struct nouveau_vm *vm)
+nv44_vm_flush(struct nvkm_vm *vm)
{
- struct nv04_vmmgr_priv *priv = (void *)vm->vmm;
+ struct nv04_mmu_priv *priv = (void *)vm->mmu;
nv_wr32(priv, 0x100814, priv->base.limit - NV44_GART_PAGE);
nv_wr32(priv, 0x100808, 0x00000020);
if (!nv_wait(priv, 0x100808, 0x00000001, 0x00000001))
@@ -151,26 +149,26 @@ nv44_vm_flush(struct nouveau_vm *vm)
}
/*******************************************************************************
- * VMMGR subdev
+ * MMU subdev
******************************************************************************/
static int
-nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv44_mmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nouveau_device *device = nv_device(parent);
- struct nv04_vmmgr_priv *priv;
+ struct nvkm_device *device = nv_device(parent);
+ struct nv04_mmu_priv *priv;
int ret;
if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
- !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
- return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
- data, size, pobject);
+ !nvkm_boolopt(device->cfgopt, "NvPCIE", true)) {
+ return nvkm_object_ctor(parent, engine, &nv04_mmu_oclass,
+ data, size, pobject);
}
- ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIEGART",
- "pciegart", &priv);
+ ret = nvkm_mmu_create(parent, engine, oclass, "PCIEGART",
+ "pciegart", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -191,15 +189,15 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return -ENOMEM;
}
- ret = nouveau_vm_create(&priv->base, 0, NV44_GART_SIZE, 0, 4096,
- &priv->vm);
+ ret = nvkm_vm_create(&priv->base, 0, NV44_GART_SIZE, 0, 4096,
+ &priv->vm);
if (ret)
return ret;
- ret = nouveau_gpuobj_new(nv_object(priv), NULL,
- (NV44_GART_SIZE / NV44_GART_PAGE) * 4,
- 512 * 1024, NVOBJ_FLAG_ZERO_ALLOC,
- &priv->vm->pgt[0].obj[0]);
+ ret = nvkm_gpuobj_new(nv_object(priv), NULL,
+ (NV44_GART_SIZE / NV44_GART_PAGE) * 4,
+ 512 * 1024, NVOBJ_FLAG_ZERO_ALLOC,
+ &priv->vm->pgt[0].obj[0]);
priv->vm->pgt[0].refcount[0] = 1;
if (ret)
return ret;
@@ -208,14 +206,14 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
}
static int
-nv44_vmmgr_init(struct nouveau_object *object)
+nv44_mmu_init(struct nvkm_object *object)
{
- struct nv04_vmmgr_priv *priv = (void *)object;
- struct nouveau_gpuobj *gart = priv->vm->pgt[0].obj[0];
+ struct nv04_mmu_priv *priv = (void *)object;
+ struct nvkm_gpuobj *gart = priv->vm->pgt[0].obj[0];
u32 addr;
int ret;
- ret = nouveau_vmmgr_init(&priv->base);
+ ret = nvkm_mmu_init(&priv->base);
if (ret)
return ret;
@@ -237,13 +235,13 @@ nv44_vmmgr_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
-nv44_vmmgr_oclass = {
- .handle = NV_SUBDEV(VM, 0x44),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv44_vmmgr_ctor,
- .dtor = nv04_vmmgr_dtor,
- .init = nv44_vmmgr_init,
- .fini = _nouveau_vmmgr_fini,
+struct nvkm_oclass
+nv44_mmu_oclass = {
+ .handle = NV_SUBDEV(MMU, 0x44),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv44_mmu_ctor,
+ .dtor = nv04_mmu_dtor,
+ .init = nv44_mmu_init,
+ .fini = _nvkm_mmu_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
index a4aa81a2173b..b83550fa7f96 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
@@ -21,22 +21,20 @@
*
* Authors: Ben Skeggs
*/
+#include <subdev/mmu.h>
+#include <subdev/bar.h>
+#include <subdev/fb.h>
+#include <subdev/timer.h>
-#include <core/device.h>
+#include <core/engine.h>
#include <core/gpuobj.h>
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <subdev/bar.h>
-#include <subdev/vm.h>
-
-struct nv50_vmmgr_priv {
- struct nouveau_vmmgr base;
+struct nv50_mmu_priv {
+ struct nvkm_mmu base;
};
static void
-nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
- struct nouveau_gpuobj *pgt[2])
+nv50_vm_map_pgt(struct nvkm_gpuobj *pgd, u32 pde, struct nvkm_gpuobj *pgt[2])
{
u64 phys = 0xdeadcafe00000000ULL;
u32 coverage = 0;
@@ -64,7 +62,7 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
}
static inline u64
-vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
+vm_addr(struct nvkm_vma *vma, u64 phys, u32 memtype, u32 target)
{
phys |= 1; /* present */
phys |= (u64)memtype << 40;
@@ -77,8 +75,8 @@ vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target)
}
static void
-nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
- struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
+nv50_vm_map(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+ struct nvkm_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
{
u32 comp = (mem->memtype & 0x180) >> 7;
u32 block, target;
@@ -86,8 +84,8 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
/* IGPs don't have real VRAM, re-target to stolen system memory */
target = 0;
- if (nouveau_fb(vma->vm->vmm)->ram->stolen) {
- phys += nouveau_fb(vma->vm->vmm)->ram->stolen;
+ if (nvkm_fb(vma->vm->mmu)->ram->stolen) {
+ phys += nvkm_fb(vma->vm->mmu)->ram->stolen;
target = 3;
}
@@ -124,8 +122,8 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
static void
-nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
- struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
+nv50_vm_map_sg(struct nvkm_vma *vma, struct nvkm_gpuobj *pgt,
+ struct nvkm_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
{
u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 3 : 2;
pte <<= 3;
@@ -138,7 +136,7 @@ nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
}
static void
-nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
+nv50_vm_unmap(struct nvkm_gpuobj *pgt, u32 pte, u32 cnt)
{
pte <<= 3;
while (cnt--) {
@@ -149,11 +147,11 @@ nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
static void
-nv50_vm_flush(struct nouveau_vm *vm)
+nv50_vm_flush(struct nvkm_vm *vm)
{
- struct nv50_vmmgr_priv *priv = (void *)vm->vmm;
- struct nouveau_bar *bar = nouveau_bar(priv);
- struct nouveau_engine *engine;
+ struct nv50_mmu_priv *priv = (void *)vm->mmu;
+ struct nvkm_bar *bar = nvkm_bar(priv);
+ struct nvkm_engine *engine;
int i, vme;
bar->flush(bar);
@@ -164,21 +162,24 @@ nv50_vm_flush(struct nouveau_vm *vm)
continue;
/* unfortunate hw bug workaround... */
- engine = nouveau_engine(priv, i);
+ engine = nvkm_engine(priv, i);
if (engine && engine->tlb_flush) {
engine->tlb_flush(engine);
continue;
}
switch (i) {
- case NVDEV_ENGINE_GR : vme = 0x00; break;
- case NVDEV_ENGINE_VP : vme = 0x01; break;
- case NVDEV_SUBDEV_BAR : vme = 0x06; break;
- case NVDEV_ENGINE_PPP :
- case NVDEV_ENGINE_MPEG : vme = 0x08; break;
- case NVDEV_ENGINE_BSP : vme = 0x09; break;
- case NVDEV_ENGINE_CRYPT: vme = 0x0a; break;
- case NVDEV_ENGINE_COPY0: vme = 0x0d; break;
+ case NVDEV_ENGINE_GR : vme = 0x00; break;
+ case NVDEV_ENGINE_VP :
+ case NVDEV_ENGINE_MSPDEC: vme = 0x01; break;
+ case NVDEV_SUBDEV_BAR : vme = 0x06; break;
+ case NVDEV_ENGINE_MSPPP :
+ case NVDEV_ENGINE_MPEG : vme = 0x08; break;
+ case NVDEV_ENGINE_BSP :
+ case NVDEV_ENGINE_MSVLD : vme = 0x09; break;
+ case NVDEV_ENGINE_CIPHER:
+ case NVDEV_ENGINE_SEC : vme = 0x0a; break;
+ case NVDEV_ENGINE_CE0 : vme = 0x0d; break;
default:
continue;
}
@@ -191,25 +192,25 @@ nv50_vm_flush(struct nouveau_vm *vm)
}
static int
-nv50_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
- u64 mm_offset, struct nouveau_vm **pvm)
+nv50_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length,
+ u64 mm_offset, struct nvkm_vm **pvm)
{
- u32 block = (1 << (vmm->pgt_bits + 12));
+ u32 block = (1 << (mmu->pgt_bits + 12));
if (block > length)
block = length;
- return nouveau_vm_create(vmm, offset, length, mm_offset, block, pvm);
+ return nvkm_vm_create(mmu, offset, length, mm_offset, block, pvm);
}
static int
-nv50_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_mmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv50_vmmgr_priv *priv;
+ struct nv50_mmu_priv *priv;
int ret;
- ret = nouveau_vmmgr_create(parent, engine, oclass, "VM", "vm", &priv);
+ ret = nvkm_mmu_create(parent, engine, oclass, "VM", "vm", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -228,13 +229,13 @@ nv50_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
-nv50_vmmgr_oclass = {
- .handle = NV_SUBDEV(VM, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv50_vmmgr_ctor,
- .dtor = _nouveau_vmmgr_dtor,
- .init = _nouveau_vmmgr_init,
- .fini = _nouveau_vmmgr_fini,
+struct nvkm_oclass
+nv50_mmu_oclass = {
+ .handle = NV_SUBDEV(MMU, 0x50),
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = nv50_mmu_ctor,
+ .dtor = _nvkm_mmu_dtor,
+ .init = _nvkm_mmu_init,
+ .fini = _nvkm_mmu_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/Kbuild
new file mode 100644
index 000000000000..1a479e050b54
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/Kbuild
@@ -0,0 +1,3 @@
+nvkm-y += nvkm/subdev/mxm/base.o
+nvkm-y += nvkm/subdev/mxm/mxms.o
+nvkm-y += nvkm/subdev/mxm/nv50.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
index 51fcf7960417..0ca9dcabb6d3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
@@ -21,18 +21,16 @@
*
* Authors: Ben Skeggs
*/
+#include "mxms.h"
+#include <core/device.h>
#include <core/option.h>
-
-#include <subdev/i2c.h>
-#include <subdev/mxm.h>
#include <subdev/bios.h>
#include <subdev/bios/mxm.h>
-
-#include "mxms.h"
+#include <subdev/i2c.h>
static bool
-mxm_shadow_rom_fetch(struct nouveau_i2c_port *i2c, u8 addr,
+mxm_shadow_rom_fetch(struct nvkm_i2c_port *i2c, u8 addr,
u8 offset, u8 size, u8 *data)
{
struct i2c_msg msgs[] = {
@@ -44,11 +42,11 @@ mxm_shadow_rom_fetch(struct nouveau_i2c_port *i2c, u8 addr,
}
static bool
-mxm_shadow_rom(struct nouveau_mxm *mxm, u8 version)
+mxm_shadow_rom(struct nvkm_mxm *mxm, u8 version)
{
- struct nouveau_bios *bios = nouveau_bios(mxm);
- struct nouveau_i2c *i2c = nouveau_i2c(mxm);
- struct nouveau_i2c_port *port = NULL;
+ struct nvkm_bios *bios = nvkm_bios(mxm);
+ struct nvkm_i2c *i2c = nvkm_i2c(mxm);
+ struct nvkm_i2c_port *port = NULL;
u8 i2cidx, mxms[6], addr, size;
i2cidx = mxm_ddc_map(bios, 1 /* LVDS_DDC */) & 0x0f;
@@ -79,9 +77,9 @@ mxm_shadow_rom(struct nouveau_mxm *mxm, u8 version)
#if defined(CONFIG_ACPI)
static bool
-mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version)
+mxm_shadow_dsm(struct nvkm_mxm *mxm, u8 version)
{
- struct nouveau_device *device = nv_device(mxm);
+ struct nvkm_device *device = nv_device(mxm);
static char muid[] = {
0x00, 0xA4, 0x04, 0x40, 0x7D, 0x91, 0xF2, 0x4C,
0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65
@@ -129,7 +127,7 @@ mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version)
#define WMI_WMMX_GUID "F6CB5C3C-9CAE-4EBD-B577-931EA32A2CC0"
static u8
-wmi_wmmx_mxmi(struct nouveau_mxm *mxm, u8 version)
+wmi_wmmx_mxmi(struct nvkm_mxm *mxm, u8 version)
{
u32 mxmi_args[] = { 0x494D584D /* MXMI */, version, 0 };
struct acpi_buffer args = { sizeof(mxmi_args), mxmi_args };
@@ -158,7 +156,7 @@ wmi_wmmx_mxmi(struct nouveau_mxm *mxm, u8 version)
}
static bool
-mxm_shadow_wmi(struct nouveau_mxm *mxm, u8 version)
+mxm_shadow_wmi(struct nvkm_mxm *mxm, u8 version)
{
u32 mxms_args[] = { 0x534D584D /* MXMS */, version, 0 };
struct acpi_buffer args = { sizeof(mxms_args), mxms_args };
@@ -186,7 +184,7 @@ mxm_shadow_wmi(struct nouveau_mxm *mxm, u8 version)
obj = retn.pointer;
if (obj->type == ACPI_TYPE_BUFFER) {
mxm->mxms = kmemdup(obj->buffer.pointer,
- obj->buffer.length, GFP_KERNEL);
+ obj->buffer.length, GFP_KERNEL);
}
kfree(obj);
@@ -196,7 +194,7 @@ mxm_shadow_wmi(struct nouveau_mxm *mxm, u8 version)
static struct mxm_shadow_h {
const char *name;
- bool (*exec)(struct nouveau_mxm *, u8 version);
+ bool (*exec)(struct nvkm_mxm *, u8 version);
} _mxm_shadow[] = {
{ "ROM", mxm_shadow_rom },
#if defined(CONFIG_ACPI)
@@ -209,7 +207,7 @@ static struct mxm_shadow_h {
};
static int
-mxm_shadow(struct nouveau_mxm *mxm, u8 version)
+mxm_shadow(struct nvkm_mxm *mxm, u8 version)
{
struct mxm_shadow_h *shadow = _mxm_shadow;
do {
@@ -225,19 +223,18 @@ mxm_shadow(struct nouveau_mxm *mxm, u8 version)
}
int
-nouveau_mxm_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+nvkm_mxm_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_device *device = nv_device(parent);
- struct nouveau_bios *bios = nouveau_bios(device);
- struct nouveau_mxm *mxm;
+ struct nvkm_device *device = nv_device(parent);
+ struct nvkm_bios *bios = nvkm_bios(device);
+ struct nvkm_mxm *mxm;
u8 ver, len;
u16 data;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "MXM", "mxm",
- length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "MXM", "mxm",
+ length, pobject);
mxm = *pobject;
if (ret)
return ret;
@@ -268,7 +265,7 @@ nouveau_mxm_create_(struct nouveau_object *parent,
mxms_version(mxm) >> 8, mxms_version(mxm) & 0xff);
mxms_foreach(mxm, 0, NULL, NULL);
- if (nouveau_boolopt(device->cfgopt, "NvMXMDCB", true))
+ if (nvkm_boolopt(device->cfgopt, "NvMXMDCB", true))
mxm->action |= MXM_SANITISE_DCB;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/mxms.c
index 4bde7f7f7b81..a9b1d63fed58 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/mxms.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/mxms.c
@@ -21,22 +21,20 @@
*
* Authors: Ben Skeggs
*/
-
-#include <subdev/mxm.h>
#include "mxms.h"
#define ROM16(x) le16_to_cpu(*(u16 *)&(x))
#define ROM32(x) le32_to_cpu(*(u32 *)&(x))
static u8 *
-mxms_data(struct nouveau_mxm *mxm)
+mxms_data(struct nvkm_mxm *mxm)
{
return mxm->mxms;
}
u16
-mxms_version(struct nouveau_mxm *mxm)
+mxms_version(struct nvkm_mxm *mxm)
{
u8 *mxms = mxms_data(mxm);
u16 version = (mxms[4] << 8) | mxms[5];
@@ -54,19 +52,19 @@ mxms_version(struct nouveau_mxm *mxm)
}
u16
-mxms_headerlen(struct nouveau_mxm *mxm)
+mxms_headerlen(struct nvkm_mxm *mxm)
{
return 8;
}
u16
-mxms_structlen(struct nouveau_mxm *mxm)
+mxms_structlen(struct nvkm_mxm *mxm)
{
return *(u16 *)&mxms_data(mxm)[6];
}
bool
-mxms_checksum(struct nouveau_mxm *mxm)
+mxms_checksum(struct nvkm_mxm *mxm)
{
u16 size = mxms_headerlen(mxm) + mxms_structlen(mxm);
u8 *mxms = mxms_data(mxm), sum = 0;
@@ -80,7 +78,7 @@ mxms_checksum(struct nouveau_mxm *mxm)
}
bool
-mxms_valid(struct nouveau_mxm *mxm)
+mxms_valid(struct nvkm_mxm *mxm)
{
u8 *mxms = mxms_data(mxm);
if (*(u32 *)mxms != 0x5f4d584d) {
@@ -95,8 +93,8 @@ mxms_valid(struct nouveau_mxm *mxm)
}
bool
-mxms_foreach(struct nouveau_mxm *mxm, u8 types,
- bool (*exec)(struct nouveau_mxm *, u8 *, void *), void *info)
+mxms_foreach(struct nvkm_mxm *mxm, u8 types,
+ bool (*exec)(struct nvkm_mxm *, u8 *, void *), void *info)
{
u8 *mxms = mxms_data(mxm);
u8 *desc = mxms + mxms_headerlen(mxm);
@@ -180,7 +178,7 @@ mxms_foreach(struct nouveau_mxm *mxm, u8 types,
}
void
-mxms_output_device(struct nouveau_mxm *mxm, u8 *pdata, struct mxms_odev *desc)
+mxms_output_device(struct nvkm_mxm *mxm, u8 *pdata, struct mxms_odev *desc)
{
u64 data = ROM32(pdata[0]);
if (mxms_version(mxm) >= 0x0300)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/mxms.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/mxms.h
new file mode 100644
index 000000000000..4ef804012d06
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/mxms.h
@@ -0,0 +1,22 @@
+#ifndef __NVMXM_MXMS_H__
+#define __NVMXM_MXMS_H__
+#include <subdev/mxm.h>
+
+struct mxms_odev {
+ u8 outp_type;
+ u8 conn_type;
+ u8 ddc_port;
+ u8 dig_conn;
+};
+
+void mxms_output_device(struct nvkm_mxm *, u8 *, struct mxms_odev *);
+
+u16 mxms_version(struct nvkm_mxm *);
+u16 mxms_headerlen(struct nvkm_mxm *);
+u16 mxms_structlen(struct nvkm_mxm *);
+bool mxms_checksum(struct nvkm_mxm *);
+bool mxms_valid(struct nvkm_mxm *);
+
+bool mxms_foreach(struct nvkm_mxm *, u8,
+ bool (*)(struct nvkm_mxm *, u8 *, void *), void *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/nv50.c
index fcaabe8456e3..42cac13ca629 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/nv50.c
@@ -21,17 +21,15 @@
*
* Authors: Ben Skeggs
*/
+#include "mxms.h"
-#include <subdev/mxm.h>
#include <subdev/bios.h>
#include <subdev/bios/conn.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/mxm.h>
-#include "mxms.h"
-
struct nv50_mxm_priv {
- struct nouveau_mxm base;
+ struct nvkm_mxm base;
};
struct context {
@@ -40,7 +38,7 @@ struct context {
};
static bool
-mxm_match_tmds_partner(struct nouveau_mxm *mxm, u8 *data, void *info)
+mxm_match_tmds_partner(struct nvkm_mxm *mxm, u8 *data, void *info)
{
struct context *ctx = info;
struct mxms_odev desc;
@@ -53,9 +51,9 @@ mxm_match_tmds_partner(struct nouveau_mxm *mxm, u8 *data, void *info)
}
static bool
-mxm_match_dcb(struct nouveau_mxm *mxm, u8 *data, void *info)
+mxm_match_dcb(struct nvkm_mxm *mxm, u8 *data, void *info)
{
- struct nouveau_bios *bios = nouveau_bios(mxm);
+ struct nvkm_bios *bios = nvkm_bios(mxm);
struct context *ctx = info;
u64 desc = *(u64 *)data;
@@ -98,9 +96,9 @@ mxm_match_dcb(struct nouveau_mxm *mxm, u8 *data, void *info)
}
static int
-mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb)
+mxm_dcb_sanitise_entry(struct nvkm_bios *bios, void *data, int idx, u16 pdcb)
{
- struct nouveau_mxm *mxm = data;
+ struct nvkm_mxm *mxm = data;
struct context ctx = { .outp = (u32 *)(bios->data + pdcb) };
u8 type, i2cidx, link, ver, len;
u8 *conn;
@@ -180,7 +178,7 @@ mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb)
}
static bool
-mxm_show_unmatched(struct nouveau_mxm *mxm, u8 *data, void *info)
+mxm_show_unmatched(struct nvkm_mxm *mxm, u8 *data, void *info)
{
u64 desc = *(u64 *)data;
if ((desc & 0xf0) != 0xf0)
@@ -189,9 +187,9 @@ mxm_show_unmatched(struct nouveau_mxm *mxm, u8 *data, void *info)
}
static void
-mxm_dcb_sanitise(struct nouveau_mxm *mxm)
+mxm_dcb_sanitise(struct nvkm_mxm *mxm)
{
- struct nouveau_bios *bios = nouveau_bios(mxm);
+ struct nvkm_bios *bios = nvkm_bios(mxm);
u8 ver, hdr, cnt, len;
u16 dcb = dcb_table(bios, &ver, &hdr, &cnt, &len);
if (dcb == 0x0000 || ver != 0x40) {
@@ -204,14 +202,14 @@ mxm_dcb_sanitise(struct nouveau_mxm *mxm)
}
static int
-nv50_mxm_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_mxm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_mxm_priv *priv;
int ret;
- ret = nouveau_mxm_create(parent, engine, oclass, &priv);
+ ret = nvkm_mxm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -221,13 +219,13 @@ nv50_mxm_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv50_mxm_oclass = {
.handle = NV_SUBDEV(MXM, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_mxm_ctor,
- .dtor = _nouveau_mxm_dtor,
- .init = _nouveau_mxm_init,
- .fini = _nouveau_mxm_fini,
+ .dtor = _nvkm_mxm_dtor,
+ .init = _nvkm_mxm_init,
+ .fini = _nvkm_mxm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild
new file mode 100644
index 000000000000..9a150d520225
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild
@@ -0,0 +1,8 @@
+nvkm-y += nvkm/subdev/pmu/base.o
+nvkm-y += nvkm/subdev/pmu/memx.o
+nvkm-y += nvkm/subdev/pmu/gt215.o
+nvkm-y += nvkm/subdev/pmu/gf100.o
+nvkm-y += nvkm/subdev/pmu/gf110.o
+nvkm-y += nvkm/subdev/pmu/gk104.o
+nvkm-y += nvkm/subdev/pmu/gk208.o
+nvkm-y += nvkm/subdev/pmu/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
new file mode 100644
index 000000000000..054b2d2eec35
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+#include <subdev/timer.h>
+
+void
+nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
+{
+ const struct nvkm_pmu_impl *impl = (void *)nv_oclass(pmu);
+ if (impl->pgob)
+ impl->pgob(pmu, enable);
+}
+
+static int
+nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2],
+ u32 process, u32 message, u32 data0, u32 data1)
+{
+ struct nvkm_subdev *subdev = nv_subdev(pmu);
+ u32 addr;
+
+ /* wait for a free slot in the fifo */
+ addr = nv_rd32(pmu, 0x10a4a0);
+ if (!nv_wait_ne(pmu, 0x10a4b0, 0xffffffff, addr ^ 8))
+ return -EBUSY;
+
+ /* we currently only support a single process at a time waiting
+ * on a synchronous reply, take the PMU mutex and tell the
+ * receive handler what we're waiting for
+ */
+ if (reply) {
+ mutex_lock(&subdev->mutex);
+ pmu->recv.message = message;
+ pmu->recv.process = process;
+ }
+
+ /* acquire data segment access */
+ do {
+ nv_wr32(pmu, 0x10a580, 0x00000001);
+ } while (nv_rd32(pmu, 0x10a580) != 0x00000001);
+
+ /* write the packet */
+ nv_wr32(pmu, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) +
+ pmu->send.base));
+ nv_wr32(pmu, 0x10a1c4, process);
+ nv_wr32(pmu, 0x10a1c4, message);
+ nv_wr32(pmu, 0x10a1c4, data0);
+ nv_wr32(pmu, 0x10a1c4, data1);
+ nv_wr32(pmu, 0x10a4a0, (addr + 1) & 0x0f);
+
+ /* release data segment access */
+ nv_wr32(pmu, 0x10a580, 0x00000000);
+
+ /* wait for reply, if requested */
+ if (reply) {
+ wait_event(pmu->recv.wait, (pmu->recv.process == 0));
+ reply[0] = pmu->recv.data[0];
+ reply[1] = pmu->recv.data[1];
+ mutex_unlock(&subdev->mutex);
+ }
+
+ return 0;
+}
+
+static void
+nvkm_pmu_recv(struct work_struct *work)
+{
+ struct nvkm_pmu *pmu = container_of(work, struct nvkm_pmu, recv.work);
+ u32 process, message, data0, data1;
+
+ /* nothing to do if GET == PUT */
+ u32 addr = nv_rd32(pmu, 0x10a4cc);
+ if (addr == nv_rd32(pmu, 0x10a4c8))
+ return;
+
+ /* acquire data segment access */
+ do {
+ nv_wr32(pmu, 0x10a580, 0x00000002);
+ } while (nv_rd32(pmu, 0x10a580) != 0x00000002);
+
+ /* read the packet */
+ nv_wr32(pmu, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) +
+ pmu->recv.base));
+ process = nv_rd32(pmu, 0x10a1c4);
+ message = nv_rd32(pmu, 0x10a1c4);
+ data0 = nv_rd32(pmu, 0x10a1c4);
+ data1 = nv_rd32(pmu, 0x10a1c4);
+ nv_wr32(pmu, 0x10a4cc, (addr + 1) & 0x0f);
+
+ /* release data segment access */
+ nv_wr32(pmu, 0x10a580, 0x00000000);
+
+ /* wake process if it's waiting on a synchronous reply */
+ if (pmu->recv.process) {
+ if (process == pmu->recv.process &&
+ message == pmu->recv.message) {
+ pmu->recv.data[0] = data0;
+ pmu->recv.data[1] = data1;
+ pmu->recv.process = 0;
+ wake_up(&pmu->recv.wait);
+ return;
+ }
+ }
+
+ /* right now there's no other expected responses from the engine,
+ * so assume that any unexpected message is an error.
+ */
+ nv_warn(pmu, "%c%c%c%c 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ (char)((process & 0x000000ff) >> 0),
+ (char)((process & 0x0000ff00) >> 8),
+ (char)((process & 0x00ff0000) >> 16),
+ (char)((process & 0xff000000) >> 24),
+ process, message, data0, data1);
+}
+
+static void
+nvkm_pmu_intr(struct nvkm_subdev *subdev)
+{
+ struct nvkm_pmu *pmu = (void *)subdev;
+ u32 disp = nv_rd32(pmu, 0x10a01c);
+ u32 intr = nv_rd32(pmu, 0x10a008) & disp & ~(disp >> 16);
+
+ if (intr & 0x00000020) {
+ u32 stat = nv_rd32(pmu, 0x10a16c);
+ if (stat & 0x80000000) {
+ nv_error(pmu, "UAS fault at 0x%06x addr 0x%08x\n",
+ stat & 0x00ffffff, nv_rd32(pmu, 0x10a168));
+ nv_wr32(pmu, 0x10a16c, 0x00000000);
+ intr &= ~0x00000020;
+ }
+ }
+
+ if (intr & 0x00000040) {
+ schedule_work(&pmu->recv.work);
+ nv_wr32(pmu, 0x10a004, 0x00000040);
+ intr &= ~0x00000040;
+ }
+
+ if (intr & 0x00000080) {
+ nv_info(pmu, "wr32 0x%06x 0x%08x\n", nv_rd32(pmu, 0x10a7a0),
+ nv_rd32(pmu, 0x10a7a4));
+ nv_wr32(pmu, 0x10a004, 0x00000080);
+ intr &= ~0x00000080;
+ }
+
+ if (intr) {
+ nv_error(pmu, "intr 0x%08x\n", intr);
+ nv_wr32(pmu, 0x10a004, intr);
+ }
+}
+
+int
+_nvkm_pmu_fini(struct nvkm_object *object, bool suspend)
+{
+ struct nvkm_pmu *pmu = (void *)object;
+
+ nv_wr32(pmu, 0x10a014, 0x00000060);
+ flush_work(&pmu->recv.work);
+
+ return nvkm_subdev_fini(&pmu->base, suspend);
+}
+
+int
+_nvkm_pmu_init(struct nvkm_object *object)
+{
+ const struct nvkm_pmu_impl *impl = (void *)object->oclass;
+ struct nvkm_pmu *pmu = (void *)object;
+ int ret, i;
+
+ ret = nvkm_subdev_init(&pmu->base);
+ if (ret)
+ return ret;
+
+ nv_subdev(pmu)->intr = nvkm_pmu_intr;
+ pmu->message = nvkm_pmu_send;
+ pmu->pgob = nvkm_pmu_pgob;
+
+ /* prevent previous ucode from running, wait for idle, reset */
+ nv_wr32(pmu, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */
+ nv_wait(pmu, 0x10a04c, 0xffffffff, 0x00000000);
+ nv_mask(pmu, 0x000200, 0x00002000, 0x00000000);
+ nv_mask(pmu, 0x000200, 0x00002000, 0x00002000);
+ nv_rd32(pmu, 0x000200);
+ nv_wait(pmu, 0x10a10c, 0x00000006, 0x00000000);
+
+ /* upload data segment */
+ nv_wr32(pmu, 0x10a1c0, 0x01000000);
+ for (i = 0; i < impl->data.size / 4; i++)
+ nv_wr32(pmu, 0x10a1c4, impl->data.data[i]);
+
+ /* upload code segment */
+ nv_wr32(pmu, 0x10a180, 0x01000000);
+ for (i = 0; i < impl->code.size / 4; i++) {
+ if ((i & 0x3f) == 0)
+ nv_wr32(pmu, 0x10a188, i >> 6);
+ nv_wr32(pmu, 0x10a184, impl->code.data[i]);
+ }
+
+ /* start it running */
+ nv_wr32(pmu, 0x10a10c, 0x00000000);
+ nv_wr32(pmu, 0x10a104, 0x00000000);
+ nv_wr32(pmu, 0x10a100, 0x00000002);
+
+ /* wait for valid host->pmu ring configuration */
+ if (!nv_wait_ne(pmu, 0x10a4d0, 0xffffffff, 0x00000000))
+ return -EBUSY;
+ pmu->send.base = nv_rd32(pmu, 0x10a4d0) & 0x0000ffff;
+ pmu->send.size = nv_rd32(pmu, 0x10a4d0) >> 16;
+
+ /* wait for valid pmu->host ring configuration */
+ if (!nv_wait_ne(pmu, 0x10a4dc, 0xffffffff, 0x00000000))
+ return -EBUSY;
+ pmu->recv.base = nv_rd32(pmu, 0x10a4dc) & 0x0000ffff;
+ pmu->recv.size = nv_rd32(pmu, 0x10a4dc) >> 16;
+
+ nv_wr32(pmu, 0x10a010, 0x000000e0);
+ return 0;
+}
+
+int
+nvkm_pmu_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
+{
+ struct nvkm_pmu *pmu;
+ int ret;
+
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "PMU",
+ "pmu", length, pobject);
+ pmu = *pobject;
+ if (ret)
+ return ret;
+
+ INIT_WORK(&pmu->recv.work, nvkm_pmu_recv);
+ init_waitqueue_head(&pmu->recv.wait);
+ return 0;
+}
+
+int
+_nvkm_pmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct nvkm_pmu *pmu;
+ int ret = nvkm_pmu_create(parent, engine, oclass, &pmu);
+ *pobject = nv_object(pmu);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/arith.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/arith.fuc
index 214a6d9e088d..214a6d9e088d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/arith.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/arith.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3
index 21bf8cc7618f..37e8407b7462 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3
@@ -32,7 +32,7 @@
#include "macros.fuc"
-.section #nvc0_pwr_data
+.section #gf100_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
@@ -56,7 +56,7 @@
#undef INCLUDE_DATA
.align 256
-.section #nvc0_pwr_code
+.section #gf100_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h
index 90221d973f84..302557c52d03 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvc0_pwr_data[] = {
+uint32_t gf100_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
@@ -916,7 +916,7 @@ uint32_t nvc0_pwr_data[] = {
0x00000000,
};
-uint32_t nvc0_pwr_code[] = {
+uint32_t gf100_pmu_code[] = {
0x039e0ef5,
/* 0x0004: rd32 */
0x07a007f1,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf110.fuc4
index b85443261569..ae9c3f18ae01 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf110.fuc4
@@ -32,7 +32,7 @@
#include "macros.fuc"
-.section #nvd0_pwr_data
+.section #gf110_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
@@ -56,7 +56,7 @@
#undef INCLUDE_DATA
.align 256
-.section #nvd0_pwr_code
+.section #gf110_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf110.fuc4.h
index 7e16aab44d85..a0c499e4543c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf110.fuc4.h
@@ -1,4 +1,4 @@
-uint32_t nvd0_pwr_data[] = {
+uint32_t gf110_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
@@ -915,7 +915,7 @@ uint32_t nvd0_pwr_data[] = {
0x00000000,
};
-uint32_t nvd0_pwr_code[] = {
+uint32_t gf110_pmu_code[] = {
0x034d0ef5,
/* 0x0004: rd32 */
0x07a007f1,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5
index b439519ec866..093dc81880f4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5
@@ -32,7 +32,7 @@
#include "macros.fuc"
-.section #nv108_pwr_data
+.section #gk208_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
@@ -56,7 +56,7 @@
#undef INCLUDE_DATA
.align 256
-.section #nv108_pwr_code
+.section #gk208_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h
index 713e11e2953d..fe4f63deeaab 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h
@@ -1,4 +1,4 @@
-uint32_t nv108_pwr_data[] = {
+uint32_t gk208_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
@@ -915,7 +915,7 @@ uint32_t nv108_pwr_data[] = {
0x00000000,
};
-uint32_t nv108_pwr_code[] = {
+uint32_t gk208_pmu_code[] = {
0x031c0ef5,
/* 0x0004: rd32 */
0xf607a040,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3
index daa06c1c655e..393049fc8b2d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3
@@ -32,7 +32,7 @@
#include "macros.fuc"
-.section #nva3_pwr_data
+.section #gt215_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
@@ -56,7 +56,7 @@
#undef INCLUDE_DATA
.align 256
-.section #nva3_pwr_code
+.section #gt215_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h
index d1f9b6cb66d7..2686f8fad0f5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nva3_pwr_data[] = {
+uint32_t gt215_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
@@ -916,7 +916,7 @@ uint32_t nva3_pwr_data[] = {
0x00000000,
};
-uint32_t nva3_pwr_code[] = {
+uint32_t gt215_pmu_code[] = {
0x039e0ef5,
/* 0x0004: rd32 */
0x07a007f1,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc
index c2bb616a8da5..c2bb616a8da5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/i2c_.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/i2c_.fuc
index 757dda700024..757dda700024 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/i2c_.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/i2c_.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/idle.fuc
index 98f1c3738b42..98f1c3738b42 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/idle.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc
index 5cf5be63cbef..5cf5be63cbef 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc
index 96fc984dafdc..96fc984dafdc 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc
index ec03f9a4290b..ec03f9a4290b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/os.h
index c8b06cb77e72..c8b06cb77e72 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/os.h
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc
index 38eadf705cbf..38eadf705cbf 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc
index 0c3a71bf5459..0c3a71bf5459 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
index 9a773e66efa4..78a4ea0101f1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
@@ -21,21 +21,20 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
-#include "fuc/nvc0.fuc.h"
+#include "fuc/gf100.fuc3.h"
-struct nouveau_oclass *
-nvc0_pwr_oclass = &(struct nvkm_pwr_impl) {
- .base.handle = NV_SUBDEV(PWR, 0xc0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = _nouveau_pwr_init,
- .fini = _nouveau_pwr_fini,
+struct nvkm_oclass *
+gf100_pmu_oclass = &(struct nvkm_pmu_impl) {
+ .base.handle = NV_SUBDEV(PMU, 0xc0),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_pmu_ctor,
+ .dtor = _nvkm_pmu_dtor,
+ .init = _nvkm_pmu_init,
+ .fini = _nvkm_pmu_fini,
},
- .code.data = nvc0_pwr_code,
- .code.size = sizeof(nvc0_pwr_code),
- .data.data = nvc0_pwr_data,
- .data.size = sizeof(nvc0_pwr_data),
+ .code.data = gf100_pmu_code,
+ .code.size = sizeof(gf100_pmu_code),
+ .data.data = gf100_pmu_data,
+ .data.size = sizeof(gf100_pmu_data),
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf110.c
index 2b29be5d08ac..6b3a23839ff0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf110.c
@@ -21,21 +21,20 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
-#include "fuc/nvd0.fuc.h"
+#include "fuc/gf110.fuc4.h"
-struct nouveau_oclass *
-nvd0_pwr_oclass = &(struct nvkm_pwr_impl) {
- .base.handle = NV_SUBDEV(PWR, 0xd0),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = _nouveau_pwr_init,
- .fini = _nouveau_pwr_fini,
+struct nvkm_oclass *
+gf110_pmu_oclass = &(struct nvkm_pmu_impl) {
+ .base.handle = NV_SUBDEV(PMU, 0xd0),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_pmu_ctor,
+ .dtor = _nvkm_pmu_dtor,
+ .init = _nvkm_pmu_init,
+ .fini = _nvkm_pmu_fini,
},
- .code.data = nvd0_pwr_code,
- .code.size = sizeof(nvd0_pwr_code),
- .data.data = nvd0_pwr_data,
- .data.size = sizeof(nvd0_pwr_data),
+ .code.data = gf110_pmu_code,
+ .code.size = sizeof(gf110_pmu_code),
+ .data.data = gf110_pmu_data,
+ .data.size = sizeof(gf110_pmu_data),
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
index d76612999b9f..28fdb8ea9ed8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
@@ -21,49 +21,47 @@
*
* Authors: Ben Skeggs
*/
-
+#define gf110_pmu_code gk104_pmu_code
+#define gf110_pmu_data gk104_pmu_data
#include "priv.h"
-
-#define nvd0_pwr_code gk104_pwr_code
-#define nvd0_pwr_data gk104_pwr_data
-#include "fuc/nvd0.fuc.h"
+#include "fuc/gf110.fuc4.h"
static void
-gk104_pwr_pgob(struct nouveau_pwr *ppwr, bool enable)
+gk104_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
{
- nv_mask(ppwr, 0x000200, 0x00001000, 0x00000000);
- nv_rd32(ppwr, 0x000200);
- nv_mask(ppwr, 0x000200, 0x08000000, 0x08000000);
+ nv_mask(pmu, 0x000200, 0x00001000, 0x00000000);
+ nv_rd32(pmu, 0x000200);
+ nv_mask(pmu, 0x000200, 0x08000000, 0x08000000);
msleep(50);
- nv_mask(ppwr, 0x10a78c, 0x00000002, 0x00000002);
- nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000001);
- nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000000);
+ nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000002);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000);
- nv_mask(ppwr, 0x020004, 0xc0000000, enable ? 0xc0000000 : 0x40000000);
+ nv_mask(pmu, 0x020004, 0xc0000000, enable ? 0xc0000000 : 0x40000000);
msleep(50);
- nv_mask(ppwr, 0x10a78c, 0x00000002, 0x00000000);
- nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000001);
- nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000000);
+ nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000000);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x08000000, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x00001000, 0x00001000);
- nv_rd32(ppwr, 0x000200);
+ nv_mask(pmu, 0x000200, 0x08000000, 0x00000000);
+ nv_mask(pmu, 0x000200, 0x00001000, 0x00001000);
+ nv_rd32(pmu, 0x000200);
}
-struct nouveau_oclass *
-gk104_pwr_oclass = &(struct nvkm_pwr_impl) {
- .base.handle = NV_SUBDEV(PWR, 0xe4),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = _nouveau_pwr_init,
- .fini = _nouveau_pwr_fini,
+struct nvkm_oclass *
+gk104_pmu_oclass = &(struct nvkm_pmu_impl) {
+ .base.handle = NV_SUBDEV(PMU, 0xe4),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_pmu_ctor,
+ .dtor = _nvkm_pmu_dtor,
+ .init = _nvkm_pmu_init,
+ .fini = _nvkm_pmu_fini,
},
- .code.data = gk104_pwr_code,
- .code.size = sizeof(gk104_pwr_code),
- .data.data = gk104_pwr_data,
- .data.size = sizeof(gk104_pwr_data),
- .pgob = gk104_pwr_pgob,
+ .code.data = gk104_pmu_code,
+ .code.size = sizeof(gk104_pmu_code),
+ .data.data = gk104_pmu_data,
+ .data.size = sizeof(gk104_pmu_data),
+ .pgob = gk104_pmu_pgob,
}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
index 04ff7c3c34e9..6f9c09af1a49 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
@@ -21,21 +21,20 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
-#include "fuc/nv108.fuc.h"
+#include "fuc/gk208.fuc5.h"
-struct nouveau_oclass *
-nv108_pwr_oclass = &(struct nvkm_pwr_impl) {
- .base.handle = NV_SUBDEV(PWR, 0x00),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = _nouveau_pwr_init,
- .fini = _nouveau_pwr_fini,
+struct nvkm_oclass *
+gk208_pmu_oclass = &(struct nvkm_pmu_impl) {
+ .base.handle = NV_SUBDEV(PMU, 0x00),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_pmu_ctor,
+ .dtor = _nvkm_pmu_dtor,
+ .init = _nvkm_pmu_init,
+ .fini = _nvkm_pmu_fini,
},
- .code.data = nv108_pwr_code,
- .code.size = sizeof(nv108_pwr_code),
- .data.data = nv108_pwr_data,
- .data.size = sizeof(nv108_pwr_data),
+ .code.data = gk208_pmu_code,
+ .code.size = sizeof(gk208_pmu_code),
+ .data.data = gk208_pmu_data,
+ .data.size = sizeof(gk208_pmu_data),
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
new file mode 100644
index 000000000000..a49934bbe637
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "priv.h"
+
+#include <subdev/clk.h>
+#include <subdev/timer.h>
+#include <subdev/volt.h>
+
+#define BUSY_SLOT 0
+#define CLK_SLOT 7
+
+struct gk20a_pmu_dvfs_data {
+ int p_load_target;
+ int p_load_max;
+ int p_smooth;
+ unsigned int avg_load;
+};
+
+struct gk20a_pmu_priv {
+ struct nvkm_pmu base;
+ struct nvkm_alarm alarm;
+ struct gk20a_pmu_dvfs_data *data;
+};
+
+struct gk20a_pmu_dvfs_dev_status {
+ unsigned long total;
+ unsigned long busy;
+ int cur_state;
+};
+
+static int
+gk20a_pmu_dvfs_target(struct gk20a_pmu_priv *priv, int *state)
+{
+ struct nvkm_clk *clk = nvkm_clk(priv);
+
+ return nvkm_clk_astate(clk, *state, 0, false);
+}
+
+static int
+gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu_priv *priv, int *state)
+{
+ struct nvkm_clk *clk = nvkm_clk(priv);
+
+ *state = clk->pstate;
+ return 0;
+}
+
+static int
+gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu_priv *priv,
+ int *state, int load)
+{
+ struct gk20a_pmu_dvfs_data *data = priv->data;
+ struct nvkm_clk *clk = nvkm_clk(priv);
+ int cur_level, level;
+
+ /* For GK20A, the performance level is directly mapped to pstate */
+ level = cur_level = clk->pstate;
+
+ if (load > data->p_load_max) {
+ level = min(clk->state_nr - 1, level + (clk->state_nr / 3));
+ } else {
+ level += ((load - data->p_load_target) * 10 /
+ data->p_load_target) / 2;
+ level = max(0, level);
+ level = min(clk->state_nr - 1, level);
+ }
+
+ nv_trace(priv, "cur level = %d, new level = %d\n", cur_level, level);
+
+ *state = level;
+
+ if (level == cur_level)
+ return 0;
+ else
+ return 1;
+}
+
+static int
+gk20a_pmu_dvfs_get_dev_status(struct gk20a_pmu_priv *priv,
+ struct gk20a_pmu_dvfs_dev_status *status)
+{
+ status->busy = nv_rd32(priv, 0x10a508 + (BUSY_SLOT * 0x10));
+ status->total= nv_rd32(priv, 0x10a508 + (CLK_SLOT * 0x10));
+ return 0;
+}
+
+static void
+gk20a_pmu_dvfs_reset_dev_status(struct gk20a_pmu_priv *priv)
+{
+ nv_wr32(priv, 0x10a508 + (BUSY_SLOT * 0x10), 0x80000000);
+ nv_wr32(priv, 0x10a508 + (CLK_SLOT * 0x10), 0x80000000);
+}
+
+static void
+gk20a_pmu_dvfs_work(struct nvkm_alarm *alarm)
+{
+ struct gk20a_pmu_priv *priv =
+ container_of(alarm, struct gk20a_pmu_priv, alarm);
+ struct gk20a_pmu_dvfs_data *data = priv->data;
+ struct gk20a_pmu_dvfs_dev_status status;
+ struct nvkm_clk *clk = nvkm_clk(priv);
+ struct nvkm_volt *volt = nvkm_volt(priv);
+ u32 utilization = 0;
+ int state, ret;
+
+ /*
+ * The PMU is initialized before CLK and VOLT, so we have to make sure the
+ * CLK and VOLT are ready here.
+ */
+ if (!clk || !volt)
+ goto resched;
+
+ ret = gk20a_pmu_dvfs_get_dev_status(priv, &status);
+ if (ret) {
+ nv_warn(priv, "failed to get device status\n");
+ goto resched;
+ }
+
+ if (status.total)
+ utilization = div_u64((u64)status.busy * 100, status.total);
+
+ data->avg_load = (data->p_smooth * data->avg_load) + utilization;
+ data->avg_load /= data->p_smooth + 1;
+ nv_trace(priv, "utilization = %d %%, avg_load = %d %%\n",
+ utilization, data->avg_load);
+
+ ret = gk20a_pmu_dvfs_get_cur_state(priv, &state);
+ if (ret) {
+ nv_warn(priv, "failed to get current state\n");
+ goto resched;
+ }
+
+ if (gk20a_pmu_dvfs_get_target_state(priv, &state, data->avg_load)) {
+ nv_trace(priv, "set new state to %d\n", state);
+ gk20a_pmu_dvfs_target(priv, &state);
+ }
+
+resched:
+ gk20a_pmu_dvfs_reset_dev_status(priv);
+ nvkm_timer_alarm(priv, 100000000, alarm);
+}
+
+int
+gk20a_pmu_fini(struct nvkm_object *object, bool suspend)
+{
+ struct nvkm_pmu *pmu = (void *)object;
+ struct gk20a_pmu_priv *priv = (void *)pmu;
+
+ nvkm_timer_alarm_cancel(priv, &priv->alarm);
+
+ return nvkm_subdev_fini(&pmu->base, suspend);
+}
+
+int
+gk20a_pmu_init(struct nvkm_object *object)
+{
+ struct nvkm_pmu *pmu = (void *)object;
+ struct gk20a_pmu_priv *priv = (void *)pmu;
+ int ret;
+
+ ret = nvkm_subdev_init(&pmu->base);
+ if (ret)
+ return ret;
+
+ pmu->pgob = nvkm_pmu_pgob;
+
+ /* init pwr perf counter */
+ nv_wr32(pmu, 0x10a504 + (BUSY_SLOT * 0x10), 0x00200001);
+ nv_wr32(pmu, 0x10a50c + (BUSY_SLOT * 0x10), 0x00000002);
+ nv_wr32(pmu, 0x10a50c + (CLK_SLOT * 0x10), 0x00000003);
+
+ nvkm_timer_alarm(pmu, 2000000000, &priv->alarm);
+ return ret;
+}
+
+struct gk20a_pmu_dvfs_data gk20a_dvfs_data= {
+ .p_load_target = 70,
+ .p_load_max = 90,
+ .p_smooth = 1,
+};
+
+static int
+gk20a_pmu_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gk20a_pmu_priv *priv;
+ int ret;
+
+ ret = nvkm_pmu_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ priv->data = &gk20a_dvfs_data;
+
+ nvkm_alarm_init(&priv->alarm, gk20a_pmu_dvfs_work);
+ return 0;
+}
+
+struct nvkm_oclass *
+gk20a_pmu_oclass = &(struct nvkm_pmu_impl) {
+ .base.handle = NV_SUBDEV(PMU, 0xea),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gk20a_pmu_ctor,
+ .dtor = _nvkm_pmu_dtor,
+ .init = gk20a_pmu_init,
+ .fini = gk20a_pmu_fini,
+ },
+}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
index 998d53076b8b..30aaeb21de41 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
@@ -21,30 +21,29 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
-#include "fuc/nva3.fuc.h"
+#include "fuc/gt215.fuc3.h"
static int
-nva3_pwr_init(struct nouveau_object *object)
+gt215_pmu_init(struct nvkm_object *object)
{
- struct nouveau_pwr *ppwr = (void *)object;
- nv_mask(ppwr, 0x022210, 0x00000001, 0x00000000);
- nv_mask(ppwr, 0x022210, 0x00000001, 0x00000001);
- return nouveau_pwr_init(ppwr);
+ struct nvkm_pmu *pmu = (void *)object;
+ nv_mask(pmu, 0x022210, 0x00000001, 0x00000000);
+ nv_mask(pmu, 0x022210, 0x00000001, 0x00000001);
+ return nvkm_pmu_init(pmu);
}
-struct nouveau_oclass *
-nva3_pwr_oclass = &(struct nvkm_pwr_impl) {
- .base.handle = NV_SUBDEV(PWR, 0xa3),
- .base.ofuncs = &(struct nouveau_ofuncs) {
- .ctor = _nouveau_pwr_ctor,
- .dtor = _nouveau_pwr_dtor,
- .init = nva3_pwr_init,
- .fini = _nouveau_pwr_fini,
+struct nvkm_oclass *
+gt215_pmu_oclass = &(struct nvkm_pmu_impl) {
+ .base.handle = NV_SUBDEV(PMU, 0xa3),
+ .base.ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = _nvkm_pmu_ctor,
+ .dtor = _nvkm_pmu_dtor,
+ .init = gt215_pmu_init,
+ .fini = _nvkm_pmu_fini,
},
- .code.data = nva3_pwr_code,
- .code.size = sizeof(nva3_pwr_code),
- .data.data = nva3_pwr_data,
- .data.size = sizeof(nva3_pwr_data),
+ .code.data = gt215_pmu_code,
+ .code.size = sizeof(gt215_pmu_code),
+ .data.data = gt215_pmu_data,
+ .data.size = sizeof(gt215_pmu_data),
}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
new file mode 100644
index 000000000000..b75c5b885980
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
@@ -0,0 +1,200 @@
+#ifndef __NVKM_PMU_MEMX_H__
+#define __NVKM_PMU_MEMX_H__
+#include "priv.h"
+
+#include <core/device.h>
+
+struct nvkm_memx {
+ struct nvkm_pmu *pmu;
+ u32 base;
+ u32 size;
+ struct {
+ u32 mthd;
+ u32 size;
+ u32 data[64];
+ } c;
+};
+
+static void
+memx_out(struct nvkm_memx *memx)
+{
+ struct nvkm_pmu *pmu = memx->pmu;
+ int i;
+
+ if (memx->c.mthd) {
+ nv_wr32(pmu, 0x10a1c4, (memx->c.size << 16) | memx->c.mthd);
+ for (i = 0; i < memx->c.size; i++)
+ nv_wr32(pmu, 0x10a1c4, memx->c.data[i]);
+ memx->c.mthd = 0;
+ memx->c.size = 0;
+ }
+}
+
+static void
+memx_cmd(struct nvkm_memx *memx, u32 mthd, u32 size, u32 data[])
+{
+ if ((memx->c.size + size >= ARRAY_SIZE(memx->c.data)) ||
+ (memx->c.mthd && memx->c.mthd != mthd))
+ memx_out(memx);
+ memcpy(&memx->c.data[memx->c.size], data, size * sizeof(data[0]));
+ memx->c.size += size;
+ memx->c.mthd = mthd;
+}
+
+int
+nvkm_memx_init(struct nvkm_pmu *pmu, struct nvkm_memx **pmemx)
+{
+ struct nvkm_memx *memx;
+ u32 reply[2];
+ int ret;
+
+ ret = pmu->message(pmu, reply, PROC_MEMX, MEMX_MSG_INFO,
+ MEMX_INFO_DATA, 0);
+ if (ret)
+ return ret;
+
+ memx = *pmemx = kzalloc(sizeof(*memx), GFP_KERNEL);
+ if (!memx)
+ return -ENOMEM;
+ memx->pmu = pmu;
+ memx->base = reply[0];
+ memx->size = reply[1];
+
+ /* acquire data segment access */
+ do {
+ nv_wr32(pmu, 0x10a580, 0x00000003);
+ } while (nv_rd32(pmu, 0x10a580) != 0x00000003);
+ nv_wr32(pmu, 0x10a1c0, 0x01000000 | memx->base);
+ return 0;
+}
+
+int
+nvkm_memx_fini(struct nvkm_memx **pmemx, bool exec)
+{
+ struct nvkm_memx *memx = *pmemx;
+ struct nvkm_pmu *pmu = memx->pmu;
+ u32 finish, reply[2];
+
+ /* flush the cache... */
+ memx_out(memx);
+
+ /* release data segment access */
+ finish = nv_rd32(pmu, 0x10a1c0) & 0x00ffffff;
+ nv_wr32(pmu, 0x10a580, 0x00000000);
+
+ /* call MEMX process to execute the script, and wait for reply */
+ if (exec) {
+ pmu->message(pmu, reply, PROC_MEMX, MEMX_MSG_EXEC,
+ memx->base, finish);
+ }
+
+ nv_debug(memx->pmu, "Exec took %uns, PMU_IN %08x\n",
+ reply[0], reply[1]);
+ kfree(memx);
+ return 0;
+}
+
+void
+nvkm_memx_wr32(struct nvkm_memx *memx, u32 addr, u32 data)
+{
+ nv_debug(memx->pmu, "R[%06x] = 0x%08x\n", addr, data);
+ memx_cmd(memx, MEMX_WR32, 2, (u32[]){ addr, data });
+}
+
+void
+nvkm_memx_wait(struct nvkm_memx *memx,
+ u32 addr, u32 mask, u32 data, u32 nsec)
+{
+ nv_debug(memx->pmu, "R[%06x] & 0x%08x == 0x%08x, %d us\n",
+ addr, mask, data, nsec);
+ memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, mask, data, nsec });
+ memx_out(memx); /* fuc can't handle multiple */
+}
+
+void
+nvkm_memx_nsec(struct nvkm_memx *memx, u32 nsec)
+{
+ nv_debug(memx->pmu, " DELAY = %d ns\n", nsec);
+ memx_cmd(memx, MEMX_DELAY, 1, (u32[]){ nsec });
+ memx_out(memx); /* fuc can't handle multiple */
+}
+
+void
+nvkm_memx_wait_vblank(struct nvkm_memx *memx)
+{
+ struct nvkm_pmu *pmu = memx->pmu;
+ u32 heads, x, y, px = 0;
+ int i, head_sync;
+
+ if (nv_device(pmu)->chipset < 0xd0) {
+ heads = nv_rd32(pmu, 0x610050);
+ for (i = 0; i < 2; i++) {
+ /* Heuristic: sync to head with biggest resolution */
+ if (heads & (2 << (i << 3))) {
+ x = nv_rd32(pmu, 0x610b40 + (0x540 * i));
+ y = (x & 0xffff0000) >> 16;
+ x &= 0x0000ffff;
+ if ((x * y) > px) {
+ px = (x * y);
+ head_sync = i;
+ }
+ }
+ }
+ }
+
+ if (px == 0) {
+ nv_debug(memx->pmu, "WAIT VBLANK !NO ACTIVE HEAD\n");
+ return;
+ }
+
+ nv_debug(memx->pmu, "WAIT VBLANK HEAD%d\n", head_sync);
+ memx_cmd(memx, MEMX_VBLANK, 1, (u32[]){ head_sync });
+ memx_out(memx); /* fuc can't handle multiple */
+}
+
+void
+nvkm_memx_train(struct nvkm_memx *memx)
+{
+ nv_debug(memx->pmu, " MEM TRAIN\n");
+ memx_cmd(memx, MEMX_TRAIN, 0, NULL);
+}
+
+int
+nvkm_memx_train_result(struct nvkm_pmu *pmu, u32 *res, int rsize)
+{
+ u32 reply[2], base, size, i;
+ int ret;
+
+ ret = pmu->message(pmu, reply, PROC_MEMX, MEMX_MSG_INFO,
+ MEMX_INFO_TRAIN, 0);
+ if (ret)
+ return ret;
+
+ base = reply[0];
+ size = reply[1] >> 2;
+ if (size > rsize)
+ return -ENOMEM;
+
+ /* read the packet */
+ nv_wr32(pmu, 0x10a1c0, 0x02000000 | base);
+
+ for (i = 0; i < size; i++)
+ res[i] = nv_rd32(pmu, 0x10a1c4);
+
+ return 0;
+}
+
+void
+nvkm_memx_block(struct nvkm_memx *memx)
+{
+ nv_debug(memx->pmu, " HOST BLOCKED\n");
+ memx_cmd(memx, MEMX_ENTER, 0, NULL);
+}
+
+void
+nvkm_memx_unblock(struct nvkm_memx *memx)
+{
+ nv_debug(memx->pmu, " HOST UNBLOCKED\n");
+ memx_cmd(memx, MEMX_LEAVE, 0, NULL);
+}
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
new file mode 100644
index 000000000000..998410563bfd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
@@ -0,0 +1,43 @@
+#ifndef __NVKM_PMU_PRIV_H__
+#define __NVKM_PMU_PRIV_H__
+#include <subdev/pmu.h>
+#include <subdev/pmu/fuc/os.h>
+
+#define nvkm_pmu_create(p, e, o, d) \
+ nvkm_pmu_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nvkm_pmu_destroy(p) \
+ nvkm_subdev_destroy(&(p)->base)
+#define nvkm_pmu_init(p) ({ \
+ struct nvkm_pmu *_pmu = (p); \
+ _nvkm_pmu_init(nv_object(_pmu)); \
+})
+#define nvkm_pmu_fini(p,s) ({ \
+ struct nvkm_pmu *_pmu = (p); \
+ _nvkm_pmu_fini(nv_object(_pmu), (s)); \
+})
+
+int nvkm_pmu_create_(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, int, void **);
+
+int _nvkm_pmu_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+#define _nvkm_pmu_dtor _nvkm_subdev_dtor
+int _nvkm_pmu_init(struct nvkm_object *);
+int _nvkm_pmu_fini(struct nvkm_object *, bool);
+void nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable);
+
+struct nvkm_pmu_impl {
+ struct nvkm_oclass base;
+ struct {
+ u32 *data;
+ u32 size;
+ } code;
+ struct {
+ u32 *data;
+ u32 size;
+ } data;
+
+ void (*pgob)(struct nvkm_pmu *, bool);
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
new file mode 100644
index 000000000000..5837cf1292d9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
@@ -0,0 +1,13 @@
+nvkm-y += nvkm/subdev/therm/base.o
+nvkm-y += nvkm/subdev/therm/fan.o
+nvkm-y += nvkm/subdev/therm/fannil.o
+nvkm-y += nvkm/subdev/therm/fanpwm.o
+nvkm-y += nvkm/subdev/therm/fantog.o
+nvkm-y += nvkm/subdev/therm/ic.o
+nvkm-y += nvkm/subdev/therm/temp.o
+nvkm-y += nvkm/subdev/therm/nv40.o
+nvkm-y += nvkm/subdev/therm/nv50.o
+nvkm-y += nvkm/subdev/therm/g84.o
+nvkm-y += nvkm/subdev/therm/gt215.o
+nvkm-y += nvkm/subdev/therm/gf110.o
+nvkm-y += nvkm/subdev/therm/gm107.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
index 9ad01da6eacb..ec327cb64a0d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
@@ -21,21 +21,17 @@
*
* Authors: Martin Peres
*/
+#include "priv.h"
-#include <core/object.h>
#include <core/device.h>
-#include <subdev/bios.h>
-
-#include "priv.h"
-
static int
-nouveau_therm_update_trip(struct nouveau_therm *therm)
+nvkm_therm_update_trip(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_therm_trip_point *trip = priv->fan->bios.trip,
- *cur_trip = NULL,
- *last_trip = priv->last_trip;
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvbios_therm_trip_point *trip = priv->fan->bios.trip,
+ *cur_trip = NULL,
+ *last_trip = priv->last_trip;
u8 temp = therm->temp_get(therm);
u16 duty, i;
@@ -63,9 +59,9 @@ nouveau_therm_update_trip(struct nouveau_therm *therm)
}
static int
-nouveau_therm_update_linear(struct nouveau_therm *therm)
+nvkm_therm_update_linear(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
u8 linear_min_temp = priv->fan->bios.linear_min_temp;
u8 linear_max_temp = priv->fan->bios.linear_max_temp;
u8 temp = therm->temp_get(therm);
@@ -82,15 +78,14 @@ nouveau_therm_update_linear(struct nouveau_therm *therm)
duty *= (priv->fan->bios.max_duty - priv->fan->bios.min_duty);
duty /= (linear_max_temp - linear_min_temp);
duty += priv->fan->bios.min_duty;
-
return duty;
}
static void
-nouveau_therm_update(struct nouveau_therm *therm, int mode)
+nvkm_therm_update(struct nvkm_therm *therm, int mode)
{
- struct nouveau_timer *ptimer = nouveau_timer(therm);
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_timer *ptimer = nvkm_timer(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
unsigned long flags;
bool immd = true;
bool poll = true;
@@ -102,20 +97,20 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
priv->mode = mode;
switch (mode) {
- case NOUVEAU_THERM_CTRL_MANUAL:
+ case NVKM_THERM_CTRL_MANUAL:
ptimer->alarm_cancel(ptimer, &priv->alarm);
- duty = nouveau_therm_fan_get(therm);
+ duty = nvkm_therm_fan_get(therm);
if (duty < 0)
duty = 100;
poll = false;
break;
- case NOUVEAU_THERM_CTRL_AUTO:
+ case NVKM_THERM_CTRL_AUTO:
switch(priv->fan->bios.fan_mode) {
case NVBIOS_THERM_FAN_TRIP:
- duty = nouveau_therm_update_trip(therm);
+ duty = nvkm_therm_update_trip(therm);
break;
case NVBIOS_THERM_FAN_LINEAR:
- duty = nouveau_therm_update_linear(therm);
+ duty = nvkm_therm_update_linear(therm);
break;
case NVBIOS_THERM_FAN_OTHER:
if (priv->cstate)
@@ -125,7 +120,7 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
}
immd = false;
break;
- case NOUVEAU_THERM_CTRL_NONE:
+ case NVKM_THERM_CTRL_NONE:
default:
ptimer->alarm_cancel(ptimer, &priv->alarm);
poll = false;
@@ -137,36 +132,36 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode)
if (duty >= 0) {
nv_debug(therm, "FAN target request: %d%%\n", duty);
- nouveau_therm_fan_set(therm, immd, duty);
+ nvkm_therm_fan_set(therm, immd, duty);
}
}
int
-nouveau_therm_cstate(struct nouveau_therm *ptherm, int fan, int dir)
+nvkm_therm_cstate(struct nvkm_therm *ptherm, int fan, int dir)
{
- struct nouveau_therm_priv *priv = (void *)ptherm;
+ struct nvkm_therm_priv *priv = (void *)ptherm;
if (!dir || (dir < 0 && fan < priv->cstate) ||
(dir > 0 && fan > priv->cstate)) {
nv_debug(ptherm, "default fan speed -> %d%%\n", fan);
priv->cstate = fan;
- nouveau_therm_update(ptherm, -1);
+ nvkm_therm_update(ptherm, -1);
}
return 0;
}
static void
-nouveau_therm_alarm(struct nouveau_alarm *alarm)
+nvkm_therm_alarm(struct nvkm_alarm *alarm)
{
- struct nouveau_therm_priv *priv =
- container_of(alarm, struct nouveau_therm_priv, alarm);
- nouveau_therm_update(&priv->base, -1);
+ struct nvkm_therm_priv *priv =
+ container_of(alarm, struct nvkm_therm_priv, alarm);
+ nvkm_therm_update(&priv->base, -1);
}
int
-nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode)
+nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_device *device = nv_device(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_device *device = nv_device(therm);
static const char *name[] = {
"disabled",
"manual",
@@ -175,51 +170,51 @@ nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode)
/* The default PPWR ucode on fermi interferes with fan management */
if ((mode >= ARRAY_SIZE(name)) ||
- (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0 &&
- !nouveau_subdev(device, NVDEV_SUBDEV_PWR)))
+ (mode != NVKM_THERM_CTRL_NONE && device->card_type >= NV_C0 &&
+ !nvkm_subdev(device, NVDEV_SUBDEV_PMU)))
return -EINVAL;
/* do not allow automatic fan management if the thermal sensor is
* not available */
- if (mode == NOUVEAU_THERM_CTRL_AUTO && therm->temp_get(therm) < 0)
+ if (mode == NVKM_THERM_CTRL_AUTO && therm->temp_get(therm) < 0)
return -EINVAL;
if (priv->mode == mode)
return 0;
nv_info(therm, "fan management: %s\n", name[mode]);
- nouveau_therm_update(therm, mode);
+ nvkm_therm_update(therm, mode);
return 0;
}
int
-nouveau_therm_attr_get(struct nouveau_therm *therm,
- enum nouveau_therm_attr_type type)
+nvkm_therm_attr_get(struct nvkm_therm *therm,
+ enum nvkm_therm_attr_type type)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
switch (type) {
- case NOUVEAU_THERM_ATTR_FAN_MIN_DUTY:
+ case NVKM_THERM_ATTR_FAN_MIN_DUTY:
return priv->fan->bios.min_duty;
- case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY:
+ case NVKM_THERM_ATTR_FAN_MAX_DUTY:
return priv->fan->bios.max_duty;
- case NOUVEAU_THERM_ATTR_FAN_MODE:
+ case NVKM_THERM_ATTR_FAN_MODE:
return priv->mode;
- case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
+ case NVKM_THERM_ATTR_THRS_FAN_BOOST:
return priv->bios_sensor.thrs_fan_boost.temp;
- case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST:
+ case NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST:
return priv->bios_sensor.thrs_fan_boost.hysteresis;
- case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK:
+ case NVKM_THERM_ATTR_THRS_DOWN_CLK:
return priv->bios_sensor.thrs_down_clock.temp;
- case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST:
+ case NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST:
return priv->bios_sensor.thrs_down_clock.hysteresis;
- case NOUVEAU_THERM_ATTR_THRS_CRITICAL:
+ case NVKM_THERM_ATTR_THRS_CRITICAL:
return priv->bios_sensor.thrs_critical.temp;
- case NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST:
+ case NVKM_THERM_ATTR_THRS_CRITICAL_HYST:
return priv->bios_sensor.thrs_critical.hysteresis;
- case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN:
+ case NVKM_THERM_ATTR_THRS_SHUTDOWN:
return priv->bios_sensor.thrs_shutdown.temp;
- case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST:
+ case NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST:
return priv->bios_sensor.thrs_shutdown.hysteresis;
}
@@ -227,57 +222,57 @@ nouveau_therm_attr_get(struct nouveau_therm *therm,
}
int
-nouveau_therm_attr_set(struct nouveau_therm *therm,
- enum nouveau_therm_attr_type type, int value)
+nvkm_therm_attr_set(struct nvkm_therm *therm,
+ enum nvkm_therm_attr_type type, int value)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
switch (type) {
- case NOUVEAU_THERM_ATTR_FAN_MIN_DUTY:
+ case NVKM_THERM_ATTR_FAN_MIN_DUTY:
if (value < 0)
value = 0;
if (value > priv->fan->bios.max_duty)
value = priv->fan->bios.max_duty;
priv->fan->bios.min_duty = value;
return 0;
- case NOUVEAU_THERM_ATTR_FAN_MAX_DUTY:
+ case NVKM_THERM_ATTR_FAN_MAX_DUTY:
if (value < 0)
value = 0;
if (value < priv->fan->bios.min_duty)
value = priv->fan->bios.min_duty;
priv->fan->bios.max_duty = value;
return 0;
- case NOUVEAU_THERM_ATTR_FAN_MODE:
- return nouveau_therm_fan_mode(therm, value);
- case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST:
+ case NVKM_THERM_ATTR_FAN_MODE:
+ return nvkm_therm_fan_mode(therm, value);
+ case NVKM_THERM_ATTR_THRS_FAN_BOOST:
priv->bios_sensor.thrs_fan_boost.temp = value;
priv->sensor.program_alarms(therm);
return 0;
- case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST_HYST:
+ case NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST:
priv->bios_sensor.thrs_fan_boost.hysteresis = value;
priv->sensor.program_alarms(therm);
return 0;
- case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK:
+ case NVKM_THERM_ATTR_THRS_DOWN_CLK:
priv->bios_sensor.thrs_down_clock.temp = value;
priv->sensor.program_alarms(therm);
return 0;
- case NOUVEAU_THERM_ATTR_THRS_DOWN_CLK_HYST:
+ case NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST:
priv->bios_sensor.thrs_down_clock.hysteresis = value;
priv->sensor.program_alarms(therm);
return 0;
- case NOUVEAU_THERM_ATTR_THRS_CRITICAL:
+ case NVKM_THERM_ATTR_THRS_CRITICAL:
priv->bios_sensor.thrs_critical.temp = value;
priv->sensor.program_alarms(therm);
return 0;
- case NOUVEAU_THERM_ATTR_THRS_CRITICAL_HYST:
+ case NVKM_THERM_ATTR_THRS_CRITICAL_HYST:
priv->bios_sensor.thrs_critical.hysteresis = value;
priv->sensor.program_alarms(therm);
return 0;
- case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN:
+ case NVKM_THERM_ATTR_THRS_SHUTDOWN:
priv->bios_sensor.thrs_shutdown.temp = value;
priv->sensor.program_alarms(therm);
return 0;
- case NOUVEAU_THERM_ATTR_THRS_SHUTDOWN_HYST:
+ case NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST:
priv->bios_sensor.thrs_shutdown.hysteresis = value;
priv->sensor.program_alarms(therm);
return 0;
@@ -287,88 +282,86 @@ nouveau_therm_attr_set(struct nouveau_therm *therm,
}
int
-_nouveau_therm_init(struct nouveau_object *object)
+_nvkm_therm_init(struct nvkm_object *object)
{
- struct nouveau_therm *therm = (void *)object;
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm *therm = (void *)object;
+ struct nvkm_therm_priv *priv = (void *)therm;
int ret;
- ret = nouveau_subdev_init(&therm->base);
+ ret = nvkm_subdev_init(&therm->base);
if (ret)
return ret;
if (priv->suspend >= 0) {
/* restore the pwm value only when on manual or auto mode */
if (priv->suspend > 0)
- nouveau_therm_fan_set(therm, true, priv->fan->percent);
+ nvkm_therm_fan_set(therm, true, priv->fan->percent);
- nouveau_therm_fan_mode(therm, priv->suspend);
+ nvkm_therm_fan_mode(therm, priv->suspend);
}
- nouveau_therm_sensor_init(therm);
- nouveau_therm_fan_init(therm);
+ nvkm_therm_sensor_init(therm);
+ nvkm_therm_fan_init(therm);
return 0;
}
int
-_nouveau_therm_fini(struct nouveau_object *object, bool suspend)
+_nvkm_therm_fini(struct nvkm_object *object, bool suspend)
{
- struct nouveau_therm *therm = (void *)object;
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm *therm = (void *)object;
+ struct nvkm_therm_priv *priv = (void *)therm;
- nouveau_therm_fan_fini(therm, suspend);
- nouveau_therm_sensor_fini(therm, suspend);
+ nvkm_therm_fan_fini(therm, suspend);
+ nvkm_therm_sensor_fini(therm, suspend);
if (suspend) {
priv->suspend = priv->mode;
- priv->mode = NOUVEAU_THERM_CTRL_NONE;
+ priv->mode = NVKM_THERM_CTRL_NONE;
}
- return nouveau_subdev_fini(&therm->base, suspend);
+ return nvkm_subdev_fini(&therm->base, suspend);
}
int
-nouveau_therm_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass,
- int length, void **pobject)
+nvkm_therm_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_therm_priv *priv;
+ struct nvkm_therm_priv *priv;
int ret;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PTHERM",
- "therm", length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "PTHERM",
+ "therm", length, pobject);
priv = *pobject;
if (ret)
return ret;
- nouveau_alarm_init(&priv->alarm, nouveau_therm_alarm);
+ nvkm_alarm_init(&priv->alarm, nvkm_therm_alarm);
spin_lock_init(&priv->lock);
spin_lock_init(&priv->sensor.alarm_program_lock);
- priv->base.fan_get = nouveau_therm_fan_user_get;
- priv->base.fan_set = nouveau_therm_fan_user_set;
- priv->base.fan_sense = nouveau_therm_fan_sense;
- priv->base.attr_get = nouveau_therm_attr_get;
- priv->base.attr_set = nouveau_therm_attr_set;
+ priv->base.fan_get = nvkm_therm_fan_user_get;
+ priv->base.fan_set = nvkm_therm_fan_user_set;
+ priv->base.fan_sense = nvkm_therm_fan_sense;
+ priv->base.attr_get = nvkm_therm_attr_get;
+ priv->base.attr_set = nvkm_therm_attr_set;
priv->mode = priv->suspend = -1; /* undefined */
return 0;
}
int
-nouveau_therm_preinit(struct nouveau_therm *therm)
+nvkm_therm_preinit(struct nvkm_therm *therm)
{
- nouveau_therm_sensor_ctor(therm);
- nouveau_therm_ic_ctor(therm);
- nouveau_therm_fan_ctor(therm);
+ nvkm_therm_sensor_ctor(therm);
+ nvkm_therm_ic_ctor(therm);
+ nvkm_therm_fan_ctor(therm);
- nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
- nouveau_therm_sensor_preinit(therm);
+ nvkm_therm_fan_mode(therm, NVKM_THERM_CTRL_AUTO);
+ nvkm_therm_sensor_preinit(therm);
return 0;
}
void
-_nouveau_therm_dtor(struct nouveau_object *object)
+_nvkm_therm_dtor(struct nvkm_object *object)
{
- struct nouveau_therm_priv *priv = (void *)object;
+ struct nvkm_therm_priv *priv = (void *)object;
kfree(priv->fan);
- nouveau_subdev_destroy(&priv->base.base);
+ nvkm_subdev_destroy(&priv->base.base);
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c
index 3656d605168f..434fa745ca40 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c
@@ -22,23 +22,18 @@
* Authors: Ben Skeggs
* Martin Peres
*/
-
#include "priv.h"
-#include <core/object.h>
-#include <core/device.h>
-
+#include <subdev/bios/fan.h>
#include <subdev/gpio.h>
#include <subdev/timer.h>
-#include <subdev/bios/fan.h>
-
static int
-nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target)
+nvkm_fan_update(struct nvkm_fan *fan, bool immediate, int target)
{
- struct nouveau_therm *therm = fan->parent;
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_timer *ptimer = nouveau_timer(priv);
+ struct nvkm_therm *therm = fan->parent;
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_timer *ptimer = nvkm_timer(priv);
unsigned long flags;
int ret = 0;
int duty;
@@ -107,32 +102,32 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target)
}
static void
-nouveau_fan_alarm(struct nouveau_alarm *alarm)
+nvkm_fan_alarm(struct nvkm_alarm *alarm)
{
- struct nouveau_fan *fan = container_of(alarm, struct nouveau_fan, alarm);
- nouveau_fan_update(fan, false, -1);
+ struct nvkm_fan *fan = container_of(alarm, struct nvkm_fan, alarm);
+ nvkm_fan_update(fan, false, -1);
}
int
-nouveau_therm_fan_get(struct nouveau_therm *therm)
+nvkm_therm_fan_get(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
return priv->fan->get(therm);
}
int
-nouveau_therm_fan_set(struct nouveau_therm *therm, bool immediate, int percent)
+nvkm_therm_fan_set(struct nvkm_therm *therm, bool immediate, int percent)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- return nouveau_fan_update(priv->fan, immediate, percent);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ return nvkm_fan_update(priv->fan, immediate, percent);
}
int
-nouveau_therm_fan_sense(struct nouveau_therm *therm)
+nvkm_therm_fan_sense(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_timer *ptimer = nouveau_timer(therm);
- struct nouveau_gpio *gpio = nouveau_gpio(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_timer *ptimer = nvkm_timer(therm);
+ struct nvkm_gpio *gpio = nvkm_gpio(therm);
u32 cycles, cur, prev;
u64 start, end, tach;
@@ -168,26 +163,26 @@ nouveau_therm_fan_sense(struct nouveau_therm *therm)
}
int
-nouveau_therm_fan_user_get(struct nouveau_therm *therm)
+nvkm_therm_fan_user_get(struct nvkm_therm *therm)
{
- return nouveau_therm_fan_get(therm);
+ return nvkm_therm_fan_get(therm);
}
int
-nouveau_therm_fan_user_set(struct nouveau_therm *therm, int percent)
+nvkm_therm_fan_user_set(struct nvkm_therm *therm, int percent)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
- if (priv->mode != NOUVEAU_THERM_CTRL_MANUAL)
+ if (priv->mode != NVKM_THERM_CTRL_MANUAL)
return -EINVAL;
- return nouveau_therm_fan_set(therm, true, percent);
+ return nvkm_therm_fan_set(therm, true, percent);
}
static void
-nouveau_therm_fan_set_defaults(struct nouveau_therm *therm)
+nvkm_therm_fan_set_defaults(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
priv->fan->bios.pwm_freq = 0;
priv->fan->bios.min_duty = 0;
@@ -199,9 +194,9 @@ nouveau_therm_fan_set_defaults(struct nouveau_therm *therm)
}
static void
-nouveau_therm_fan_safety_checks(struct nouveau_therm *therm)
+nvkm_therm_fan_safety_checks(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
if (priv->fan->bios.min_duty > 100)
priv->fan->bios.min_duty = 100;
@@ -213,16 +208,16 @@ nouveau_therm_fan_safety_checks(struct nouveau_therm *therm)
}
int
-nouveau_therm_fan_init(struct nouveau_therm *therm)
+nvkm_therm_fan_init(struct nvkm_therm *therm)
{
return 0;
}
int
-nouveau_therm_fan_fini(struct nouveau_therm *therm, bool suspend)
+nvkm_therm_fan_fini(struct nvkm_therm *therm, bool suspend)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_timer *ptimer = nouveau_timer(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_timer *ptimer = nvkm_timer(therm);
if (suspend)
ptimer->alarm_cancel(ptimer, &priv->fan->alarm);
@@ -230,11 +225,11 @@ nouveau_therm_fan_fini(struct nouveau_therm *therm, bool suspend)
}
int
-nouveau_therm_fan_ctor(struct nouveau_therm *therm)
+nvkm_therm_fan_ctor(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_gpio *gpio = nouveau_gpio(therm);
- struct nouveau_bios *bios = nouveau_bios(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_gpio *gpio = nvkm_gpio(therm);
+ struct nvkm_bios *bios = nvkm_bios(therm);
struct dcb_gpio_func func;
int ret;
@@ -246,15 +241,15 @@ nouveau_therm_fan_ctor(struct nouveau_therm *therm)
nv_debug(therm, "GPIO_FAN is in input mode\n");
ret = -EINVAL;
} else {
- ret = nouveau_fanpwm_create(therm, &func);
+ ret = nvkm_fanpwm_create(therm, &func);
if (ret != 0)
- ret = nouveau_fantog_create(therm, &func);
+ ret = nvkm_fantog_create(therm, &func);
}
}
/* no controllable fan found, create a dummy fan module */
if (ret != 0) {
- ret = nouveau_fannil_create(therm);
+ ret = nvkm_fannil_create(therm);
if (ret)
return ret;
}
@@ -262,7 +257,7 @@ nouveau_therm_fan_ctor(struct nouveau_therm *therm)
nv_info(therm, "FAN control: %s\n", priv->fan->type);
/* read the current speed, it is useful when resuming */
- priv->fan->percent = nouveau_therm_fan_get(therm);
+ priv->fan->percent = nvkm_therm_fan_get(therm);
/* attempt to detect a tachometer connection */
ret = gpio->find(gpio, 0, DCB_GPIO_FAN_SENSE, 0xff, &priv->fan->tach);
@@ -271,17 +266,17 @@ nouveau_therm_fan_ctor(struct nouveau_therm *therm)
/* initialise fan bump/slow update handling */
priv->fan->parent = therm;
- nouveau_alarm_init(&priv->fan->alarm, nouveau_fan_alarm);
+ nvkm_alarm_init(&priv->fan->alarm, nvkm_fan_alarm);
spin_lock_init(&priv->fan->lock);
/* other random init... */
- nouveau_therm_fan_set_defaults(therm);
+ nvkm_therm_fan_set_defaults(therm);
nvbios_perf_fan_parse(bios, &priv->fan->perf);
if (!nvbios_fan_parse(bios, &priv->fan->bios)) {
nv_debug(therm, "parsing the fan table failed\n");
if (nvbios_therm_fan_parse(bios, &priv->fan->bios))
nv_error(therm, "parsing both fan tables failed\n");
}
- nouveau_therm_fan_safety_checks(therm);
+ nvkm_therm_fan_safety_checks(therm);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fannil.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fannil.c
index b78c182e1d51..534e5970ec9c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/fannil.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fannil.c
@@ -21,26 +21,25 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
static int
-nouveau_fannil_get(struct nouveau_therm *therm)
+nvkm_fannil_get(struct nvkm_therm *therm)
{
return -ENODEV;
}
static int
-nouveau_fannil_set(struct nouveau_therm *therm, int percent)
+nvkm_fannil_set(struct nvkm_therm *therm, int percent)
{
return -ENODEV;
}
int
-nouveau_fannil_create(struct nouveau_therm *therm)
+nvkm_fannil_create(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *tpriv = (void *)therm;
- struct nouveau_fan *priv;
+ struct nvkm_therm_priv *tpriv = (void *)therm;
+ struct nvkm_fan *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
tpriv->fan = priv;
@@ -48,7 +47,7 @@ nouveau_fannil_create(struct nouveau_therm *therm)
return -ENOMEM;
priv->type = "none / external";
- priv->get = nouveau_fannil_get;
- priv->set = nouveau_fannil_set;
+ priv->get = nvkm_fannil_get;
+ priv->set = nvkm_fannil_set;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c
index c629d7f2a6a4..bde5ceaeb70a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c
@@ -22,25 +22,25 @@
* Authors: Ben Skeggs
* Martin Peres
*/
+#include "priv.h"
+#include <core/device.h>
#include <core/option.h>
-#include <subdev/gpio.h>
#include <subdev/bios.h>
#include <subdev/bios/fan.h>
+#include <subdev/gpio.h>
-#include "priv.h"
-
-struct nouveau_fanpwm_priv {
- struct nouveau_fan base;
+struct nvkm_fanpwm_priv {
+ struct nvkm_fan base;
struct dcb_gpio_func func;
};
static int
-nouveau_fanpwm_get(struct nouveau_therm *therm)
+nvkm_fanpwm_get(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *tpriv = (void *)therm;
- struct nouveau_fanpwm_priv *priv = (void *)tpriv->fan;
- struct nouveau_gpio *gpio = nouveau_gpio(therm);
+ struct nvkm_therm_priv *tpriv = (void *)therm;
+ struct nvkm_fanpwm_priv *priv = (void *)tpriv->fan;
+ struct nvkm_gpio *gpio = nvkm_gpio(therm);
int card_type = nv_device(therm)->card_type;
u32 divs, duty;
int ret;
@@ -57,10 +57,10 @@ nouveau_fanpwm_get(struct nouveau_therm *therm)
}
static int
-nouveau_fanpwm_set(struct nouveau_therm *therm, int percent)
+nvkm_fanpwm_set(struct nvkm_therm *therm, int percent)
{
- struct nouveau_therm_priv *tpriv = (void *)therm;
- struct nouveau_fanpwm_priv *priv = (void *)tpriv->fan;
+ struct nvkm_therm_priv *tpriv = (void *)therm;
+ struct nvkm_fanpwm_priv *priv = (void *)tpriv->fan;
int card_type = nv_device(therm)->card_type;
u32 divs, duty;
int ret;
@@ -84,18 +84,18 @@ nouveau_fanpwm_set(struct nouveau_therm *therm, int percent)
}
int
-nouveau_fanpwm_create(struct nouveau_therm *therm, struct dcb_gpio_func *func)
+nvkm_fanpwm_create(struct nvkm_therm *therm, struct dcb_gpio_func *func)
{
- struct nouveau_device *device = nv_device(therm);
- struct nouveau_therm_priv *tpriv = (void *)therm;
- struct nouveau_bios *bios = nouveau_bios(therm);
- struct nouveau_fanpwm_priv *priv;
+ struct nvkm_device *device = nv_device(therm);
+ struct nvkm_therm_priv *tpriv = (void *)therm;
+ struct nvkm_bios *bios = nvkm_bios(therm);
+ struct nvkm_fanpwm_priv *priv;
struct nvbios_therm_fan fan;
u32 divs, duty;
nvbios_fan_parse(bios, &fan);
- if (!nouveau_boolopt(device->cfgopt, "NvFanPWM", func->param) ||
+ if (!nvkm_boolopt(device->cfgopt, "NvFanPWM", func->param) ||
!therm->pwm_ctrl || fan.type == NVBIOS_THERM_FAN_TOGGLE ||
therm->pwm_get(therm, func->line, &divs, &duty) == -ENODEV)
return -ENODEV;
@@ -106,8 +106,8 @@ nouveau_fanpwm_create(struct nouveau_therm *therm, struct dcb_gpio_func *func)
return -ENOMEM;
priv->base.type = "PWM";
- priv->base.get = nouveau_fanpwm_get;
- priv->base.set = nouveau_fanpwm_set;
+ priv->base.get = nvkm_fanpwm_get;
+ priv->base.set = nvkm_fanpwm_set;
priv->func = *func;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c
index f69dab11f720..4ce041e81371 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c
@@ -21,18 +21,14 @@
*
* Authors: Martin Peres
*/
-
#include "priv.h"
-#include <core/object.h>
-#include <core/device.h>
-
#include <subdev/gpio.h>
#include <subdev/timer.h>
-struct nouveau_fantog_priv {
- struct nouveau_fan base;
- struct nouveau_alarm alarm;
+struct nvkm_fantog_priv {
+ struct nvkm_fan base;
+ struct nvkm_alarm alarm;
spinlock_t lock;
u32 period_us;
u32 percent;
@@ -40,11 +36,11 @@ struct nouveau_fantog_priv {
};
static void
-nouveau_fantog_update(struct nouveau_fantog_priv *priv, int percent)
+nvkm_fantog_update(struct nvkm_fantog_priv *priv, int percent)
{
- struct nouveau_therm_priv *tpriv = (void *)priv->base.parent;
- struct nouveau_timer *ptimer = nouveau_timer(tpriv);
- struct nouveau_gpio *gpio = nouveau_gpio(tpriv);
+ struct nvkm_therm_priv *tpriv = (void *)priv->base.parent;
+ struct nvkm_timer *ptimer = nvkm_timer(tpriv);
+ struct nvkm_gpio *gpio = nvkm_gpio(tpriv);
unsigned long flags;
int duty;
@@ -66,37 +62,37 @@ nouveau_fantog_update(struct nouveau_fantog_priv *priv, int percent)
}
static void
-nouveau_fantog_alarm(struct nouveau_alarm *alarm)
+nvkm_fantog_alarm(struct nvkm_alarm *alarm)
{
- struct nouveau_fantog_priv *priv =
- container_of(alarm, struct nouveau_fantog_priv, alarm);
- nouveau_fantog_update(priv, -1);
+ struct nvkm_fantog_priv *priv =
+ container_of(alarm, struct nvkm_fantog_priv, alarm);
+ nvkm_fantog_update(priv, -1);
}
static int
-nouveau_fantog_get(struct nouveau_therm *therm)
+nvkm_fantog_get(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *tpriv = (void *)therm;
- struct nouveau_fantog_priv *priv = (void *)tpriv->fan;
+ struct nvkm_therm_priv *tpriv = (void *)therm;
+ struct nvkm_fantog_priv *priv = (void *)tpriv->fan;
return priv->percent;
}
static int
-nouveau_fantog_set(struct nouveau_therm *therm, int percent)
+nvkm_fantog_set(struct nvkm_therm *therm, int percent)
{
- struct nouveau_therm_priv *tpriv = (void *)therm;
- struct nouveau_fantog_priv *priv = (void *)tpriv->fan;
+ struct nvkm_therm_priv *tpriv = (void *)therm;
+ struct nvkm_fantog_priv *priv = (void *)tpriv->fan;
if (therm->pwm_ctrl)
therm->pwm_ctrl(therm, priv->func.line, false);
- nouveau_fantog_update(priv, percent);
+ nvkm_fantog_update(priv, percent);
return 0;
}
int
-nouveau_fantog_create(struct nouveau_therm *therm, struct dcb_gpio_func *func)
+nvkm_fantog_create(struct nvkm_therm *therm, struct dcb_gpio_func *func)
{
- struct nouveau_therm_priv *tpriv = (void *)therm;
- struct nouveau_fantog_priv *priv;
+ struct nvkm_therm_priv *tpriv = (void *)therm;
+ struct nvkm_fantog_priv *priv;
int ret;
if (therm->pwm_ctrl) {
@@ -111,9 +107,9 @@ nouveau_fantog_create(struct nouveau_therm *therm, struct dcb_gpio_func *func)
return -ENOMEM;
priv->base.type = "toggle";
- priv->base.get = nouveau_fantog_get;
- priv->base.set = nouveau_fantog_set;
- nouveau_alarm_init(&priv->alarm, nouveau_fantog_alarm);
+ priv->base.get = nvkm_fantog_get;
+ priv->base.set = nvkm_fantog_set;
+ nvkm_alarm_init(&priv->alarm, nvkm_fantog_alarm);
priv->period_us = 100000; /* 10Hz */
priv->percent = 100;
priv->func = *func;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
index 14e2e09bfc24..85b5d0c18c0b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
@@ -22,18 +22,18 @@
* Authors: Ben Skeggs
* Martin Peres
*/
-
#include "priv.h"
+
#include <subdev/fuse.h>
-struct nv84_therm_priv {
- struct nouveau_therm_priv base;
+struct g84_therm_priv {
+ struct nvkm_therm_priv base;
};
int
-nv84_temp_get(struct nouveau_therm *therm)
+g84_temp_get(struct nvkm_therm *therm)
{
- struct nouveau_fuse *fuse = nouveau_fuse(therm);
+ struct nvkm_fuse *fuse = nvkm_fuse(therm);
if (nv_ro32(fuse, 0x1a8) == 1)
return nv_rd32(therm, 0x20400);
@@ -42,9 +42,9 @@ nv84_temp_get(struct nouveau_therm *therm)
}
void
-nv84_sensor_setup(struct nouveau_therm *therm)
+g84_sensor_setup(struct nvkm_therm *therm)
{
- struct nouveau_fuse *fuse = nouveau_fuse(therm);
+ struct nvkm_fuse *fuse = nvkm_fuse(therm);
/* enable temperature reading for cards with insane defaults */
if (nv_ro32(fuse, 0x1a8) == 1) {
@@ -55,9 +55,9 @@ nv84_sensor_setup(struct nouveau_therm *therm)
}
static void
-nv84_therm_program_alarms(struct nouveau_therm *therm)
+g84_therm_program_alarms(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
unsigned long flags;
@@ -92,53 +92,53 @@ nv84_therm_program_alarms(struct nouveau_therm *therm)
/* must be called with alarm_program_lock taken ! */
static void
-nv84_therm_threshold_hyst_emulation(struct nouveau_therm *therm,
+g84_therm_threshold_hyst_emulation(struct nvkm_therm *therm,
uint32_t thrs_reg, u8 status_bit,
const struct nvbios_therm_threshold *thrs,
- enum nouveau_therm_thrs thrs_name)
+ enum nvkm_therm_thrs thrs_name)
{
- enum nouveau_therm_thrs_direction direction;
- enum nouveau_therm_thrs_state prev_state, new_state;
+ enum nvkm_therm_thrs_direction direction;
+ enum nvkm_therm_thrs_state prev_state, new_state;
int temp, cur;
- prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name);
+ prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name);
temp = nv_rd32(therm, thrs_reg);
/* program the next threshold */
if (temp == thrs->temp) {
nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis);
- new_state = NOUVEAU_THERM_THRS_HIGHER;
+ new_state = NVKM_THERM_THRS_HIGHER;
} else {
nv_wr32(therm, thrs_reg, thrs->temp);
- new_state = NOUVEAU_THERM_THRS_LOWER;
+ new_state = NVKM_THERM_THRS_LOWER;
}
/* fix the state (in case someone reprogrammed the alarms) */
cur = therm->temp_get(therm);
- if (new_state == NOUVEAU_THERM_THRS_LOWER && cur > thrs->temp)
- new_state = NOUVEAU_THERM_THRS_HIGHER;
- else if (new_state == NOUVEAU_THERM_THRS_HIGHER &&
+ if (new_state == NVKM_THERM_THRS_LOWER && cur > thrs->temp)
+ new_state = NVKM_THERM_THRS_HIGHER;
+ else if (new_state == NVKM_THERM_THRS_HIGHER &&
cur < thrs->temp - thrs->hysteresis)
- new_state = NOUVEAU_THERM_THRS_LOWER;
- nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
+ new_state = NVKM_THERM_THRS_LOWER;
+ nvkm_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
/* find the direction */
if (prev_state < new_state)
- direction = NOUVEAU_THERM_THRS_RISING;
+ direction = NVKM_THERM_THRS_RISING;
else if (prev_state > new_state)
- direction = NOUVEAU_THERM_THRS_FALLING;
+ direction = NVKM_THERM_THRS_FALLING;
else
return;
/* advertise a change in direction */
- nouveau_therm_sensor_event(therm, thrs_name, direction);
+ nvkm_therm_sensor_event(therm, thrs_name, direction);
}
static void
-nv84_therm_intr(struct nouveau_subdev *subdev)
+g84_therm_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_therm *therm = nouveau_therm(subdev);
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm *therm = nvkm_therm(subdev);
+ struct nvkm_therm_priv *priv = (void *)therm;
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
unsigned long flags;
uint32_t intr;
@@ -149,33 +149,33 @@ nv84_therm_intr(struct nouveau_subdev *subdev)
/* THRS_4: downclock */
if (intr & 0x002) {
- nv84_therm_threshold_hyst_emulation(therm, 0x20414, 24,
- &sensor->thrs_down_clock,
- NOUVEAU_THERM_THRS_DOWNCLOCK);
+ g84_therm_threshold_hyst_emulation(therm, 0x20414, 24,
+ &sensor->thrs_down_clock,
+ NVKM_THERM_THRS_DOWNCLOCK);
intr &= ~0x002;
}
/* shutdown */
if (intr & 0x004) {
- nv84_therm_threshold_hyst_emulation(therm, 0x20480, 20,
+ g84_therm_threshold_hyst_emulation(therm, 0x20480, 20,
&sensor->thrs_shutdown,
- NOUVEAU_THERM_THRS_SHUTDOWN);
+ NVKM_THERM_THRS_SHUTDOWN);
intr &= ~0x004;
}
/* THRS_1 : fan boost */
if (intr & 0x008) {
- nv84_therm_threshold_hyst_emulation(therm, 0x204c4, 21,
+ g84_therm_threshold_hyst_emulation(therm, 0x204c4, 21,
&sensor->thrs_fan_boost,
- NOUVEAU_THERM_THRS_FANBOOST);
+ NVKM_THERM_THRS_FANBOOST);
intr &= ~0x008;
}
/* THRS_2 : critical */
if (intr & 0x010) {
- nv84_therm_threshold_hyst_emulation(therm, 0x204c0, 22,
+ g84_therm_threshold_hyst_emulation(therm, 0x204c0, 22,
&sensor->thrs_critical,
- NOUVEAU_THERM_THRS_CRITICAL);
+ NVKM_THERM_THRS_CRITICAL);
intr &= ~0x010;
}
@@ -190,30 +190,28 @@ nv84_therm_intr(struct nouveau_subdev *subdev)
}
static int
-nv84_therm_init(struct nouveau_object *object)
+g84_therm_init(struct nvkm_object *object)
{
- struct nv84_therm_priv *priv = (void *)object;
+ struct g84_therm_priv *priv = (void *)object;
int ret;
- ret = nouveau_therm_init(&priv->base.base);
+ ret = nvkm_therm_init(&priv->base.base);
if (ret)
return ret;
- nv84_sensor_setup(&priv->base.base);
-
+ g84_sensor_setup(&priv->base.base);
return 0;
}
static int
-nv84_therm_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+g84_therm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nv84_therm_priv *priv;
+ struct g84_therm_priv *priv;
int ret;
- ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ ret = nvkm_therm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -222,29 +220,29 @@ nv84_therm_ctor(struct nouveau_object *parent,
priv->base.base.pwm_get = nv50_fan_pwm_get;
priv->base.base.pwm_set = nv50_fan_pwm_set;
priv->base.base.pwm_clock = nv50_fan_pwm_clock;
- priv->base.base.temp_get = nv84_temp_get;
- priv->base.sensor.program_alarms = nv84_therm_program_alarms;
- nv_subdev(priv)->intr = nv84_therm_intr;
+ priv->base.base.temp_get = g84_temp_get;
+ priv->base.sensor.program_alarms = g84_therm_program_alarms;
+ nv_subdev(priv)->intr = g84_therm_intr;
/* init the thresholds */
- nouveau_therm_sensor_set_threshold_state(&priv->base.base,
- NOUVEAU_THERM_THRS_SHUTDOWN,
- NOUVEAU_THERM_THRS_LOWER);
- nouveau_therm_sensor_set_threshold_state(&priv->base.base,
- NOUVEAU_THERM_THRS_FANBOOST,
- NOUVEAU_THERM_THRS_LOWER);
- nouveau_therm_sensor_set_threshold_state(&priv->base.base,
- NOUVEAU_THERM_THRS_CRITICAL,
- NOUVEAU_THERM_THRS_LOWER);
- nouveau_therm_sensor_set_threshold_state(&priv->base.base,
- NOUVEAU_THERM_THRS_DOWNCLOCK,
- NOUVEAU_THERM_THRS_LOWER);
-
- return nouveau_therm_preinit(&priv->base.base);
+ nvkm_therm_sensor_set_threshold_state(&priv->base.base,
+ NVKM_THERM_THRS_SHUTDOWN,
+ NVKM_THERM_THRS_LOWER);
+ nvkm_therm_sensor_set_threshold_state(&priv->base.base,
+ NVKM_THERM_THRS_FANBOOST,
+ NVKM_THERM_THRS_LOWER);
+ nvkm_therm_sensor_set_threshold_state(&priv->base.base,
+ NVKM_THERM_THRS_CRITICAL,
+ NVKM_THERM_THRS_LOWER);
+ nvkm_therm_sensor_set_threshold_state(&priv->base.base,
+ NVKM_THERM_THRS_DOWNCLOCK,
+ NVKM_THERM_THRS_LOWER);
+
+ return nvkm_therm_preinit(&priv->base.base);
}
int
-nv84_therm_fini(struct nouveau_object *object, bool suspend)
+g84_therm_fini(struct nvkm_object *object, bool suspend)
{
/* Disable PTherm IRQs */
nv_wr32(object, 0x20000, 0x00000000);
@@ -253,16 +251,16 @@ nv84_therm_fini(struct nouveau_object *object, bool suspend)
nv_wr32(object, 0x20100, 0xffffffff);
nv_wr32(object, 0x1100, 0x10000); /* PBUS */
- return _nouveau_therm_fini(object, suspend);
+ return _nvkm_therm_fini(object, suspend);
}
-struct nouveau_oclass
-nv84_therm_oclass = {
+struct nvkm_oclass
+g84_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x84),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nv84_therm_ctor,
- .dtor = _nouveau_therm_dtor,
- .init = nv84_therm_init,
- .fini = nv84_therm_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = g84_therm_ctor,
+ .dtor = _nvkm_therm_dtor,
+ .init = g84_therm_init,
+ .fini = g84_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf110.c
index b70f7cc649b8..46b7e656a752 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf110.c
@@ -21,15 +21,16 @@
*
* Authors: Ben Skeggs
*/
-
#include "priv.h"
-struct nvd0_therm_priv {
- struct nouveau_therm_priv base;
+#include <core/device.h>
+
+struct gf110_therm_priv {
+ struct nvkm_therm_priv base;
};
static int
-pwm_info(struct nouveau_therm *therm, int line)
+pwm_info(struct nvkm_therm *therm, int line)
{
u32 gpio = nv_rd32(therm, 0x00d610 + (line * 0x04));
@@ -53,7 +54,7 @@ pwm_info(struct nouveau_therm *therm, int line)
}
static int
-nvd0_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable)
+gf110_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
{
u32 data = enable ? 0x00000040 : 0x00000000;
int indx = pwm_info(therm, line);
@@ -66,7 +67,7 @@ nvd0_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable)
}
static int
-nvd0_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
+gf110_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
{
int indx = pwm_info(therm, line);
if (indx < 0)
@@ -87,7 +88,7 @@ nvd0_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
}
static int
-nvd0_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
+gf110_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
{
int indx = pwm_info(therm, line);
if (indx < 0)
@@ -103,7 +104,7 @@ nvd0_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
}
static int
-nvd0_fan_pwm_clock(struct nouveau_therm *therm, int line)
+gf110_fan_pwm_clock(struct nvkm_therm *therm, int line)
{
int indx = pwm_info(therm, line);
if (indx < 0)
@@ -115,12 +116,12 @@ nvd0_fan_pwm_clock(struct nouveau_therm *therm, int line)
}
int
-nvd0_therm_init(struct nouveau_object *object)
+gf110_therm_init(struct nvkm_object *object)
{
- struct nvd0_therm_priv *priv = (void *)object;
+ struct gf110_therm_priv *priv = (void *)object;
int ret;
- ret = nouveau_therm_init(&priv->base.base);
+ ret = nvkm_therm_init(&priv->base.base);
if (ret)
return ret;
@@ -137,38 +138,37 @@ nvd0_therm_init(struct nouveau_object *object)
}
static int
-nvd0_therm_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gf110_therm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nvd0_therm_priv *priv;
+ struct gf110_therm_priv *priv;
int ret;
- ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ ret = nvkm_therm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
- nv84_sensor_setup(&priv->base.base);
+ g84_sensor_setup(&priv->base.base);
- priv->base.base.pwm_ctrl = nvd0_fan_pwm_ctrl;
- priv->base.base.pwm_get = nvd0_fan_pwm_get;
- priv->base.base.pwm_set = nvd0_fan_pwm_set;
- priv->base.base.pwm_clock = nvd0_fan_pwm_clock;
- priv->base.base.temp_get = nv84_temp_get;
- priv->base.base.fan_sense = nva3_therm_fan_sense;
- priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
- return nouveau_therm_preinit(&priv->base.base);
+ priv->base.base.pwm_ctrl = gf110_fan_pwm_ctrl;
+ priv->base.base.pwm_get = gf110_fan_pwm_get;
+ priv->base.base.pwm_set = gf110_fan_pwm_set;
+ priv->base.base.pwm_clock = gf110_fan_pwm_clock;
+ priv->base.base.temp_get = g84_temp_get;
+ priv->base.base.fan_sense = gt215_therm_fan_sense;
+ priv->base.sensor.program_alarms = nvkm_therm_program_alarms_polling;
+ return nvkm_therm_preinit(&priv->base.base);
}
-struct nouveau_oclass
-nvd0_therm_oclass = {
+struct nvkm_oclass
+gf110_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0xd0),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nvd0_therm_ctor,
- .dtor = _nouveau_therm_dtor,
- .init = nvd0_therm_init,
- .fini = nv84_therm_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gf110_therm_ctor,
+ .dtor = _nvkm_therm_dtor,
+ .init = gf110_therm_init,
+ .fini = g84_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c
index 668cf3322285..2fd110f09878 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm107.c
@@ -21,22 +21,23 @@
*
* Authors: Martin Peres
*/
-
#include "priv.h"
+#include <core/device.h>
+
struct gm107_therm_priv {
- struct nouveau_therm_priv base;
+ struct nvkm_therm_priv base;
};
static int
-gm107_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable)
+gm107_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
{
/* nothing to do, it seems hardwired */
return 0;
}
static int
-gm107_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
+gm107_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
{
*divs = nv_rd32(therm, 0x10eb20) & 0x1fff;
*duty = nv_rd32(therm, 0x10eb24) & 0x1fff;
@@ -44,7 +45,7 @@ gm107_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
}
static int
-gm107_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
+gm107_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
{
nv_mask(therm, 0x10eb10, 0x1fff, divs); /* keep the high bits */
nv_wr32(therm, 0x10eb14, duty | 0x80000000);
@@ -52,21 +53,20 @@ gm107_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
}
static int
-gm107_fan_pwm_clock(struct nouveau_therm *therm, int line)
+gm107_fan_pwm_clock(struct nvkm_therm *therm, int line)
{
return nv_device(therm)->crystal * 1000;
}
static int
-gm107_therm_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gm107_therm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct gm107_therm_priv *priv;
int ret;
- ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ ret = nvkm_therm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -75,19 +75,19 @@ gm107_therm_ctor(struct nouveau_object *parent,
priv->base.base.pwm_get = gm107_fan_pwm_get;
priv->base.base.pwm_set = gm107_fan_pwm_set;
priv->base.base.pwm_clock = gm107_fan_pwm_clock;
- priv->base.base.temp_get = nv84_temp_get;
- priv->base.base.fan_sense = nva3_therm_fan_sense;
- priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
- return nouveau_therm_preinit(&priv->base.base);
+ priv->base.base.temp_get = g84_temp_get;
+ priv->base.base.fan_sense = gt215_therm_fan_sense;
+ priv->base.sensor.program_alarms = nvkm_therm_program_alarms_polling;
+ return nvkm_therm_preinit(&priv->base.base);
}
-struct nouveau_oclass
+struct nvkm_oclass
gm107_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x117),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gm107_therm_ctor,
- .dtor = _nouveau_therm_dtor,
- .init = nvd0_therm_init,
- .fini = nv84_therm_fini,
+ .dtor = _nvkm_therm_dtor,
+ .init = gf110_therm_init,
+ .fini = g84_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
index 7893357a7e9f..e99be20332f2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
@@ -21,17 +21,17 @@
*
* Authors: Ben Skeggs
*/
+#include "priv.h"
+#include <core/device.h>
#include <subdev/gpio.h>
-#include "priv.h"
-
-struct nva3_therm_priv {
- struct nouveau_therm_priv base;
+struct gt215_therm_priv {
+ struct nvkm_therm_priv base;
};
int
-nva3_therm_fan_sense(struct nouveau_therm *therm)
+gt215_therm_fan_sense(struct nvkm_therm *therm)
{
u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff;
u32 ctrl = nv_rd32(therm, 0x00e720);
@@ -41,17 +41,17 @@ nva3_therm_fan_sense(struct nouveau_therm *therm)
}
static int
-nva3_therm_init(struct nouveau_object *object)
+gt215_therm_init(struct nvkm_object *object)
{
- struct nva3_therm_priv *priv = (void *)object;
+ struct gt215_therm_priv *priv = (void *)object;
struct dcb_gpio_func *tach = &priv->base.fan->tach;
int ret;
- ret = nouveau_therm_init(&priv->base.base);
+ ret = nvkm_therm_init(&priv->base.base);
if (ret)
return ret;
- nv84_sensor_setup(&priv->base.base);
+ g84_sensor_setup(&priv->base.base);
/* enable fan tach, count revolutions per-second */
nv_mask(priv, 0x00e720, 0x00000003, 0x00000002);
@@ -66,15 +66,14 @@ nva3_therm_init(struct nouveau_object *object)
}
static int
-nva3_therm_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gt215_therm_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
- struct nva3_therm_priv *priv;
+ struct gt215_therm_priv *priv;
int ret;
- ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ ret = nvkm_therm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -83,19 +82,19 @@ nva3_therm_ctor(struct nouveau_object *parent,
priv->base.base.pwm_get = nv50_fan_pwm_get;
priv->base.base.pwm_set = nv50_fan_pwm_set;
priv->base.base.pwm_clock = nv50_fan_pwm_clock;
- priv->base.base.temp_get = nv84_temp_get;
- priv->base.base.fan_sense = nva3_therm_fan_sense;
- priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
- return nouveau_therm_preinit(&priv->base.base);
+ priv->base.base.temp_get = g84_temp_get;
+ priv->base.base.fan_sense = gt215_therm_fan_sense;
+ priv->base.sensor.program_alarms = nvkm_therm_program_alarms_polling;
+ return nvkm_therm_preinit(&priv->base.base);
}
-struct nouveau_oclass
-nva3_therm_oclass = {
+struct nvkm_oclass
+gt215_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0xa3),
- .ofuncs = &(struct nouveau_ofuncs) {
- .ctor = nva3_therm_ctor,
- .dtor = _nouveau_therm_dtor,
- .init = nva3_therm_init,
- .fini = nv84_therm_fini,
+ .ofuncs = &(struct nvkm_ofuncs) {
+ .ctor = gt215_therm_ctor,
+ .dtor = _nvkm_therm_dtor,
+ .init = gt215_therm_init,
+ .fini = g84_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c
index ca9ad9fd47be..09fc4605e853 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/ic.c
@@ -21,17 +21,16 @@
*
* Authors: Martin Peres
*/
-
#include "priv.h"
-#include <subdev/i2c.h>
#include <subdev/bios/extdev.h>
+#include <subdev/i2c.h>
static bool
-probe_monitoring_device(struct nouveau_i2c_port *i2c,
+probe_monitoring_device(struct nvkm_i2c_port *i2c,
struct i2c_board_info *info, void *data)
{
- struct nouveau_therm_priv *priv = data;
+ struct nvkm_therm_priv *priv = data;
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
struct i2c_client *client;
@@ -52,11 +51,10 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c,
"temp offset %+i C)\n",
info->type, info->addr, sensor->offset_constant);
priv->ic = client;
-
return true;
}
-static struct nouveau_i2c_board_info
+static struct nvkm_i2c_board_info
nv_board_infos[] = {
{ { I2C_BOARD_INFO("w83l785ts", 0x2d) }, 0 },
{ { I2C_BOARD_INFO("w83781d", 0x2d) }, 0 },
@@ -82,15 +80,15 @@ nv_board_infos[] = {
};
void
-nouveau_therm_ic_ctor(struct nouveau_therm *therm)
+nvkm_therm_ic_ctor(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_bios *bios = nouveau_bios(therm);
- struct nouveau_i2c *i2c = nouveau_i2c(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_bios *bios = nvkm_bios(therm);
+ struct nvkm_i2c *i2c = nvkm_i2c(therm);
struct nvbios_extdev_func extdev_entry;
if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_LM89, &extdev_entry)) {
- struct nouveau_i2c_board_info board[] = {
+ struct nvkm_i2c_board_info board[] = {
{ { I2C_BOARD_INFO("lm90", extdev_entry.addr >> 1) }, 0},
{ }
};
@@ -102,7 +100,7 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm)
}
if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_ADT7473, &extdev_entry)) {
- struct nouveau_i2c_board_info board[] = {
+ struct nvkm_i2c_board_info board[] = {
{ { I2C_BOARD_INFO("adt7473", extdev_entry.addr >> 1) }, 20 },
{ }
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv40.c
index 002e51b3af93..8496fffd4688 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv40.c
@@ -22,19 +22,20 @@
* Authors: Ben Skeggs
* Martin Peres
*/
-
#include "priv.h"
+#include <core/device.h>
+
struct nv40_therm_priv {
- struct nouveau_therm_priv base;
+ struct nvkm_therm_priv base;
};
enum nv40_sensor_style { INVALID_STYLE = -1, OLD_STYLE = 0, NEW_STYLE = 1 };
static enum nv40_sensor_style
-nv40_sensor_style(struct nouveau_therm *therm)
+nv40_sensor_style(struct nvkm_therm *therm)
{
- struct nouveau_device *device = nv_device(therm);
+ struct nvkm_device *device = nv_device(therm);
switch (device->chipset) {
case 0x43:
@@ -58,7 +59,7 @@ nv40_sensor_style(struct nouveau_therm *therm)
}
static int
-nv40_sensor_setup(struct nouveau_therm *therm)
+nv40_sensor_setup(struct nvkm_therm *therm)
{
enum nv40_sensor_style style = nv40_sensor_style(therm);
@@ -77,9 +78,9 @@ nv40_sensor_setup(struct nouveau_therm *therm)
}
static int
-nv40_temp_get(struct nouveau_therm *therm)
+nv40_temp_get(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
enum nv40_sensor_style style = nv40_sensor_style(therm);
int core_temp;
@@ -110,7 +111,7 @@ nv40_temp_get(struct nouveau_therm *therm)
}
static int
-nv40_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable)
+nv40_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
{
u32 mask = enable ? 0x80000000 : 0x0000000;
if (line == 2) nv_mask(therm, 0x0010f0, 0x80000000, mask);
@@ -123,7 +124,7 @@ nv40_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable)
}
static int
-nv40_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
+nv40_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
{
if (line == 2) {
u32 reg = nv_rd32(therm, 0x0010f0);
@@ -149,7 +150,7 @@ nv40_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
}
static int
-nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
+nv40_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
{
if (line == 2) {
nv_mask(therm, 0x0010f0, 0x7fff7fff, (duty << 16) | divs);
@@ -166,9 +167,9 @@ nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
}
void
-nv40_therm_intr(struct nouveau_subdev *subdev)
+nv40_therm_intr(struct nvkm_subdev *subdev)
{
- struct nouveau_therm *therm = nouveau_therm(subdev);
+ struct nvkm_therm *therm = nvkm_therm(subdev);
uint32_t stat = nv_rd32(therm, 0x1100);
/* traitement */
@@ -180,15 +181,15 @@ nv40_therm_intr(struct nouveau_subdev *subdev)
}
static int
-nv40_therm_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_therm_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv40_therm_priv *priv;
int ret;
- ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ ret = nvkm_therm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -197,28 +198,28 @@ nv40_therm_ctor(struct nouveau_object *parent,
priv->base.base.pwm_get = nv40_fan_pwm_get;
priv->base.base.pwm_set = nv40_fan_pwm_set;
priv->base.base.temp_get = nv40_temp_get;
- priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
+ priv->base.sensor.program_alarms = nvkm_therm_program_alarms_polling;
nv_subdev(priv)->intr = nv40_therm_intr;
- return nouveau_therm_preinit(&priv->base.base);
+ return nvkm_therm_preinit(&priv->base.base);
}
static int
-nv40_therm_init(struct nouveau_object *object)
+nv40_therm_init(struct nvkm_object *object)
{
- struct nouveau_therm *therm = (void *)object;
+ struct nvkm_therm *therm = (void *)object;
nv40_sensor_setup(therm);
- return _nouveau_therm_init(object);
+ return _nvkm_therm_init(object);
}
-struct nouveau_oclass
+struct nvkm_oclass
nv40_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv40_therm_ctor,
- .dtor = _nouveau_therm_dtor,
+ .dtor = _nvkm_therm_dtor,
.init = nv40_therm_init,
- .fini = _nouveau_therm_fini,
+ .fini = _nvkm_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv50.c
index 321db927d638..1ef59e8922d4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/nv50.c
@@ -22,15 +22,16 @@
* Authors: Ben Skeggs
* Martin Peres
*/
-
#include "priv.h"
+#include <core/device.h>
+
struct nv50_therm_priv {
- struct nouveau_therm_priv base;
+ struct nvkm_therm_priv base;
};
static int
-pwm_info(struct nouveau_therm *therm, int *line, int *ctrl, int *indx)
+pwm_info(struct nvkm_therm *therm, int *line, int *ctrl, int *indx)
{
if (*line == 0x04) {
*ctrl = 0x00e100;
@@ -55,7 +56,7 @@ pwm_info(struct nouveau_therm *therm, int *line, int *ctrl, int *indx)
}
int
-nv50_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable)
+nv50_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
{
u32 data = enable ? 0x00000001 : 0x00000000;
int ctrl, id, ret = pwm_info(therm, &line, &ctrl, &id);
@@ -65,7 +66,7 @@ nv50_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable)
}
int
-nv50_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
+nv50_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
{
int ctrl, id, ret = pwm_info(therm, &line, &ctrl, &id);
if (ret)
@@ -81,7 +82,7 @@ nv50_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty)
}
int
-nv50_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
+nv50_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
{
int ctrl, id, ret = pwm_info(therm, &line, &ctrl, &id);
if (ret)
@@ -93,7 +94,7 @@ nv50_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
}
int
-nv50_fan_pwm_clock(struct nouveau_therm *therm, int line)
+nv50_fan_pwm_clock(struct nvkm_therm *therm, int line)
{
int chipset = nv_device(therm)->chipset;
int crystal = nv_device(therm)->crystal;
@@ -119,16 +120,16 @@ nv50_fan_pwm_clock(struct nouveau_therm *therm, int line)
}
static void
-nv50_sensor_setup(struct nouveau_therm *therm)
+nv50_sensor_setup(struct nvkm_therm *therm)
{
nv_mask(therm, 0x20010, 0x40000000, 0x0);
mdelay(20); /* wait for the temperature to stabilize */
}
static int
-nv50_temp_get(struct nouveau_therm *therm)
+nv50_temp_get(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
int core_temp;
@@ -151,15 +152,15 @@ nv50_temp_get(struct nouveau_therm *therm)
}
static int
-nv50_therm_ctor(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv50_therm_ctor(struct nvkm_object *parent,
+ struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv50_therm_priv *priv;
int ret;
- ret = nouveau_therm_create(parent, engine, oclass, &priv);
+ ret = nvkm_therm_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -169,29 +170,29 @@ nv50_therm_ctor(struct nouveau_object *parent,
priv->base.base.pwm_set = nv50_fan_pwm_set;
priv->base.base.pwm_clock = nv50_fan_pwm_clock;
priv->base.base.temp_get = nv50_temp_get;
- priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
+ priv->base.sensor.program_alarms = nvkm_therm_program_alarms_polling;
nv_subdev(priv)->intr = nv40_therm_intr;
- return nouveau_therm_preinit(&priv->base.base);
+ return nvkm_therm_preinit(&priv->base.base);
}
static int
-nv50_therm_init(struct nouveau_object *object)
+nv50_therm_init(struct nvkm_object *object)
{
- struct nouveau_therm *therm = (void *)object;
+ struct nvkm_therm *therm = (void *)object;
nv50_sensor_setup(therm);
- return _nouveau_therm_init(object);
+ return _nvkm_therm_init(object);
}
-struct nouveau_oclass
+struct nvkm_oclass
nv50_therm_oclass = {
.handle = NV_SUBDEV(THERM, 0x50),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv50_therm_ctor,
- .dtor = _nouveau_therm_dtor,
+ .dtor = _nvkm_therm_dtor,
.init = nv50_therm_init,
- .fini = _nouveau_therm_fini,
+ .fini = _nvkm_therm_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
new file mode 100644
index 000000000000..916a149efe6e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
@@ -0,0 +1,153 @@
+#ifndef __NVTHERM_PRIV_H__
+#define __NVTHERM_PRIV_H__
+/*
+ * Copyright 2012 The Nouveau community
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Martin Peres
+ */
+#include <subdev/therm.h>
+#include <subdev/bios.h>
+#include <subdev/bios/extdev.h>
+#include <subdev/bios/gpio.h>
+#include <subdev/bios/perf.h>
+#include <subdev/bios/therm.h>
+#include <subdev/timer.h>
+
+struct nvkm_fan {
+ struct nvkm_therm *parent;
+ const char *type;
+
+ struct nvbios_therm_fan bios;
+ struct nvbios_perf_fan perf;
+
+ struct nvkm_alarm alarm;
+ spinlock_t lock;
+ int percent;
+
+ int (*get)(struct nvkm_therm *);
+ int (*set)(struct nvkm_therm *, int percent);
+
+ struct dcb_gpio_func tach;
+};
+
+enum nvkm_therm_thrs_direction {
+ NVKM_THERM_THRS_FALLING = 0,
+ NVKM_THERM_THRS_RISING = 1
+};
+
+enum nvkm_therm_thrs_state {
+ NVKM_THERM_THRS_LOWER = 0,
+ NVKM_THERM_THRS_HIGHER = 1
+};
+
+enum nvkm_therm_thrs {
+ NVKM_THERM_THRS_FANBOOST = 0,
+ NVKM_THERM_THRS_DOWNCLOCK = 1,
+ NVKM_THERM_THRS_CRITICAL = 2,
+ NVKM_THERM_THRS_SHUTDOWN = 3,
+ NVKM_THERM_THRS_NR
+};
+
+struct nvkm_therm_priv {
+ struct nvkm_therm base;
+
+ /* automatic thermal management */
+ struct nvkm_alarm alarm;
+ spinlock_t lock;
+ struct nvbios_therm_trip_point *last_trip;
+ int mode;
+ int cstate;
+ int suspend;
+
+ /* bios */
+ struct nvbios_therm_sensor bios_sensor;
+
+ /* fan priv */
+ struct nvkm_fan *fan;
+
+ /* alarms priv */
+ struct {
+ spinlock_t alarm_program_lock;
+ struct nvkm_alarm therm_poll_alarm;
+ enum nvkm_therm_thrs_state alarm_state[NVKM_THERM_THRS_NR];
+ void (*program_alarms)(struct nvkm_therm *);
+ } sensor;
+
+ /* what should be done if the card overheats */
+ struct {
+ void (*downclock)(struct nvkm_therm *, bool active);
+ void (*pause)(struct nvkm_therm *, bool active);
+ } emergency;
+
+ /* ic */
+ struct i2c_client *ic;
+};
+
+int nvkm_therm_fan_mode(struct nvkm_therm *, int mode);
+int nvkm_therm_attr_get(struct nvkm_therm *, enum nvkm_therm_attr_type);
+int nvkm_therm_attr_set(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
+
+void nvkm_therm_ic_ctor(struct nvkm_therm *);
+
+int nvkm_therm_sensor_ctor(struct nvkm_therm *);
+
+int nvkm_therm_fan_ctor(struct nvkm_therm *);
+int nvkm_therm_fan_init(struct nvkm_therm *);
+int nvkm_therm_fan_fini(struct nvkm_therm *, bool suspend);
+int nvkm_therm_fan_get(struct nvkm_therm *);
+int nvkm_therm_fan_set(struct nvkm_therm *, bool now, int percent);
+int nvkm_therm_fan_user_get(struct nvkm_therm *);
+int nvkm_therm_fan_user_set(struct nvkm_therm *, int percent);
+
+int nvkm_therm_fan_sense(struct nvkm_therm *);
+
+int nvkm_therm_preinit(struct nvkm_therm *);
+
+int nvkm_therm_sensor_init(struct nvkm_therm *);
+int nvkm_therm_sensor_fini(struct nvkm_therm *, bool suspend);
+void nvkm_therm_sensor_preinit(struct nvkm_therm *);
+void nvkm_therm_sensor_set_threshold_state(struct nvkm_therm *,
+ enum nvkm_therm_thrs,
+ enum nvkm_therm_thrs_state);
+enum nvkm_therm_thrs_state
+nvkm_therm_sensor_get_threshold_state(struct nvkm_therm *,
+ enum nvkm_therm_thrs);
+void nvkm_therm_sensor_event(struct nvkm_therm *, enum nvkm_therm_thrs,
+ enum nvkm_therm_thrs_direction);
+void nvkm_therm_program_alarms_polling(struct nvkm_therm *);
+
+void nv40_therm_intr(struct nvkm_subdev *);
+int nv50_fan_pwm_ctrl(struct nvkm_therm *, int, bool);
+int nv50_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *);
+int nv50_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
+int nv50_fan_pwm_clock(struct nvkm_therm *, int);
+int g84_temp_get(struct nvkm_therm *);
+void g84_sensor_setup(struct nvkm_therm *);
+int g84_therm_fini(struct nvkm_object *, bool suspend);
+
+int gt215_therm_fan_sense(struct nvkm_therm *);
+
+int gf110_therm_init(struct nvkm_object *);
+
+int nvkm_fanpwm_create(struct nvkm_therm *, struct dcb_gpio_func *);
+int nvkm_fantog_create(struct nvkm_therm *, struct dcb_gpio_func *);
+int nvkm_fannil_create(struct nvkm_therm *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
index 6212537b90c5..aa13744f3854 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
@@ -21,18 +21,12 @@
*
* Authors: Martin Peres
*/
-
#include "priv.h"
-#include <core/object.h>
-#include <core/device.h>
-
-#include <subdev/bios.h>
-
static void
-nouveau_therm_temp_set_defaults(struct nouveau_therm *therm)
+nvkm_therm_temp_set_defaults(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
priv->bios_sensor.offset_constant = 0;
@@ -51,9 +45,9 @@ nouveau_therm_temp_set_defaults(struct nouveau_therm *therm)
static void
-nouveau_therm_temp_safety_checks(struct nouveau_therm *therm)
+nvkm_therm_temp_safety_checks(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
struct nvbios_therm_sensor *s = &priv->bios_sensor;
/* enforce a minimum hysteresis on thresholds */
@@ -64,20 +58,21 @@ nouveau_therm_temp_safety_checks(struct nouveau_therm *therm)
}
/* must be called with alarm_program_lock taken ! */
-void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm,
- enum nouveau_therm_thrs thrs,
- enum nouveau_therm_thrs_state st)
+void
+nvkm_therm_sensor_set_threshold_state(struct nvkm_therm *therm,
+ enum nvkm_therm_thrs thrs,
+ enum nvkm_therm_thrs_state st)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
priv->sensor.alarm_state[thrs] = st;
}
/* must be called with alarm_program_lock taken ! */
-enum nouveau_therm_thrs_state
-nouveau_therm_sensor_get_threshold_state(struct nouveau_therm *therm,
- enum nouveau_therm_thrs thrs)
+enum nvkm_therm_thrs_state
+nvkm_therm_sensor_get_threshold_state(struct nvkm_therm *therm,
+ enum nvkm_therm_thrs thrs)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
return priv->sensor.alarm_state[thrs];
}
@@ -88,11 +83,11 @@ nv_poweroff_work(struct work_struct *work)
kfree(work);
}
-void nouveau_therm_sensor_event(struct nouveau_therm *therm,
- enum nouveau_therm_thrs thrs,
- enum nouveau_therm_thrs_direction dir)
+void
+nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
+ enum nvkm_therm_thrs_direction dir)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
bool active;
const char *thresolds[] = {
"fanboost", "downclock", "critical", "shutdown"
@@ -102,30 +97,30 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
if (thrs < 0 || thrs > 3)
return;
- if (dir == NOUVEAU_THERM_THRS_FALLING)
+ if (dir == NVKM_THERM_THRS_FALLING)
nv_info(therm, "temperature (%i C) went below the '%s' threshold\n",
temperature, thresolds[thrs]);
else
nv_info(therm, "temperature (%i C) hit the '%s' threshold\n",
temperature, thresolds[thrs]);
- active = (dir == NOUVEAU_THERM_THRS_RISING);
+ active = (dir == NVKM_THERM_THRS_RISING);
switch (thrs) {
- case NOUVEAU_THERM_THRS_FANBOOST:
+ case NVKM_THERM_THRS_FANBOOST:
if (active) {
- nouveau_therm_fan_set(therm, true, 100);
- nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO);
+ nvkm_therm_fan_set(therm, true, 100);
+ nvkm_therm_fan_mode(therm, NVKM_THERM_CTRL_AUTO);
}
break;
- case NOUVEAU_THERM_THRS_DOWNCLOCK:
+ case NVKM_THERM_THRS_DOWNCLOCK:
if (priv->emergency.downclock)
priv->emergency.downclock(therm, active);
break;
- case NOUVEAU_THERM_THRS_CRITICAL:
+ case NVKM_THERM_THRS_CRITICAL:
if (priv->emergency.pause)
priv->emergency.pause(therm, active);
break;
- case NOUVEAU_THERM_THRS_SHUTDOWN:
+ case NVKM_THERM_THRS_SHUTDOWN:
if (active) {
struct work_struct *work;
@@ -136,7 +131,7 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
}
}
break;
- case NOUVEAU_THERM_THRS_NR:
+ case NVKM_THERM_THRS_NR:
break;
}
@@ -144,53 +139,53 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
/* must be called with alarm_program_lock taken ! */
static void
-nouveau_therm_threshold_hyst_polling(struct nouveau_therm *therm,
- const struct nvbios_therm_threshold *thrs,
- enum nouveau_therm_thrs thrs_name)
+nvkm_therm_threshold_hyst_polling(struct nvkm_therm *therm,
+ const struct nvbios_therm_threshold *thrs,
+ enum nvkm_therm_thrs thrs_name)
{
- enum nouveau_therm_thrs_direction direction;
- enum nouveau_therm_thrs_state prev_state, new_state;
+ enum nvkm_therm_thrs_direction direction;
+ enum nvkm_therm_thrs_state prev_state, new_state;
int temp = therm->temp_get(therm);
- prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name);
+ prev_state = nvkm_therm_sensor_get_threshold_state(therm, thrs_name);
- if (temp >= thrs->temp && prev_state == NOUVEAU_THERM_THRS_LOWER) {
- direction = NOUVEAU_THERM_THRS_RISING;
- new_state = NOUVEAU_THERM_THRS_HIGHER;
+ if (temp >= thrs->temp && prev_state == NVKM_THERM_THRS_LOWER) {
+ direction = NVKM_THERM_THRS_RISING;
+ new_state = NVKM_THERM_THRS_HIGHER;
} else if (temp <= thrs->temp - thrs->hysteresis &&
- prev_state == NOUVEAU_THERM_THRS_HIGHER) {
- direction = NOUVEAU_THERM_THRS_FALLING;
- new_state = NOUVEAU_THERM_THRS_LOWER;
+ prev_state == NVKM_THERM_THRS_HIGHER) {
+ direction = NVKM_THERM_THRS_FALLING;
+ new_state = NVKM_THERM_THRS_LOWER;
} else
return; /* nothing to do */
- nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
- nouveau_therm_sensor_event(therm, thrs_name, direction);
+ nvkm_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
+ nvkm_therm_sensor_event(therm, thrs_name, direction);
}
static void
-alarm_timer_callback(struct nouveau_alarm *alarm)
+alarm_timer_callback(struct nvkm_alarm *alarm)
{
- struct nouveau_therm_priv *priv =
- container_of(alarm, struct nouveau_therm_priv, sensor.therm_poll_alarm);
+ struct nvkm_therm_priv *priv =
+ container_of(alarm, struct nvkm_therm_priv, sensor.therm_poll_alarm);
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
- struct nouveau_timer *ptimer = nouveau_timer(priv);
- struct nouveau_therm *therm = &priv->base;
+ struct nvkm_timer *ptimer = nvkm_timer(priv);
+ struct nvkm_therm *therm = &priv->base;
unsigned long flags;
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
- nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_fan_boost,
- NOUVEAU_THERM_THRS_FANBOOST);
+ nvkm_therm_threshold_hyst_polling(therm, &sensor->thrs_fan_boost,
+ NVKM_THERM_THRS_FANBOOST);
- nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_down_clock,
- NOUVEAU_THERM_THRS_DOWNCLOCK);
+ nvkm_therm_threshold_hyst_polling(therm, &sensor->thrs_down_clock,
+ NVKM_THERM_THRS_DOWNCLOCK);
- nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_critical,
- NOUVEAU_THERM_THRS_CRITICAL);
+ nvkm_therm_threshold_hyst_polling(therm, &sensor->thrs_critical,
+ NVKM_THERM_THRS_CRITICAL);
- nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_shutdown,
- NOUVEAU_THERM_THRS_SHUTDOWN);
+ nvkm_therm_threshold_hyst_polling(therm, &sensor->thrs_shutdown,
+ NVKM_THERM_THRS_SHUTDOWN);
spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
@@ -200,9 +195,9 @@ alarm_timer_callback(struct nouveau_alarm *alarm)
}
void
-nouveau_therm_program_alarms_polling(struct nouveau_therm *therm)
+nvkm_therm_program_alarms_polling(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
nv_debug(therm,
@@ -217,18 +212,18 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm)
}
int
-nouveau_therm_sensor_init(struct nouveau_therm *therm)
+nvkm_therm_sensor_init(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
+ struct nvkm_therm_priv *priv = (void *)therm;
priv->sensor.program_alarms(therm);
return 0;
}
int
-nouveau_therm_sensor_fini(struct nouveau_therm *therm, bool suspend)
+nvkm_therm_sensor_fini(struct nvkm_therm *therm, bool suspend)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_timer *ptimer = nouveau_timer(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_timer *ptimer = nvkm_timer(therm);
if (suspend)
ptimer->alarm_cancel(ptimer, &priv->sensor.therm_poll_alarm);
@@ -236,7 +231,7 @@ nouveau_therm_sensor_fini(struct nouveau_therm *therm, bool suspend)
}
void
-nouveau_therm_sensor_preinit(struct nouveau_therm *therm)
+nvkm_therm_sensor_preinit(struct nvkm_therm *therm)
{
const char *sensor_avail = "yes";
@@ -247,18 +242,18 @@ nouveau_therm_sensor_preinit(struct nouveau_therm *therm)
}
int
-nouveau_therm_sensor_ctor(struct nouveau_therm *therm)
+nvkm_therm_sensor_ctor(struct nvkm_therm *therm)
{
- struct nouveau_therm_priv *priv = (void *)therm;
- struct nouveau_bios *bios = nouveau_bios(therm);
+ struct nvkm_therm_priv *priv = (void *)therm;
+ struct nvkm_bios *bios = nvkm_bios(therm);
- nouveau_alarm_init(&priv->sensor.therm_poll_alarm, alarm_timer_callback);
+ nvkm_alarm_init(&priv->sensor.therm_poll_alarm, alarm_timer_callback);
- nouveau_therm_temp_set_defaults(therm);
+ nvkm_therm_temp_set_defaults(therm);
if (nvbios_therm_sensor_parse(bios, NVBIOS_THERM_DOMAIN_CORE,
&priv->bios_sensor))
nv_error(therm, "nvbios_therm_sensor_parse failed\n");
- nouveau_therm_temp_safety_checks(therm);
+ nvkm_therm_temp_safety_checks(therm);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/Kbuild
new file mode 100644
index 000000000000..d1d38b4ba30a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/Kbuild
@@ -0,0 +1,3 @@
+nvkm-y += nvkm/subdev/timer/base.o
+nvkm-y += nvkm/subdev/timer/nv04.o
+nvkm-y += nvkm/subdev/timer/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
index cf8a0e0f8ee3..d894061ced52 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
@@ -21,13 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
-#include "subdev/timer.h"
+#include <subdev/timer.h>
bool
-nouveau_timer_wait_eq(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
+nvkm_timer_wait_eq(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
{
- struct nouveau_timer *ptimer = nouveau_timer(obj);
+ struct nvkm_timer *ptimer = nvkm_timer(obj);
u64 time0;
time0 = ptimer->read(ptimer);
@@ -45,9 +44,9 @@ nouveau_timer_wait_eq(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
}
bool
-nouveau_timer_wait_ne(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
+nvkm_timer_wait_ne(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
{
- struct nouveau_timer *ptimer = nouveau_timer(obj);
+ struct nvkm_timer *ptimer = nvkm_timer(obj);
u64 time0;
time0 = ptimer->read(ptimer);
@@ -65,9 +64,9 @@ nouveau_timer_wait_ne(void *obj, u64 nsec, u32 addr, u32 mask, u32 data)
}
bool
-nouveau_timer_wait_cb(void *obj, u64 nsec, bool (*func)(void *), void *data)
+nvkm_timer_wait_cb(void *obj, u64 nsec, bool (*func)(void *), void *data)
{
- struct nouveau_timer *ptimer = nouveau_timer(obj);
+ struct nvkm_timer *ptimer = nvkm_timer(obj);
u64 time0;
time0 = ptimer->read(ptimer);
@@ -80,15 +79,15 @@ nouveau_timer_wait_cb(void *obj, u64 nsec, bool (*func)(void *), void *data)
}
void
-nouveau_timer_alarm(void *obj, u32 nsec, struct nouveau_alarm *alarm)
+nvkm_timer_alarm(void *obj, u32 nsec, struct nvkm_alarm *alarm)
{
- struct nouveau_timer *ptimer = nouveau_timer(obj);
+ struct nvkm_timer *ptimer = nvkm_timer(obj);
ptimer->alarm(ptimer, nsec, alarm);
}
void
-nouveau_timer_alarm_cancel(void *obj, struct nouveau_alarm *alarm)
+nvkm_timer_alarm_cancel(void *obj, struct nvkm_alarm *alarm)
{
- struct nouveau_timer *ptimer = nouveau_timer(obj);
+ struct nvkm_timer *ptimer = nvkm_timer(obj);
ptimer->alarm_cancel(ptimer, alarm);
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/gk20a.c
index 37484db1f7fc..80e38063dd9b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/gk20a.c
@@ -21,18 +21,17 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
static int
-gk20a_timer_init(struct nouveau_object *object)
+gk20a_timer_init(struct nvkm_object *object)
{
struct nv04_timer_priv *priv = (void *)object;
u32 hi = upper_32_bits(priv->suspend_time);
u32 lo = lower_32_bits(priv->suspend_time);
int ret;
- ret = nouveau_timer_init(&priv->base);
+ ret = nvkm_timer_init(&priv->base);
if (ret)
return ret;
@@ -45,10 +44,10 @@ gk20a_timer_init(struct nouveau_object *object)
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gk20a_timer_oclass = {
.handle = NV_SUBDEV(TIMER, 0xff),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_timer_ctor,
.dtor = nv04_timer_dtor,
.init = gk20a_timer_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c
index 240ed0b983a9..6b7facbe59a2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c
@@ -21,11 +21,12 @@
*
* Authors: Ben Skeggs
*/
-
#include "nv04.h"
+#include <core/device.h>
+
static u64
-nv04_timer_read(struct nouveau_timer *ptimer)
+nv04_timer_read(struct nvkm_timer *ptimer)
{
struct nv04_timer_priv *priv = (void *)ptimer;
u32 hi, lo;
@@ -39,10 +40,10 @@ nv04_timer_read(struct nouveau_timer *ptimer)
}
static void
-nv04_timer_alarm_trigger(struct nouveau_timer *ptimer)
+nv04_timer_alarm_trigger(struct nvkm_timer *ptimer)
{
struct nv04_timer_priv *priv = (void *)ptimer;
- struct nouveau_alarm *alarm, *atemp;
+ struct nvkm_alarm *alarm, *atemp;
unsigned long flags;
LIST_HEAD(exec);
@@ -71,11 +72,10 @@ nv04_timer_alarm_trigger(struct nouveau_timer *ptimer)
}
static void
-nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
- struct nouveau_alarm *alarm)
+nv04_timer_alarm(struct nvkm_timer *ptimer, u64 time, struct nvkm_alarm *alarm)
{
struct nv04_timer_priv *priv = (void *)ptimer;
- struct nouveau_alarm *list;
+ struct nvkm_alarm *list;
unsigned long flags;
alarm->timestamp = ptimer->read(ptimer) + time;
@@ -99,8 +99,7 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
}
static void
-nv04_timer_alarm_cancel(struct nouveau_timer *ptimer,
- struct nouveau_alarm *alarm)
+nv04_timer_alarm_cancel(struct nvkm_timer *ptimer, struct nvkm_alarm *alarm)
{
struct nv04_timer_priv *priv = (void *)ptimer;
unsigned long flags;
@@ -110,7 +109,7 @@ nv04_timer_alarm_cancel(struct nouveau_timer *ptimer,
}
static void
-nv04_timer_intr(struct nouveau_subdev *subdev)
+nv04_timer_intr(struct nvkm_subdev *subdev)
{
struct nv04_timer_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, NV04_PTIMER_INTR_0);
@@ -128,24 +127,24 @@ nv04_timer_intr(struct nouveau_subdev *subdev)
}
int
-nv04_timer_fini(struct nouveau_object *object, bool suspend)
+nv04_timer_fini(struct nvkm_object *object, bool suspend)
{
struct nv04_timer_priv *priv = (void *)object;
if (suspend)
priv->suspend_time = nv04_timer_read(&priv->base);
nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
- return nouveau_timer_fini(&priv->base, suspend);
+ return nvkm_timer_fini(&priv->base, suspend);
}
static int
-nv04_timer_init(struct nouveau_object *object)
+nv04_timer_init(struct nvkm_object *object)
{
- struct nouveau_device *device = nv_device(object);
+ struct nvkm_device *device = nv_device(object);
struct nv04_timer_priv *priv = (void *)object;
u32 m = 1, f, n, d, lo, hi;
int ret;
- ret = nouveau_timer_init(&priv->base);
+ ret = nvkm_timer_init(&priv->base);
if (ret)
return ret;
@@ -155,7 +154,7 @@ nv04_timer_init(struct nouveau_object *object)
/* determine base clock for timer source */
#if 0 /*XXX*/
if (device->chipset < 0x40) {
- n = nouveau_hw_get_clock(device, PLL_CORE);
+ n = nvkm_hw_get_clock(device, PLL_CORE);
} else
#endif
if (device->chipset <= 0x40) {
@@ -217,26 +216,25 @@ nv04_timer_init(struct nouveau_object *object)
nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
nv_wr32(priv, NV04_PTIMER_TIME_1, hi);
nv_wr32(priv, NV04_PTIMER_TIME_0, lo);
-
return 0;
}
void
-nv04_timer_dtor(struct nouveau_object *object)
+nv04_timer_dtor(struct nvkm_object *object)
{
struct nv04_timer_priv *priv = (void *)object;
- return nouveau_timer_destroy(&priv->base);
+ return nvkm_timer_destroy(&priv->base);
}
int
-nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv04_timer_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv04_timer_priv *priv;
int ret;
- ret = nouveau_timer_create(parent, engine, oclass, &priv);
+ ret = nvkm_timer_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -252,10 +250,10 @@ nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv04_timer_oclass = {
.handle = NV_SUBDEV(TIMER, 0x04),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv04_timer_ctor,
.dtor = nv04_timer_dtor,
.init = nv04_timer_init,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.h
index 4bc152697c37..89996a9826b1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.h
@@ -1,6 +1,5 @@
#ifndef __NVKM_TIMER_NV04_H__
#define __NVKM_TIMER_NV04_H__
-
#include "priv.h"
#define NV04_PTIMER_INTR_0 0x009100
@@ -12,16 +11,15 @@
#define NV04_PTIMER_ALARM_0 0x009420
struct nv04_timer_priv {
- struct nouveau_timer base;
+ struct nvkm_timer base;
struct list_head alarms;
spinlock_t lock;
u64 suspend_time;
};
-int nv04_timer_ctor(struct nouveau_object *, struct nouveau_object *,
- struct nouveau_oclass *, void *, u32,
- struct nouveau_object **);
-void nv04_timer_dtor(struct nouveau_object *);
-int nv04_timer_fini(struct nouveau_object *, bool);
-
+int nv04_timer_ctor(struct nvkm_object *, struct nvkm_object *,
+ struct nvkm_oclass *, void *, u32,
+ struct nvkm_object **);
+void nv04_timer_dtor(struct nvkm_object *);
+int nv04_timer_fini(struct nvkm_object *, bool);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/priv.h
index 799dae3f2300..08e29a3da188 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/priv.h
@@ -1,6 +1,4 @@
#ifndef __NVKM_TIMER_PRIV_H__
#define __NVKM_TIMER_PRIV_H__
-
#include <subdev/timer.h>
-
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild
new file mode 100644
index 000000000000..6b46ff4213a3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild
@@ -0,0 +1,4 @@
+nvkm-y += nvkm/subdev/volt/base.o
+nvkm-y += nvkm/subdev/volt/gpio.o
+nvkm-y += nvkm/subdev/volt/nv40.o
+nvkm-y += nvkm/subdev/volt/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
index 26ccd8df193f..39f15803f2d4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
@@ -21,15 +21,13 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/volt.h>
-
#include <subdev/bios.h>
#include <subdev/bios/vmap.h>
#include <subdev/bios/volt.h>
static int
-nouveau_volt_get(struct nouveau_volt *volt)
+nvkm_volt_get(struct nvkm_volt *volt)
{
if (volt->vid_get) {
int ret = volt->vid_get(volt), i;
@@ -46,7 +44,7 @@ nouveau_volt_get(struct nouveau_volt *volt)
}
static int
-nouveau_volt_set(struct nouveau_volt *volt, u32 uv)
+nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
{
if (volt->vid_set) {
int i, ret = -EINVAL;
@@ -63,9 +61,9 @@ nouveau_volt_set(struct nouveau_volt *volt, u32 uv)
}
static int
-nouveau_volt_map(struct nouveau_volt *volt, u8 id)
+nvkm_volt_map(struct nvkm_volt *volt, u8 id)
{
- struct nouveau_bios *bios = nouveau_bios(volt);
+ struct nvkm_bios *bios = nvkm_bios(volt);
struct nvbios_vmap_entry info;
u8 ver, len;
u16 vmap;
@@ -73,7 +71,7 @@ nouveau_volt_map(struct nouveau_volt *volt, u8 id)
vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info);
if (vmap) {
if (info.link != 0xff) {
- int ret = nouveau_volt_map(volt, info.link);
+ int ret = nvkm_volt_map(volt, info.link);
if (ret < 0)
return ret;
info.min += ret;
@@ -85,15 +83,15 @@ nouveau_volt_map(struct nouveau_volt *volt, u8 id)
}
static int
-nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
+nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition)
{
- int ret = nouveau_volt_map(volt, id);
+ int ret = nvkm_volt_map(volt, id);
if (ret >= 0) {
- int prev = nouveau_volt_get(volt);
+ int prev = nvkm_volt_get(volt);
if (!condition || prev < 0 ||
(condition < 0 && ret < prev) ||
(condition > 0 && ret > prev)) {
- ret = nouveau_volt_set(volt, ret);
+ ret = nvkm_volt_set(volt, ret);
} else {
ret = 0;
}
@@ -101,8 +99,8 @@ nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
return ret;
}
-static void nouveau_volt_parse_bios(struct nouveau_bios *bios,
- struct nouveau_volt *volt)
+static void
+nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt)
{
struct nvbios_volt_entry ivid;
struct nvbios_volt info;
@@ -125,7 +123,7 @@ static void nouveau_volt_parse_bios(struct nouveau_bios *bios,
} else if (data && info.vidmask) {
for (i = 0; i < cnt; i++) {
data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
- &ivid);
+ &ivid);
if (data) {
volt->vid[volt->vid_nr].uv = ivid.voltage;
volt->vid[volt->vid_nr].vid = ivid.vid;
@@ -137,12 +135,12 @@ static void nouveau_volt_parse_bios(struct nouveau_bios *bios,
}
int
-_nouveau_volt_init(struct nouveau_object *object)
+_nvkm_volt_init(struct nvkm_object *object)
{
- struct nouveau_volt *volt = (void *)object;
+ struct nvkm_volt *volt = (void *)object;
int ret;
- ret = nouveau_subdev_init(&volt->base);
+ ret = nvkm_subdev_init(&volt->base);
if (ret)
return ret;
@@ -158,34 +156,33 @@ _nouveau_volt_init(struct nouveau_object *object)
}
void
-_nouveau_volt_dtor(struct nouveau_object *object)
+_nvkm_volt_dtor(struct nvkm_object *object)
{
- struct nouveau_volt *volt = (void *)object;
- nouveau_subdev_destroy(&volt->base);
+ struct nvkm_volt *volt = (void *)object;
+ nvkm_subdev_destroy(&volt->base);
}
int
-nouveau_volt_create_(struct nouveau_object *parent,
- struct nouveau_object *engine,
- struct nouveau_oclass *oclass, int length, void **pobject)
+nvkm_volt_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, int length, void **pobject)
{
- struct nouveau_bios *bios = nouveau_bios(parent);
- struct nouveau_volt *volt;
+ struct nvkm_bios *bios = nvkm_bios(parent);
+ struct nvkm_volt *volt;
int ret, i;
- ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT",
- "voltage", length, pobject);
+ ret = nvkm_subdev_create_(parent, engine, oclass, 0, "VOLT",
+ "voltage", length, pobject);
volt = *pobject;
if (ret)
return ret;
- volt->get = nouveau_volt_get;
- volt->set = nouveau_volt_set;
- volt->set_id = nouveau_volt_set_id;
+ volt->get = nvkm_volt_get;
+ volt->set = nvkm_volt_set;
+ volt->set_id = nvkm_volt_set_id;
/* Assuming the non-bios device should build the voltage table later */
if (bios)
- nouveau_volt_parse_bios(bios, volt);
+ nvkm_volt_parse_bios(bios, volt);
if (volt->vid_nr) {
for (i = 0; i < volt->vid_nr; i++) {
@@ -196,10 +193,10 @@ nouveau_volt_create_(struct nouveau_object *parent,
/*XXX: this is an assumption.. there probably exists boards
* out there with i2c-connected voltage controllers too..
*/
- ret = nouveau_voltgpio_init(volt);
+ ret = nvkm_voltgpio_init(volt);
if (ret == 0) {
- volt->vid_get = nouveau_voltgpio_get;
- volt->vid_set = nouveau_voltgpio_set;
+ volt->vid_get = nvkm_voltgpio_get;
+ volt->vid_set = nvkm_voltgpio_set;
}
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
index 717368ef31ac..871fd51011db 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
@@ -19,11 +19,10 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-
+#include <subdev/volt.h>
#ifdef __KERNEL__
#include <nouveau_platform.h>
#endif
-#include <subdev/volt.h>
struct cvb_coef {
int c0;
@@ -35,7 +34,7 @@ struct cvb_coef {
};
struct gk20a_volt_priv {
- struct nouveau_volt base;
+ struct nvkm_volt base;
struct regulator *vdd;
};
@@ -62,8 +61,7 @@ const struct cvb_coef gk20a_cvb_coef[] = {
* cvb_mv = ((c2 * speedo / s_scale + c1) * speedo / s_scale + c0)
*/
static inline int
-gk20a_volt_get_cvb_voltage(int speedo, int s_scale,
- const struct cvb_coef *coef)
+gk20a_volt_get_cvb_voltage(int speedo, int s_scale, const struct cvb_coef *coef)
{
int mv;
@@ -79,7 +77,7 @@ gk20a_volt_get_cvb_voltage(int speedo, int s_scale,
*/
static inline int
gk20a_volt_get_cvb_t_voltage(int speedo, int temp, int s_scale, int t_scale,
- const struct cvb_coef *coef)
+ const struct cvb_coef *coef)
{
int cvb_mv, mv;
@@ -103,7 +101,7 @@ gk20a_volt_calc_voltage(const struct cvb_coef *coef, int speedo)
}
static int
-gk20a_volt_vid_get(struct nouveau_volt *volt)
+gk20a_volt_vid_get(struct nvkm_volt *volt)
{
struct gk20a_volt_priv *priv = (void *)volt;
int i, uv;
@@ -118,7 +116,7 @@ gk20a_volt_vid_get(struct nouveau_volt *volt)
}
static int
-gk20a_volt_vid_set(struct nouveau_volt *volt, u8 vid)
+gk20a_volt_vid_set(struct nvkm_volt *volt, u8 vid)
{
struct gk20a_volt_priv *priv = (void *)volt;
@@ -127,7 +125,7 @@ gk20a_volt_vid_set(struct nouveau_volt *volt, u8 vid)
}
static int
-gk20a_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
+gk20a_volt_set_id(struct nvkm_volt *volt, u8 id, int condition)
{
struct gk20a_volt_priv *priv = (void *)volt;
int prev_uv = regulator_get_voltage(priv->vdd);
@@ -148,16 +146,16 @@ gk20a_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
}
static int
-gk20a_volt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+gk20a_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct gk20a_volt_priv *priv;
- struct nouveau_volt *volt;
+ struct nvkm_volt *volt;
struct nouveau_platform_device *plat;
int i, ret, uv;
- ret = nouveau_volt_create(parent, engine, oclass, &priv);
+ ret = nvkm_volt_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -187,13 +185,13 @@ gk20a_volt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
gk20a_volt_oclass = {
.handle = NV_SUBDEV(VOLT, 0xea),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = gk20a_volt_ctor,
- .dtor = _nouveau_volt_dtor,
- .init = _nouveau_volt_init,
- .fini = _nouveau_volt_fini,
+ .dtor = _nvkm_volt_dtor,
+ .init = _nvkm_volt_init,
+ .fini = _nvkm_volt_fini,
},
};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gpio.c
index 755fa91bcd09..b778deb32d93 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gpio.c
@@ -21,10 +21,10 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/volt.h>
-#include <subdev/gpio.h>
+#include <subdev/bios.h>
#include <subdev/bios/gpio.h>
+#include <subdev/gpio.h>
static const u8 tags[] = {
DCB_GPIO_VID0, DCB_GPIO_VID1, DCB_GPIO_VID2, DCB_GPIO_VID3,
@@ -32,9 +32,9 @@ static const u8 tags[] = {
};
int
-nouveau_voltgpio_get(struct nouveau_volt *volt)
+nvkm_voltgpio_get(struct nvkm_volt *volt)
{
- struct nouveau_gpio *gpio = nouveau_gpio(volt);
+ struct nvkm_gpio *gpio = nvkm_gpio(volt);
u8 vid = 0;
int i;
@@ -51,9 +51,9 @@ nouveau_voltgpio_get(struct nouveau_volt *volt)
}
int
-nouveau_voltgpio_set(struct nouveau_volt *volt, u8 vid)
+nvkm_voltgpio_set(struct nvkm_volt *volt, u8 vid)
{
- struct nouveau_gpio *gpio = nouveau_gpio(volt);
+ struct nvkm_gpio *gpio = nvkm_gpio(volt);
int i;
for (i = 0; i < ARRAY_SIZE(tags); i++, vid >>= 1) {
@@ -68,9 +68,9 @@ nouveau_voltgpio_set(struct nouveau_volt *volt, u8 vid)
}
int
-nouveau_voltgpio_init(struct nouveau_volt *volt)
+nvkm_voltgpio_init(struct nvkm_volt *volt)
{
- struct nouveau_gpio *gpio = nouveau_gpio(volt);
+ struct nvkm_gpio *gpio = nvkm_gpio(volt);
struct dcb_gpio_func func;
int i;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c
index 87d5358376a6..0ac5a3f8c9a8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c
@@ -21,22 +21,21 @@
*
* Authors: Ben Skeggs
*/
-
#include <subdev/volt.h>
struct nv40_volt_priv {
- struct nouveau_volt base;
+ struct nvkm_volt base;
};
static int
-nv40_volt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nv40_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
+ struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
{
struct nv40_volt_priv *priv;
int ret;
- ret = nouveau_volt_create(parent, engine, oclass, &priv);
+ ret = nvkm_volt_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
@@ -44,13 +43,13 @@ nv40_volt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return 0;
}
-struct nouveau_oclass
+struct nvkm_oclass
nv40_volt_oclass = {
.handle = NV_SUBDEV(VOLT, 0x40),
- .ofuncs = &(struct nouveau_ofuncs) {
+ .ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv40_volt_ctor,
- .dtor = _nouveau_volt_dtor,
- .init = _nouveau_volt_init,
- .fini = _nouveau_volt_fini,
+ .dtor = _nvkm_volt_dtor,
+ .init = _nvkm_volt_init,
+ .fini = _nvkm_volt_fini,
},
};
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 8436c6857cda..d292d24b3a6e 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -334,17 +334,23 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
goto fail;
}
- drm_fb_helper_single_add_all_connectors(helper);
+ ret = drm_fb_helper_single_add_all_connectors(helper);
+ if (ret)
+ goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);
- drm_fb_helper_initial_config(helper, 32);
+ ret = drm_fb_helper_initial_config(helper, 32);
+ if (ret)
+ goto fini;
priv->fbdev = helper;
return helper;
+fini:
+ drm_fb_helper_fini(helper);
fail:
kfree(fbdev);
return NULL;
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 024e98ef8e4d..d84583776d50 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -10,6 +10,7 @@ menu "Display Panels"
config DRM_PANEL_SIMPLE
tristate "support for simple panels"
depends on OF
+ depends on BACKLIGHT_CLASS_DEVICE
help
DRM panel driver for dumb panels that need at most a regulator and
a GPIO to be powered up. Optionally a backlight can be attached so
@@ -31,6 +32,7 @@ config DRM_PANEL_SHARP_LQ101R1SX01
tristate "Sharp LQ101R1SX01 panel"
depends on OF
depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
help
Say Y here if you want to enable support for Sharp LQ101R1SX01
TFT-LCD modules. The panel has a 2560x1600 resolution and uses
diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 9d81759d82fc..3cce3ca19601 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -19,8 +19,6 @@
#include <video/mipi_display.h>
-#include <linux/host1x.h>
-
struct sharp_panel {
struct drm_panel base;
/* the datasheet refers to them as DSI-LINK1 and DSI-LINK2 */
@@ -41,6 +39,16 @@ static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel)
return container_of(panel, struct sharp_panel, base);
}
+static void sharp_wait_frames(struct sharp_panel *sharp, unsigned int frames)
+{
+ unsigned int refresh = drm_mode_vrefresh(sharp->mode);
+
+ if (WARN_ON(frames > refresh))
+ return;
+
+ msleep(1000 / (refresh / frames));
+}
+
static int sharp_panel_write(struct sharp_panel *sharp, u16 offset, u8 value)
{
u8 payload[3] = { offset >> 8, offset & 0xff, value };
@@ -106,6 +114,8 @@ static int sharp_panel_unprepare(struct drm_panel *panel)
if (!sharp->prepared)
return 0;
+ sharp_wait_frames(sharp, 4);
+
err = mipi_dsi_dcs_set_display_off(sharp->link1);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -170,15 +180,13 @@ static int sharp_panel_prepare(struct drm_panel *panel)
if (err < 0)
return err;
- usleep_range(10000, 20000);
-
- err = mipi_dsi_dcs_soft_reset(sharp->link1);
- if (err < 0) {
- dev_err(panel->dev, "soft reset failed: %d\n", err);
- goto poweroff;
- }
-
- msleep(120);
+ /*
+ * According to the datasheet, the panel needs around 10 ms to fully
+ * power up. At least another 120 ms is required before exiting sleep
+ * mode to make sure the panel is ready. Throw in another 20 ms for
+ * good measure.
+ */
+ msleep(150);
err = mipi_dsi_dcs_exit_sleep_mode(sharp->link1);
if (err < 0) {
@@ -238,6 +246,9 @@ static int sharp_panel_prepare(struct drm_panel *panel)
sharp->prepared = true;
+ /* wait for 6 frames before continuing */
+ sharp_wait_frames(sharp, 6);
+
return 0;
poweroff:
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index e95385bf8356..39806c335339 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -61,6 +61,8 @@ struct panel_desc {
unsigned int disable;
unsigned int unprepare;
} delay;
+
+ u32 bus_format;
};
struct panel_simple {
@@ -111,6 +113,9 @@ static int panel_simple_get_fixed_modes(struct panel_simple *panel)
connector->display_info.bpc = panel->desc->bpc;
connector->display_info.width_mm = panel->desc->size.width;
connector->display_info.height_mm = panel->desc->size.height;
+ if (panel->desc->bus_format)
+ drm_display_info_set_bus_formats(&connector->display_info,
+ &panel->desc->bus_format, 1);
return num;
}
@@ -443,6 +448,34 @@ static const struct panel_desc auo_b133htn01 = {
},
};
+static const struct drm_display_mode avic_tm070ddh03_mode = {
+ .clock = 51200,
+ .hdisplay = 1024,
+ .hsync_start = 1024 + 160,
+ .hsync_end = 1024 + 160 + 4,
+ .htotal = 1024 + 160 + 4 + 156,
+ .vdisplay = 600,
+ .vsync_start = 600 + 17,
+ .vsync_end = 600 + 17 + 1,
+ .vtotal = 600 + 17 + 1 + 17,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc avic_tm070ddh03 = {
+ .modes = &avic_tm070ddh03_mode,
+ .num_modes = 1,
+ .bpc = 8,
+ .size = {
+ .width = 154,
+ .height = 90,
+ },
+ .delay = {
+ .prepare = 20,
+ .enable = 200,
+ .disable = 200,
+ },
+};
+
static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
.clock = 72070,
.hdisplay = 1366,
@@ -558,6 +591,30 @@ static const struct panel_desc foxlink_fl500wvr00_a0t = {
.width = 108,
.height = 65,
},
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+};
+
+static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
+ .clock = 9000,
+ .hdisplay = 480,
+ .hsync_start = 480 + 5,
+ .hsync_end = 480 + 5 + 1,
+ .htotal = 480 + 5 + 1 + 40,
+ .vdisplay = 272,
+ .vsync_start = 272 + 8,
+ .vsync_end = 272 + 8 + 1,
+ .vtotal = 272 + 8 + 1 + 8,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc giantplus_gpg482739qs5 = {
+ .modes = &giantplus_gpg482739qs5_mode,
+ .num_modes = 1,
+ .bpc = 8,
+ .size = {
+ .width = 95,
+ .height = 54,
+ },
};
static const struct drm_display_mode hannstar_hsd070pww1_mode = {
@@ -739,6 +796,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "auo,b133xtn01",
.data = &auo_b133xtn01,
}, {
+ .compatible = "avic,tm070ddh03",
+ .data = &avic_tm070ddh03,
+ }, {
.compatible = "chunghwa,claa101wa01a",
.data = &chunghwa_claa101wa01a
}, {
@@ -757,6 +817,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "foxlink,fl500wvr00-a0t",
.data = &foxlink_fl500wvr00_a0t,
}, {
+ .compatible = "giantplus,gpg482739qs5",
+ .data = &giantplus_gpg482739qs5
+ }, {
.compatible = "hannstar,hsd070pww1",
.data = &hannstar_hsd070pww1,
}, {
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index 3d7c1d00a424..f778c0e8ae3c 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -686,14 +686,24 @@ int qxl_fbdev_init(struct qxl_device *qdev)
ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper,
qxl_num_crtc /* num_crtc - QXL supports just 1 */,
QXLFB_CONN_LIMIT);
- if (ret) {
- kfree(qfbdev);
- return ret;
- }
+ if (ret)
+ goto free;
+
+ ret = drm_fb_helper_single_add_all_connectors(&qfbdev->helper);
+ if (ret)
+ goto fini;
+
+ ret = drm_fb_helper_initial_config(&qfbdev->helper, bpp_sel);
+ if (ret)
+ goto fini;
- drm_fb_helper_single_add_all_connectors(&qfbdev->helper);
- drm_fb_helper_initial_config(&qfbdev->helper, bpp_sel);
return 0;
+
+fini:
+ drm_fb_helper_fini(&qfbdev->helper);
+free:
+ kfree(qfbdev);
+ return ret;
}
void qxl_fbdev_fini(struct qxl_device *qdev)
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 12bc21219a0e..4605633e253b 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -2,7 +2,7 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
-ccflags-y := -Iinclude/drm
+ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include
hostprogs-y := mkregtable
clean-files := rn50_reg_safe.h r100_reg_safe.h r200_reg_safe.h rv515_reg_safe.h r300_reg_safe.h r420_reg_safe.h rs600_reg_safe.h r600_reg_safe.h evergreen_reg_safe.h cayman_reg_safe.h
@@ -80,8 +80,10 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \
trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \
- ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \
- radeon_sync.o
+ ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o \
+ radeon_sync.o radeon_audio.o
+
+radeon-$(CONFIG_MMU_NOTIFIER) += radeon_mn.o
# add async DMA block
radeon-y += \
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index db42a670f995..5bf825dfaa09 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -623,10 +623,8 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
drm_dp_dpcd_writeb(dp_info->aux,
DP_DOWNSPREAD_CTRL, 0);
- if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
- (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
+ if (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)
drm_dp_dpcd_writeb(dp_info->aux, DP_EDP_CONFIGURATION_SET, 1);
- }
/* set the lane count on the sink */
tmp = dp_info->dp_lane_count;
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index b8cd7975f797..7c9df1eac065 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -27,6 +27,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/radeon_drm.h>
#include "radeon.h"
+#include "radeon_audio.h"
#include "atom.h"
#include <linux/backlight.h>
@@ -664,6 +665,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
int
atombios_get_encoder_mode(struct drm_encoder *encoder)
{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
@@ -728,6 +731,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
dig_connector = radeon_connector->con_priv;
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
+ if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))
+ return ATOM_ENCODER_MODE_DP_AUDIO;
return ATOM_ENCODER_MODE_DP;
} else if (radeon_audio != 0) {
if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
@@ -742,6 +747,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
}
break;
case DRM_MODE_CONNECTOR_eDP:
+ if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))
+ return ATOM_ENCODER_MODE_DP_AUDIO;
return ATOM_ENCODER_MODE_DP;
case DRM_MODE_CONNECTOR_DVIA:
case DRM_MODE_CONNECTOR_VGA:
@@ -1615,6 +1622,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
struct radeon_connector *radeon_connector = NULL;
struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
bool travis_quirk = false;
+ int encoder_mode;
if (connector) {
radeon_connector = to_radeon_connector(connector);
@@ -1710,6 +1718,11 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
}
break;
}
+
+ encoder_mode = atombios_get_encoder_mode(encoder);
+ if (radeon_audio != 0 &&
+ (encoder_mode == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(encoder_mode)))
+ radeon_audio_dpms(encoder, mode);
}
static void
@@ -2123,6 +2136,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ int encoder_mode;
radeon_encoder->pixel_clock = adjusted_mode->clock;
@@ -2149,6 +2163,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* handled in dpms */
+ encoder_mode = atombios_get_encoder_mode(encoder);
+ if (radeon_audio != 0 &&
+ (encoder_mode == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(encoder_mode)))
+ radeon_audio_mode_set(encoder, adjusted_mode);
break;
case ENCODER_OBJECT_ID_INTERNAL_DDI:
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
@@ -2170,13 +2188,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
}
atombios_apply_encoder_quirks(encoder, adjusted_mode);
-
- if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
- if (rdev->asic->display.hdmi_enable)
- radeon_hdmi_enable(rdev, encoder, true);
- if (rdev->asic->display.hdmi_setmode)
- radeon_hdmi_setmode(rdev, encoder, adjusted_mode);
- }
}
static bool
@@ -2442,10 +2453,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
disable_done:
if (radeon_encoder_is_digital(encoder)) {
- if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
- if (rdev->asic->display.hdmi_enable)
- radeon_hdmi_enable(rdev, encoder, false);
- }
dig = radeon_encoder->enc_priv;
dig->dig_encoder = -1;
}
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index 0b2929de9f41..db08f17be76b 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -2277,6 +2277,7 @@ static void btc_update_requested_ps(struct radeon_device *rdev,
eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps;
}
+#if 0
void btc_dpm_reset_asic(struct radeon_device *rdev)
{
rv770_restrict_performance_levels_before_switch(rdev);
@@ -2284,6 +2285,7 @@ void btc_dpm_reset_asic(struct radeon_device *rdev)
btc_set_boot_state_timing(rdev);
rv770_set_boot_state(rdev);
}
+#endif
int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
{
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index f373a81ba3d5..bcd2f1fe803f 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -187,6 +187,9 @@ static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate);
static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
PPSMC_Msg msg, u32 parameter);
+static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev);
+static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev);
+
static struct ci_power_info *ci_get_pi(struct radeon_device *rdev)
{
struct ci_power_info *pi = rdev->pm.dpm.priv;
@@ -1043,22 +1046,24 @@ static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev)
return -EINVAL;
}
+ pi->fan_is_controlled_by_smc = true;
return 0;
}
-#if 0
static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev)
{
PPSMC_Result ret;
+ struct ci_power_info *pi = ci_get_pi(rdev);
ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl);
- if (ret == PPSMC_Result_OK)
+ if (ret == PPSMC_Result_OK) {
+ pi->fan_is_controlled_by_smc = false;
return 0;
- else
+ } else
return -EINVAL;
}
-static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
+int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
u32 *speed)
{
u32 duty, duty100;
@@ -1083,21 +1088,22 @@ static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
return 0;
}
-static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
+int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
u32 speed)
{
u32 tmp;
u32 duty, duty100;
u64 tmp64;
+ struct ci_power_info *pi = ci_get_pi(rdev);
if (rdev->pm.no_fan)
return -ENOENT;
- if (speed > 100)
+ if (pi->fan_is_controlled_by_smc)
return -EINVAL;
- if (rdev->pm.dpm.fan.ucode_fan_control)
- ci_fan_ctrl_stop_smc_fan_control(rdev);
+ if (speed > 100)
+ return -EINVAL;
duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
@@ -1112,11 +1118,38 @@ static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
tmp |= FDO_STATIC_DUTY(duty);
WREG32_SMC(CG_FDO_CTRL0, tmp);
- ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
-
return 0;
}
+void ci_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode)
+{
+ if (mode) {
+ /* stop auto-manage */
+ if (rdev->pm.dpm.fan.ucode_fan_control)
+ ci_fan_ctrl_stop_smc_fan_control(rdev);
+ ci_fan_ctrl_set_static_mode(rdev, mode);
+ } else {
+ /* restart auto-manage */
+ if (rdev->pm.dpm.fan.ucode_fan_control)
+ ci_thermal_start_smc_fan_control(rdev);
+ else
+ ci_fan_ctrl_set_default_mode(rdev);
+ }
+}
+
+u32 ci_fan_ctrl_get_mode(struct radeon_device *rdev)
+{
+ struct ci_power_info *pi = ci_get_pi(rdev);
+ u32 tmp;
+
+ if (pi->fan_is_controlled_by_smc)
+ return 0;
+
+ tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK;
+ return (tmp >> FDO_PWM_MODE_SHIFT);
+}
+
+#if 0
static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev,
u32 *speed)
{
@@ -1698,10 +1731,12 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev,
return 0;
}
+#if 0
static int ci_set_boot_state(struct radeon_device *rdev)
{
return ci_enable_sclk_mclk_dpm(rdev, false);
}
+#endif
static u32 ci_get_average_sclk_freq(struct radeon_device *rdev)
{
@@ -5343,10 +5378,12 @@ int ci_dpm_set_power_state(struct radeon_device *rdev)
return 0;
}
+#if 0
void ci_dpm_reset_asic(struct radeon_device *rdev)
{
ci_set_boot_state(rdev);
}
+#endif
void ci_dpm_display_configuration_changed(struct radeon_device *rdev)
{
diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h
index 84e3d3bcf9f3..723220ffbea2 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.h
+++ b/drivers/gpu/drm/radeon/ci_dpm.h
@@ -291,6 +291,7 @@ struct ci_power_info {
struct ci_ps requested_ps;
/* fan control */
bool fan_ctrl_is_in_default_mode;
+ bool fan_is_controlled_by_smc;
u32 t_min;
u32 fan_ctrl_default_mode;
};
diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c
index e78bcad7a43e..35c6f648ba04 100644
--- a/drivers/gpu/drm/radeon/ci_smc.c
+++ b/drivers/gpu/drm/radeon/ci_smc.c
@@ -184,6 +184,7 @@ PPSMC_Result ci_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg)
return (PPSMC_Result)tmp;
}
+#if 0
PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev)
{
u32 tmp;
@@ -201,6 +202,7 @@ PPSMC_Result ci_wait_for_smc_inactive(struct radeon_device *rdev)
return PPSMC_Result_OK;
}
+#endif
int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
{
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 64fdae558d36..e6a4ba236c70 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -27,6 +27,7 @@
#include "drmP.h"
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include "cikd.h"
#include "atom.h"
#include "cik_blit_shaders.h"
@@ -3904,7 +3905,21 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
struct radeon_ring *ring = &rdev->ring[fence->ring];
u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
- /* EVENT_WRITE_EOP - flush caches, send int */
+ /* Workaround for cache flush problems. First send a dummy EOP
+ * event down the pipe with seq one below.
+ */
+ radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
+ radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
+ EOP_TC_ACTION_EN |
+ EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
+ EVENT_INDEX(5)));
+ radeon_ring_write(ring, addr & 0xfffffffc);
+ radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) |
+ DATA_SEL(1) | INT_SEL(0));
+ radeon_ring_write(ring, fence->seq - 1);
+ radeon_ring_write(ring, 0);
+
+ /* Then send the real EOP event down the pipe. */
radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
EOP_TC_ACTION_EN |
@@ -5707,6 +5722,28 @@ void cik_pcie_gart_tlb_flush(struct radeon_device *rdev)
WREG32(VM_INVALIDATE_REQUEST, 0x1);
}
+static void cik_pcie_init_compute_vmid(struct radeon_device *rdev)
+{
+ int i;
+ uint32_t sh_mem_bases, sh_mem_config;
+
+ sh_mem_bases = 0x6000 | 0x6000 << 16;
+ sh_mem_config = ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED);
+ sh_mem_config |= DEFAULT_MTYPE(MTYPE_NONCACHED);
+
+ mutex_lock(&rdev->srbm_mutex);
+ for (i = 8; i < 16; i++) {
+ cik_srbm_select(rdev, 0, 0, 0, i);
+ /* CP and shaders */
+ WREG32(SH_MEM_CONFIG, sh_mem_config);
+ WREG32(SH_MEM_APE1_BASE, 1);
+ WREG32(SH_MEM_APE1_LIMIT, 0);
+ WREG32(SH_MEM_BASES, sh_mem_bases);
+ }
+ cik_srbm_select(rdev, 0, 0, 0, 0);
+ mutex_unlock(&rdev->srbm_mutex);
+}
+
/**
* cik_pcie_gart_enable - gart enable
*
@@ -5820,6 +5857,8 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
cik_srbm_select(rdev, 0, 0, 0, 0);
mutex_unlock(&rdev->srbm_mutex);
+ cik_pcie_init_compute_vmid(rdev);
+
cik_pcie_gart_tlb_flush(rdev);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
(unsigned)(rdev->mc.gtt_size >> 20),
@@ -7334,7 +7373,6 @@ int cik_irq_set(struct radeon_device *rdev)
u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
u32 grbm_int_cntl = 0;
u32 dma_cntl, dma_cntl1;
- u32 thermal_int;
if (!rdev->irq.installed) {
WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
@@ -7364,13 +7402,6 @@ int cik_irq_set(struct radeon_device *rdev)
cp_m1p0 = RREG32(CP_ME1_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
- if (rdev->flags & RADEON_IS_IGP)
- thermal_int = RREG32_SMC(CG_THERMAL_INT_CTRL) &
- ~(THERM_INTH_MASK | THERM_INTL_MASK);
- else
- thermal_int = RREG32_SMC(CG_THERMAL_INT) &
- ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
-
/* enable CP interrupts on all rings */
if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
DRM_DEBUG("cik_irq_set: sw int gfx\n");
@@ -7474,14 +7505,6 @@ int cik_irq_set(struct radeon_device *rdev)
hpd6 |= DC_HPDx_INT_EN;
}
- if (rdev->irq.dpm_thermal) {
- DRM_DEBUG("dpm thermal\n");
- if (rdev->flags & RADEON_IS_IGP)
- thermal_int |= THERM_INTH_MASK | THERM_INTL_MASK;
- else
- thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
- }
-
WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, dma_cntl);
@@ -7528,11 +7551,6 @@ int cik_irq_set(struct radeon_device *rdev)
WREG32(DC_HPD5_INT_CONTROL, hpd5);
WREG32(DC_HPD6_INT_CONTROL, hpd6);
- if (rdev->flags & RADEON_IS_IGP)
- WREG32_SMC(CG_THERMAL_INT_CTRL, thermal_int);
- else
- WREG32_SMC(CG_THERMAL_INT, thermal_int);
-
return 0;
}
@@ -8493,7 +8511,7 @@ static int cik_startup(struct radeon_device *rdev)
return r;
}
- r = dce6_audio_init(rdev);
+ r = radeon_audio_init(rdev);
if (r)
return r;
@@ -8551,7 +8569,7 @@ int cik_suspend(struct radeon_device *rdev)
{
radeon_kfd_suspend(rdev);
radeon_pm_suspend(rdev);
- dce6_audio_fini(rdev);
+ radeon_audio_fini(rdev);
radeon_vm_manager_fini(rdev);
cik_cp_enable(rdev, false);
cik_sdma_enable(rdev, false);
diff --git a/drivers/gpu/drm/radeon/cik_reg.h b/drivers/gpu/drm/radeon/cik_reg.h
index 79c45e8a536b..f667347d8157 100644
--- a/drivers/gpu/drm/radeon/cik_reg.h
+++ b/drivers/gpu/drm/radeon/cik_reg.h
@@ -147,140 +147,41 @@
#define CIK_LB_DESKTOP_HEIGHT 0x6b0c
+#define KFD_CIK_SDMA_QUEUE_OFFSET 0x200
+
#define CP_HQD_IQ_RPTR 0xC970u
#define AQL_ENABLE (1U << 0)
-
-#define IDLE (1 << 2)
-
-struct cik_mqd {
- uint32_t header;
- uint32_t compute_dispatch_initiator;
- uint32_t compute_dim_x;
- uint32_t compute_dim_y;
- uint32_t compute_dim_z;
- uint32_t compute_start_x;
- uint32_t compute_start_y;
- uint32_t compute_start_z;
- uint32_t compute_num_thread_x;
- uint32_t compute_num_thread_y;
- uint32_t compute_num_thread_z;
- uint32_t compute_pipelinestat_enable;
- uint32_t compute_perfcount_enable;
- uint32_t compute_pgm_lo;
- uint32_t compute_pgm_hi;
- uint32_t compute_tba_lo;
- uint32_t compute_tba_hi;
- uint32_t compute_tma_lo;
- uint32_t compute_tma_hi;
- uint32_t compute_pgm_rsrc1;
- uint32_t compute_pgm_rsrc2;
- uint32_t compute_vmid;
- uint32_t compute_resource_limits;
- uint32_t compute_static_thread_mgmt_se0;
- uint32_t compute_static_thread_mgmt_se1;
- uint32_t compute_tmpring_size;
- uint32_t compute_static_thread_mgmt_se2;
- uint32_t compute_static_thread_mgmt_se3;
- uint32_t compute_restart_x;
- uint32_t compute_restart_y;
- uint32_t compute_restart_z;
- uint32_t compute_thread_trace_enable;
- uint32_t compute_misc_reserved;
- uint32_t compute_user_data_0;
- uint32_t compute_user_data_1;
- uint32_t compute_user_data_2;
- uint32_t compute_user_data_3;
- uint32_t compute_user_data_4;
- uint32_t compute_user_data_5;
- uint32_t compute_user_data_6;
- uint32_t compute_user_data_7;
- uint32_t compute_user_data_8;
- uint32_t compute_user_data_9;
- uint32_t compute_user_data_10;
- uint32_t compute_user_data_11;
- uint32_t compute_user_data_12;
- uint32_t compute_user_data_13;
- uint32_t compute_user_data_14;
- uint32_t compute_user_data_15;
- uint32_t cp_compute_csinvoc_count_lo;
- uint32_t cp_compute_csinvoc_count_hi;
- uint32_t cp_mqd_base_addr_lo;
- uint32_t cp_mqd_base_addr_hi;
- uint32_t cp_hqd_active;
- uint32_t cp_hqd_vmid;
- uint32_t cp_hqd_persistent_state;
- uint32_t cp_hqd_pipe_priority;
- uint32_t cp_hqd_queue_priority;
- uint32_t cp_hqd_quantum;
- uint32_t cp_hqd_pq_base_lo;
- uint32_t cp_hqd_pq_base_hi;
- uint32_t cp_hqd_pq_rptr;
- uint32_t cp_hqd_pq_rptr_report_addr_lo;
- uint32_t cp_hqd_pq_rptr_report_addr_hi;
- uint32_t cp_hqd_pq_wptr_poll_addr_lo;
- uint32_t cp_hqd_pq_wptr_poll_addr_hi;
- uint32_t cp_hqd_pq_doorbell_control;
- uint32_t cp_hqd_pq_wptr;
- uint32_t cp_hqd_pq_control;
- uint32_t cp_hqd_ib_base_addr_lo;
- uint32_t cp_hqd_ib_base_addr_hi;
- uint32_t cp_hqd_ib_rptr;
- uint32_t cp_hqd_ib_control;
- uint32_t cp_hqd_iq_timer;
- uint32_t cp_hqd_iq_rptr;
- uint32_t cp_hqd_dequeue_request;
- uint32_t cp_hqd_dma_offload;
- uint32_t cp_hqd_sema_cmd;
- uint32_t cp_hqd_msg_type;
- uint32_t cp_hqd_atomic0_preop_lo;
- uint32_t cp_hqd_atomic0_preop_hi;
- uint32_t cp_hqd_atomic1_preop_lo;
- uint32_t cp_hqd_atomic1_preop_hi;
- uint32_t cp_hqd_hq_status0;
- uint32_t cp_hqd_hq_control0;
- uint32_t cp_mqd_control;
- uint32_t cp_mqd_query_time_lo;
- uint32_t cp_mqd_query_time_hi;
- uint32_t cp_mqd_connect_start_time_lo;
- uint32_t cp_mqd_connect_start_time_hi;
- uint32_t cp_mqd_connect_end_time_lo;
- uint32_t cp_mqd_connect_end_time_hi;
- uint32_t cp_mqd_connect_end_wf_count;
- uint32_t cp_mqd_connect_end_pq_rptr;
- uint32_t cp_mqd_connect_end_pq_wptr;
- uint32_t cp_mqd_connect_end_ib_rptr;
- uint32_t reserved_96;
- uint32_t reserved_97;
- uint32_t reserved_98;
- uint32_t reserved_99;
- uint32_t iqtimer_pkt_header;
- uint32_t iqtimer_pkt_dw0;
- uint32_t iqtimer_pkt_dw1;
- uint32_t iqtimer_pkt_dw2;
- uint32_t iqtimer_pkt_dw3;
- uint32_t iqtimer_pkt_dw4;
- uint32_t iqtimer_pkt_dw5;
- uint32_t iqtimer_pkt_dw6;
- uint32_t reserved_108;
- uint32_t reserved_109;
- uint32_t reserved_110;
- uint32_t reserved_111;
- uint32_t queue_doorbell_id0;
- uint32_t queue_doorbell_id1;
- uint32_t queue_doorbell_id2;
- uint32_t queue_doorbell_id3;
- uint32_t queue_doorbell_id4;
- uint32_t queue_doorbell_id5;
- uint32_t queue_doorbell_id6;
- uint32_t queue_doorbell_id7;
- uint32_t queue_doorbell_id8;
- uint32_t queue_doorbell_id9;
- uint32_t queue_doorbell_id10;
- uint32_t queue_doorbell_id11;
- uint32_t queue_doorbell_id12;
- uint32_t queue_doorbell_id13;
- uint32_t queue_doorbell_id14;
- uint32_t queue_doorbell_id15;
-};
+#define SDMA0_RLC0_RB_CNTL 0xD400u
+#define SDMA_RB_VMID(x) (x << 24)
+#define SDMA0_RLC0_RB_BASE 0xD404u
+#define SDMA0_RLC0_RB_BASE_HI 0xD408u
+#define SDMA0_RLC0_RB_RPTR 0xD40Cu
+#define SDMA0_RLC0_RB_WPTR 0xD410u
+#define SDMA0_RLC0_RB_WPTR_POLL_CNTL 0xD414u
+#define SDMA0_RLC0_RB_WPTR_POLL_ADDR_HI 0xD418u
+#define SDMA0_RLC0_RB_WPTR_POLL_ADDR_LO 0xD41Cu
+#define SDMA0_RLC0_RB_RPTR_ADDR_HI 0xD420u
+#define SDMA0_RLC0_RB_RPTR_ADDR_LO 0xD424u
+#define SDMA0_RLC0_IB_CNTL 0xD428u
+#define SDMA0_RLC0_IB_RPTR 0xD42Cu
+#define SDMA0_RLC0_IB_OFFSET 0xD430u
+#define SDMA0_RLC0_IB_BASE_LO 0xD434u
+#define SDMA0_RLC0_IB_BASE_HI 0xD438u
+#define SDMA0_RLC0_IB_SIZE 0xD43Cu
+#define SDMA0_RLC0_SKIP_CNTL 0xD440u
+#define SDMA0_RLC0_CONTEXT_STATUS 0xD444u
+#define SDMA_RLC_IDLE (1 << 2)
+#define SDMA0_RLC0_DOORBELL 0xD448u
+#define SDMA_OFFSET(x) (x << 0)
+#define SDMA_DB_ENABLE (1 << 28)
+#define SDMA0_RLC0_VIRTUAL_ADDR 0xD49Cu
+#define SDMA_ATC (1 << 0)
+#define SDMA_VA_PTR32 (1 << 4)
+#define SDMA_VA_SHARED_BASE(x) (x << 8)
+#define SDMA0_RLC0_APE1_CNTL 0xD4A0u
+#define SDMA0_RLC0_DOORBELL_LOG 0xD4A4u
+#define SDMA0_RLC0_WATERMARK 0xD4A8u
+#define SDMA0_CNTL 0xD010
+#define SDMA1_CNTL 0xD810
#endif
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index 42cd0cffe210..f86eb54e7763 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -283,6 +283,33 @@ static void cik_sdma_rlc_stop(struct radeon_device *rdev)
}
/**
+ * cik_sdma_ctx_switch_enable - enable/disable sdma engine preemption
+ *
+ * @rdev: radeon_device pointer
+ * @enable: enable/disable preemption.
+ *
+ * Halt or unhalt the async dma engines (CIK).
+ */
+static void cik_sdma_ctx_switch_enable(struct radeon_device *rdev, bool enable)
+{
+ uint32_t reg_offset, value;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (i == 0)
+ reg_offset = SDMA0_REGISTER_OFFSET;
+ else
+ reg_offset = SDMA1_REGISTER_OFFSET;
+ value = RREG32(SDMA0_CNTL + reg_offset);
+ if (enable)
+ value |= AUTO_CTXSW_ENABLE;
+ else
+ value &= ~AUTO_CTXSW_ENABLE;
+ WREG32(SDMA0_CNTL + reg_offset, value);
+ }
+}
+
+/**
* cik_sdma_enable - stop the async dma engines
*
* @rdev: radeon_device pointer
@@ -312,6 +339,8 @@ void cik_sdma_enable(struct radeon_device *rdev, bool enable)
me_cntl |= SDMA_HALT;
WREG32(SDMA0_ME_CNTL + reg_offset, me_cntl);
}
+
+ cik_sdma_ctx_switch_enable(rdev, enable);
}
/**
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
index 9aad0327e4d1..ca058589ddef 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -2005,11 +2005,13 @@ int cypress_dpm_set_power_state(struct radeon_device *rdev)
return 0;
}
+#if 0
void cypress_dpm_reset_asic(struct radeon_device *rdev)
{
rv770_restrict_performance_levels_before_switch(rdev);
rv770_set_boot_state(rdev);
}
+#endif
void cypress_dpm_display_configuration_changed(struct radeon_device *rdev)
{
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c
index bafdf92a5732..f04205170b8a 100644
--- a/drivers/gpu/drm/radeon/dce3_1_afmt.c
+++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c
@@ -24,37 +24,17 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include "r600d.h"
-static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder)
+void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count)
{
struct radeon_device *rdev = encoder->dev->dev_private;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
u32 tmp;
- u8 *sadb = NULL;
- int sad_count;
-
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
- if (sad_count < 0) {
- DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
- sad_count = 0;
- }
/* program the speaker allocation */
- tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER);
+ tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER);
tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
/* set HDMI mode */
tmp |= HDMI_CONNECTION;
@@ -62,19 +42,32 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder)
tmp |= SPEAKER_ALLOCATION(sadb[0]);
else
tmp |= SPEAKER_ALLOCATION(5); /* stereo */
- WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp);
-
- kfree(sadb);
+ WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp);
}
-static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)
+void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count)
{
struct radeon_device *rdev = encoder->dev->dev_private;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
- struct cea_sad *sads;
- int i, sad_count;
+ u32 tmp;
+
+ /* program the speaker allocation */
+ tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER);
+ tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK);
+ /* set DP mode */
+ tmp |= DP_CONNECTION;
+ if (sad_count)
+ tmp |= SPEAKER_ALLOCATION(sadb[0]);
+ else
+ tmp |= SPEAKER_ALLOCATION(5); /* stereo */
+ WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp);
+}
+void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder,
+ struct cea_sad *sads, int sad_count)
+{
+ int i;
+ struct radeon_device *rdev = encoder->dev->dev_private;
static const u16 eld_reg_to_type[][2] = {
{ AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM },
{ AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 },
@@ -90,25 +83,6 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)
{ AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
};
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
- if (sad_count <= 0) {
- DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
- return;
- }
- BUG_ON(!sads);
-
for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
u32 value = 0;
u8 stereo_freqs = 0;
@@ -135,110 +109,124 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)
value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
- WREG32(eld_reg_to_type[i][0], value);
+ WREG32_ENDPOINT(0, eld_reg_to_type[i][0], value);
}
-
- kfree(sads);
}
-/*
- * update the info frames with the data from the current display mode
- */
-void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
+void dce3_2_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock)
{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
- struct hdmi_avi_infoframe frame;
- uint32_t offset;
- ssize_t err;
-
- if (!dig || !dig->afmt)
- return;
-
- /* Silent, r600_hdmi_enable will raise WARN for us */
- if (!dig->afmt->enabled)
+ struct radeon_encoder *radeon_encoder;
+ struct radeon_encoder_atom_dig *dig;
+ unsigned int max_ratio = clock / 24000;
+ u32 dto_phase;
+ u32 wallclock_ratio;
+ u32 dto_cntl;
+
+ if (!crtc)
return;
- offset = dig->afmt->offset;
-
- /* disable audio prior to setting up hw */
- dig->afmt->pin = r600_audio_get_pin(rdev);
- r600_audio_enable(rdev, dig->afmt->pin, 0);
- r600_audio_set_dto(encoder, mode->clock);
+ radeon_encoder = to_radeon_encoder(crtc->encoder);
+ dig = radeon_encoder->enc_priv;
- WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
- HDMI0_NULL_SEND); /* send null packets when required */
-
- WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000);
+ if (!dig)
+ return;
- if (ASIC_IS_DCE32(rdev)) {
- WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
- HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
- HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
- WREG32(AFMT_AUDIO_PACKET_CONTROL + offset,
- AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */
- AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
+ if (max_ratio >= 8) {
+ dto_phase = 192 * 1000;
+ wallclock_ratio = 3;
+ } else if (max_ratio >= 4) {
+ dto_phase = 96 * 1000;
+ wallclock_ratio = 2;
+ } else if (max_ratio >= 2) {
+ dto_phase = 48 * 1000;
+ wallclock_ratio = 1;
} else {
- WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
- HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */
- HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
- HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */
- HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
+ dto_phase = 24 * 1000;
+ wallclock_ratio = 0;
}
- if (ASIC_IS_DCE32(rdev)) {
- dce3_2_afmt_write_speaker_allocation(encoder);
- dce3_2_afmt_write_sad_regs(encoder);
+ /* Express [24MHz / target pixel clock] as an exact rational
+ * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
+ * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
+ */
+ if (dig->dig_encoder == 0) {
+ dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+ dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+ WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
+ WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
+ WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
+ WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
+ } else {
+ dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+ dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+ WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl);
+ WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase);
+ WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
+ WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
}
+}
+
+void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset,
+ const struct radeon_hdmi_acr *acr)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
WREG32(HDMI0_ACR_PACKET_CONTROL + offset,
- HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */
- HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
-
- WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
- HDMI0_NULL_SEND | /* send null packets when required */
- HDMI0_GC_SEND | /* send general control packets */
- HDMI0_GC_CONT); /* send general control packets every frame */
-
- /* TODO: HDMI0_AUDIO_INFO_UPDATE */
- WREG32(HDMI0_INFOFRAME_CONTROL0 + offset,
- HDMI0_AVI_INFO_SEND | /* enable AVI info frames */
- HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */
- HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
- HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */
-
- WREG32(HDMI0_INFOFRAME_CONTROL1 + offset,
- HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */
- HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */
-
- WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */
-
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
- if (err < 0) {
- DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
- return;
- }
+ HDMI0_ACR_SOURCE | /* select SW CTS value */
+ HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
+
+ WREG32_P(HDMI0_ACR_32_0 + offset,
+ HDMI0_ACR_CTS_32(acr->cts_32khz),
+ ~HDMI0_ACR_CTS_32_MASK);
+ WREG32_P(HDMI0_ACR_32_1 + offset,
+ HDMI0_ACR_N_32(acr->n_32khz),
+ ~HDMI0_ACR_N_32_MASK);
+
+ WREG32_P(HDMI0_ACR_44_0 + offset,
+ HDMI0_ACR_CTS_44(acr->cts_44_1khz),
+ ~HDMI0_ACR_CTS_44_MASK);
+ WREG32_P(HDMI0_ACR_44_1 + offset,
+ HDMI0_ACR_N_44(acr->n_44_1khz),
+ ~HDMI0_ACR_N_44_MASK);
+
+ WREG32_P(HDMI0_ACR_48_0 + offset,
+ HDMI0_ACR_CTS_48(acr->cts_48khz),
+ ~HDMI0_ACR_CTS_48_MASK);
+ WREG32_P(HDMI0_ACR_48_1 + offset,
+ HDMI0_ACR_N_48(acr->n_48khz),
+ ~HDMI0_ACR_N_48_MASK);
+}
- err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
- if (err < 0) {
- DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
- return;
- }
+void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
- r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
- r600_hdmi_update_ACR(encoder, mode->clock);
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
+ HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
+ HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
- /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
- WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF);
- WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF);
- WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001);
- WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + offset,
+ AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */
+ AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
- r600_hdmi_audio_workaround(encoder);
+ WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,
+ HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
+ HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */
- /* enable audio after to setting up hw */
- r600_audio_enable(rdev, dig->afmt->pin, 0xf);
+ WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset,
+ HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */
+}
+
+void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (mute)
+ WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE);
+ else
+ WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE);
}
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c
index f312edf4d50e..192c80389151 100644
--- a/drivers/gpu/drm/radeon/dce6_afmt.c
+++ b/drivers/gpu/drm/radeon/dce6_afmt.c
@@ -23,9 +23,10 @@
#include <linux/hdmi.h>
#include <drm/drmP.h>
#include "radeon.h"
+#include "radeon_audio.h"
#include "sid.h"
-static u32 dce6_endpoint_rreg(struct radeon_device *rdev,
+u32 dce6_endpoint_rreg(struct radeon_device *rdev,
u32 block_offset, u32 reg)
{
unsigned long flags;
@@ -39,7 +40,7 @@ static u32 dce6_endpoint_rreg(struct radeon_device *rdev,
return r;
}
-static void dce6_endpoint_wreg(struct radeon_device *rdev,
+void dce6_endpoint_wreg(struct radeon_device *rdev,
u32 block_offset, u32 reg, u32 v)
{
unsigned long flags;
@@ -54,10 +55,6 @@ static void dce6_endpoint_wreg(struct radeon_device *rdev,
spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
}
-#define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg))
-#define WREG32_ENDPOINT(block, reg, v) dce6_endpoint_wreg(rdev, (block), (reg), (v))
-
-
static void dce6_afmt_get_connected_pins(struct radeon_device *rdev)
{
int i;
@@ -105,13 +102,11 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder)
}
void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
- struct drm_display_mode *mode)
+ struct drm_connector *connector, struct drm_display_mode *mode)
{
struct radeon_device *rdev = encoder->dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
u32 tmp = 0, offset;
if (!dig || !dig->afmt || !dig->afmt->pin)
@@ -119,18 +114,6 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
offset = dig->afmt->pin->offset;
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
if (connector->latency_present[1])
tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
@@ -147,40 +130,19 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
}
-void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
+void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count)
{
struct radeon_device *rdev = encoder->dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
u32 offset, tmp;
- u8 *sadb = NULL;
- int sad_count;
if (!dig || !dig->afmt || !dig->afmt->pin)
return;
offset = dig->afmt->pin->offset;
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
- if (sad_count < 0) {
- DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
- sad_count = 0;
- }
-
/* program the speaker allocation */
tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
@@ -191,21 +153,41 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
else
tmp |= SPEAKER_ALLOCATION(5); /* stereo */
WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
-
- kfree(sadb);
}
-void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
+void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count)
{
struct radeon_device *rdev = encoder->dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- u32 offset;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
- struct cea_sad *sads;
- int i, sad_count;
+ u32 offset, tmp;
+
+ if (!dig || !dig->afmt || !dig->afmt->pin)
+ return;
+ offset = dig->afmt->pin->offset;
+
+ /* program the speaker allocation */
+ tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
+ tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK);
+ /* set DP mode */
+ tmp |= DP_CONNECTION;
+ if (sad_count)
+ tmp |= SPEAKER_ALLOCATION(sadb[0]);
+ else
+ tmp |= SPEAKER_ALLOCATION(5); /* stereo */
+ WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
+}
+
+void dce6_afmt_write_sad_regs(struct drm_encoder *encoder,
+ struct cea_sad *sads, int sad_count)
+{
+ u32 offset;
+ int i;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ struct radeon_device *rdev = encoder->dev->dev_private;
static const u16 eld_reg_to_type[][2] = {
{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM },
{ AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 },
@@ -226,25 +208,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
offset = dig->afmt->pin->offset;
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
- if (sad_count <= 0) {
- DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
- return;
- }
- BUG_ON(!sads);
-
for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
u32 value = 0;
u8 stereo_freqs = 0;
@@ -273,13 +236,6 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value);
}
-
- kfree(sads);
-}
-
-static int dce6_audio_chipset_supported(struct radeon_device *rdev)
-{
- return !ASIC_IS_NODCE(rdev);
}
void dce6_audio_enable(struct radeon_device *rdev,
@@ -293,64 +249,76 @@ void dce6_audio_enable(struct radeon_device *rdev,
enable_mask ? AUDIO_ENABLED : 0);
}
-static const u32 pin_offsets[7] =
-{
- (0x5e00 - 0x5e00),
- (0x5e18 - 0x5e00),
- (0x5e30 - 0x5e00),
- (0x5e48 - 0x5e00),
- (0x5e60 - 0x5e00),
- (0x5e78 - 0x5e00),
- (0x5e90 - 0x5e00),
-};
-
-int dce6_audio_init(struct radeon_device *rdev)
+void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock)
{
- int i;
+ /* Two dtos; generally use dto0 for HDMI */
+ u32 value = 0;
- if (!radeon_audio || !dce6_audio_chipset_supported(rdev))
- return 0;
+ if (crtc)
+ value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
- rdev->audio.enabled = true;
+ WREG32(DCCG_AUDIO_DTO_SOURCE, value);
- if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */
- rdev->audio.num_pins = 7;
- else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */
- rdev->audio.num_pins = 3;
- else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */
- rdev->audio.num_pins = 7;
- else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */
- rdev->audio.num_pins = 6;
- else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */
- rdev->audio.num_pins = 2;
- else /* SI: 6 streams, 6 endpoints */
- rdev->audio.num_pins = 6;
+ /* Express [24MHz / target pixel clock] as an exact rational
+ * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
+ * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
+ */
+ WREG32(DCCG_AUDIO_DTO0_PHASE, 24000);
+ WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
+}
- for (i = 0; i < rdev->audio.num_pins; i++) {
- rdev->audio.pin[i].channels = -1;
- rdev->audio.pin[i].rate = -1;
- rdev->audio.pin[i].bits_per_sample = -1;
- rdev->audio.pin[i].status_bits = 0;
- rdev->audio.pin[i].category_code = 0;
- rdev->audio.pin[i].connected = false;
- rdev->audio.pin[i].offset = pin_offsets[i];
- rdev->audio.pin[i].id = i;
- /* disable audio. it will be set up later */
- dce6_audio_enable(rdev, &rdev->audio.pin[i], false);
- }
+void dce6_dp_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock)
+{
+ /* Two dtos; generally use dto1 for DP */
+ u32 value = 0;
+ value |= DCCG_AUDIO_DTO_SEL;
+
+ if (crtc)
+ value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
+
+ WREG32(DCCG_AUDIO_DTO_SOURCE, value);
- return 0;
+ /* Express [24MHz / target pixel clock] as an exact rational
+ * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
+ * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
+ */
+ WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
+ WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
}
-void dce6_audio_fini(struct radeon_device *rdev)
+void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable)
{
- int i;
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset;
- if (!rdev->audio.enabled)
+ if (!dig || !dig->afmt)
return;
- for (i = 0; i < rdev->audio.num_pins; i++)
- dce6_audio_enable(rdev, &rdev->audio.pin[i], false);
+ offset = dig->afmt->offset;
+
+ if (enable) {
+ if (dig->afmt->enabled)
+ return;
+
+ WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));
+ WREG32(EVERGREEN_DP_SEC_CNTL + offset,
+ EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */
+ EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */
+ EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */
+ EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */
+ radeon_audio_enable(rdev, dig->afmt->pin, true);
+ } else {
+ if (!dig->afmt->enabled)
+ return;
+
+ WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0);
+ radeon_audio_enable(rdev, dig->afmt->pin, false);
+ }
- rdev->audio.enabled = false;
+ dig->afmt->enabled = enable;
}
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 85995b4e3338..78600f534c80 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -26,6 +26,7 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include <drm/radeon_drm.h>
#include "evergreend.h"
#include "atom.h"
@@ -5286,7 +5287,7 @@ static int evergreen_startup(struct radeon_device *rdev)
return r;
}
- r = r600_audio_init(rdev);
+ r = radeon_audio_init(rdev);
if (r) {
DRM_ERROR("radeon: audio init failed\n");
return r;
@@ -5332,7 +5333,7 @@ int evergreen_resume(struct radeon_device *rdev)
int evergreen_suspend(struct radeon_device *rdev)
{
radeon_pm_suspend(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
uvd_v1_0_fini(rdev);
radeon_uvd_suspend(rdev);
r700_cp_stop(rdev);
@@ -5482,7 +5483,7 @@ int evergreen_init(struct radeon_device *rdev)
void evergreen_fini(struct radeon_device *rdev)
{
radeon_pm_fini(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
r700_cp_fini(rdev);
r600_dma_fini(rdev);
r600_irq_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 924b1b7ab455..c9e0fbbf76a3 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -83,6 +83,7 @@ struct evergreen_cs_track {
u32 htile_offset;
u32 htile_surface;
struct radeon_bo *htile_bo;
+ unsigned long indirect_draw_buffer_size;
};
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
@@ -1896,6 +1897,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
}
break;
}
+ case PACKET3_INDEX_BUFFER_SIZE:
+ {
+ if (pkt->count != 0) {
+ DRM_ERROR("bad INDEX_BUFFER_SIZE\n");
+ return -EINVAL;
+ }
+ break;
+ }
case PACKET3_DRAW_INDEX:
{
uint64_t offset;
@@ -2006,6 +2015,67 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
return r;
}
break;
+ case PACKET3_SET_BASE:
+ {
+ /*
+ DW 1 HEADER Header of the packet. Shader_Type in bit 1 of the Header will correspond to the shader type of the Load, see Type-3 Packet.
+ 2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies which base address is specified in the last two DWs.
+ 0001: DX11 Draw_Index_Indirect Patch Table Base: Base address for Draw_Index_Indirect data.
+ 3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned Address. Bits [2:0] - Reserved
+ 4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits of Address [47:32]
+ */
+ if (pkt->count != 2) {
+ DRM_ERROR("bad SET_BASE\n");
+ return -EINVAL;
+ }
+
+ /* currently only supporting setting indirect draw buffer base address */
+ if (idx_value != 1) {
+ DRM_ERROR("bad SET_BASE\n");
+ return -EINVAL;
+ }
+
+ r = radeon_cs_packet_next_reloc(p, &reloc, 0);
+ if (r) {
+ DRM_ERROR("bad SET_BASE\n");
+ return -EINVAL;
+ }
+
+ track->indirect_draw_buffer_size = radeon_bo_size(reloc->robj);
+
+ ib[idx+1] = reloc->gpu_offset;
+ ib[idx+2] = upper_32_bits(reloc->gpu_offset) & 0xff;
+
+ break;
+ }
+ case PACKET3_DRAW_INDIRECT:
+ case PACKET3_DRAW_INDEX_INDIRECT:
+ {
+ u64 size = pkt->opcode == PACKET3_DRAW_INDIRECT ? 16 : 20;
+
+ /*
+ DW 1 HEADER
+ 2 DATA_OFFSET Bits [31:0] + byte aligned offset where the required data structure starts. Bits 1:0 are zero
+ 3 DRAW_INITIATOR Draw Initiator Register. Written to the VGT_DRAW_INITIATOR register for the assigned context
+ */
+ if (pkt->count != 1) {
+ DRM_ERROR("bad DRAW_INDIRECT\n");
+ return -EINVAL;
+ }
+
+ if (idx_value + size > track->indirect_draw_buffer_size) {
+ dev_warn(p->dev, "DRAW_INDIRECT buffer too small %u + %llu > %lu\n",
+ idx_value, size, track->indirect_draw_buffer_size);
+ return -EINVAL;
+ }
+
+ r = evergreen_cs_track_check(p);
+ if (r) {
+ dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
+ return r;
+ }
+ break;
+ }
case PACKET3_DISPATCH_DIRECT:
if (pkt->count != 3) {
DRM_ERROR("bad DISPATCH_DIRECT\n");
@@ -3243,7 +3313,13 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev,
switch (pkt->opcode) {
case PACKET3_NOP:
+ break;
case PACKET3_SET_BASE:
+ if (idx_value != 1) {
+ DRM_ERROR("bad SET_BASE");
+ return -EINVAL;
+ }
+ break;
case PACKET3_CLEAR_STATE:
case PACKET3_INDEX_BUFFER_SIZE:
case PACKET3_DISPATCH_DIRECT:
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index 53abd9b17a50..1d9aebc79595 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -29,17 +29,12 @@
#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include "evergreend.h"
#include "atom.h"
-extern void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder);
-extern void dce6_afmt_write_sad_regs(struct drm_encoder *encoder);
-extern void dce6_afmt_select_pin(struct drm_encoder *encoder);
-extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
- struct drm_display_mode *mode);
-
/* enable the audio stream */
-static void dce4_audio_enable(struct radeon_device *rdev,
+void dce4_audio_enable(struct radeon_device *rdev,
struct r600_audio_pin *pin,
u8 enable_mask)
{
@@ -69,48 +64,42 @@ static void dce4_audio_enable(struct radeon_device *rdev,
WREG32(AZ_HOT_PLUG_CONTROL, tmp);
}
-/*
- * update the N and CTS parameters for a given pixel clock rate
- */
-static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
+void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset,
+ const struct radeon_hdmi_acr *acr)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
- struct radeon_hdmi_acr acr = r600_hdmi_acr(clock);
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- uint32_t offset = dig->afmt->offset;
+ int bpc = 8;
- WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr.cts_32khz));
- WREG32(HDMI_ACR_32_1 + offset, acr.n_32khz);
+ if (encoder->crtc) {
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+ bpc = radeon_crtc->bpc;
+ }
- WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr.cts_44_1khz));
- WREG32(HDMI_ACR_44_1 + offset, acr.n_44_1khz);
+ if (bpc > 8)
+ WREG32(HDMI_ACR_PACKET_CONTROL + offset,
+ HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
+ else
+ WREG32(HDMI_ACR_PACKET_CONTROL + offset,
+ HDMI_ACR_SOURCE | /* select SW CTS value */
+ HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
+
+ WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr->cts_32khz));
+ WREG32(HDMI_ACR_32_1 + offset, acr->n_32khz);
- WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr.cts_48khz));
- WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz);
+ WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr->cts_44_1khz));
+ WREG32(HDMI_ACR_44_1 + offset, acr->n_44_1khz);
+
+ WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr->cts_48khz));
+ WREG32(HDMI_ACR_48_1 + offset, acr->n_48khz);
}
-static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder,
- struct drm_display_mode *mode)
+void dce4_afmt_write_latency_fields(struct drm_encoder *encoder,
+ struct drm_connector *connector, struct drm_display_mode *mode)
{
struct radeon_device *rdev = encoder->dev->dev_private;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
u32 tmp = 0;
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
if (connector->latency_present[1])
tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
@@ -124,38 +113,17 @@ static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder,
else
tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255);
}
- WREG32(AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp);
+ WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp);
}
-static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
+void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count)
{
struct radeon_device *rdev = encoder->dev->dev_private;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
u32 tmp;
- u8 *sadb = NULL;
- int sad_count;
-
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
- if (sad_count < 0) {
- DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
- sad_count = 0;
- }
/* program the speaker allocation */
- tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER);
+ tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER);
tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
/* set HDMI mode */
tmp |= HDMI_CONNECTION;
@@ -163,19 +131,32 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
tmp |= SPEAKER_ALLOCATION(sadb[0]);
else
tmp |= SPEAKER_ALLOCATION(5); /* stereo */
- WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp);
-
- kfree(sadb);
+ WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp);
}
-static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
+void dce4_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count)
{
struct radeon_device *rdev = encoder->dev->dev_private;
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector = NULL;
- struct cea_sad *sads;
- int i, sad_count;
+ u32 tmp;
+ /* program the speaker allocation */
+ tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER);
+ tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK);
+ /* set DP mode */
+ tmp |= DP_CONNECTION;
+ if (sad_count)
+ tmp |= SPEAKER_ALLOCATION(sadb[0]);
+ else
+ tmp |= SPEAKER_ALLOCATION(5); /* stereo */
+ WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp);
+}
+
+void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder,
+ struct cea_sad *sads, int sad_count)
+{
+ int i;
+ struct radeon_device *rdev = encoder->dev->dev_private;
static const u16 eld_reg_to_type[][2] = {
{ AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM },
{ AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 },
@@ -191,25 +172,6 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
{ AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
};
- list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- radeon_connector = to_radeon_connector(connector);
- break;
- }
- }
-
- if (!radeon_connector) {
- DRM_ERROR("Couldn't find encoder's connector\n");
- return;
- }
-
- sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
- if (sad_count <= 0) {
- DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
- return;
- }
- BUG_ON(!sads);
-
for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
u32 value = 0;
u8 stereo_freqs = 0;
@@ -236,25 +198,17 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
- WREG32(eld_reg_to_type[i][0], value);
+ WREG32_ENDPOINT(0, eld_reg_to_type[i][0], value);
}
-
- kfree(sads);
}
/*
- * build a HDMI Video Info Frame
+ * build a AVI Info Frame
*/
-static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
- void *buffer, size_t size)
+void evergreen_set_avi_packet(struct radeon_device *rdev, u32 offset,
+ unsigned char *buffer, size_t size)
{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- uint32_t offset = dig->afmt->offset;
uint8_t *frame = buffer + 3;
- uint8_t *header = buffer;
WREG32(AFMT_AVI_INFO0 + offset,
frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
@@ -263,104 +217,103 @@ static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
WREG32(AFMT_AVI_INFO2 + offset,
frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
WREG32(AFMT_AVI_INFO3 + offset,
- frame[0xC] | (frame[0xD] << 8) | (header[1] << 24));
+ frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24));
+
+ WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset,
+ HDMI_AVI_INFO_SEND | /* enable AVI info frames */
+ HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */
+
+ WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset,
+ HDMI_AVI_INFO_LINE(2), /* anything other than 0 */
+ ~HDMI_AVI_INFO_LINE_MASK);
}
-static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
+void dce4_hdmi_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock)
{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
- u32 base_rate = 24000;
- u32 max_ratio = clock / base_rate;
+ unsigned int max_ratio = clock / 24000;
u32 dto_phase;
- u32 dto_modulo = clock;
u32 wallclock_ratio;
- u32 dto_cntl;
-
- if (!dig || !dig->afmt)
- return;
-
- if (ASIC_IS_DCE6(rdev)) {
- dto_phase = 24 * 1000;
+ u32 value;
+
+ if (max_ratio >= 8) {
+ dto_phase = 192 * 1000;
+ wallclock_ratio = 3;
+ } else if (max_ratio >= 4) {
+ dto_phase = 96 * 1000;
+ wallclock_ratio = 2;
+ } else if (max_ratio >= 2) {
+ dto_phase = 48 * 1000;
+ wallclock_ratio = 1;
} else {
- if (max_ratio >= 8) {
- dto_phase = 192 * 1000;
- wallclock_ratio = 3;
- } else if (max_ratio >= 4) {
- dto_phase = 96 * 1000;
- wallclock_ratio = 2;
- } else if (max_ratio >= 2) {
- dto_phase = 48 * 1000;
- wallclock_ratio = 1;
- } else {
- dto_phase = 24 * 1000;
- wallclock_ratio = 0;
- }
- dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
- dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
- WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
+ dto_phase = 24 * 1000;
+ wallclock_ratio = 0;
}
- /* XXX two dtos; generally use dto0 for hdmi */
+ value = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+ value |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+ value &= ~DCCG_AUDIO_DTO1_USE_512FBR_DTO;
+ WREG32(DCCG_AUDIO_DTO0_CNTL, value);
+
+ /* Two dtos; generally use dto0 for HDMI */
+ value = 0;
+
+ if (crtc)
+ value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
+
+ WREG32(DCCG_AUDIO_DTO_SOURCE, value);
+
/* Express [24MHz / target pixel clock] as an exact rational
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
*/
- WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
- WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
+ WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
}
-
-/*
- * update the info frames with the data from the current display mode
- */
-void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
+void dce4_dp_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock)
{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
- u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
- struct hdmi_avi_infoframe frame;
- uint32_t offset;
- ssize_t err;
- uint32_t val;
- int bpc = 8;
+ u32 value;
- if (!dig || !dig->afmt)
- return;
+ value = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+ value |= DCCG_AUDIO_DTO1_USE_512FBR_DTO;
+ WREG32(DCCG_AUDIO_DTO1_CNTL, value);
- /* Silent, r600_hdmi_enable will raise WARN for us */
- if (!dig->afmt->enabled)
- return;
- offset = dig->afmt->offset;
+ /* Two dtos; generally use dto1 for DP */
+ value = 0;
+ value |= DCCG_AUDIO_DTO_SEL;
- /* hdmi deep color mode general control packets setup, if bpc > 8 */
- if (encoder->crtc) {
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
- bpc = radeon_crtc->bpc;
- }
+ if (crtc)
+ value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
- /* disable audio prior to setting up hw */
- if (ASIC_IS_DCE6(rdev)) {
- dig->afmt->pin = dce6_audio_get_pin(rdev);
- dce6_audio_enable(rdev, dig->afmt->pin, 0);
- } else {
- dig->afmt->pin = r600_audio_get_pin(rdev);
- dce4_audio_enable(rdev, dig->afmt->pin, 0);
- }
+ WREG32(DCCG_AUDIO_DTO_SOURCE, value);
+
+ /* Express [24MHz / target pixel clock] as an exact rational
+ * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
+ * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
+ */
+ WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
+ WREG32(DCCG_AUDIO_DTO1_MODULE, rdev->clock.max_pixel_clock * 10);
+}
- evergreen_audio_set_dto(encoder, mode->clock);
+void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
WREG32(HDMI_VBI_PACKET_CONTROL + offset,
- HDMI_NULL_SEND); /* send null packets when required */
+ HDMI_NULL_SEND | /* send null packets when required */
+ HDMI_GC_SEND | /* send general control packets */
+ HDMI_GC_CONT); /* send general control packets every frame */
+}
- WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000);
+void dce4_hdmi_set_color_depth(struct drm_encoder *encoder, u32 offset, int bpc)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ uint32_t val;
val = RREG32(HDMI_CONTROL + offset);
val &= ~HDMI_DEEP_COLOR_ENABLE;
@@ -390,113 +343,59 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
}
WREG32(HDMI_CONTROL + offset, val);
+}
- WREG32(HDMI_VBI_PACKET_CONTROL + offset,
- HDMI_NULL_SEND | /* send null packets when required */
- HDMI_GC_SEND | /* send general control packets */
- HDMI_GC_CONT); /* send general control packets every frame */
+void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
WREG32(HDMI_INFOFRAME_CONTROL0 + offset,
- HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
- HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */
+ HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
+ HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */
WREG32(AFMT_INFOFRAME_CONTROL0 + offset,
- AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */
+ AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */
WREG32(HDMI_INFOFRAME_CONTROL1 + offset,
- HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */
-
- WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */
+ HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */
WREG32(HDMI_AUDIO_PACKET_CONTROL + offset,
- HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */
- HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
-
- WREG32(AFMT_AUDIO_PACKET_CONTROL + offset,
- AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
-
- /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */
-
- if (bpc > 8)
- WREG32(HDMI_ACR_PACKET_CONTROL + offset,
- HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
- else
- WREG32(HDMI_ACR_PACKET_CONTROL + offset,
- HDMI_ACR_SOURCE | /* select SW CTS value */
- HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
-
- evergreen_hdmi_update_ACR(encoder, mode->clock);
+ HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */
+ HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
WREG32(AFMT_60958_0 + offset,
- AFMT_60958_CS_CHANNEL_NUMBER_L(1));
+ AFMT_60958_CS_CHANNEL_NUMBER_L(1));
WREG32(AFMT_60958_1 + offset,
- AFMT_60958_CS_CHANNEL_NUMBER_R(2));
+ AFMT_60958_CS_CHANNEL_NUMBER_R(2));
WREG32(AFMT_60958_2 + offset,
- AFMT_60958_CS_CHANNEL_NUMBER_2(3) |
- AFMT_60958_CS_CHANNEL_NUMBER_3(4) |
- AFMT_60958_CS_CHANNEL_NUMBER_4(5) |
- AFMT_60958_CS_CHANNEL_NUMBER_5(6) |
- AFMT_60958_CS_CHANNEL_NUMBER_6(7) |
- AFMT_60958_CS_CHANNEL_NUMBER_7(8));
-
- if (ASIC_IS_DCE6(rdev)) {
- dce6_afmt_write_speaker_allocation(encoder);
- } else {
- dce4_afmt_write_speaker_allocation(encoder);
- }
+ AFMT_60958_CS_CHANNEL_NUMBER_2(3) |
+ AFMT_60958_CS_CHANNEL_NUMBER_3(4) |
+ AFMT_60958_CS_CHANNEL_NUMBER_4(5) |
+ AFMT_60958_CS_CHANNEL_NUMBER_5(6) |
+ AFMT_60958_CS_CHANNEL_NUMBER_6(7) |
+ AFMT_60958_CS_CHANNEL_NUMBER_7(8));
WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset,
- AFMT_AUDIO_CHANNEL_ENABLE(0xff));
-
- /* fglrx sets 0x40 in 0x5f80 here */
-
- if (ASIC_IS_DCE6(rdev)) {
- dce6_afmt_select_pin(encoder);
- dce6_afmt_write_sad_regs(encoder);
- dce6_afmt_write_latency_fields(encoder, mode);
- } else {
- evergreen_hdmi_write_sad_regs(encoder);
- dce4_afmt_write_latency_fields(encoder, mode);
- }
-
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
- if (err < 0) {
- DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
- return;
- }
-
- err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
- if (err < 0) {
- DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
- return;
- }
-
- evergreen_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
-
- WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset,
- HDMI_AVI_INFO_SEND | /* enable AVI info frames */
- HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */
+ AFMT_AUDIO_CHANNEL_ENABLE(0xff));
- WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset,
- HDMI_AVI_INFO_LINE(2), /* anything other than 0 */
- ~HDMI_AVI_INFO_LINE_MASK);
+ /* allow 60958 channel status and send audio packets fields to be updated */
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + offset,
+ AFMT_AUDIO_SAMPLE_SEND | AFMT_RESET_FIFO_WHEN_AUDIO_DIS | AFMT_60958_CS_UPDATE);
+}
- WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset,
- AFMT_AUDIO_SAMPLE_SEND); /* send audio packets */
- /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
- WREG32(AFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF);
- WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);
- WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001);
- WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001);
+void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
- /* enable audio after to setting up hw */
- if (ASIC_IS_DCE6(rdev))
- dce6_audio_enable(rdev, dig->afmt->pin, 1);
+ if (mute)
+ WREG32_OR(HDMI_GC + offset, HDMI_GC_AVMUTE);
else
- dce4_audio_enable(rdev, dig->afmt->pin, 0xf);
+ WREG32_AND(HDMI_GC + offset, ~HDMI_GC_AVMUTE);
}
void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
@@ -516,10 +415,7 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
return;
if (!enable && dig->afmt->pin) {
- if (ASIC_IS_DCE6(rdev))
- dce6_audio_enable(rdev, dig->afmt->pin, 0);
- else
- dce4_audio_enable(rdev, dig->afmt->pin, 0);
+ radeon_audio_enable(rdev, dig->afmt->pin, 0);
dig->afmt->pin = NULL;
}
@@ -528,3 +424,57 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",
enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id);
}
+
+void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ offset = dig->afmt->offset;
+
+ if (enable) {
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct radeon_connector_atom_dig *dig_connector;
+ uint32_t val;
+
+ if (dig->afmt->enabled)
+ return;
+
+ WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));
+
+ if (radeon_connector->con_priv) {
+ dig_connector = radeon_connector->con_priv;
+ val = RREG32(EVERGREEN_DP_SEC_AUD_N + offset);
+ val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf);
+
+ if (dig_connector->dp_clock == 162000)
+ val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(3);
+ else
+ val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(5);
+
+ WREG32(EVERGREEN_DP_SEC_AUD_N + offset, val);
+ }
+
+ WREG32(EVERGREEN_DP_SEC_CNTL + offset,
+ EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */
+ EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */
+ EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */
+ EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */
+ radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
+ } else {
+ if (!dig->afmt->enabled)
+ return;
+
+ WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0);
+ radeon_audio_enable(rdev, dig->afmt->pin, 0);
+ }
+
+ dig->afmt->enabled = enable;
+}
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 23bff590fb6e..aa939dfed3a3 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -251,4 +251,19 @@
/* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */
#define EVERGREEN_HDMI_BASE 0x7030
+/* Display Port block */
+#define EVERGREEN_DP_SEC_CNTL 0x7280
+# define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0)
+# define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4)
+# define EVERGREEN_DP_SEC_ATP_ENABLE (1 << 8)
+# define EVERGREEN_DP_SEC_AIP_ENABLE (1 << 12)
+# define EVERGREEN_DP_SEC_GSP_ENABLE (1 << 20)
+# define EVERGREEN_DP_SEC_AVI_ENABLE (1 << 24)
+# define EVERGREEN_DP_SEC_MPG_ENABLE (1 << 28)
+#define EVERGREEN_DP_SEC_TIMESTAMP 0x72a4
+# define EVERGREEN_DP_SEC_TIMESTAMP_MODE(x) (((x) & 0x3) << 0)
+#define EVERGREEN_DP_SEC_AUD_N 0x7294
+# define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24)
+# define EVERGREEN_DP_SEC_SS_EN (1 << 28)
+
#endif
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index b066d6711b8d..ee83d2a88750 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -509,6 +509,7 @@
#define DCCG_AUDIO_DTO1_MODULE 0x05c4
#define DCCG_AUDIO_DTO1_LOAD 0x05c8
#define DCCG_AUDIO_DTO1_CNTL 0x05cc
+# define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3)
/* DCE 4.0 AFMT */
#define HDMI_CONTROL 0x7030
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index e3e9c10cfba9..0e236d067d66 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -1169,6 +1169,19 @@ void kv_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
}
}
+static void kv_enable_thermal_int(struct radeon_device *rdev, bool enable)
+{
+ u32 thermal_int;
+
+ thermal_int = RREG32_SMC(CG_THERMAL_INT_CTRL);
+ if (enable)
+ thermal_int |= THERM_INTH_MASK | THERM_INTL_MASK;
+ else
+ thermal_int &= ~(THERM_INTH_MASK | THERM_INTL_MASK);
+ WREG32_SMC(CG_THERMAL_INT_CTRL, thermal_int);
+
+}
+
int kv_dpm_enable(struct radeon_device *rdev)
{
struct kv_power_info *pi = kv_get_pi(rdev);
@@ -1280,8 +1293,7 @@ int kv_dpm_late_enable(struct radeon_device *rdev)
DRM_ERROR("kv_set_thermal_temperature_range failed\n");
return ret;
}
- rdev->irq.dpm_thermal = true;
- radeon_irq_set(rdev);
+ kv_enable_thermal_int(rdev, true);
}
/* powerdown unused blocks for now */
@@ -1312,6 +1324,7 @@ void kv_dpm_disable(struct radeon_device *rdev)
kv_stop_dpm(rdev);
kv_enable_ulv(rdev, false);
kv_reset_am(rdev);
+ kv_enable_thermal_int(rdev, false);
kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
}
@@ -1925,6 +1938,7 @@ void kv_dpm_setup_asic(struct radeon_device *rdev)
kv_init_sclk_t(rdev);
}
+#if 0
void kv_dpm_reset_asic(struct radeon_device *rdev)
{
struct kv_power_info *pi = kv_get_pi(rdev);
@@ -1945,6 +1959,7 @@ void kv_dpm_reset_asic(struct radeon_device *rdev)
kv_set_enabled_level(rdev, pi->graphics_boot_level);
}
}
+#endif
//XXX use sumo_dpm_display_configuration_changed
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index aea48c89b241..24242a7f0ac3 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -27,6 +27,7 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include <drm/radeon_drm.h>
#include "nid.h"
#include "atom.h"
@@ -2097,15 +2098,9 @@ static int cayman_startup(struct radeon_device *rdev)
return r;
}
- if (ASIC_IS_DCE6(rdev)) {
- r = dce6_audio_init(rdev);
- if (r)
- return r;
- } else {
- r = r600_audio_init(rdev);
- if (r)
- return r;
- }
+ r = radeon_audio_init(rdev);
+ if (r)
+ return r;
return 0;
}
@@ -2140,10 +2135,7 @@ int cayman_resume(struct radeon_device *rdev)
int cayman_suspend(struct radeon_device *rdev)
{
radeon_pm_suspend(rdev);
- if (ASIC_IS_DCE6(rdev))
- dce6_audio_fini(rdev);
- else
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
radeon_vm_manager_fini(rdev);
cayman_cp_enable(rdev, false);
cayman_dma_stop(rdev);
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 6d2f16cf2c1c..7bc9f8d9804a 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -3862,11 +3862,13 @@ void ni_dpm_post_set_power_state(struct radeon_device *rdev)
ni_update_current_ps(rdev, new_ps);
}
+#if 0
void ni_dpm_reset_asic(struct radeon_device *rdev)
{
ni_restrict_performance_levels_before_switch(rdev);
rv770_set_boot_state(rdev);
}
+#endif
union power_info {
struct _ATOM_POWERPLAY_INFO info;
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index ef5d6066fa5b..07a71a2488c9 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -33,6 +33,7 @@
#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include "radeon_mode.h"
#include "r600d.h"
#include "atom.h"
@@ -3054,7 +3055,7 @@ static int r600_startup(struct radeon_device *rdev)
return r;
}
- r = r600_audio_init(rdev);
+ r = radeon_audio_init(rdev);
if (r) {
DRM_ERROR("radeon: audio init failed\n");
return r;
@@ -3105,7 +3106,7 @@ int r600_resume(struct radeon_device *rdev)
int r600_suspend(struct radeon_device *rdev)
{
radeon_pm_suspend(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
r600_cp_stop(rdev);
if (rdev->has_uvd) {
uvd_v1_0_fini(rdev);
@@ -3224,7 +3225,7 @@ int r600_init(struct radeon_device *rdev)
void r600_fini(struct radeon_device *rdev)
{
radeon_pm_fini(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
r600_cp_fini(rdev);
r600_irq_fini(rdev);
if (rdev->has_uvd) {
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index b90dc0eb08e6..62c91ed669ce 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -29,6 +29,7 @@
#include <drm/radeon_drm.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include "r600d.h"
#include "atom.h"
@@ -55,30 +56,6 @@ enum r600_hdmi_iec_status_bits {
AUDIO_STATUS_LEVEL = 0x80
};
-static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
- /* 32kHz 44.1kHz 48kHz */
- /* Clock N CTS N CTS N CTS */
- { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
- { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
- { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
- { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
- { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
- { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
- { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
- { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
- { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
- { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
-};
-
-
-/*
- * check if the chipset is supported
- */
-static int r600_audio_chipset_supported(struct radeon_device *rdev)
-{
- return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev);
-}
-
static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev)
{
struct r600_audio_pin status;
@@ -191,155 +168,56 @@ void r600_audio_enable(struct radeon_device *rdev,
WREG32(AZ_HOT_PLUG_CONTROL, tmp);
}
-/*
- * initialize the audio vars
- */
-int r600_audio_init(struct radeon_device *rdev)
-{
- if (!radeon_audio || !r600_audio_chipset_supported(rdev))
- return 0;
-
- rdev->audio.enabled = true;
-
- rdev->audio.num_pins = 1;
- rdev->audio.pin[0].channels = -1;
- rdev->audio.pin[0].rate = -1;
- rdev->audio.pin[0].bits_per_sample = -1;
- rdev->audio.pin[0].status_bits = 0;
- rdev->audio.pin[0].category_code = 0;
- rdev->audio.pin[0].id = 0;
- /* disable audio. it will be set up later */
- r600_audio_enable(rdev, &rdev->audio.pin[0], 0);
-
- return 0;
-}
-
-/*
- * release the audio timer
- * TODO: How to do this correctly on SMP systems?
- */
-void r600_audio_fini(struct radeon_device *rdev)
-{
- if (!rdev->audio.enabled)
- return;
-
- r600_audio_enable(rdev, &rdev->audio.pin[0], 0);
-
- rdev->audio.enabled = false;
-}
-
struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev)
{
/* only one pin on 6xx-NI */
return &rdev->audio.pin[0];
}
-/*
- * calculate CTS and N values if they are not found in the table
- */
-static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq)
-{
- int n, cts;
- unsigned long div, mul;
-
- /* Safe, but overly large values */
- n = 128 * freq;
- cts = clock * 1000;
-
- /* Smallest valid fraction */
- div = gcd(n, cts);
-
- n /= div;
- cts /= div;
-
- /*
- * The optimal N is 128*freq/1000. Calculate the closest larger
- * value that doesn't truncate any bits.
- */
- mul = ((128*freq/1000) + (n-1))/n;
-
- n *= mul;
- cts *= mul;
-
- /* Check that we are in spec (not always possible) */
- if (n < (128*freq/1500))
- printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
- if (n > (128*freq/300))
- printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
-
- *N = n;
- *CTS = cts;
-
- DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
- *N, *CTS, freq);
-}
-
-struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
-{
- struct radeon_hdmi_acr res;
- u8 i;
-
- /* Precalculated values for common clocks */
- for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) {
- if (r600_hdmi_predefined_acr[i].clock == clock)
- return r600_hdmi_predefined_acr[i];
- }
-
- /* And odd clocks get manually calculated */
- r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
- r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
- r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
-
- return res;
-}
-
-/*
- * update the N and CTS parameters for a given pixel clock rate
- */
-void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
+void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,
+ const struct radeon_hdmi_acr *acr)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
- struct radeon_hdmi_acr acr = r600_hdmi_acr(clock);
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- uint32_t offset = dig->afmt->offset;
+
+ /* DCE 3.0 uses register that's normally for CRC_CONTROL */
+ uint32_t acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :
+ HDMI0_ACR_PACKET_CONTROL;
+ WREG32_P(acr_ctl + offset,
+ HDMI0_ACR_SOURCE | /* select SW CTS value */
+ HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */
+ ~(HDMI0_ACR_SOURCE |
+ HDMI0_ACR_AUTO_SEND));
WREG32_P(HDMI0_ACR_32_0 + offset,
- HDMI0_ACR_CTS_32(acr.cts_32khz),
- ~HDMI0_ACR_CTS_32_MASK);
+ HDMI0_ACR_CTS_32(acr->cts_32khz),
+ ~HDMI0_ACR_CTS_32_MASK);
WREG32_P(HDMI0_ACR_32_1 + offset,
- HDMI0_ACR_N_32(acr.n_32khz),
- ~HDMI0_ACR_N_32_MASK);
+ HDMI0_ACR_N_32(acr->n_32khz),
+ ~HDMI0_ACR_N_32_MASK);
WREG32_P(HDMI0_ACR_44_0 + offset,
- HDMI0_ACR_CTS_44(acr.cts_44_1khz),
- ~HDMI0_ACR_CTS_44_MASK);
+ HDMI0_ACR_CTS_44(acr->cts_44_1khz),
+ ~HDMI0_ACR_CTS_44_MASK);
WREG32_P(HDMI0_ACR_44_1 + offset,
- HDMI0_ACR_N_44(acr.n_44_1khz),
- ~HDMI0_ACR_N_44_MASK);
+ HDMI0_ACR_N_44(acr->n_44_1khz),
+ ~HDMI0_ACR_N_44_MASK);
WREG32_P(HDMI0_ACR_48_0 + offset,
- HDMI0_ACR_CTS_48(acr.cts_48khz),
- ~HDMI0_ACR_CTS_48_MASK);
+ HDMI0_ACR_CTS_48(acr->cts_48khz),
+ ~HDMI0_ACR_CTS_48_MASK);
WREG32_P(HDMI0_ACR_48_1 + offset,
- HDMI0_ACR_N_48(acr.n_48khz),
- ~HDMI0_ACR_N_48_MASK);
+ HDMI0_ACR_N_48(acr->n_48khz),
+ ~HDMI0_ACR_N_48_MASK);
}
/*
* build a HDMI Video Info Frame
*/
-void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer,
- size_t size)
+void r600_set_avi_packet(struct radeon_device *rdev, u32 offset,
+ unsigned char *buffer, size_t size)
{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- uint32_t offset = dig->afmt->offset;
uint8_t *frame = buffer + 3;
- uint8_t *header = buffer;
WREG32(HDMI0_AVI_INFO0 + offset,
frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
@@ -348,7 +226,14 @@ void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer,
WREG32(HDMI0_AVI_INFO2 + offset,
frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
WREG32(HDMI0_AVI_INFO3 + offset,
- frame[0xC] | (frame[0xD] << 8) | (header[1] << 24));
+ frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24));
+
+ WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,
+ HDMI0_AVI_INFO_SEND | /* enable AVI info frames */
+ HDMI0_AVI_INFO_CONT); /* send AVI info frames every frame/field */
+
+ WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset,
+ HDMI0_AVI_INFO_LINE(2)); /* anything other than 0 */
}
/*
@@ -425,188 +310,94 @@ void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
value, ~HDMI0_AUDIO_TEST_EN);
}
-void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
+void r600_hdmi_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock)
{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- u32 base_rate = 24000;
- u32 max_ratio = clock / base_rate;
- u32 dto_phase;
- u32 dto_modulo = clock;
- u32 wallclock_ratio;
- u32 dto_cntl;
+ struct radeon_encoder *radeon_encoder;
+ struct radeon_encoder_atom_dig *dig;
- if (!dig || !dig->afmt)
+ if (!crtc)
return;
- if (max_ratio >= 8) {
- dto_phase = 192 * 1000;
- wallclock_ratio = 3;
- } else if (max_ratio >= 4) {
- dto_phase = 96 * 1000;
- wallclock_ratio = 2;
- } else if (max_ratio >= 2) {
- dto_phase = 48 * 1000;
- wallclock_ratio = 1;
- } else {
- dto_phase = 24 * 1000;
- wallclock_ratio = 0;
- }
+ radeon_encoder = to_radeon_encoder(crtc->encoder);
+ dig = radeon_encoder->enc_priv;
- /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
- * doesn't matter which one you use. Just use the first one.
- */
- /* XXX two dtos; generally use dto0 for hdmi */
- /* Express [24MHz / target pixel clock] as an exact rational
- * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
- * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
- */
- if (ASIC_IS_DCE32(rdev)) {
- if (dig->dig_encoder == 0) {
- dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
- dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
- WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
- WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
- WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
- WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
- } else {
- dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
- dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
- WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl);
- WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase);
- WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo);
- WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
- }
+ if (!dig)
+ return;
+
+ if (dig->dig_encoder == 0) {
+ WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100);
+ WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
+ WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
} else {
- /* according to the reg specs, this should DCE3.2 only, but in
- * practice it seems to cover DCE2.0/3.0/3.1 as well.
- */
- if (dig->dig_encoder == 0) {
- WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
- WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
- WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
- } else {
- WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100);
- WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);
- WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
- }
+ WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100);
+ WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);
+ WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
}
}
-/*
- * update the info frames with the data from the current display mode
- */
-void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
+void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
- struct hdmi_avi_infoframe frame;
- uint32_t offset;
- uint32_t acr_ctl;
- ssize_t err;
-
- if (!dig || !dig->afmt)
- return;
-
- /* Silent, r600_hdmi_enable will raise WARN for us */
- if (!dig->afmt->enabled)
- return;
- offset = dig->afmt->offset;
- /* disable audio prior to setting up hw */
- dig->afmt->pin = r600_audio_get_pin(rdev);
- r600_audio_enable(rdev, dig->afmt->pin, 0xf);
+ WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset,
+ HDMI0_NULL_SEND | /* send null packets when required */
+ HDMI0_GC_SEND | /* send general control packets */
+ HDMI0_GC_CONT); /* send general control packets every frame */
+}
- r600_audio_set_dto(encoder, mode->clock);
+void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
- HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */
- HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
- HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */
- HDMI0_60958_CS_UPDATE, /* allow 60958 channel status fields to be updated */
- ~(HDMI0_AUDIO_SAMPLE_SEND |
- HDMI0_AUDIO_DELAY_EN_MASK |
- HDMI0_AUDIO_PACKETS_PER_LINE_MASK |
- HDMI0_60958_CS_UPDATE));
-
- /* DCE 3.0 uses register that's normally for CRC_CONTROL */
- acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :
- HDMI0_ACR_PACKET_CONTROL;
- WREG32_P(acr_ctl + offset,
- HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */
- HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */
- ~(HDMI0_ACR_SOURCE |
- HDMI0_ACR_AUTO_SEND));
-
- WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset,
- HDMI0_NULL_SEND | /* send null packets when required */
- HDMI0_GC_SEND | /* send general control packets */
- HDMI0_GC_CONT); /* send general control packets every frame */
+ HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */
+ HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
+ HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */
+ HDMI0_60958_CS_UPDATE, /* allow 60958 channel status fields to be updated */
+ ~(HDMI0_AUDIO_SAMPLE_SEND |
+ HDMI0_AUDIO_DELAY_EN_MASK |
+ HDMI0_AUDIO_PACKETS_PER_LINE_MASK |
+ HDMI0_60958_CS_UPDATE));
WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,
- HDMI0_AVI_INFO_SEND | /* enable AVI info frames */
- HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */
- HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
- HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */
+ HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
+ HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */
WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset,
- HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */
- HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */
- ~(HDMI0_AVI_INFO_LINE_MASK |
- HDMI0_AUDIO_INFO_LINE_MASK));
-
- WREG32_AND(HDMI0_GC + offset,
- ~HDMI0_GC_AVMUTE); /* unset HDMI0_GC_AVMUTE */
-
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
- if (err < 0) {
- DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
- return;
- }
-
- err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
- if (err < 0) {
- DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
- return;
- }
-
- r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
-
- /* fglrx duplicates INFOFRAME_CONTROL0 & INFOFRAME_CONTROL1 ops here */
+ HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */
+ ~HDMI0_AUDIO_INFO_LINE_MASK);
WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset,
- ~(HDMI0_GENERIC0_SEND |
- HDMI0_GENERIC0_CONT |
- HDMI0_GENERIC0_UPDATE |
- HDMI0_GENERIC1_SEND |
- HDMI0_GENERIC1_CONT |
- HDMI0_GENERIC0_LINE_MASK |
- HDMI0_GENERIC1_LINE_MASK));
-
- r600_hdmi_update_ACR(encoder, mode->clock);
+ ~(HDMI0_GENERIC0_SEND |
+ HDMI0_GENERIC0_CONT |
+ HDMI0_GENERIC0_UPDATE |
+ HDMI0_GENERIC1_SEND |
+ HDMI0_GENERIC1_CONT |
+ HDMI0_GENERIC0_LINE_MASK |
+ HDMI0_GENERIC1_LINE_MASK));
WREG32_P(HDMI0_60958_0 + offset,
- HDMI0_60958_CS_CHANNEL_NUMBER_L(1),
- ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK |
- HDMI0_60958_CS_CLOCK_ACCURACY_MASK));
+ HDMI0_60958_CS_CHANNEL_NUMBER_L(1),
+ ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK |
+ HDMI0_60958_CS_CLOCK_ACCURACY_MASK));
WREG32_P(HDMI0_60958_1 + offset,
- HDMI0_60958_CS_CHANNEL_NUMBER_R(2),
- ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK);
+ HDMI0_60958_CS_CHANNEL_NUMBER_R(2),
+ ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK);
+}
- /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
- WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF);
- WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF);
- WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001);
- WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);
+void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
- /* enable audio after to setting up hw */
- r600_audio_enable(rdev, dig->afmt->pin, 0xf);
+ if (mute)
+ WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE);
+ else
+ WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE);
}
/**
@@ -692,7 +483,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
return;
if (!enable && dig->afmt->pin) {
- r600_audio_enable(rdev, dig->afmt->pin, 0);
+ radeon_audio_enable(rdev, dig->afmt->pin, 0);
dig->afmt->pin = NULL;
}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 3f2a8d3febca..5587603b4a89 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1758,6 +1758,9 @@ struct r600_audio {
bool enabled;
struct r600_audio_pin pin[RADEON_MAX_AFMT_BLOCKS];
int num_pins;
+ struct radeon_audio_funcs *hdmi_funcs;
+ struct radeon_audio_funcs *dp_funcs;
+ struct radeon_audio_basic_funcs *funcs;
};
/*
@@ -1778,8 +1781,16 @@ void radeon_test_syncing(struct radeon_device *rdev);
/*
* MMU Notifier
*/
+#if defined(CONFIG_MMU_NOTIFIER)
int radeon_mn_register(struct radeon_bo *bo, unsigned long addr);
void radeon_mn_unregister(struct radeon_bo *bo);
+#else
+static inline int radeon_mn_register(struct radeon_bo *bo, unsigned long addr)
+{
+ return -ENODEV;
+}
+static inline void radeon_mn_unregister(struct radeon_bo *bo) {}
+#endif
/*
* Debugfs
@@ -1969,6 +1980,10 @@ struct radeon_asic {
bool (*vblank_too_short)(struct radeon_device *rdev);
void (*powergate_uvd)(struct radeon_device *rdev, bool gate);
void (*enable_bapm)(struct radeon_device *rdev, bool enable);
+ void (*fan_ctrl_set_mode)(struct radeon_device *rdev, u32 mode);
+ u32 (*fan_ctrl_get_mode)(struct radeon_device *rdev);
+ int (*set_fan_speed_percent)(struct radeon_device *rdev, u32 speed);
+ int (*get_fan_speed_percent)(struct radeon_device *rdev, u32 *speed);
} dpm;
/* pageflipping */
struct {
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index ed0e10eee2dc..c0ecd128b14b 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -647,8 +647,6 @@ static struct radeon_asic rs600_asic = {
.wait_for_vblank = &avivo_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &r600_hdmi_enable,
- .hdmi_setmode = &r600_hdmi_setmode,
},
.copy = {
.blit = &r100_copy_blit,
@@ -716,8 +714,6 @@ static struct radeon_asic rs690_asic = {
.wait_for_vblank = &avivo_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &r600_hdmi_enable,
- .hdmi_setmode = &r600_hdmi_setmode,
},
.copy = {
.blit = &r100_copy_blit,
@@ -948,8 +944,6 @@ static struct radeon_asic r600_asic = {
.wait_for_vblank = &avivo_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &r600_hdmi_enable,
- .hdmi_setmode = &r600_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1035,8 +1029,6 @@ static struct radeon_asic rv6xx_asic = {
.wait_for_vblank = &avivo_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &r600_hdmi_enable,
- .hdmi_setmode = &r600_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1127,8 +1119,6 @@ static struct radeon_asic rs780_asic = {
.wait_for_vblank = &avivo_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &r600_hdmi_enable,
- .hdmi_setmode = &r600_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1232,8 +1222,6 @@ static struct radeon_asic rv770_asic = {
.wait_for_vblank = &avivo_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &r600_hdmi_enable,
- .hdmi_setmode = &dce3_1_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1351,8 +1339,6 @@ static struct radeon_asic evergreen_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1444,8 +1430,6 @@ static struct radeon_asic sumo_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1536,8 +1520,6 @@ static struct radeon_asic btc_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1683,8 +1665,6 @@ static struct radeon_asic cayman_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1787,8 +1767,6 @@ static struct radeon_asic trinity_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1921,8 +1899,6 @@ static struct radeon_asic si_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &r600_copy_cpdma,
@@ -1975,6 +1951,10 @@ static struct radeon_asic si_asic = {
.debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level,
.force_performance_level = &si_dpm_force_performance_level,
.vblank_too_short = &ni_dpm_vblank_too_short,
+ .fan_ctrl_set_mode = &si_fan_ctrl_set_mode,
+ .fan_ctrl_get_mode = &si_fan_ctrl_get_mode,
+ .get_fan_speed_percent = &si_fan_ctrl_get_fan_speed_percent,
+ .set_fan_speed_percent = &si_fan_ctrl_set_fan_speed_percent,
},
.pflip = {
.page_flip = &evergreen_page_flip,
@@ -2085,8 +2065,6 @@ static struct radeon_asic ci_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &cik_copy_cpdma,
@@ -2141,6 +2119,10 @@ static struct radeon_asic ci_asic = {
.force_performance_level = &ci_dpm_force_performance_level,
.vblank_too_short = &ci_dpm_vblank_too_short,
.powergate_uvd = &ci_dpm_powergate_uvd,
+ .fan_ctrl_set_mode = &ci_fan_ctrl_set_mode,
+ .fan_ctrl_get_mode = &ci_fan_ctrl_get_mode,
+ .get_fan_speed_percent = &ci_fan_ctrl_get_fan_speed_percent,
+ .set_fan_speed_percent = &ci_fan_ctrl_set_fan_speed_percent,
},
.pflip = {
.page_flip = &evergreen_page_flip,
@@ -2193,8 +2175,6 @@ static struct radeon_asic kv_asic = {
.wait_for_vblank = &dce4_wait_for_vblank,
.set_backlight_level = &atombios_set_backlight_level,
.get_backlight_level = &atombios_get_backlight_level,
- .hdmi_enable = &evergreen_hdmi_enable,
- .hdmi_setmode = &evergreen_hdmi_setmode,
},
.copy = {
.blit = &cik_copy_cpdma,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 8d787d115653..72bdd3bf0d8e 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -394,7 +394,6 @@ void r600_irq_suspend(struct radeon_device *rdev);
void r600_disable_interrupts(struct radeon_device *rdev);
void r600_rlc_stop(struct radeon_device *rdev);
/* r600 audio */
-int r600_audio_init(struct radeon_device *rdev);
void r600_audio_fini(struct radeon_device *rdev);
void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock);
void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer,
@@ -403,8 +402,6 @@ void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock);
void r600_hdmi_audio_workaround(struct drm_encoder *encoder);
int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
void r600_hdmi_update_audio_settings(struct drm_encoder *encoder);
-void r600_hdmi_enable(struct drm_encoder *encoder, bool enable);
-void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
int r600_mc_wait_for_idle(struct radeon_device *rdev);
u32 r600_get_xclk(struct radeon_device *rdev);
uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
@@ -473,8 +470,6 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev,
u32 rv770_get_xclk(struct radeon_device *rdev);
int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
int rv770_get_temp(struct radeon_device *rdev);
-/* hdmi */
-void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
/* rv7xx pm */
int rv770_dpm_init(struct radeon_device *rdev);
int rv770_dpm_enable(struct radeon_device *rdev);
@@ -544,8 +539,6 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages,
struct reservation_object *resv);
-void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
-void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
int evergreen_get_temp(struct radeon_device *rdev);
int sumo_get_temp(struct radeon_device *rdev);
int tn_get_temp(struct radeon_device *rdev);
@@ -684,7 +677,6 @@ void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable);
/* DCE6 - SI */
void dce6_bandwidth_update(struct radeon_device *rdev);
-int dce6_audio_init(struct radeon_device *rdev);
void dce6_audio_fini(struct radeon_device *rdev);
/*
@@ -748,6 +740,12 @@ void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m);
int si_dpm_force_performance_level(struct radeon_device *rdev,
enum radeon_dpm_forced_level level);
+int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
+ u32 *speed);
+int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
+ u32 speed);
+u32 si_fan_ctrl_get_mode(struct radeon_device *rdev);
+void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode);
/* DCE8 - CIK */
void dce8_bandwidth_update(struct radeon_device *rdev);
@@ -865,6 +863,13 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev,
bool ci_dpm_vblank_too_short(struct radeon_device *rdev);
void ci_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
+int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
+ u32 *speed);
+int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
+ u32 speed);
+u32 ci_fan_ctrl_get_mode(struct radeon_device *rdev);
+void ci_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode);
+
int kv_dpm_init(struct radeon_device *rdev);
int kv_dpm_enable(struct radeon_device *rdev);
int kv_dpm_late_enable(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index dbc94f300297..fc1b3f34cf18 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -3289,6 +3289,7 @@ int radeon_atom_get_voltage_evv(struct radeon_device *rdev,
args.in.ucVoltageType = VOLTAGE_TYPE_VDDC;
args.in.ucVoltageMode = ATOM_GET_VOLTAGE_EVV_VOLTAGE;
+ args.in.usVoltageLevel = cpu_to_le16(virtual_voltage_id);
args.in.ulSCLKFreq =
cpu_to_le32(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].clk);
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
new file mode 100644
index 000000000000..a3ceef6d9632
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -0,0 +1,766 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Slava Grigorev <slava.grigorev@amd.com>
+ */
+
+#include <linux/gcd.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include "radeon.h"
+#include "atom.h"
+#include "radeon_audio.h"
+
+void r600_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin,
+ u8 enable_mask);
+void dce4_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin,
+ u8 enable_mask);
+void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin,
+ u8 enable_mask);
+u32 dce6_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg);
+void dce6_endpoint_wreg(struct radeon_device *rdev,
+ u32 offset, u32 reg, u32 v);
+void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder,
+ struct cea_sad *sads, int sad_count);
+void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder,
+ struct cea_sad *sads, int sad_count);
+void dce6_afmt_write_sad_regs(struct drm_encoder *encoder,
+ struct cea_sad *sads, int sad_count);
+void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count);
+void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count);
+void dce4_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count);
+void dce4_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count);
+void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count);
+void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count);
+void dce4_afmt_write_latency_fields(struct drm_encoder *encoder,
+ struct drm_connector *connector, struct drm_display_mode *mode);
+void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
+ struct drm_connector *connector, struct drm_display_mode *mode);
+struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev);
+struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev);
+void dce6_afmt_select_pin(struct drm_encoder *encoder);
+void r600_hdmi_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock);
+void dce3_2_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock);
+void dce4_hdmi_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock);
+void dce4_dp_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock);
+void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock);
+void dce6_dp_audio_set_dto(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock);
+void r600_set_avi_packet(struct radeon_device *rdev, u32 offset,
+ unsigned char *buffer, size_t size);
+void evergreen_set_avi_packet(struct radeon_device *rdev, u32 offset,
+ unsigned char *buffer, size_t size);
+void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,
+ const struct radeon_hdmi_acr *acr);
+void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset,
+ const struct radeon_hdmi_acr *acr);
+void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset,
+ const struct radeon_hdmi_acr *acr);
+void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset);
+void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset);
+void dce4_hdmi_set_color_depth(struct drm_encoder *encoder,
+ u32 offset, int bpc);
+void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset);
+void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset);
+void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset);
+void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute);
+void dce3_2_set_mute(struct drm_encoder *encoder, u32 offset, bool mute);
+void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute);
+static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode);
+static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode);
+void r600_hdmi_enable(struct drm_encoder *encoder, bool enable);
+void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
+void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable);
+void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable);
+
+static const u32 pin_offsets[7] =
+{
+ (0x5e00 - 0x5e00),
+ (0x5e18 - 0x5e00),
+ (0x5e30 - 0x5e00),
+ (0x5e48 - 0x5e00),
+ (0x5e60 - 0x5e00),
+ (0x5e78 - 0x5e00),
+ (0x5e90 - 0x5e00),
+};
+
+static u32 radeon_audio_rreg(struct radeon_device *rdev, u32 offset, u32 reg)
+{
+ return RREG32(reg);
+}
+
+static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset,
+ u32 reg, u32 v)
+{
+ WREG32(reg, v);
+}
+
+static struct radeon_audio_basic_funcs r600_funcs = {
+ .endpoint_rreg = radeon_audio_rreg,
+ .endpoint_wreg = radeon_audio_wreg,
+ .enable = r600_audio_enable,
+};
+
+static struct radeon_audio_basic_funcs dce32_funcs = {
+ .endpoint_rreg = radeon_audio_rreg,
+ .endpoint_wreg = radeon_audio_wreg,
+ .enable = r600_audio_enable,
+};
+
+static struct radeon_audio_basic_funcs dce4_funcs = {
+ .endpoint_rreg = radeon_audio_rreg,
+ .endpoint_wreg = radeon_audio_wreg,
+ .enable = dce4_audio_enable,
+};
+
+static struct radeon_audio_basic_funcs dce6_funcs = {
+ .endpoint_rreg = dce6_endpoint_rreg,
+ .endpoint_wreg = dce6_endpoint_wreg,
+ .enable = dce6_audio_enable,
+};
+
+static struct radeon_audio_funcs r600_hdmi_funcs = {
+ .get_pin = r600_audio_get_pin,
+ .set_dto = r600_hdmi_audio_set_dto,
+ .update_acr = r600_hdmi_update_acr,
+ .set_vbi_packet = r600_set_vbi_packet,
+ .set_avi_packet = r600_set_avi_packet,
+ .set_audio_packet = r600_set_audio_packet,
+ .set_mute = r600_set_mute,
+ .mode_set = radeon_audio_hdmi_mode_set,
+ .dpms = r600_hdmi_enable,
+};
+
+static struct radeon_audio_funcs dce32_hdmi_funcs = {
+ .get_pin = r600_audio_get_pin,
+ .write_sad_regs = dce3_2_afmt_write_sad_regs,
+ .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation,
+ .set_dto = dce3_2_audio_set_dto,
+ .update_acr = dce3_2_hdmi_update_acr,
+ .set_vbi_packet = r600_set_vbi_packet,
+ .set_avi_packet = r600_set_avi_packet,
+ .set_audio_packet = dce3_2_set_audio_packet,
+ .set_mute = dce3_2_set_mute,
+ .mode_set = radeon_audio_hdmi_mode_set,
+ .dpms = r600_hdmi_enable,
+};
+
+static struct radeon_audio_funcs dce32_dp_funcs = {
+ .get_pin = r600_audio_get_pin,
+ .write_sad_regs = dce3_2_afmt_write_sad_regs,
+ .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation,
+ .set_dto = dce3_2_audio_set_dto,
+ .set_avi_packet = r600_set_avi_packet,
+ .set_audio_packet = dce3_2_set_audio_packet,
+};
+
+static struct radeon_audio_funcs dce4_hdmi_funcs = {
+ .get_pin = r600_audio_get_pin,
+ .write_sad_regs = evergreen_hdmi_write_sad_regs,
+ .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation,
+ .write_latency_fields = dce4_afmt_write_latency_fields,
+ .set_dto = dce4_hdmi_audio_set_dto,
+ .update_acr = evergreen_hdmi_update_acr,
+ .set_vbi_packet = dce4_set_vbi_packet,
+ .set_color_depth = dce4_hdmi_set_color_depth,
+ .set_avi_packet = evergreen_set_avi_packet,
+ .set_audio_packet = dce4_set_audio_packet,
+ .set_mute = dce4_set_mute,
+ .mode_set = radeon_audio_hdmi_mode_set,
+ .dpms = evergreen_hdmi_enable,
+};
+
+static struct radeon_audio_funcs dce4_dp_funcs = {
+ .get_pin = r600_audio_get_pin,
+ .write_sad_regs = evergreen_hdmi_write_sad_regs,
+ .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation,
+ .write_latency_fields = dce4_afmt_write_latency_fields,
+ .set_dto = dce4_dp_audio_set_dto,
+ .set_avi_packet = evergreen_set_avi_packet,
+ .set_audio_packet = dce4_set_audio_packet,
+ .mode_set = radeon_audio_dp_mode_set,
+ .dpms = evergreen_enable_dp_audio_packets,
+};
+
+static struct radeon_audio_funcs dce6_hdmi_funcs = {
+ .select_pin = dce6_afmt_select_pin,
+ .get_pin = dce6_audio_get_pin,
+ .write_sad_regs = dce6_afmt_write_sad_regs,
+ .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation,
+ .write_latency_fields = dce6_afmt_write_latency_fields,
+ .set_dto = dce6_hdmi_audio_set_dto,
+ .update_acr = evergreen_hdmi_update_acr,
+ .set_vbi_packet = dce4_set_vbi_packet,
+ .set_color_depth = dce4_hdmi_set_color_depth,
+ .set_avi_packet = evergreen_set_avi_packet,
+ .set_audio_packet = dce4_set_audio_packet,
+ .set_mute = dce4_set_mute,
+ .mode_set = radeon_audio_hdmi_mode_set,
+ .dpms = evergreen_hdmi_enable,
+};
+
+static struct radeon_audio_funcs dce6_dp_funcs = {
+ .select_pin = dce6_afmt_select_pin,
+ .get_pin = dce6_audio_get_pin,
+ .write_sad_regs = dce6_afmt_write_sad_regs,
+ .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation,
+ .write_latency_fields = dce6_afmt_write_latency_fields,
+ .set_dto = dce6_dp_audio_set_dto,
+ .set_avi_packet = evergreen_set_avi_packet,
+ .set_audio_packet = dce4_set_audio_packet,
+ .mode_set = radeon_audio_dp_mode_set,
+ .dpms = dce6_enable_dp_audio_packets,
+};
+
+static void radeon_audio_interface_init(struct radeon_device *rdev)
+{
+ if (ASIC_IS_DCE6(rdev)) {
+ rdev->audio.funcs = &dce6_funcs;
+ rdev->audio.hdmi_funcs = &dce6_hdmi_funcs;
+ rdev->audio.dp_funcs = &dce6_dp_funcs;
+ } else if (ASIC_IS_DCE4(rdev)) {
+ rdev->audio.funcs = &dce4_funcs;
+ rdev->audio.hdmi_funcs = &dce4_hdmi_funcs;
+ rdev->audio.dp_funcs = &dce4_dp_funcs;
+ } else if (ASIC_IS_DCE32(rdev)) {
+ rdev->audio.funcs = &dce32_funcs;
+ rdev->audio.hdmi_funcs = &dce32_hdmi_funcs;
+ rdev->audio.dp_funcs = &dce32_dp_funcs;
+ } else {
+ rdev->audio.funcs = &r600_funcs;
+ rdev->audio.hdmi_funcs = &r600_hdmi_funcs;
+ rdev->audio.dp_funcs = 0;
+ }
+}
+
+static int radeon_audio_chipset_supported(struct radeon_device *rdev)
+{
+ return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev);
+}
+
+int radeon_audio_init(struct radeon_device *rdev)
+{
+ int i;
+
+ if (!radeon_audio || !radeon_audio_chipset_supported(rdev))
+ return 0;
+
+ rdev->audio.enabled = true;
+
+ if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */
+ rdev->audio.num_pins = 3;
+ else if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */
+ rdev->audio.num_pins = 7;
+ else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */
+ rdev->audio.num_pins = 7;
+ else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */
+ rdev->audio.num_pins = 2;
+ else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */
+ rdev->audio.num_pins = 6;
+ else if (ASIC_IS_DCE6(rdev)) /* SI: 6 streams, 6 endpoints */
+ rdev->audio.num_pins = 6;
+ else
+ rdev->audio.num_pins = 1;
+
+ for (i = 0; i < rdev->audio.num_pins; i++) {
+ rdev->audio.pin[i].channels = -1;
+ rdev->audio.pin[i].rate = -1;
+ rdev->audio.pin[i].bits_per_sample = -1;
+ rdev->audio.pin[i].status_bits = 0;
+ rdev->audio.pin[i].category_code = 0;
+ rdev->audio.pin[i].connected = false;
+ rdev->audio.pin[i].offset = pin_offsets[i];
+ rdev->audio.pin[i].id = i;
+ }
+
+ radeon_audio_interface_init(rdev);
+
+ /* disable audio. it will be set up later */
+ for (i = 0; i < rdev->audio.num_pins; i++)
+ radeon_audio_enable(rdev, &rdev->audio.pin[i], false);
+
+ return 0;
+}
+
+u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, u32 offset, u32 reg)
+{
+ if (rdev->audio.funcs->endpoint_rreg)
+ return rdev->audio.funcs->endpoint_rreg(rdev, offset, reg);
+
+ return 0;
+}
+
+void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset,
+ u32 reg, u32 v)
+{
+ if (rdev->audio.funcs->endpoint_wreg)
+ rdev->audio.funcs->endpoint_wreg(rdev, offset, reg, v);
+}
+
+static void radeon_audio_write_sad_regs(struct drm_encoder *encoder)
+{
+ struct radeon_encoder *radeon_encoder;
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector = NULL;
+ struct cea_sad *sads;
+ int sad_count;
+
+ list_for_each_entry(connector,
+ &encoder->dev->mode_config.connector_list, head) {
+ if (connector->encoder == encoder) {
+ radeon_connector = to_radeon_connector(connector);
+ break;
+ }
+ }
+
+ if (!radeon_connector) {
+ DRM_ERROR("Couldn't find encoder's connector\n");
+ return;
+ }
+
+ sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
+ if (sad_count <= 0) {
+ DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
+ return;
+ }
+ BUG_ON(!sads);
+
+ radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs)
+ radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count);
+
+ kfree(sads);
+}
+
+static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector = NULL;
+ u8 *sadb = NULL;
+ int sad_count;
+
+ list_for_each_entry(connector,
+ &encoder->dev->mode_config.connector_list, head) {
+ if (connector->encoder == encoder) {
+ radeon_connector = to_radeon_connector(connector);
+ break;
+ }
+ }
+
+ if (!radeon_connector) {
+ DRM_ERROR("Couldn't find encoder's connector\n");
+ return;
+ }
+
+ sad_count = drm_edid_to_speaker_allocation(
+ radeon_connector_edid(connector), &sadb);
+ if (sad_count < 0) {
+ DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n",
+ sad_count);
+ sad_count = 0;
+ }
+
+ if (radeon_encoder->audio && radeon_encoder->audio->write_speaker_allocation)
+ radeon_encoder->audio->write_speaker_allocation(encoder, sadb, sad_count);
+
+ kfree(sadb);
+}
+
+static void radeon_audio_write_latency_fields(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+{
+ struct radeon_encoder *radeon_encoder;
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector = 0;
+
+ list_for_each_entry(connector,
+ &encoder->dev->mode_config.connector_list, head) {
+ if (connector->encoder == encoder) {
+ radeon_connector = to_radeon_connector(connector);
+ break;
+ }
+ }
+
+ if (!radeon_connector) {
+ DRM_ERROR("Couldn't find encoder's connector\n");
+ return;
+ }
+
+ radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields)
+ radeon_encoder->audio->write_latency_fields(encoder, connector, mode);
+}
+
+struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder)
+{
+ struct radeon_device *rdev = encoder->dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_encoder->audio && radeon_encoder->audio->get_pin)
+ return radeon_encoder->audio->get_pin(rdev);
+
+ return NULL;
+}
+
+static void radeon_audio_select_pin(struct drm_encoder *encoder)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_encoder->audio && radeon_encoder->audio->select_pin)
+ radeon_encoder->audio->select_pin(encoder);
+}
+
+void radeon_audio_enable(struct radeon_device *rdev,
+ struct r600_audio_pin *pin, u8 enable_mask)
+{
+ if (rdev->audio.funcs->enable)
+ rdev->audio.funcs->enable(rdev, pin, enable_mask);
+}
+
+void radeon_audio_detect(struct drm_connector *connector,
+ enum drm_connector_status status)
+{
+ struct radeon_device *rdev;
+ struct radeon_encoder *radeon_encoder;
+ struct radeon_encoder_atom_dig *dig;
+
+ if (!connector || !connector->encoder)
+ return;
+
+ rdev = connector->encoder->dev->dev_private;
+ radeon_encoder = to_radeon_encoder(connector->encoder);
+ dig = radeon_encoder->enc_priv;
+
+ if (status == connector_status_connected) {
+ struct radeon_connector *radeon_connector;
+ int sink_type;
+
+ if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+ radeon_encoder->audio = NULL;
+ return;
+ }
+
+ radeon_connector = to_radeon_connector(connector);
+ sink_type = radeon_dp_getsinktype(radeon_connector);
+
+ if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort &&
+ sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
+ radeon_encoder->audio = rdev->audio.dp_funcs;
+ else
+ radeon_encoder->audio = rdev->audio.hdmi_funcs;
+
+ radeon_audio_write_speaker_allocation(connector->encoder);
+ radeon_audio_write_sad_regs(connector->encoder);
+ if (connector->encoder->crtc)
+ radeon_audio_write_latency_fields(connector->encoder,
+ &connector->encoder->crtc->mode);
+ radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
+ } else {
+ radeon_audio_enable(rdev, dig->afmt->pin, 0);
+ }
+}
+
+void radeon_audio_fini(struct radeon_device *rdev)
+{
+ int i;
+
+ if (!rdev->audio.enabled)
+ return;
+
+ for (i = 0; i < rdev->audio.num_pins; i++)
+ radeon_audio_enable(rdev, &rdev->audio.pin[i], false);
+
+ rdev->audio.enabled = false;
+}
+
+static void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock)
+{
+ struct radeon_device *rdev = encoder->dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_crtc *crtc = to_radeon_crtc(encoder->crtc);
+
+ if (radeon_encoder->audio && radeon_encoder->audio->set_dto)
+ radeon_encoder->audio->set_dto(rdev, crtc, clock);
+}
+
+static int radeon_audio_set_avi_packet(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+{
+ struct radeon_device *rdev = encoder->dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
+ struct hdmi_avi_infoframe frame;
+ int err;
+
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ if (err < 0) {
+ DRM_ERROR("failed to setup AVI infoframe: %d\n", err);
+ return err;
+ }
+
+ err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ DRM_ERROR("failed to pack AVI infoframe: %d\n", err);
+ return err;
+ }
+
+ if (dig && dig->afmt &&
+ radeon_encoder->audio && radeon_encoder->audio->set_avi_packet)
+ radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset,
+ buffer, sizeof(buffer));
+
+ return 0;
+}
+
+/*
+ * calculate CTS and N values if they are not found in the table
+ */
+static void radeon_audio_calc_cts(unsigned int clock, int *CTS, int *N, int freq)
+{
+ int n, cts;
+ unsigned long div, mul;
+
+ /* Safe, but overly large values */
+ n = 128 * freq;
+ cts = clock * 1000;
+
+ /* Smallest valid fraction */
+ div = gcd(n, cts);
+
+ n /= div;
+ cts /= div;
+
+ /*
+ * The optimal N is 128*freq/1000. Calculate the closest larger
+ * value that doesn't truncate any bits.
+ */
+ mul = ((128*freq/1000) + (n-1))/n;
+
+ n *= mul;
+ cts *= mul;
+
+ /* Check that we are in spec (not always possible) */
+ if (n < (128*freq/1500))
+ printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
+ if (n > (128*freq/300))
+ printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
+
+ *N = n;
+ *CTS = cts;
+
+ DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
+ *N, *CTS, freq);
+}
+
+static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock)
+{
+ static struct radeon_hdmi_acr res;
+ u8 i;
+
+ static const struct radeon_hdmi_acr hdmi_predefined_acr[] = {
+ /* 32kHz 44.1kHz 48kHz */
+ /* Clock N CTS N CTS N CTS */
+ { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
+ { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
+ { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
+ { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
+ { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
+ { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
+ { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
+ { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
+ { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
+ { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
+ };
+
+ /* Precalculated values for common clocks */
+ for (i = 0; i < ARRAY_SIZE(hdmi_predefined_acr); i++)
+ if (hdmi_predefined_acr[i].clock == clock)
+ return &hdmi_predefined_acr[i];
+
+ /* And odd clocks get manually calculated */
+ radeon_audio_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
+ radeon_audio_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
+ radeon_audio_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
+
+ return &res;
+}
+
+/*
+ * update the N and CTS parameters for a given pixel clock rate
+ */
+static void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock)
+{
+ const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock);
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ if (radeon_encoder->audio && radeon_encoder->audio->update_acr)
+ radeon_encoder->audio->update_acr(encoder, dig->afmt->offset, acr);
+}
+
+static void radeon_audio_set_vbi_packet(struct drm_encoder *encoder)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ if (radeon_encoder->audio && radeon_encoder->audio->set_vbi_packet)
+ radeon_encoder->audio->set_vbi_packet(encoder, dig->afmt->offset);
+}
+
+static void radeon_hdmi_set_color_depth(struct drm_encoder *encoder)
+{
+ int bpc = 8;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ if (encoder->crtc) {
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+ bpc = radeon_crtc->bpc;
+ }
+
+ if (radeon_encoder->audio && radeon_encoder->audio->set_color_depth)
+ radeon_encoder->audio->set_color_depth(encoder, dig->afmt->offset, bpc);
+}
+
+static void radeon_audio_set_audio_packet(struct drm_encoder *encoder)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ if (radeon_encoder->audio && radeon_encoder->audio->set_audio_packet)
+ radeon_encoder->audio->set_audio_packet(encoder, dig->afmt->offset);
+}
+
+static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ if (radeon_encoder->audio && radeon_encoder->audio->set_mute)
+ radeon_encoder->audio->set_mute(encoder, dig->afmt->offset, mute);
+}
+
+/*
+ * update the info frames with the data from the current display mode
+ */
+static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+{
+ struct radeon_device *rdev = encoder->dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ /* disable audio prior to setting up hw */
+ dig->afmt->pin = radeon_audio_get_pin(encoder);
+ radeon_audio_enable(rdev, dig->afmt->pin, 0);
+
+ radeon_audio_set_dto(encoder, mode->clock);
+ radeon_audio_set_vbi_packet(encoder);
+ radeon_hdmi_set_color_depth(encoder);
+ radeon_audio_set_mute(encoder, false);
+ radeon_audio_update_acr(encoder, mode->clock);
+ radeon_audio_set_audio_packet(encoder);
+ radeon_audio_select_pin(encoder);
+
+ if (radeon_audio_set_avi_packet(encoder, mode) < 0)
+ return;
+
+ /* enable audio after to setting up hw */
+ radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
+}
+
+static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!dig || !dig->afmt)
+ return;
+
+ /* disable audio prior to setting up hw */
+ dig->afmt->pin = radeon_audio_get_pin(encoder);
+ radeon_audio_enable(rdev, dig->afmt->pin, 0);
+
+ radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10);
+ radeon_audio_set_audio_packet(encoder);
+ radeon_audio_select_pin(encoder);
+
+ if (radeon_audio_set_avi_packet(encoder, mode) < 0)
+ return;
+
+ /* enable audio after to setting up hw */
+ radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
+}
+
+void radeon_audio_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_encoder->audio && radeon_encoder->audio->mode_set)
+ radeon_encoder->audio->mode_set(encoder, mode);
+}
+
+void radeon_audio_dpms(struct drm_encoder *encoder, int mode)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+ if (radeon_encoder->audio && radeon_encoder->audio->dpms)
+ radeon_encoder->audio->dpms(encoder, mode == DRM_MODE_DPMS_ON);
+}
diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h
new file mode 100644
index 000000000000..c92d059ab204
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_audio.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Slava Grigorev <slava.grigorev@amd.com>
+ */
+
+#ifndef __RADEON_AUDIO_H__
+#define __RADEON_AUDIO_H__
+
+#include <linux/types.h>
+
+#define RREG32_ENDPOINT(block, reg) \
+ radeon_audio_endpoint_rreg(rdev, (block), (reg))
+#define WREG32_ENDPOINT(block, reg, v) \
+ radeon_audio_endpoint_wreg(rdev, (block), (reg), (v))
+
+struct radeon_audio_basic_funcs
+{
+ u32 (*endpoint_rreg)(struct radeon_device *rdev, u32 offset, u32 reg);
+ void (*endpoint_wreg)(struct radeon_device *rdev,
+ u32 offset, u32 reg, u32 v);
+ void (*enable)(struct radeon_device *rdev,
+ struct r600_audio_pin *pin, u8 enable_mask);
+};
+
+struct radeon_audio_funcs
+{
+ void (*select_pin)(struct drm_encoder *encoder);
+ struct r600_audio_pin* (*get_pin)(struct radeon_device *rdev);
+ void (*write_latency_fields)(struct drm_encoder *encoder,
+ struct drm_connector *connector, struct drm_display_mode *mode);
+ void (*write_sad_regs)(struct drm_encoder *encoder,
+ struct cea_sad *sads, int sad_count);
+ void (*write_speaker_allocation)(struct drm_encoder *encoder,
+ u8 *sadb, int sad_count);
+ void (*set_dto)(struct radeon_device *rdev,
+ struct radeon_crtc *crtc, unsigned int clock);
+ void (*update_acr)(struct drm_encoder *encoder, long offset,
+ const struct radeon_hdmi_acr *acr);
+ void (*set_vbi_packet)(struct drm_encoder *encoder, u32 offset);
+ void (*set_color_depth)(struct drm_encoder *encoder, u32 offset, int bpc);
+ void (*set_avi_packet)(struct radeon_device *rdev, u32 offset,
+ unsigned char *buffer, size_t size);
+ void (*set_audio_packet)(struct drm_encoder *encoder, u32 offset);
+ void (*set_mute)(struct drm_encoder *encoder, u32 offset, bool mute);
+ void (*mode_set)(struct drm_encoder *encoder,
+ struct drm_display_mode *mode);
+ void (*dpms)(struct drm_encoder *encoder, bool mode);
+};
+
+int radeon_audio_init(struct radeon_device *rdev);
+void radeon_audio_detect(struct drm_connector *connector,
+ enum drm_connector_status status);
+u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev,
+ u32 offset, u32 reg);
+void radeon_audio_endpoint_wreg(struct radeon_device *rdev,
+ u32 offset, u32 reg, u32 v);
+struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder);
+void radeon_audio_enable(struct radeon_device *rdev,
+ struct r600_audio_pin *pin, u8 enable_mask);
+void radeon_audio_fini(struct radeon_device *rdev);
+void radeon_audio_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode);
+void radeon_audio_dpms(struct drm_encoder *encoder, int mode);
+
+#endif
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 26baa9c05f6c..27def67cb6be 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -29,6 +29,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/radeon_drm.h>
#include "radeon.h"
+#include "radeon_audio.h"
#include "atom.h"
#include <linux/pm_runtime.h>
@@ -1332,6 +1333,9 @@ out:
/* updated in get modes as well since we need to know if it's analog or digital */
radeon_connector_update_scratch_regs(connector, ret);
+ if (radeon_audio != 0)
+ radeon_audio_detect(connector, ret);
+
exit:
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev);
@@ -1654,6 +1658,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
}
radeon_connector_update_scratch_regs(connector, ret);
+
+ if (radeon_audio != 0)
+ radeon_audio_detect(connector, ret);
+
out:
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 4f50fb0e3d93..5d684beb48d3 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -88,9 +88,10 @@
* 2.39.0 - Add INFO query for number of active CUs
* 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting
* CS to GPU on >= r600
+ * 2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing support
*/
#define KMS_DRIVER_MAJOR 2
-#define KMS_DRIVER_MINOR 40
+#define KMS_DRIVER_MINOR 41
#define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 29b9220ec399..ea276ff6d174 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -390,18 +390,27 @@ int radeon_fbdev_init(struct radeon_device *rdev)
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
rdev->num_crtc,
RADEONFB_CONN_LIMIT);
- if (ret) {
- kfree(rfbdev);
- return ret;
- }
+ if (ret)
+ goto free;
- drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
+ ret = drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
+ if (ret)
+ goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(rdev->ddev);
- drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
+ ret = drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
+ if (ret)
+ goto fini;
+
return 0;
+
+fini:
+ drm_fb_helper_fini(&rfbdev->helper);
+free:
+ kfree(rfbdev);
+ return ret;
}
void radeon_fbdev_fini(struct radeon_device *rdev)
@@ -419,16 +428,6 @@ void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state);
}
-int radeon_fbdev_total_size(struct radeon_device *rdev)
-{
- struct radeon_bo *robj;
- int size = 0;
-
- robj = gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj);
- size += radeon_bo_size(robj);
- return size;
-}
-
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
{
if (robj == gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj))
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index add622008407..9590bcd321c0 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -1048,11 +1048,6 @@ struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev,
return NULL;
}
-struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
-{
- return NULL;
-}
-
void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
u8 slave_addr,
u8 addr,
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c
index bef9a0953284..061eaa9c19c7 100644
--- a/drivers/gpu/drm/radeon/radeon_kfd.c
+++ b/drivers/gpu/drm/radeon/radeon_kfd.c
@@ -30,22 +30,22 @@
#include "radeon_kfd.h"
#include "radeon_ucode.h"
#include <linux/firmware.h>
+#include "cik_structs.h"
#define CIK_PIPE_PER_MEC (4)
struct kgd_mem {
- struct radeon_sa_bo *sa_bo;
+ struct radeon_bo *bo;
uint64_t gpu_addr;
- void *ptr;
+ void *cpu_ptr;
};
-static int init_sa_manager(struct kgd_dev *kgd, unsigned int size);
-static void fini_sa_manager(struct kgd_dev *kgd);
-static int allocate_mem(struct kgd_dev *kgd, size_t size, size_t alignment,
- enum kgd_memory_pool pool, struct kgd_mem **mem);
+static int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
+ void **mem_obj, uint64_t *gpu_addr,
+ void **cpu_ptr);
-static void free_mem(struct kgd_dev *kgd, struct kgd_mem *mem);
+static void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj);
static uint64_t get_vmem_size(struct kgd_dev *kgd);
static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd);
@@ -64,36 +64,37 @@ static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid,
static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
unsigned int vmid);
-static int kgd_init_memory(struct kgd_dev *kgd);
-
static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
uint32_t queue_id, uint32_t __user *wptr);
-
+static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd);
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id);
+static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
+static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+ unsigned int timeout);
static const struct kfd2kgd_calls kfd2kgd = {
- .init_sa_manager = init_sa_manager,
- .fini_sa_manager = fini_sa_manager,
- .allocate_mem = allocate_mem,
- .free_mem = free_mem,
+ .init_gtt_mem_allocation = alloc_gtt_mem,
+ .free_gtt_mem = free_gtt_mem,
.get_vmem_size = get_vmem_size,
.get_gpu_clock_counter = get_gpu_clock_counter,
.get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz,
.program_sh_mem_settings = kgd_program_sh_mem_settings,
.set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
- .init_memory = kgd_init_memory,
.init_pipeline = kgd_init_pipeline,
.hqd_load = kgd_hqd_load,
+ .hqd_sdma_load = kgd_hqd_sdma_load,
.hqd_is_occupied = kgd_hqd_is_occupied,
+ .hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_hqd_destroy,
+ .hqd_sdma_destroy = kgd_hqd_sdma_destroy,
.get_fw_version = get_fw_version
};
@@ -194,87 +195,78 @@ int radeon_kfd_resume(struct radeon_device *rdev)
return r;
}
-static u32 pool_to_domain(enum kgd_memory_pool p)
-{
- switch (p) {
- case KGD_POOL_FRAMEBUFFER: return RADEON_GEM_DOMAIN_VRAM;
- default: return RADEON_GEM_DOMAIN_GTT;
- }
-}
-
-static int init_sa_manager(struct kgd_dev *kgd, unsigned int size)
+static int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
+ void **mem_obj, uint64_t *gpu_addr,
+ void **cpu_ptr)
{
struct radeon_device *rdev = (struct radeon_device *)kgd;
+ struct kgd_mem **mem = (struct kgd_mem **) mem_obj;
int r;
BUG_ON(kgd == NULL);
+ BUG_ON(gpu_addr == NULL);
+ BUG_ON(cpu_ptr == NULL);
- r = radeon_sa_bo_manager_init(rdev, &rdev->kfd_bo,
- size,
- RADEON_GPU_PAGE_SIZE,
- RADEON_GEM_DOMAIN_GTT,
- RADEON_GEM_GTT_WC);
+ *mem = kmalloc(sizeof(struct kgd_mem), GFP_KERNEL);
+ if ((*mem) == NULL)
+ return -ENOMEM;
- if (r)
+ r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT,
+ RADEON_GEM_GTT_WC, NULL, NULL, &(*mem)->bo);
+ if (r) {
+ dev_err(rdev->dev,
+ "failed to allocate BO for amdkfd (%d)\n", r);
return r;
+ }
- r = radeon_sa_bo_manager_start(rdev, &rdev->kfd_bo);
- if (r)
- radeon_sa_bo_manager_fini(rdev, &rdev->kfd_bo);
-
- return r;
-}
-
-static void fini_sa_manager(struct kgd_dev *kgd)
-{
- struct radeon_device *rdev = (struct radeon_device *)kgd;
-
- BUG_ON(kgd == NULL);
-
- radeon_sa_bo_manager_suspend(rdev, &rdev->kfd_bo);
- radeon_sa_bo_manager_fini(rdev, &rdev->kfd_bo);
-}
-
-static int allocate_mem(struct kgd_dev *kgd, size_t size, size_t alignment,
- enum kgd_memory_pool pool, struct kgd_mem **mem)
-{
- struct radeon_device *rdev = (struct radeon_device *)kgd;
- u32 domain;
- int r;
-
- BUG_ON(kgd == NULL);
-
- domain = pool_to_domain(pool);
- if (domain != RADEON_GEM_DOMAIN_GTT) {
- dev_err(rdev->dev,
- "Only allowed to allocate gart memory for kfd\n");
- return -EINVAL;
+ /* map the buffer */
+ r = radeon_bo_reserve((*mem)->bo, true);
+ if (r) {
+ dev_err(rdev->dev, "(%d) failed to reserve bo for amdkfd\n", r);
+ goto allocate_mem_reserve_bo_failed;
}
- *mem = kmalloc(sizeof(struct kgd_mem), GFP_KERNEL);
- if ((*mem) == NULL)
- return -ENOMEM;
+ r = radeon_bo_pin((*mem)->bo, RADEON_GEM_DOMAIN_GTT,
+ &(*mem)->gpu_addr);
+ if (r) {
+ dev_err(rdev->dev, "(%d) failed to pin bo for amdkfd\n", r);
+ goto allocate_mem_pin_bo_failed;
+ }
+ *gpu_addr = (*mem)->gpu_addr;
- r = radeon_sa_bo_new(rdev, &rdev->kfd_bo, &(*mem)->sa_bo, size,
- alignment);
+ r = radeon_bo_kmap((*mem)->bo, &(*mem)->cpu_ptr);
if (r) {
- dev_err(rdev->dev, "failed to get memory for kfd (%d)\n", r);
- return r;
+ dev_err(rdev->dev,
+ "(%d) failed to map bo to kernel for amdkfd\n", r);
+ goto allocate_mem_kmap_bo_failed;
}
+ *cpu_ptr = (*mem)->cpu_ptr;
- (*mem)->ptr = radeon_sa_bo_cpu_addr((*mem)->sa_bo);
- (*mem)->gpu_addr = radeon_sa_bo_gpu_addr((*mem)->sa_bo);
+ radeon_bo_unreserve((*mem)->bo);
return 0;
+
+allocate_mem_kmap_bo_failed:
+ radeon_bo_unpin((*mem)->bo);
+allocate_mem_pin_bo_failed:
+ radeon_bo_unreserve((*mem)->bo);
+allocate_mem_reserve_bo_failed:
+ radeon_bo_unref(&(*mem)->bo);
+
+ return r;
}
-static void free_mem(struct kgd_dev *kgd, struct kgd_mem *mem)
+static void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj)
{
- struct radeon_device *rdev = (struct radeon_device *)kgd;
+ struct kgd_mem *mem = (struct kgd_mem *) mem_obj;
- BUG_ON(kgd == NULL);
+ BUG_ON(mem == NULL);
- radeon_sa_bo_free(rdev, &mem->sa_bo, NULL);
+ radeon_bo_reserve(mem->bo, true);
+ radeon_bo_kunmap(mem->bo);
+ radeon_bo_unpin(mem->bo);
+ radeon_bo_unreserve(mem->bo);
+ radeon_bo_unref(&(mem->bo));
kfree(mem);
}
@@ -397,42 +389,6 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
return 0;
}
-static int kgd_init_memory(struct kgd_dev *kgd)
-{
- /*
- * Configure apertures:
- * LDS: 0x60000000'00000000 - 0x60000001'00000000 (4GB)
- * Scratch: 0x60000001'00000000 - 0x60000002'00000000 (4GB)
- * GPUVM: 0x60010000'00000000 - 0x60020000'00000000 (1TB)
- */
- int i;
- uint32_t sh_mem_bases = PRIVATE_BASE(0x6000) | SHARED_BASE(0x6000);
-
- for (i = 8; i < 16; i++) {
- uint32_t sh_mem_config;
-
- lock_srbm(kgd, 0, 0, 0, i);
-
- sh_mem_config = ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED);
- sh_mem_config |= DEFAULT_MTYPE(MTYPE_NONCACHED);
-
- write_register(kgd, SH_MEM_CONFIG, sh_mem_config);
-
- write_register(kgd, SH_MEM_BASES, sh_mem_bases);
-
- /* Scratch aperture is not supported for now. */
- write_register(kgd, SH_STATIC_MEM_CONFIG, 0);
-
- /* APE1 disabled for now. */
- write_register(kgd, SH_MEM_APE1_BASE, 1);
- write_register(kgd, SH_MEM_APE1_LIMIT, 0);
-
- unlock_srbm(kgd);
- }
-
- return 0;
-}
-
static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr)
{
@@ -451,11 +407,28 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
return 0;
}
+static inline uint32_t get_sdma_base_addr(struct cik_sdma_rlc_registers *m)
+{
+ uint32_t retval;
+
+ retval = m->sdma_engine_id * SDMA1_REGISTER_OFFSET +
+ m->sdma_queue_id * KFD_CIK_SDMA_QUEUE_OFFSET;
+
+ pr_debug("kfd: sdma base address: 0x%x\n", retval);
+
+ return retval;
+}
+
static inline struct cik_mqd *get_mqd(void *mqd)
{
return (struct cik_mqd *)mqd;
}
+static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
+{
+ return (struct cik_sdma_rlc_registers *)mqd;
+}
+
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
uint32_t queue_id, uint32_t __user *wptr)
{
@@ -533,6 +506,45 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
return 0;
}
+static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd)
+{
+ struct cik_sdma_rlc_registers *m;
+ uint32_t sdma_base_addr;
+
+ m = get_sdma_mqd(mqd);
+ sdma_base_addr = get_sdma_base_addr(m);
+
+ write_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_VIRTUAL_ADDR,
+ m->sdma_rlc_virtual_addr);
+
+ write_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_RB_BASE,
+ m->sdma_rlc_rb_base);
+
+ write_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_RB_BASE_HI,
+ m->sdma_rlc_rb_base_hi);
+
+ write_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_RB_RPTR_ADDR_LO,
+ m->sdma_rlc_rb_rptr_addr_lo);
+
+ write_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_RB_RPTR_ADDR_HI,
+ m->sdma_rlc_rb_rptr_addr_hi);
+
+ write_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_DOORBELL,
+ m->sdma_rlc_doorbell);
+
+ write_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_RB_CNTL,
+ m->sdma_rlc_rb_cntl);
+
+ return 0;
+}
+
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id)
{
@@ -554,6 +566,24 @@ static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
return retval;
}
+static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
+{
+ struct cik_sdma_rlc_registers *m;
+ uint32_t sdma_base_addr;
+ uint32_t sdma_rlc_rb_cntl;
+
+ m = get_sdma_mqd(mqd);
+ sdma_base_addr = get_sdma_base_addr(m);
+
+ sdma_rlc_rb_cntl = read_register(kgd,
+ sdma_base_addr + SDMA0_RLC0_RB_CNTL);
+
+ if (sdma_rlc_rb_cntl & SDMA_RB_ENABLE)
+ return true;
+
+ return false;
+}
+
static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id)
@@ -583,6 +613,39 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
return 0;
}
+static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
+ unsigned int timeout)
+{
+ struct cik_sdma_rlc_registers *m;
+ uint32_t sdma_base_addr;
+ uint32_t temp;
+
+ m = get_sdma_mqd(mqd);
+ sdma_base_addr = get_sdma_base_addr(m);
+
+ temp = read_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_CNTL);
+ temp = temp & ~SDMA_RB_ENABLE;
+ write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_CNTL, temp);
+
+ while (true) {
+ temp = read_register(kgd, sdma_base_addr +
+ SDMA0_RLC0_CONTEXT_STATUS);
+ if (temp & SDMA_RLC_IDLE)
+ break;
+ if (timeout == 0)
+ return -ETIME;
+ msleep(20);
+ timeout -= 20;
+ }
+
+ write_register(kgd, sdma_base_addr + SDMA0_RLC0_DOORBELL, 0);
+ write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_RPTR, 0);
+ write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_WPTR, 0);
+ write_register(kgd, sdma_base_addr + SDMA0_RLC0_RB_BASE, 0);
+
+ return 0;
+}
+
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
{
struct radeon_device *rdev = (struct radeon_device *) kgd;
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.h b/drivers/gpu/drm/radeon/radeon_kfd.h
index f90e161ca507..1103f9082f6b 100644
--- a/drivers/gpu/drm/radeon/radeon_kfd.h
+++ b/drivers/gpu/drm/radeon/radeon_kfd.h
@@ -29,7 +29,7 @@
#define RADEON_KFD_H_INCLUDED
#include <linux/types.h>
-#include "../amd/include/kgd_kfd_interface.h"
+#include "kgd_kfd_interface.h"
struct radeon_device;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 390db897f322..920a8be8abad 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -449,6 +449,7 @@ struct radeon_encoder {
int audio_polling_active;
bool is_ext_encoder;
u16 caps;
+ struct radeon_audio_funcs *audio;
};
struct radeon_connector_atom_dig {
@@ -745,8 +746,6 @@ extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connec
extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux);
-extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
-
extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev,
struct radeon_atom_ss *ss,
int id);
@@ -925,7 +924,6 @@ void dce8_program_fmt(struct drm_encoder *encoder);
int radeon_fbdev_init(struct radeon_device *rdev);
void radeon_fbdev_fini(struct radeon_device *rdev);
void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
-int radeon_fbdev_total_size(struct radeon_device *rdev);
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
void radeon_fb_output_poll_changed(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 86fc56434b28..43e09942823e 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -238,6 +238,18 @@ int radeon_bo_create(struct radeon_device *rdev,
* See https://bugs.freedesktop.org/show_bug.cgi?id=84627
*/
bo->flags &= ~RADEON_GEM_GTT_WC;
+#elif defined(CONFIG_X86) && !defined(CONFIG_X86_PAT)
+ /* Don't try to enable write-combining when it can't work, or things
+ * may be slow
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=88758
+ */
+
+#warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \
+ thanks to write-combining
+
+ DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
+ "better performance thanks to write-combining\n");
+ bo->flags &= ~RADEON_GEM_GTT_WC;
#endif
radeon_ttm_placement_from_domain(bo, domain);
@@ -576,12 +588,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
return 0;
}
-int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
- struct vm_area_struct *vma)
-{
- return ttm_fbdev_mmap(vma, &bo->tbo);
-}
-
int radeon_bo_get_surface_reg(struct radeon_bo *bo)
{
struct radeon_device *rdev = bo->rdev;
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index 3b0b377f76cb..d8d295ee7c12 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -143,8 +143,6 @@ extern void radeon_bo_fini(struct radeon_device *rdev);
extern int radeon_bo_list_validate(struct radeon_device *rdev,
struct ww_acquire_ctx *ticket,
struct list_head *head, int ring);
-extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
- struct vm_area_struct *vma);
extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
u32 tiling_flags, u32 pitch);
extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index f7da8fe96a66..9f758d39420d 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -24,6 +24,7 @@
#include "radeon.h"
#include "avivod.h"
#include "atom.h"
+#include "r600_dpm.h"
#include <linux/power_supply.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
@@ -554,6 +555,100 @@ fail:
return count;
}
+static ssize_t radeon_hwmon_get_pwm1_enable(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct radeon_device *rdev = dev_get_drvdata(dev);
+ u32 pwm_mode = 0;
+
+ if (rdev->asic->dpm.fan_ctrl_get_mode)
+ pwm_mode = rdev->asic->dpm.fan_ctrl_get_mode(rdev);
+
+ /* never 0 (full-speed), fuse or smc-controlled always */
+ return sprintf(buf, "%i\n", pwm_mode == FDO_PWM_MODE_STATIC ? 1 : 2);
+}
+
+static ssize_t radeon_hwmon_set_pwm1_enable(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct radeon_device *rdev = dev_get_drvdata(dev);
+ int err;
+ int value;
+
+ if(!rdev->asic->dpm.fan_ctrl_set_mode)
+ return -EINVAL;
+
+ err = kstrtoint(buf, 10, &value);
+ if (err)
+ return err;
+
+ switch (value) {
+ case 1: /* manual, percent-based */
+ rdev->asic->dpm.fan_ctrl_set_mode(rdev, FDO_PWM_MODE_STATIC);
+ break;
+ default: /* disable */
+ rdev->asic->dpm.fan_ctrl_set_mode(rdev, 0);
+ break;
+ }
+
+ return count;
+}
+
+static ssize_t radeon_hwmon_get_pwm1_min(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%i\n", 0);
+}
+
+static ssize_t radeon_hwmon_get_pwm1_max(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%i\n", 255);
+}
+
+static ssize_t radeon_hwmon_set_pwm1(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct radeon_device *rdev = dev_get_drvdata(dev);
+ int err;
+ u32 value;
+
+ err = kstrtou32(buf, 10, &value);
+ if (err)
+ return err;
+
+ value = (value * 100) / 255;
+
+ err = rdev->asic->dpm.set_fan_speed_percent(rdev, value);
+ if (err)
+ return err;
+
+ return count;
+}
+
+static ssize_t radeon_hwmon_get_pwm1(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct radeon_device *rdev = dev_get_drvdata(dev);
+ int err;
+ u32 speed;
+
+ err = rdev->asic->dpm.get_fan_speed_percent(rdev, &speed);
+ if (err)
+ return err;
+
+ speed = (speed * 255) / 100;
+
+ return sprintf(buf, "%i\n", speed);
+}
+
static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile);
static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method);
static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, radeon_get_dpm_state, radeon_set_dpm_state);
@@ -601,11 +696,20 @@ static ssize_t radeon_hwmon_show_temp_thresh(struct device *dev,
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, radeon_hwmon_show_temp_thresh, NULL, 1);
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, radeon_hwmon_get_pwm1, radeon_hwmon_set_pwm1, 0);
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, radeon_hwmon_get_pwm1_enable, radeon_hwmon_set_pwm1_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO, radeon_hwmon_get_pwm1_min, NULL, 0);
+static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO, radeon_hwmon_get_pwm1_max, NULL, 0);
+
static struct attribute *hwmon_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm1_min.dev_attr.attr,
+ &sensor_dev_attr_pwm1_max.dev_attr.attr,
NULL
};
@@ -614,6 +718,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
{
struct device *dev = container_of(kobj, struct device, kobj);
struct radeon_device *rdev = dev_get_drvdata(dev);
+ umode_t effective_mode = attr->mode;
/* Skip limit attributes if DPM is not enabled */
if (rdev->pm.pm_method != PM_METHOD_DPM &&
@@ -621,7 +726,35 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr))
return 0;
- return attr->mode;
+ /* Skip fan attributes if fan is not present */
+ if (rdev->pm.no_fan &&
+ (attr == &sensor_dev_attr_pwm1.dev_attr.attr ||
+ attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr ||
+ attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
+ attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
+ return 0;
+
+ /* mask fan attributes if we have no bindings for this asic to expose */
+ if ((!rdev->asic->dpm.get_fan_speed_percent &&
+ attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't query fan */
+ (!rdev->asic->dpm.fan_ctrl_get_mode &&
+ attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't query state */
+ effective_mode &= ~S_IRUGO;
+
+ if ((!rdev->asic->dpm.set_fan_speed_percent &&
+ attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't manage fan */
+ (!rdev->asic->dpm.fan_ctrl_set_mode &&
+ attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */
+ effective_mode &= ~S_IWUSR;
+
+ /* hide max/min values if we can't both query and manage the fan */
+ if ((!rdev->asic->dpm.set_fan_speed_percent &&
+ !rdev->asic->dpm.get_fan_speed_percent) &&
+ (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr ||
+ attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))
+ return 0;
+
+ return effective_mode;
}
static const struct attribute_group hwmon_attrgroup = {
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 74bce91aecc1..d81182ad53ec 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -38,6 +38,7 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include "atom.h"
#include "rs600d.h"
@@ -1016,7 +1017,7 @@ static int rs600_startup(struct radeon_device *rdev)
return r;
}
- r = r600_audio_init(rdev);
+ r = radeon_audio_init(rdev);
if (r) {
dev_err(rdev->dev, "failed initializing audio\n");
return r;
@@ -1057,7 +1058,7 @@ int rs600_resume(struct radeon_device *rdev)
int rs600_suspend(struct radeon_device *rdev)
{
radeon_pm_suspend(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
r100_cp_disable(rdev);
radeon_wb_disable(rdev);
rs600_irq_disable(rdev);
@@ -1068,7 +1069,7 @@ int rs600_suspend(struct radeon_device *rdev)
void rs600_fini(struct radeon_device *rdev)
{
radeon_pm_fini(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
r100_cp_fini(rdev);
radeon_wb_fini(rdev);
radeon_ib_pool_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 0a2d36e81108..516ca27cfa12 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -28,6 +28,7 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include "atom.h"
#include "rs690d.h"
@@ -729,7 +730,7 @@ static int rs690_startup(struct radeon_device *rdev)
return r;
}
- r = r600_audio_init(rdev);
+ r = radeon_audio_init(rdev);
if (r) {
dev_err(rdev->dev, "failed initializing audio\n");
return r;
@@ -770,7 +771,7 @@ int rs690_resume(struct radeon_device *rdev)
int rs690_suspend(struct radeon_device *rdev)
{
radeon_pm_suspend(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
r100_cp_disable(rdev);
radeon_wb_disable(rdev);
rs600_irq_disable(rdev);
@@ -781,7 +782,7 @@ int rs690_suspend(struct radeon_device *rdev)
void rs690_fini(struct radeon_device *rdev)
{
radeon_pm_fini(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
r100_cp_fini(rdev);
radeon_wb_fini(rdev);
radeon_ib_pool_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 372016e266d0..01ee96acb398 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -30,6 +30,7 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include <drm/radeon_drm.h>
#include "rv770d.h"
#include "atom.h"
@@ -1788,7 +1789,7 @@ static int rv770_startup(struct radeon_device *rdev)
return r;
}
- r = r600_audio_init(rdev);
+ r = radeon_audio_init(rdev);
if (r) {
DRM_ERROR("radeon: audio init failed\n");
return r;
@@ -1829,7 +1830,7 @@ int rv770_resume(struct radeon_device *rdev)
int rv770_suspend(struct radeon_device *rdev)
{
radeon_pm_suspend(rdev);
- r600_audio_fini(rdev);
+ radeon_audio_fini(rdev);
uvd_v1_0_fini(rdev);
radeon_uvd_suspend(rdev);
r700_cp_stop(rdev);
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c
index 755a8f96fe46..306732641b23 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -231,6 +231,7 @@ u8 rv770_get_seq_value(struct radeon_device *rdev,
MC_CG_SEQ_DRAMCONF_S0 : MC_CG_SEQ_DRAMCONF_S1;
}
+#if 0
int rv770_read_smc_soft_register(struct radeon_device *rdev,
u16 reg_offset, u32 *value)
{
@@ -240,6 +241,7 @@ int rv770_read_smc_soft_register(struct radeon_device *rdev,
pi->soft_regs_start + reg_offset,
value, pi->sram_end);
}
+#endif
int rv770_write_smc_soft_register(struct radeon_device *rdev,
u16 reg_offset, u32 value)
@@ -2075,6 +2077,7 @@ int rv770_dpm_set_power_state(struct radeon_device *rdev)
return 0;
}
+#if 0
void rv770_dpm_reset_asic(struct radeon_device *rdev)
{
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
@@ -2087,6 +2090,7 @@ void rv770_dpm_reset_asic(struct radeon_device *rdev)
if (pi->dcodt)
rv770_program_dcodt_after_state_switch(rdev, boot_ps, boot_ps);
}
+#endif
void rv770_dpm_setup_asic(struct radeon_device *rdev)
{
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h
index f776634840c9..d12beab7f3e6 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.h
+++ b/drivers/gpu/drm/radeon/rv770_dpm.h
@@ -278,8 +278,6 @@ void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
void rv770_get_engine_memory_ss(struct radeon_device *rdev);
/* smc */
-int rv770_read_smc_soft_register(struct radeon_device *rdev,
- u16 reg_offset, u32 *value);
int rv770_write_smc_soft_register(struct radeon_device *rdev,
u16 reg_offset, u32 value);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 5d89b874a1a2..73107fe9e46f 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -27,6 +27,7 @@
#include <drm/drmP.h>
#include "radeon.h"
#include "radeon_asic.h"
+#include "radeon_audio.h"
#include <drm/radeon_drm.h>
#include "sid.h"
#include "atom.h"
@@ -6869,7 +6870,7 @@ static int si_startup(struct radeon_device *rdev)
return r;
}
- r = dce6_audio_init(rdev);
+ r = radeon_audio_init(rdev);
if (r)
return r;
@@ -6908,7 +6909,7 @@ int si_resume(struct radeon_device *rdev)
int si_suspend(struct radeon_device *rdev)
{
radeon_pm_suspend(rdev);
- dce6_audio_fini(rdev);
+ radeon_audio_fini(rdev);
radeon_vm_manager_fini(rdev);
si_cp_enable(rdev, false);
cayman_dma_stop(rdev);
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index eff8a6444956..7be11651b7e6 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -1756,6 +1756,9 @@ static int si_calculate_sclk_params(struct radeon_device *rdev,
u32 engine_clock,
SISLANDS_SMC_SCLK_VALUE *sclk);
+static void si_thermal_start_smc_fan_control(struct radeon_device *rdev);
+static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev);
+
static struct si_power_info *si_get_pi(struct radeon_device *rdev)
{
struct si_power_info *pi = rdev->pm.dpm.priv;
@@ -3359,11 +3362,13 @@ int si_dpm_force_performance_level(struct radeon_device *rdev,
return 0;
}
+#if 0
static int si_set_boot_state(struct radeon_device *rdev)
{
return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ?
0 : -EINVAL;
}
+#endif
static int si_set_sw_state(struct radeon_device *rdev)
{
@@ -5973,6 +5978,10 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev)
slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
+ fan_table.temp_min = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100);
+ fan_table.temp_med = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100);
+ fan_table.temp_max = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100);
+
fan_table.slope1 = cpu_to_be16(slope1);
fan_table.slope2 = cpu_to_be16(slope2);
@@ -6012,29 +6021,35 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev)
static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev)
{
+ struct si_power_info *si_pi = si_get_pi(rdev);
PPSMC_Result ret;
ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl);
- if (ret == PPSMC_Result_OK)
+ if (ret == PPSMC_Result_OK) {
+ si_pi->fan_is_controlled_by_smc = true;
return 0;
- else
+ } else {
return -EINVAL;
+ }
}
static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev)
{
+ struct si_power_info *si_pi = si_get_pi(rdev);
PPSMC_Result ret;
ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl);
- if (ret == PPSMC_Result_OK)
+
+ if (ret == PPSMC_Result_OK) {
+ si_pi->fan_is_controlled_by_smc = false;
return 0;
- else
+ } else {
return -EINVAL;
+ }
}
-#if 0
-static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
- u32 *speed)
+int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
+ u32 *speed)
{
u32 duty, duty100;
u64 tmp64;
@@ -6058,9 +6073,10 @@ static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
return 0;
}
-static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
- u32 speed)
+int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
+ u32 speed)
{
+ struct si_power_info *si_pi = si_get_pi(rdev);
u32 tmp;
u32 duty, duty100;
u64 tmp64;
@@ -6068,11 +6084,11 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
if (rdev->pm.no_fan)
return -ENOENT;
- if (speed > 100)
+ if (si_pi->fan_is_controlled_by_smc)
return -EINVAL;
- if (rdev->pm.dpm.fan.ucode_fan_control)
- si_fan_ctrl_stop_smc_fan_control(rdev);
+ if (speed > 100)
+ return -EINVAL;
duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
@@ -6087,11 +6103,38 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
tmp |= FDO_STATIC_DUTY(duty);
WREG32(CG_FDO_CTRL0, tmp);
- si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
-
return 0;
}
+void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode)
+{
+ if (mode) {
+ /* stop auto-manage */
+ if (rdev->pm.dpm.fan.ucode_fan_control)
+ si_fan_ctrl_stop_smc_fan_control(rdev);
+ si_fan_ctrl_set_static_mode(rdev, mode);
+ } else {
+ /* restart auto-manage */
+ if (rdev->pm.dpm.fan.ucode_fan_control)
+ si_thermal_start_smc_fan_control(rdev);
+ else
+ si_fan_ctrl_set_default_mode(rdev);
+ }
+}
+
+u32 si_fan_ctrl_get_mode(struct radeon_device *rdev)
+{
+ struct si_power_info *si_pi = si_get_pi(rdev);
+ u32 tmp;
+
+ if (si_pi->fan_is_controlled_by_smc)
+ return 0;
+
+ tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK;
+ return (tmp >> FDO_PWM_MODE_SHIFT);
+}
+
+#if 0
static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev,
u32 *speed)
{
@@ -6538,13 +6581,14 @@ void si_dpm_post_set_power_state(struct radeon_device *rdev)
ni_update_current_ps(rdev, new_ps);
}
-
+#if 0
void si_dpm_reset_asic(struct radeon_device *rdev)
{
si_restrict_performance_levels_before_switch(rdev);
si_disable_ulv(rdev);
si_set_boot_state(rdev);
}
+#endif
void si_dpm_display_configuration_changed(struct radeon_device *rdev)
{
@@ -6912,7 +6956,6 @@ int si_dpm_init(struct radeon_device *rdev)
rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
si_pi->fan_ctrl_is_in_default_mode = true;
- rdev->pm.dpm.fan.ucode_fan_control = false;
return 0;
}
diff --git a/drivers/gpu/drm/radeon/si_dpm.h b/drivers/gpu/drm/radeon/si_dpm.h
index d16bb1b5f10f..1032a68be792 100644
--- a/drivers/gpu/drm/radeon/si_dpm.h
+++ b/drivers/gpu/drm/radeon/si_dpm.h
@@ -202,6 +202,7 @@ struct si_power_info {
bool fan_ctrl_is_in_default_mode;
u32 t_min;
u32 fan_ctrl_default_mode;
+ bool fan_is_controlled_by_smc;
};
#define SISLANDS_INITIAL_STATE_ARB_INDEX 0
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index 84999242c747..cbd91d226f3c 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -901,6 +901,16 @@
/* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */
#define CRTC_STATUS_FRAME_COUNT 0x6e98
+/* Audio clocks */
+#define DCCG_AUDIO_DTO_SOURCE 0x05ac
+# define DCCG_AUDIO_DTO0_SOURCE_SEL(x) ((x) << 0) /* crtc0 - crtc5 */
+# define DCCG_AUDIO_DTO_SEL (1 << 4) /* 0=dto0 1=dto1 */
+
+#define DCCG_AUDIO_DTO0_PHASE 0x05b0
+#define DCCG_AUDIO_DTO0_MODULE 0x05b4
+#define DCCG_AUDIO_DTO1_PHASE 0x05b8
+#define DCCG_AUDIO_DTO1_MODULE 0x05bc
+
#define AFMT_AUDIO_SRC_CONTROL 0x713c
#define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0)
/* AFMT_AUDIO_SRC_SELECT
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c
index 1f8a8833e1be..25fd4ced36c8 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -1338,6 +1338,7 @@ void sumo_dpm_post_set_power_state(struct radeon_device *rdev)
sumo_update_current_ps(rdev, new_ps);
}
+#if 0
void sumo_dpm_reset_asic(struct radeon_device *rdev)
{
sumo_program_bootup_state(rdev);
@@ -1349,6 +1350,7 @@ void sumo_dpm_reset_asic(struct radeon_device *rdev)
sumo_set_forced_mode_enabled(rdev);
sumo_set_forced_mode_disabled(rdev);
}
+#endif
void sumo_dpm_setup_asic(struct radeon_device *rdev)
{
@@ -1537,6 +1539,7 @@ u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev,
return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit;
}
+#if 0
u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev,
struct sumo_vid_mapping_table *vid_mapping_table,
u32 vid_7bit)
@@ -1550,6 +1553,7 @@ u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev,
return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit;
}
+#endif
static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev,
u32 vid_2bit)
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.h b/drivers/gpu/drm/radeon/sumo_dpm.h
index db1ea32a907b..07dda299c784 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.h
+++ b/drivers/gpu/drm/radeon/sumo_dpm.h
@@ -202,9 +202,6 @@ void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev,
struct sumo_vid_mapping_table *vid_mapping_table,
u32 vid_2bit);
-u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev,
- struct sumo_vid_mapping_table *vid_mapping_table,
- u32 vid_7bit);
u32 sumo_get_sleep_divider_from_id(u32 id);
u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
u32 sclk,
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c
index b4ec5c4e7969..38dacb7a3689 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -1269,6 +1269,7 @@ void trinity_dpm_setup_asic(struct radeon_device *rdev)
trinity_release_mutex(rdev);
}
+#if 0
void trinity_dpm_reset_asic(struct radeon_device *rdev)
{
struct trinity_power_info *pi = trinity_get_pi(rdev);
@@ -1284,6 +1285,7 @@ void trinity_dpm_reset_asic(struct radeon_device *rdev)
}
trinity_release_mutex(rdev);
}
+#endif
static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev,
u32 vid_2bit)
diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
index 2324a526de65..11485a4a16ae 100644
--- a/drivers/gpu/drm/rcar-du/Kconfig
+++ b/drivers/gpu/drm/rcar-du/Kconfig
@@ -1,6 +1,6 @@
config DRM_RCAR_DU
tristate "DRM Support for R-Car Display Unit"
- depends on DRM && ARM
+ depends on DRM && ARM && HAVE_DMA_ATTRS
depends on ARCH_SHMOBILE || COMPILE_TEST
select DRM_KMS_HELPER
select DRM_KMS_CMA_HELPER
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 23cc910951f4..25c7a998fc2c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -74,39 +74,77 @@ static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
if (ret < 0)
return ret;
+ ret = clk_prepare_enable(rcrtc->extclock);
+ if (ret < 0)
+ goto error_clock;
+
ret = rcar_du_group_get(rcrtc->group);
if (ret < 0)
- clk_disable_unprepare(rcrtc->clock);
+ goto error_group;
+
+ return 0;
+error_group:
+ clk_disable_unprepare(rcrtc->extclock);
+error_clock:
+ clk_disable_unprepare(rcrtc->clock);
return ret;
}
static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
{
rcar_du_group_put(rcrtc->group);
+
+ clk_disable_unprepare(rcrtc->extclock);
clk_disable_unprepare(rcrtc->clock);
}
static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
{
const struct drm_display_mode *mode = &rcrtc->crtc.mode;
+ unsigned long mode_clock = mode->clock * 1000;
unsigned long clk;
u32 value;
+ u32 escr;
u32 div;
- /* Dot clock */
+ /* Compute the clock divisor and select the internal or external dot
+ * clock based on the requested frequency.
+ */
clk = clk_get_rate(rcrtc->clock);
- div = DIV_ROUND_CLOSEST(clk, mode->clock * 1000);
+ div = DIV_ROUND_CLOSEST(clk, mode_clock);
div = clamp(div, 1U, 64U) - 1;
+ escr = div | ESCR_DCLKSEL_CLKS;
+
+ if (rcrtc->extclock) {
+ unsigned long extclk;
+ unsigned long extrate;
+ unsigned long rate;
+ u32 extdiv;
+
+ extclk = clk_get_rate(rcrtc->extclock);
+ extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock);
+ extdiv = clamp(extdiv, 1U, 64U) - 1;
+
+ rate = clk / (div + 1);
+ extrate = extclk / (extdiv + 1);
+
+ if (abs((long)extrate - (long)mode_clock) <
+ abs((long)rate - (long)mode_clock)) {
+ dev_dbg(rcrtc->group->dev->dev,
+ "crtc%u: using external clock\n", rcrtc->index);
+ escr = extdiv | ESCR_DCLKSEL_DCLKIN;
+ }
+ }
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
- ESCR_DCLKSEL_CLKS | div);
+ escr);
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0);
/* Signal polarities */
value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL)
| ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL)
- | DSMR_DIPM_DE;
+ | DSMR_DIPM_DE | DSMR_CSPM;
rcar_du_crtc_write(rcrtc, DSMR, value);
/* Display timings */
@@ -117,12 +155,15 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
mode->hsync_start - 1);
rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1);
- rcar_du_crtc_write(rcrtc, VDSR, mode->vtotal - mode->vsync_end - 2);
- rcar_du_crtc_write(rcrtc, VDER, mode->vtotal - mode->vsync_end +
- mode->vdisplay - 2);
- rcar_du_crtc_write(rcrtc, VSPR, mode->vtotal - mode->vsync_end +
- mode->vsync_start - 1);
- rcar_du_crtc_write(rcrtc, VCR, mode->vtotal - 1);
+ rcar_du_crtc_write(rcrtc, VDSR, mode->crtc_vtotal -
+ mode->crtc_vsync_end - 2);
+ rcar_du_crtc_write(rcrtc, VDER, mode->crtc_vtotal -
+ mode->crtc_vsync_end +
+ mode->crtc_vdisplay - 2);
+ rcar_du_crtc_write(rcrtc, VSPR, mode->crtc_vtotal -
+ mode->crtc_vsync_end +
+ mode->crtc_vsync_start - 1);
+ rcar_du_crtc_write(rcrtc, VCR, mode->crtc_vtotal - 1);
rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start);
rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay);
@@ -139,9 +180,10 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
*/
rcrtc->outputs |= BIT(output);
- /* Store RGB routing to DPAD0 for R8A7790. */
- if (rcar_du_has(rcdu, RCAR_DU_FEATURE_DEFR8) &&
- output == RCAR_DU_OUTPUT_DPAD0)
+ /* Store RGB routing to DPAD0, the hardware will be configured when
+ * starting the CRTC.
+ */
+ if (output == RCAR_DU_OUTPUT_DPAD0)
rcdu->dpad0_source = rcrtc->index;
}
@@ -217,6 +259,7 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
{
struct drm_crtc *crtc = &rcrtc->crtc;
+ bool interlaced;
unsigned int i;
if (rcrtc->started)
@@ -252,7 +295,10 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
* sync mode (with the HSYNC and VSYNC signals configured as outputs and
* actively driven).
*/
- rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_MASTER);
+ interlaced = rcrtc->crtc.mode.flags & DRM_MODE_FLAG_INTERLACE;
+ rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK | DSYSR_SCM_MASK,
+ (interlaced ? DSYSR_SCM_INT_VIDEO : 0) |
+ DSYSR_TVM_MASTER);
rcar_du_group_start_stop(rcrtc->group, true);
@@ -308,6 +354,9 @@ static void rcar_du_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
if (rcrtc->dpms == mode)
return;
@@ -486,7 +535,7 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
status = rcar_du_crtc_read(rcrtc, DSSR);
rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
- if (status & DSSR_VBK) {
+ if (status & DSSR_FRM) {
drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index);
rcar_du_crtc_finish_page_flip(rcrtc);
ret = IRQ_HANDLED;
@@ -542,12 +591,13 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
struct drm_crtc *crtc = &rcrtc->crtc;
unsigned int irqflags;
- char clk_name[5];
+ struct clk *clk;
+ char clk_name[9];
char *name;
int irq;
int ret;
- /* Get the CRTC clock. */
+ /* Get the CRTC clock and the optional external clock. */
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
sprintf(clk_name, "du.%u", index);
name = clk_name;
@@ -561,6 +611,15 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
return PTR_ERR(rcrtc->clock);
}
+ sprintf(clk_name, "dclkin.%u", index);
+ clk = devm_clk_get(rcdu->dev, clk_name);
+ if (!IS_ERR(clk)) {
+ rcrtc->extclock = clk;
+ } else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
+ dev_info(rcdu->dev, "can't get external clock %u\n", index);
+ return -EPROBE_DEFER;
+ }
+
rcrtc->group = rgrp;
rcrtc->mmio_offset = mmio_offsets[index];
rcrtc->index = index;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 984e6083699f..d2f89f7d2e5e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -26,6 +26,7 @@ struct rcar_du_crtc {
struct drm_crtc crtc;
struct clk *clock;
+ struct clk *extclock;
unsigned int mmio_offset;
unsigned int index;
bool started;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 7bfa09cf18d5..e0d74f821416 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -56,7 +56,8 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = {
};
static const struct rcar_du_device_info rcar_du_r8a7790_info = {
- .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+ | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.quirks = RCAR_DU_QUIRK_ALIGN_128B | RCAR_DU_QUIRK_LVDS_LANES,
.num_crtcs = 3,
.routes = {
@@ -83,7 +84,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
};
static const struct rcar_du_device_info rcar_du_r8a7791_info = {
- .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
+ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+ | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2,
.routes = {
/* R8A7791 has one RGB output, one LVDS output and one
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 0a724669f02d..c5b9ea6a7eaa 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -27,7 +27,7 @@ struct rcar_du_device;
struct rcar_du_lvdsenc;
#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */
-#define RCAR_DU_FEATURE_DEFR8 (1 << 1) /* Has DEFR8 register */
+#define RCAR_DU_FEATURE_EXT_CTRL_REGS (1 << 1) /* Has extended control registers */
#define RCAR_DU_QUIRK_ALIGN_128B (1 << 0) /* Align pitches to 128 bytes */
#define RCAR_DU_QUIRK_LVDS_LANES (1 << 1) /* LVDS lanes 1 and 3 inverted */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index 34a122a39664..279167f783f6 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -46,6 +46,9 @@ static void rcar_du_encoder_dpms(struct drm_encoder *encoder, int mode)
{
struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
if (renc->lvds)
rcar_du_lvdsenc_dpms(renc->lvds, encoder->crtc, mode);
}
@@ -190,35 +193,42 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
}
if (type == RCAR_DU_ENCODER_HDMI) {
- if (renc->lvds) {
- dev_err(rcdu->dev,
- "Chaining LVDS and HDMI encoders not supported\n");
- return -EINVAL;
- }
-
ret = rcar_du_hdmienc_init(rcdu, renc, enc_node);
if (ret < 0)
- return ret;
+ goto done;
} else {
ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
encoder_type);
if (ret < 0)
- return ret;
+ goto done;
drm_encoder_helper_add(encoder, &encoder_helper_funcs);
}
switch (encoder_type) {
case DRM_MODE_ENCODER_LVDS:
- return rcar_du_lvds_connector_init(rcdu, renc, con_node);
+ ret = rcar_du_lvds_connector_init(rcdu, renc, con_node);
+ break;
case DRM_MODE_ENCODER_DAC:
- return rcar_du_vga_connector_init(rcdu, renc);
+ ret = rcar_du_vga_connector_init(rcdu, renc);
+ break;
case DRM_MODE_ENCODER_TMDS:
- return rcar_du_hdmi_connector_init(rcdu, renc);
+ ret = rcar_du_hdmi_connector_init(rcdu, renc);
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ break;
}
+
+done:
+ if (ret < 0) {
+ if (encoder->name)
+ encoder->funcs->destroy(encoder);
+ devm_kfree(rcdu->dev, renc);
+ }
+
+ return ret;
}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 4e7614b145db..1bdc0ee0c248 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -48,9 +48,6 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
{
u32 defr8 = DEFR8_CODE | DEFR8_DEFE8;
- if (!rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8))
- return;
-
/* The DEFR8 register for the first group also controls RGB output
* routing to DPAD0
*/
@@ -69,7 +66,20 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE);
rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5);
- rcar_du_group_setup_defr8(rgrp);
+ if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
+ rcar_du_group_setup_defr8(rgrp);
+
+ /* Configure input dot clock routing. We currently hardcode the
+ * configuration to routing DOTCLKINn to DUn.
+ */
+ rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE |
+ DIDSR_LCDS_DCLKIN(2) |
+ DIDSR_LCDS_DCLKIN(1) |
+ DIDSR_LCDS_DCLKIN(0) |
+ DIDSR_PDCS_CLK(2, 0) |
+ DIDSR_PDCS_CLK(1, 0) |
+ DIDSR_PDCS_CLK(0, 0));
+ }
/* Use DS1PR and DS2PR to configure planes priorities and connects the
* superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
@@ -149,6 +159,9 @@ static int rcar_du_set_dpad0_routing(struct rcar_du_device *rcdu)
{
int ret;
+ if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_EXT_CTRL_REGS))
+ return 0;
+
/* RGB output routing to DPAD0 is configured in the DEFR8 register of
* the first group. As this function can be called with the DU0 and DU1
* CRTCs disabled, we need to enable the first group clock before
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
index 4d7d4dd46d26..ca94b029ac80 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c
@@ -95,6 +95,8 @@ int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
connector = &rcon->connector;
connector->display_info.width_mm = 0;
connector->display_info.height_mm = 0;
+ connector->interlace_allowed = true;
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
index 359bc999a9c8..221f0a17fd6a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
@@ -21,6 +21,7 @@
#include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_hdmienc.h"
+#include "rcar_du_lvdsenc.h"
struct rcar_du_hdmienc {
struct rcar_du_encoder *renc;
@@ -36,12 +37,21 @@ static void rcar_du_hdmienc_dpms(struct drm_encoder *encoder, int mode)
struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
if (hdmienc->dpms == mode)
return;
+ if (mode == DRM_MODE_DPMS_ON && hdmienc->renc->lvds)
+ rcar_du_lvdsenc_dpms(hdmienc->renc->lvds, encoder->crtc, mode);
+
if (sfuncs->dpms)
sfuncs->dpms(encoder, mode);
+ if (mode != DRM_MODE_DPMS_ON && hdmienc->renc->lvds)
+ rcar_du_lvdsenc_dpms(hdmienc->renc->lvds, encoder->crtc, mode);
+
hdmienc->dpms = mode;
}
@@ -49,8 +59,16 @@ static bool rcar_du_hdmienc_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+ struct rcar_du_hdmienc *hdmienc = to_rcar_hdmienc(encoder);
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
+ /* The internal LVDS encoder has a clock frequency operating range of
+ * 30MHz to 150MHz. Clamp the clock accordingly.
+ */
+ if (hdmienc->renc->lvds)
+ adjusted_mode->clock = clamp(adjusted_mode->clock,
+ 30000, 150000);
+
if (sfuncs->mode_fixup == NULL)
return true;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 0c5ee616b5a3..cc9136e8ee9c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -346,8 +346,14 @@ static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
/* Process the output pipeline. */
ret = rcar_du_encoders_init_one(rcdu, output, &ep);
if (ret < 0) {
- of_node_put(ep_node);
- return ret;
+ if (ret == -EPROBE_DEFER) {
+ of_node_put(ep_node);
+ return ret;
+ }
+
+ dev_info(rcdu->dev,
+ "encoder initialization failed, skipping\n");
+ continue;
}
num_encoders += ret;
@@ -413,6 +419,11 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
if (ret < 0)
return ret;
+ if (ret == 0) {
+ dev_err(rcdu->dev, "error: no encoder could be initialized\n");
+ return -EINVAL;
+ }
+
num_encoders = ret;
/* Set the possible CRTCs and possible clones. There's always at least
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 72a7cb47bd9f..50f2f2b20d39 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -104,14 +104,22 @@ void rcar_du_plane_update_base(struct rcar_du_plane *plane)
{
struct rcar_du_group *rgrp = plane->group;
unsigned int index = plane->hwindex;
+ bool interlaced;
u32 mwr;
- /* Memory pitch (expressed in pixels) */
+ interlaced = plane->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE;
+
+ /* Memory pitch (expressed in pixels). Must be doubled for interlaced
+ * operation with 32bpp formats.
+ */
if (plane->format->planes == 2)
mwr = plane->pitch;
else
mwr = plane->pitch * 8 / plane->format->bpp;
+ if (interlaced && plane->format->bpp == 32)
+ mwr *= 2;
+
rcar_du_plane_write(rgrp, index, PnMWR, mwr);
/* The Y position is expressed in raster line units and must be doubled
@@ -119,17 +127,23 @@ void rcar_du_plane_update_base(struct rcar_du_plane *plane)
* doubling the Y position is found in the R8A7779 datasheet, but the
* rule seems to apply there as well.
*
+ * Despite not being documented, doubling seem not to be needed when
+ * operating in interlaced mode.
+ *
* Similarly, for the second plane, NV12 and NV21 formats seem to
- * require a halved Y position value.
+ * require a halved Y position value, in both progressive and interlaced
+ * modes.
*/
rcar_du_plane_write(rgrp, index, PnSPXR, plane->src_x);
rcar_du_plane_write(rgrp, index, PnSPYR, plane->src_y *
- (plane->format->bpp == 32 ? 2 : 1));
+ (!interlaced && plane->format->bpp == 32 ? 2 : 1));
rcar_du_plane_write(rgrp, index, PnDSA0R, plane->dma[0]);
if (plane->format->planes == 2) {
index = (index + 1) % 8;
+ rcar_du_plane_write(rgrp, index, PnMWR, plane->pitch);
+
rcar_du_plane_write(rgrp, index, PnSPXR, plane->src_x);
rcar_du_plane_write(rgrp, index, PnSPYR, plane->src_y *
(plane->format->bpp == 16 ? 2 : 1) / 2);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
index 73f7347f740b..70fcbc471ebd 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
@@ -34,6 +34,7 @@
#define DSYSR_SCM_INT_NONE (0 << 4)
#define DSYSR_SCM_INT_SYNC (2 << 4)
#define DSYSR_SCM_INT_VIDEO (3 << 4)
+#define DSYSR_SCM_MASK (3 << 4)
#define DSMR 0x00004
#define DSMR_VSPM (1 << 28)
@@ -256,8 +257,8 @@
#define DIDSR_LCDS_LVDS0(n) (2 << (8 + (n) * 2))
#define DIDSR_LCDS_LVDS1(n) (3 << (8 + (n) * 2))
#define DIDSR_LCDS_MASK(n) (3 << (8 + (n) * 2))
-#define DIDSR_PCDS_CLK(n, clk) (clk << ((n) * 2))
-#define DIDSR_PCDS_MASK(n) (3 << ((n) * 2))
+#define DIDSR_PDCS_CLK(n, clk) (clk << ((n) * 2))
+#define DIDSR_PDCS_MASK(n) (3 << ((n) * 2))
/* -----------------------------------------------------------------------------
* Display Timing Generation Registers
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
index 752747a5e920..9d4879921cc7 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
@@ -64,6 +64,7 @@ int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
connector = &rcon->connector;
connector->display_info.width_mm = 0;
connector->display_info.height_mm = 0;
+ connector->interlace_allowed = true;
ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
DRM_MODE_CONNECTOR_VGA);
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index ca9f085efa92..35215f6867d3 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -1,13 +1,13 @@
config DRM_ROCKCHIP
tristate "DRM Support for Rockchip"
depends on DRM && ROCKCHIP_IOMMU
+ depends on RESET_CONTROLLER
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select DRM_PANEL
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
select VIDEOMODE_HELPERS
help
Choose this option if you have a Rockchip soc chipset.
@@ -15,3 +15,13 @@ config DRM_ROCKCHIP
management to userspace. This driver does not provide
2D or 3D acceleration; acceleration is performed by other
IP found on the SoC.
+
+config ROCKCHIP_DW_HDMI
+ tristate "Rockchip specific extensions for Synopsys DW HDMI"
+ depends on DRM_ROCKCHIP
+ select DRM_DW_HDMI
+ help
+ This selects support for Rockchip SoC specific extensions
+ for the Synopsys DesignWare HDMI driver. If you want to
+ enable HDMI on RK3288 based SoC, you should selet this
+ option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index 2cb0672f57ed..f3d8a19c641f 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -5,4 +5,6 @@
rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
rockchip_drm_gem.o
+obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
+
obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
new file mode 100644
index 000000000000..d236faa05b19
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <drm/drm_of.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+#include <drm/bridge/dw_hdmi.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define GRF_SOC_CON6 0x025c
+#define HDMI_SEL_VOP_LIT (1 << 4)
+
+struct rockchip_hdmi {
+ struct device *dev;
+ struct regmap *regmap;
+ struct drm_encoder encoder;
+};
+
+#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
+
+static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
+ {
+ 27000000, {
+ { 0x00b3, 0x0000},
+ { 0x2153, 0x0000},
+ { 0x40f3, 0x0000}
+ },
+ }, {
+ 36000000, {
+ { 0x00b3, 0x0000},
+ { 0x2153, 0x0000},
+ { 0x40f3, 0x0000}
+ },
+ }, {
+ 40000000, {
+ { 0x00b3, 0x0000},
+ { 0x2153, 0x0000},
+ { 0x40f3, 0x0000}
+ },
+ }, {
+ 54000000, {
+ { 0x0072, 0x0001},
+ { 0x2142, 0x0001},
+ { 0x40a2, 0x0001},
+ },
+ }, {
+ 65000000, {
+ { 0x0072, 0x0001},
+ { 0x2142, 0x0001},
+ { 0x40a2, 0x0001},
+ },
+ }, {
+ 66000000, {
+ { 0x013e, 0x0003},
+ { 0x217e, 0x0002},
+ { 0x4061, 0x0002}
+ },
+ }, {
+ 74250000, {
+ { 0x0072, 0x0001},
+ { 0x2145, 0x0002},
+ { 0x4061, 0x0002}
+ },
+ }, {
+ 83500000, {
+ { 0x0072, 0x0001},
+ },
+ }, {
+ 108000000, {
+ { 0x0051, 0x0002},
+ { 0x2145, 0x0002},
+ { 0x4061, 0x0002}
+ },
+ }, {
+ 106500000, {
+ { 0x0051, 0x0002},
+ { 0x2145, 0x0002},
+ { 0x4061, 0x0002}
+ },
+ }, {
+ 146250000, {
+ { 0x0051, 0x0002},
+ { 0x2145, 0x0002},
+ { 0x4061, 0x0002}
+ },
+ }, {
+ 148500000, {
+ { 0x0051, 0x0003},
+ { 0x214c, 0x0003},
+ { 0x4064, 0x0003}
+ },
+ }, {
+ ~0UL, {
+ { 0x00a0, 0x000a },
+ { 0x2001, 0x000f },
+ { 0x4002, 0x000f },
+ },
+ }
+};
+
+static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
+ /* pixelclk bpp8 bpp10 bpp12 */
+ {
+ 40000000, { 0x0018, 0x0018, 0x0018 },
+ }, {
+ 65000000, { 0x0028, 0x0028, 0x0028 },
+ }, {
+ 66000000, { 0x0038, 0x0038, 0x0038 },
+ }, {
+ 74250000, { 0x0028, 0x0038, 0x0038 },
+ }, {
+ 83500000, { 0x0028, 0x0038, 0x0038 },
+ }, {
+ 146250000, { 0x0038, 0x0038, 0x0038 },
+ }, {
+ 148500000, { 0x0000, 0x0038, 0x0038 },
+ }, {
+ ~0UL, { 0x0000, 0x0000, 0x0000},
+ }
+};
+
+static const struct dw_hdmi_sym_term rockchip_sym_term[] = {
+ /*pixelclk symbol term*/
+ { 74250000, 0x8009, 0x0004 },
+ { 148500000, 0x8029, 0x0004 },
+ { 297000000, 0x8039, 0x0005 },
+ { ~0UL, 0x0000, 0x0000 }
+};
+
+static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
+{
+ struct device_node *np = hdmi->dev->of_node;
+
+ hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+ if (IS_ERR(hdmi->regmap)) {
+ dev_err(hdmi->dev, "Unable to get rockchip,grf\n");
+ return PTR_ERR(hdmi->regmap);
+ }
+
+ return 0;
+}
+
+static enum drm_mode_status
+dw_hdmi_rockchip_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
+ int pclk = mode->clock * 1000;
+ bool valid = false;
+ int i;
+
+ for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
+ if (pclk == mpll_cfg[i].mpixelclock) {
+ valid = true;
+ break;
+ }
+ }
+
+ return (valid) ? MODE_OK : MODE_BAD;
+}
+
+static struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static bool
+dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adj_mode)
+{
+ return true;
+}
+
+static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adj_mode)
+{
+}
+
+static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
+{
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+ u32 val;
+ int mux;
+
+ mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
+ if (mux)
+ val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
+ else
+ val = HDMI_SEL_VOP_LIT << 16;
+
+ regmap_write(hdmi->regmap, GRF_SOC_CON6, val);
+ dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
+ (mux) ? "LIT" : "BIG");
+}
+
+static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
+{
+ rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+ ROCKCHIP_OUT_MODE_AAAA);
+}
+
+static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
+ .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
+ .mode_set = dw_hdmi_rockchip_encoder_mode_set,
+ .prepare = dw_hdmi_rockchip_encoder_prepare,
+ .commit = dw_hdmi_rockchip_encoder_commit,
+ .disable = dw_hdmi_rockchip_encoder_disable,
+};
+
+static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
+ .mode_valid = dw_hdmi_rockchip_mode_valid,
+ .mpll_cfg = rockchip_mpll_cfg,
+ .cur_ctr = rockchip_cur_ctr,
+ .sym_term = rockchip_sym_term,
+ .dev_type = RK3288_HDMI,
+};
+
+static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
+ { .compatible = "rockchip,rk3288-dw-hdmi",
+ .data = &rockchip_hdmi_drv_data
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids);
+
+static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ const struct dw_hdmi_plat_data *plat_data;
+ const struct of_device_id *match;
+ struct drm_device *drm = data;
+ struct drm_encoder *encoder;
+ struct rockchip_hdmi *hdmi;
+ struct resource *iores;
+ int irq;
+ int ret;
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+ if (!hdmi)
+ return -ENOMEM;
+
+ match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
+ plat_data = match->data;
+ hdmi->dev = &pdev->dev;
+ encoder = &hdmi->encoder;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iores)
+ return -ENXIO;
+
+ platform_set_drvdata(pdev, hdmi);
+
+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+ /*
+ * If we failed to find the CRTC(s) which this encoder is
+ * supposed to be connected to, it's because the CRTC has
+ * not been registered yet. Defer probing, and hope that
+ * the required CRTC is added later.
+ */
+ if (encoder->possible_crtcs == 0)
+ return -EPROBE_DEFER;
+
+ ret = rockchip_hdmi_parse_dt(hdmi);
+ if (ret) {
+ dev_err(hdmi->dev, "Unable to parse OF data\n");
+ return ret;
+ }
+
+ drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
+ drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+
+ return dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+}
+
+static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ return dw_hdmi_unbind(dev, master, data);
+}
+
+static const struct component_ops dw_hdmi_rockchip_ops = {
+ .bind = dw_hdmi_rockchip_bind,
+ .unbind = dw_hdmi_rockchip_unbind,
+};
+
+static int dw_hdmi_rockchip_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &dw_hdmi_rockchip_ops);
+}
+
+static int dw_hdmi_rockchip_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &dw_hdmi_rockchip_ops);
+
+ return 0;
+}
+
+static struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
+ .probe = dw_hdmi_rockchip_probe,
+ .remove = dw_hdmi_rockchip_remove,
+ .driver = {
+ .name = "dwhdmi-rockchip",
+ .of_match_table = dw_hdmi_rockchip_dt_ids,
+ },
+};
+
+module_platform_driver(dw_hdmi_rockchip_pltfm_driver);
+
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific DW-HDMI Driver Extension");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dwhdmi-rockchip");
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index a798c7c71f91..21a481b224eb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -390,6 +390,7 @@ int rockchip_drm_encoder_get_mux_id(struct device_node *node,
return -EINVAL;
}
+EXPORT_SYMBOL_GPL(rockchip_drm_encoder_get_mux_id);
static int compare_of(struct device *dev, void *data)
{
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index bc98a227dc76..7ca8799ef784 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -34,12 +34,9 @@ static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj)
rk_obj->kvaddr = dma_alloc_attrs(drm->dev, obj->size,
&rk_obj->dma_addr, GFP_KERNEL,
&rk_obj->dma_attrs);
- if (IS_ERR(rk_obj->kvaddr)) {
- int ret = PTR_ERR(rk_obj->kvaddr);
-
- DRM_ERROR("failed to allocate %#x byte dma buffer, %d",
- obj->size, ret);
- return ret;
+ if (!rk_obj->kvaddr) {
+ DRM_ERROR("failed to allocate %#x byte dma buffer", obj->size);
+ return -ENOMEM;
}
return 0;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index e7ca25b3fb38..9a5c571b95fc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -735,6 +735,7 @@ int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
return 0;
}
+EXPORT_SYMBOL_GPL(rockchip_drm_crtc_mode_config);
static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
{
diff --git a/drivers/gpu/drm/shmobile/Kconfig b/drivers/gpu/drm/shmobile/Kconfig
index a50fe0eeaa0d..b9202aa6f8ab 100644
--- a/drivers/gpu/drm/shmobile/Kconfig
+++ b/drivers/gpu/drm/shmobile/Kconfig
@@ -1,8 +1,10 @@
config DRM_SHMOBILE
tristate "DRM Support for SH Mobile"
- depends on DRM && ARM
+ depends on DRM && ARM && HAVE_DMA_ATTRS
depends on ARCH_SHMOBILE || COMPILE_TEST
+ depends on FB_SH_MOBILE_MERAM || !FB_SH_MOBILE_MERAM
select BACKLIGHT_CLASS_DEVICE
+ select BACKLIGHT_LCD_SUPPORT
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select DRM_KMS_CMA_HELPER
diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
index d6d6b705b8c1..fbccc105819b 100644
--- a/drivers/gpu/drm/sti/Kconfig
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -1,10 +1,11 @@
config DRM_STI
tristate "DRM Support for STMicroelectronics SoC stiH41x Series"
- depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
+ depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM) && HAVE_DMA_ATTRS
select RESET_CONTROLLER
select DRM_KMS_HELPER
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
+ select DRM_PANEL
select FW_LOADER_USER_HELPER_FALLBACK
help
Choose this option to enable DRM on STM stiH41x chipset
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
index 6ba9d27c1b90..f0f1e4ee2d92 100644
--- a/drivers/gpu/drm/sti/Makefile
+++ b/drivers/gpu/drm/sti/Makefile
@@ -12,6 +12,9 @@ stihdmi-y := sti_hdmi.o \
sti_hdmi_tx3g0c55phy.o \
sti_hdmi_tx3g4c28phy.o \
+stidvo-y := sti_dvo.o \
+ sti_awg_utils.o
+
obj-$(CONFIG_DRM_STI) = \
sti_vtg.o \
sti_vtac.o \
@@ -20,4 +23,5 @@ obj-$(CONFIG_DRM_STI) = \
sti_tvout.o \
sticompositor.o \
sti_hqvdp.o \
+ stidvo.o \
sti_drm_drv.o
diff --git a/drivers/gpu/drm/sti/sti_awg_utils.c b/drivers/gpu/drm/sti/sti_awg_utils.c
new file mode 100644
index 000000000000..6029a2e3db1d
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_awg_utils.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include "sti_awg_utils.h"
+
+#define AWG_OPCODE_OFFSET 10
+
+enum opcode {
+ SET,
+ RPTSET,
+ RPLSET,
+ SKIP,
+ STOP,
+ REPEAT,
+ REPLAY,
+ JUMP,
+ HOLD,
+};
+
+static int awg_generate_instr(enum opcode opcode,
+ long int arg,
+ long int mux_sel,
+ long int data_en,
+ struct awg_code_generation_params *fwparams)
+{
+ u32 instruction = 0;
+ u32 mux = (mux_sel << 8) & 0x1ff;
+ u32 data_enable = (data_en << 9) & 0x2ff;
+ long int arg_tmp = arg;
+
+ /* skip, repeat and replay arg should not exceed 1023.
+ * If user wants to exceed this value, the instruction should be
+ * duplicate and arg should be adjust for each duplicated instruction.
+ */
+
+ while (arg_tmp > 0) {
+ arg = arg_tmp;
+ if (fwparams->instruction_offset >= AWG_MAX_INST) {
+ DRM_ERROR("too many number of instructions\n");
+ return -EINVAL;
+ }
+
+ switch (opcode) {
+ case SKIP:
+ /* leave 'arg' + 1 pixel elapsing without changing
+ * output bus */
+ arg--; /* pixel adjustment */
+ arg_tmp--;
+
+ if (arg < 0) {
+ /* SKIP instruction not needed */
+ return 0;
+ }
+
+ if (arg == 0) {
+ /* SKIP 0 not permitted but we want to skip 1
+ * pixel. So we transform SKIP into SET
+ * instruction */
+ opcode = SET;
+ break;
+ }
+
+ mux = 0;
+ data_enable = 0;
+ arg = (arg << 22) >> 22;
+ arg &= (0x3ff);
+ break;
+ case REPEAT:
+ case REPLAY:
+ if (arg == 0) {
+ /* REPEAT or REPLAY instruction not needed */
+ return 0;
+ }
+
+ mux = 0;
+ data_enable = 0;
+ arg = (arg << 22) >> 22;
+ arg &= (0x3ff);
+ break;
+ case JUMP:
+ mux = 0;
+ data_enable = 0;
+ arg |= 0x40; /* for jump instruction 7th bit is 1 */
+ arg = (arg << 22) >> 22;
+ arg &= 0x3ff;
+ break;
+ case STOP:
+ arg = 0;
+ break;
+ case SET:
+ case RPTSET:
+ case RPLSET:
+ case HOLD:
+ arg = (arg << 24) >> 24;
+ arg &= (0x0ff);
+ break;
+ default:
+ DRM_ERROR("instruction %d does not exist\n", opcode);
+ return -EINVAL;
+ }
+
+ arg_tmp = arg_tmp - arg;
+
+ arg = ((arg + mux) + data_enable);
+
+ instruction = ((opcode) << AWG_OPCODE_OFFSET) | arg;
+ fwparams->ram_code[fwparams->instruction_offset] =
+ instruction & (0x3fff);
+ fwparams->instruction_offset++;
+ }
+ return 0;
+}
+
+int sti_awg_generate_code_data_enable_mode(
+ struct awg_code_generation_params *fwparams,
+ struct awg_timing *timing)
+{
+ long int val;
+ long int data_en;
+ int ret = 0;
+
+ if (timing->trailing_lines > 0) {
+ /* skip trailing lines */
+ val = timing->blanking_level;
+ data_en = 0;
+ ret |= awg_generate_instr(RPLSET, val, 0, data_en, fwparams);
+
+ val = timing->trailing_lines - 1;
+ data_en = 0;
+ ret |= awg_generate_instr(REPLAY, val, 0, data_en, fwparams);
+ }
+
+ if (timing->trailing_pixels > 0) {
+ /* skip trailing pixel */
+ val = timing->blanking_level;
+ data_en = 0;
+ ret |= awg_generate_instr(RPLSET, val, 0, data_en, fwparams);
+
+ val = timing->trailing_pixels - 1;
+ data_en = 0;
+ ret |= awg_generate_instr(SKIP, val, 0, data_en, fwparams);
+ }
+
+ /* set DE signal high */
+ val = timing->blanking_level;
+ data_en = 1;
+ ret |= awg_generate_instr((timing->trailing_pixels > 0) ? SET : RPLSET,
+ val, 0, data_en, fwparams);
+
+ if (timing->blanking_pixels > 0) {
+ /* skip the number of active pixel */
+ val = timing->active_pixels - 1;
+ data_en = 1;
+ ret |= awg_generate_instr(SKIP, val, 0, data_en, fwparams);
+
+ /* set DE signal low */
+ val = timing->blanking_level;
+ data_en = 0;
+ ret |= awg_generate_instr(SET, val, 0, data_en, fwparams);
+ }
+
+ /* replay the sequence as many active lines defined */
+ val = timing->active_lines - 1;
+ data_en = 0;
+ ret |= awg_generate_instr(REPLAY, val, 0, data_en, fwparams);
+
+ if (timing->blanking_lines > 0) {
+ /* skip blanking lines */
+ val = timing->blanking_level;
+ data_en = 0;
+ ret |= awg_generate_instr(RPLSET, val, 0, data_en, fwparams);
+
+ val = timing->blanking_lines - 1;
+ data_en = 0;
+ ret |= awg_generate_instr(REPLAY, val, 0, data_en, fwparams);
+ }
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/sti/sti_awg_utils.h b/drivers/gpu/drm/sti/sti_awg_utils.h
new file mode 100644
index 000000000000..45d599bd570a
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_awg_utils.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_AWG_UTILS_H_
+#define _STI_AWG_UTILS_H_
+
+#include <drm/drmP.h>
+
+#define AWG_MAX_INST 64
+
+struct awg_code_generation_params {
+ u32 *ram_code;
+ u8 instruction_offset;
+};
+
+struct awg_timing {
+ u32 total_lines;
+ u32 active_lines;
+ u32 blanking_lines;
+ u32 trailing_lines;
+ u32 total_pixels;
+ u32 active_pixels;
+ u32 blanking_pixels;
+ u32 trailing_pixels;
+ u32 blanking_level;
+};
+
+int sti_awg_generate_code_data_enable_mode(
+ struct awg_code_generation_params *fw_gen_params,
+ struct awg_timing *timing);
+#endif
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.c b/drivers/gpu/drm/sti/sti_drm_crtc.c
index 4c651c200f20..e6f6ef7c4866 100644
--- a/drivers/gpu/drm/sti/sti_drm_crtc.c
+++ b/drivers/gpu/drm/sti/sti_drm_crtc.c
@@ -190,11 +190,6 @@ out:
return ret;
}
-static void sti_drm_crtc_load_lut(struct drm_crtc *crtc)
-{
- /* do nothing */
-}
-
static void sti_drm_crtc_disable(struct drm_crtc *crtc)
{
struct sti_mixer *mixer = to_sti_mixer(crtc);
@@ -249,7 +244,6 @@ static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
.mode_fixup = sti_drm_crtc_mode_fixup,
.mode_set = sti_drm_crtc_mode_set,
.mode_set_base = sti_drm_crtc_mode_set_base,
- .load_lut = sti_drm_crtc_load_lut,
.disable = sti_drm_crtc_disable,
};
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
new file mode 100644
index 000000000000..aeb5070c8363
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+
+#include "sti_awg_utils.h"
+#include "sti_mixer.h"
+
+/* DVO registers */
+#define DVO_AWG_DIGSYNC_CTRL 0x0000
+#define DVO_DOF_CFG 0x0004
+#define DVO_LUT_PROG_LOW 0x0008
+#define DVO_LUT_PROG_MID 0x000C
+#define DVO_LUT_PROG_HIGH 0x0010
+#define DVO_DIGSYNC_INSTR_I 0x0100
+
+#define DVO_AWG_CTRL_EN BIT(0)
+#define DVO_AWG_FRAME_BASED_SYNC BIT(2)
+
+#define DVO_DOF_EN_LOWBYTE BIT(0)
+#define DVO_DOF_EN_MIDBYTE BIT(1)
+#define DVO_DOF_EN_HIGHBYTE BIT(2)
+#define DVO_DOF_EN BIT(6)
+#define DVO_DOF_MOD_COUNT_SHIFT 8
+
+#define DVO_LUT_ZERO 0
+#define DVO_LUT_Y_G 1
+#define DVO_LUT_Y_G_DEL 2
+#define DVO_LUT_CB_B 3
+#define DVO_LUT_CB_B_DEL 4
+#define DVO_LUT_CR_R 5
+#define DVO_LUT_CR_R_DEL 6
+#define DVO_LUT_HOLD 7
+
+struct dvo_config {
+ u32 flags;
+ u32 lowbyte;
+ u32 midbyte;
+ u32 highbyte;
+ int (*awg_fwgen_fct)(
+ struct awg_code_generation_params *fw_gen_params,
+ struct awg_timing *timing);
+};
+
+static struct dvo_config rgb_24bit_de_cfg = {
+ .flags = (0L << DVO_DOF_MOD_COUNT_SHIFT),
+ .lowbyte = DVO_LUT_CR_R,
+ .midbyte = DVO_LUT_Y_G,
+ .highbyte = DVO_LUT_CB_B,
+ .awg_fwgen_fct = sti_awg_generate_code_data_enable_mode,
+};
+
+/**
+ * STI digital video output structure
+ *
+ * @dev: driver device
+ * @drm_dev: pointer to drm device
+ * @mode: current display mode selected
+ * @regs: dvo registers
+ * @clk_pix: pixel clock for dvo
+ * @clk: clock for dvo
+ * @clk_main_parent: dvo parent clock if main path used
+ * @clk_aux_parent: dvo parent clock if aux path used
+ * @panel_node: panel node reference from device tree
+ * @panel: reference to the panel connected to the dvo
+ * @enabled: true if dvo is enabled else false
+ * @encoder: drm_encoder it is bound
+ */
+struct sti_dvo {
+ struct device dev;
+ struct drm_device *drm_dev;
+ struct drm_display_mode mode;
+ void __iomem *regs;
+ struct clk *clk_pix;
+ struct clk *clk;
+ struct clk *clk_main_parent;
+ struct clk *clk_aux_parent;
+ struct device_node *panel_node;
+ struct drm_panel *panel;
+ struct dvo_config *config;
+ bool enabled;
+ struct drm_encoder *encoder;
+ struct drm_bridge *bridge;
+};
+
+struct sti_dvo_connector {
+ struct drm_connector drm_connector;
+ struct drm_encoder *encoder;
+ struct sti_dvo *dvo;
+};
+
+#define to_sti_dvo_connector(x) \
+ container_of(x, struct sti_dvo_connector, drm_connector)
+
+#define BLANKING_LEVEL 16
+int dvo_awg_generate_code(struct sti_dvo *dvo, u8 *ram_size, u32 *ram_code)
+{
+ struct drm_display_mode *mode = &dvo->mode;
+ struct dvo_config *config = dvo->config;
+ struct awg_code_generation_params fw_gen_params;
+ struct awg_timing timing;
+
+ fw_gen_params.ram_code = ram_code;
+ fw_gen_params.instruction_offset = 0;
+
+ timing.total_lines = mode->vtotal;
+ timing.active_lines = mode->vdisplay;
+ timing.blanking_lines = mode->vsync_start - mode->vdisplay;
+ timing.trailing_lines = mode->vtotal - mode->vsync_start;
+ timing.total_pixels = mode->htotal;
+ timing.active_pixels = mode->hdisplay;
+ timing.blanking_pixels = mode->hsync_start - mode->hdisplay;
+ timing.trailing_pixels = mode->htotal - mode->hsync_start;
+ timing.blanking_level = BLANKING_LEVEL;
+
+ if (config->awg_fwgen_fct(&fw_gen_params, &timing)) {
+ DRM_ERROR("AWG firmware not properly generated\n");
+ return -EINVAL;
+ }
+
+ *ram_size = fw_gen_params.instruction_offset;
+
+ return 0;
+}
+
+/* Configure AWG, writing instructions
+ *
+ * @dvo: pointer to DVO structure
+ * @awg_ram_code: pointer to AWG instructions table
+ * @nb: nb of AWG instructions
+ */
+static void dvo_awg_configure(struct sti_dvo *dvo, u32 *awg_ram_code, int nb)
+{
+ int i;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ for (i = 0; i < nb; i++)
+ writel(awg_ram_code[i],
+ dvo->regs + DVO_DIGSYNC_INSTR_I + i * 4);
+ for (i = nb; i < AWG_MAX_INST; i++)
+ writel(0, dvo->regs + DVO_DIGSYNC_INSTR_I + i * 4);
+
+ writel(DVO_AWG_CTRL_EN, dvo->regs + DVO_AWG_DIGSYNC_CTRL);
+}
+
+static void sti_dvo_disable(struct drm_bridge *bridge)
+{
+ struct sti_dvo *dvo = bridge->driver_private;
+
+ if (!dvo->enabled)
+ return;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (dvo->config->awg_fwgen_fct)
+ writel(0x00000000, dvo->regs + DVO_AWG_DIGSYNC_CTRL);
+
+ writel(0x00000000, dvo->regs + DVO_DOF_CFG);
+
+ if (dvo->panel)
+ dvo->panel->funcs->disable(dvo->panel);
+
+ /* Disable/unprepare dvo clock */
+ clk_disable_unprepare(dvo->clk_pix);
+ clk_disable_unprepare(dvo->clk);
+
+ dvo->enabled = false;
+}
+
+static void sti_dvo_pre_enable(struct drm_bridge *bridge)
+{
+ struct sti_dvo *dvo = bridge->driver_private;
+ struct dvo_config *config = dvo->config;
+ u32 val;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (dvo->enabled)
+ return;
+
+ /* Make sure DVO is disabled */
+ writel(0x00000000, dvo->regs + DVO_DOF_CFG);
+ writel(0x00000000, dvo->regs + DVO_AWG_DIGSYNC_CTRL);
+
+ if (config->awg_fwgen_fct) {
+ u8 nb_instr;
+ u32 awg_ram_code[AWG_MAX_INST];
+ /* Configure AWG */
+ if (!dvo_awg_generate_code(dvo, &nb_instr, awg_ram_code))
+ dvo_awg_configure(dvo, awg_ram_code, nb_instr);
+ else
+ return;
+ }
+
+ /* Prepare/enable clocks */
+ if (clk_prepare_enable(dvo->clk_pix))
+ DRM_ERROR("Failed to prepare/enable dvo_pix clk\n");
+ if (clk_prepare_enable(dvo->clk))
+ DRM_ERROR("Failed to prepare/enable dvo clk\n");
+
+ if (dvo->panel)
+ dvo->panel->funcs->enable(dvo->panel);
+
+ /* Set LUT */
+ writel(config->lowbyte, dvo->regs + DVO_LUT_PROG_LOW);
+ writel(config->midbyte, dvo->regs + DVO_LUT_PROG_MID);
+ writel(config->highbyte, dvo->regs + DVO_LUT_PROG_HIGH);
+
+ /* Digital output formatter config */
+ val = (config->flags | DVO_DOF_EN);
+ writel(val, dvo->regs + DVO_DOF_CFG);
+
+ dvo->enabled = true;
+}
+
+static void sti_dvo_set_mode(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct sti_dvo *dvo = bridge->driver_private;
+ struct sti_mixer *mixer = to_sti_mixer(dvo->encoder->crtc);
+ int rate = mode->clock * 1000;
+ struct clk *clkp;
+ int ret;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode));
+
+ /* According to the path used (main or aux), the dvo clocks should
+ * have a different parent clock. */
+ if (mixer->id == STI_MIXER_MAIN)
+ clkp = dvo->clk_main_parent;
+ else
+ clkp = dvo->clk_aux_parent;
+
+ if (clkp) {
+ clk_set_parent(dvo->clk_pix, clkp);
+ clk_set_parent(dvo->clk, clkp);
+ }
+
+ /* DVO clocks = compositor clock */
+ ret = clk_set_rate(dvo->clk_pix, rate);
+ if (ret < 0) {
+ DRM_ERROR("Cannot set rate (%dHz) for dvo_pix clk\n", rate);
+ return;
+ }
+
+ ret = clk_set_rate(dvo->clk, rate);
+ if (ret < 0) {
+ DRM_ERROR("Cannot set rate (%dHz) for dvo clk\n", rate);
+ return;
+ }
+
+ /* For now, we only support 24bit data enable (DE) synchro format */
+ dvo->config = &rgb_24bit_de_cfg;
+}
+
+static void sti_dvo_bridge_nope(struct drm_bridge *bridge)
+{
+ /* do nothing */
+}
+
+static const struct drm_bridge_funcs sti_dvo_bridge_funcs = {
+ .pre_enable = sti_dvo_pre_enable,
+ .enable = sti_dvo_bridge_nope,
+ .disable = sti_dvo_disable,
+ .post_disable = sti_dvo_bridge_nope,
+ .mode_set = sti_dvo_set_mode,
+};
+
+static int sti_dvo_connector_get_modes(struct drm_connector *connector)
+{
+ struct sti_dvo_connector *dvo_connector
+ = to_sti_dvo_connector(connector);
+ struct sti_dvo *dvo = dvo_connector->dvo;
+
+ if (dvo->panel)
+ return dvo->panel->funcs->get_modes(dvo->panel);
+
+ return 0;
+}
+
+#define CLK_TOLERANCE_HZ 50
+
+static int sti_dvo_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ int target = mode->clock * 1000;
+ int target_min = target - CLK_TOLERANCE_HZ;
+ int target_max = target + CLK_TOLERANCE_HZ;
+ int result;
+ struct sti_dvo_connector *dvo_connector
+ = to_sti_dvo_connector(connector);
+ struct sti_dvo *dvo = dvo_connector->dvo;
+
+ result = clk_round_rate(dvo->clk_pix, target);
+
+ DRM_DEBUG_DRIVER("target rate = %d => available rate = %d\n",
+ target, result);
+
+ if ((result < target_min) || (result > target_max)) {
+ DRM_DEBUG_DRIVER("dvo pixclk=%d not supported\n", target);
+ return MODE_BAD;
+ }
+
+ return MODE_OK;
+}
+
+struct drm_encoder *sti_dvo_best_encoder(struct drm_connector *connector)
+{
+ struct sti_dvo_connector *dvo_connector
+ = to_sti_dvo_connector(connector);
+
+ /* Best encoder is the one associated during connector creation */
+ return dvo_connector->encoder;
+}
+
+static struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = {
+ .get_modes = sti_dvo_connector_get_modes,
+ .mode_valid = sti_dvo_connector_mode_valid,
+ .best_encoder = sti_dvo_best_encoder,
+};
+
+static enum drm_connector_status
+sti_dvo_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct sti_dvo_connector *dvo_connector
+ = to_sti_dvo_connector(connector);
+ struct sti_dvo *dvo = dvo_connector->dvo;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (!dvo->panel)
+ dvo->panel = of_drm_find_panel(dvo->panel_node);
+
+ if (dvo->panel)
+ if (!drm_panel_attach(dvo->panel, connector))
+ return connector_status_connected;
+
+ return connector_status_disconnected;
+}
+
+static void sti_dvo_connector_destroy(struct drm_connector *connector)
+{
+ struct sti_dvo_connector *dvo_connector
+ = to_sti_dvo_connector(connector);
+
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+ kfree(dvo_connector);
+}
+
+static struct drm_connector_funcs sti_dvo_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .detect = sti_dvo_connector_detect,
+ .destroy = sti_dvo_connector_destroy,
+};
+
+static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev)
+{
+ struct drm_encoder *encoder;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
+ return encoder;
+ }
+
+ return NULL;
+}
+
+static int sti_dvo_bind(struct device *dev, struct device *master, void *data)
+{
+ struct sti_dvo *dvo = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ struct drm_encoder *encoder;
+ struct sti_dvo_connector *connector;
+ struct drm_connector *drm_connector;
+ struct drm_bridge *bridge;
+ int err;
+
+ /* Set the drm device handle */
+ dvo->drm_dev = drm_dev;
+
+ encoder = sti_dvo_find_encoder(drm_dev);
+ if (!encoder)
+ return -ENOMEM;
+
+ connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
+ if (!connector)
+ return -ENOMEM;
+
+ connector->dvo = dvo;
+
+ bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
+ if (!bridge)
+ return -ENOMEM;
+
+ bridge->driver_private = dvo;
+ bridge->funcs = &sti_dvo_bridge_funcs;
+ bridge->of_node = dvo->dev.of_node;
+ err = drm_bridge_add(bridge);
+ if (err) {
+ DRM_ERROR("Failed to add bridge\n");
+ return err;
+ }
+
+ err = drm_bridge_attach(drm_dev, bridge);
+ if (err) {
+ DRM_ERROR("Failed to attach bridge\n");
+ return err;
+ }
+
+ dvo->bridge = bridge;
+ encoder->bridge = bridge;
+ connector->encoder = encoder;
+ dvo->encoder = encoder;
+
+ drm_connector = (struct drm_connector *)connector;
+
+ drm_connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+ drm_connector_init(drm_dev, drm_connector,
+ &sti_dvo_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
+ drm_connector_helper_add(drm_connector,
+ &sti_dvo_connector_helper_funcs);
+
+ err = drm_connector_register(drm_connector);
+ if (err)
+ goto err_connector;
+
+ err = drm_mode_connector_attach_encoder(drm_connector, encoder);
+ if (err) {
+ DRM_ERROR("Failed to attach a connector to a encoder\n");
+ goto err_sysfs;
+ }
+
+ return 0;
+
+err_sysfs:
+ drm_connector_unregister(drm_connector);
+err_connector:
+ drm_bridge_remove(bridge);
+ drm_connector_cleanup(drm_connector);
+ return -EINVAL;
+}
+
+static void sti_dvo_unbind(struct device *dev,
+ struct device *master, void *data)
+{
+ struct sti_dvo *dvo = dev_get_drvdata(dev);
+
+ drm_bridge_remove(dvo->bridge);
+}
+
+static const struct component_ops sti_dvo_ops = {
+ .bind = sti_dvo_bind,
+ .unbind = sti_dvo_unbind,
+};
+
+static int sti_dvo_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sti_dvo *dvo;
+ struct resource *res;
+ struct device_node *np = dev->of_node;
+
+ DRM_INFO("%s\n", __func__);
+
+ dvo = devm_kzalloc(dev, sizeof(*dvo), GFP_KERNEL);
+ if (!dvo) {
+ DRM_ERROR("Failed to allocate memory for DVO\n");
+ return -ENOMEM;
+ }
+
+ dvo->dev = pdev->dev;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvo-reg");
+ if (!res) {
+ DRM_ERROR("Invalid dvo resource\n");
+ return -ENOMEM;
+ }
+ dvo->regs = devm_ioremap_nocache(dev, res->start,
+ resource_size(res));
+ if (IS_ERR(dvo->regs))
+ return PTR_ERR(dvo->regs);
+
+ dvo->clk_pix = devm_clk_get(dev, "dvo_pix");
+ if (IS_ERR(dvo->clk_pix)) {
+ DRM_ERROR("Cannot get dvo_pix clock\n");
+ return PTR_ERR(dvo->clk_pix);
+ }
+
+ dvo->clk = devm_clk_get(dev, "dvo");
+ if (IS_ERR(dvo->clk)) {
+ DRM_ERROR("Cannot get dvo clock\n");
+ return PTR_ERR(dvo->clk);
+ }
+
+ dvo->clk_main_parent = devm_clk_get(dev, "main_parent");
+ if (IS_ERR(dvo->clk_main_parent)) {
+ DRM_DEBUG_DRIVER("Cannot get main_parent clock\n");
+ dvo->clk_main_parent = NULL;
+ }
+
+ dvo->clk_aux_parent = devm_clk_get(dev, "aux_parent");
+ if (IS_ERR(dvo->clk_aux_parent)) {
+ DRM_DEBUG_DRIVER("Cannot get aux_parent clock\n");
+ dvo->clk_aux_parent = NULL;
+ }
+
+ dvo->panel_node = of_parse_phandle(np, "sti,panel", 0);
+ if (!dvo->panel_node)
+ DRM_ERROR("No panel associated to the dvo output\n");
+
+ platform_set_drvdata(pdev, dvo);
+
+ return component_add(&pdev->dev, &sti_dvo_ops);
+}
+
+static int sti_dvo_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &sti_dvo_ops);
+ return 0;
+}
+
+static struct of_device_id dvo_of_match[] = {
+ { .compatible = "st,stih407-dvo", },
+ { /* end node */ }
+};
+MODULE_DEVICE_TABLE(of, dvo_of_match);
+
+struct platform_driver sti_dvo_driver = {
+ .driver = {
+ .name = "sti-dvo",
+ .owner = THIS_MODULE,
+ .of_match_table = dvo_of_match,
+ },
+ .probe = sti_dvo_probe,
+ .remove = sti_dvo_remove,
+};
+
+module_platform_driver(sti_dvo_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index 32448d1d1e8f..087906fd8846 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -14,15 +14,19 @@
#include "sti_layer.h"
#include "sti_vtg.h"
+#define ALPHASWITCH BIT(6)
#define ENA_COLOR_FILL BIT(8)
+#define BIGNOTLITTLE BIT(23)
#define WAIT_NEXT_VSYNC BIT(31)
/* GDP color formats */
#define GDP_RGB565 0x00
#define GDP_RGB888 0x01
#define GDP_RGB888_32 0x02
+#define GDP_XBGR8888 (GDP_RGB888_32 | BIGNOTLITTLE | ALPHASWITCH)
#define GDP_ARGB8565 0x04
#define GDP_ARGB8888 0x05
+#define GDP_ABGR8888 (GDP_ARGB8888 | BIGNOTLITTLE | ALPHASWITCH)
#define GDP_ARGB1555 0x06
#define GDP_ARGB4444 0x07
#define GDP_CLUT8 0x0B
@@ -103,7 +107,9 @@ struct sti_gdp {
static const uint32_t gdp_supported_formats[] = {
DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
DRM_FORMAT_ARGB4444,
DRM_FORMAT_ARGB1555,
DRM_FORMAT_RGB565,
@@ -129,8 +135,12 @@ static int sti_gdp_fourcc2format(int fourcc)
switch (fourcc) {
case DRM_FORMAT_XRGB8888:
return GDP_RGB888_32;
+ case DRM_FORMAT_XBGR8888:
+ return GDP_XBGR8888;
case DRM_FORMAT_ARGB8888:
return GDP_ARGB8888;
+ case DRM_FORMAT_ABGR8888:
+ return GDP_ABGR8888;
case DRM_FORMAT_ARGB4444:
return GDP_ARGB4444;
case DRM_FORMAT_ARGB1555:
@@ -157,6 +167,7 @@ static int sti_gdp_get_alpharange(int format)
case GDP_ARGB8565:
case GDP_ARGB8888:
case GDP_AYCBR8888:
+ case GDP_ABGR8888:
return GAM_GDP_ALPHARANGE_255;
}
return 0;
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index 2ae9a9b73666..a9bbb081ecad 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -508,19 +508,12 @@ static void sti_hda_bridge_nope(struct drm_bridge *bridge)
/* do nothing */
}
-static void sti_hda_brigde_destroy(struct drm_bridge *bridge)
-{
- drm_bridge_cleanup(bridge);
- kfree(bridge);
-}
-
static const struct drm_bridge_funcs sti_hda_bridge_funcs = {
.pre_enable = sti_hda_pre_enable,
.enable = sti_hda_bridge_nope,
.disable = sti_hda_disable,
.post_disable = sti_hda_bridge_nope,
.mode_set = sti_hda_set_mode,
- .destroy = sti_hda_brigde_destroy,
};
static int sti_hda_connector_get_modes(struct drm_connector *connector)
@@ -664,7 +657,8 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
return -ENOMEM;
bridge->driver_private = hda;
- drm_bridge_init(drm_dev, bridge, &sti_hda_bridge_funcs);
+ bridge->funcs = &sti_hda_bridge_funcs;
+ drm_bridge_attach(drm_dev, bridge);
encoder->bridge = bridge;
connector->encoder = encoder;
@@ -693,7 +687,6 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
err_sysfs:
drm_connector_unregister(drm_connector);
err_connector:
- drm_bridge_cleanup(bridge);
drm_connector_cleanup(drm_connector);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index d032e024b0b8..1485ade98710 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -42,8 +42,17 @@
#define HDMI_SW_DI_1_PKT_WORD5 0x0228
#define HDMI_SW_DI_1_PKT_WORD6 0x022C
#define HDMI_SW_DI_CFG 0x0230
+#define HDMI_SW_DI_2_HEAD_WORD 0x0600
+#define HDMI_SW_DI_2_PKT_WORD0 0x0604
+#define HDMI_SW_DI_2_PKT_WORD1 0x0608
+#define HDMI_SW_DI_2_PKT_WORD2 0x060C
+#define HDMI_SW_DI_2_PKT_WORD3 0x0610
+#define HDMI_SW_DI_2_PKT_WORD4 0x0614
+#define HDMI_SW_DI_2_PKT_WORD5 0x0618
+#define HDMI_SW_DI_2_PKT_WORD6 0x061C
#define HDMI_IFRAME_SLOT_AVI 1
+#define HDMI_IFRAME_SLOT_AUDIO 2
#define XCAT(prefix, x, suffix) prefix ## x ## suffix
#define HDMI_SW_DI_N_HEAD_WORD(x) XCAT(HDMI_SW_DI_, x, _HEAD_WORD)
@@ -99,6 +108,10 @@
#define HDMI_STA_SW_RST BIT(1)
+#define HDMI_INFOFRAME_HEADER_TYPE(x) (((x) & 0xff) << 0)
+#define HDMI_INFOFRAME_HEADER_VERSION(x) (((x) & 0xff) << 8)
+#define HDMI_INFOFRAME_HEADER_LEN(x) (((x) & 0x0f) << 16)
+
struct sti_hdmi_connector {
struct drm_connector drm_connector;
struct drm_encoder *encoder;
@@ -228,6 +241,90 @@ static void hdmi_config(struct sti_hdmi *hdmi)
}
/**
+ * Helper to concatenate infoframe in 32 bits word
+ *
+ * @ptr: pointer on the hdmi internal structure
+ * @data: infoframe to write
+ * @size: size to write
+ */
+static inline unsigned int hdmi_infoframe_subpack(const u8 *ptr, size_t size)
+{
+ unsigned long value = 0;
+ size_t i;
+
+ for (i = size; i > 0; i--)
+ value = (value << 8) | ptr[i - 1];
+
+ return value;
+}
+
+/**
+ * Helper to write info frame
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ * @data: infoframe to write
+ * @size: size to write
+ */
+static void hdmi_infoframe_write_infopack(struct sti_hdmi *hdmi, const u8 *data)
+{
+ const u8 *ptr = data;
+ u32 val, slot, mode, i;
+ u32 head_offset, pack_offset;
+ size_t size;
+
+ switch (*ptr) {
+ case HDMI_INFOFRAME_TYPE_AVI:
+ slot = HDMI_IFRAME_SLOT_AVI;
+ mode = HDMI_IFRAME_FIELD;
+ head_offset = HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AVI);
+ pack_offset = HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AVI);
+ size = HDMI_AVI_INFOFRAME_SIZE;
+ break;
+
+ case HDMI_INFOFRAME_TYPE_AUDIO:
+ slot = HDMI_IFRAME_SLOT_AUDIO;
+ mode = HDMI_IFRAME_FRAME;
+ head_offset = HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AUDIO);
+ pack_offset = HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AUDIO);
+ size = HDMI_AUDIO_INFOFRAME_SIZE;
+ break;
+
+ default:
+ DRM_ERROR("unsupported infoframe type: %#x\n", *ptr);
+ return;
+ }
+
+ /* Disable transmission slot for updated infoframe */
+ val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
+ val &= ~HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, slot);
+ hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
+
+ val = HDMI_INFOFRAME_HEADER_TYPE(*ptr++);
+ val |= HDMI_INFOFRAME_HEADER_VERSION(*ptr++);
+ val |= HDMI_INFOFRAME_HEADER_LEN(*ptr++);
+ writel(val, hdmi->regs + head_offset);
+
+ /*
+ * Each subpack contains 4 bytes
+ * The First Bytes of the first subpacket must contain the checksum
+ * Packet size in increase by one.
+ */
+ for (i = 0; i < size; i += sizeof(u32)) {
+ size_t num;
+
+ num = min_t(size_t, size - i, sizeof(u32));
+ val = hdmi_infoframe_subpack(ptr, num);
+ ptr += sizeof(u32);
+ writel(val, hdmi->regs + pack_offset + i);
+ }
+
+ /* Enable transmission slot for updated infoframe */
+ val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
+ val |= HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_FIELD, slot);
+ hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
+}
+
+/**
* Prepare and configure the AVI infoframe
*
* AVI infoframe are transmitted at least once per two video field and
@@ -243,8 +340,6 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
struct drm_display_mode *mode = &hdmi->mode;
struct hdmi_avi_infoframe infoframe;
u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
- u8 *frame = buffer + HDMI_INFOFRAME_HEADER_SIZE;
- u32 val;
int ret;
DRM_DEBUG_DRIVER("\n");
@@ -266,47 +361,43 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
return ret;
}
- /* Disable transmission slot for AVI infoframe */
- val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
- val &= ~HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, HDMI_IFRAME_SLOT_AVI);
- hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
+ hdmi_infoframe_write_infopack(hdmi, buffer);
- /* Infoframe header */
- val = buffer[0];
- val |= buffer[1] << 8;
- val |= buffer[2] << 16;
- hdmi_write(hdmi, val, HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AVI));
-
- /* Infoframe packet bytes */
- val = buffer[3];
- val |= *(frame++) << 8;
- val |= *(frame++) << 16;
- val |= *(frame++) << 24;
- hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AVI));
-
- val = *(frame++);
- val |= *(frame++) << 8;
- val |= *(frame++) << 16;
- val |= *(frame++) << 24;
- hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD1(HDMI_IFRAME_SLOT_AVI));
-
- val = *(frame++);
- val |= *(frame++) << 8;
- val |= *(frame++) << 16;
- val |= *(frame++) << 24;
- hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD2(HDMI_IFRAME_SLOT_AVI));
-
- val = *(frame++);
- val |= *(frame) << 8;
- hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD3(HDMI_IFRAME_SLOT_AVI));
-
- /* Enable transmission slot for AVI infoframe
- * According to the hdmi specification, AVI infoframe should be
- * transmitted at least once per two video fields
- */
- val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
- val |= HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_FIELD, HDMI_IFRAME_SLOT_AVI);
- hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
+ return 0;
+}
+
+/**
+ * Prepare and configure the AUDIO infoframe
+ *
+ * AUDIO infoframe are transmitted once per frame and
+ * contains information about HDMI transmission mode such as audio codec,
+ * sample size, ...
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ *
+ * Return negative value if error occurs
+ */
+static int hdmi_audio_infoframe_config(struct sti_hdmi *hdmi)
+{
+ struct hdmi_audio_infoframe infofame;
+ u8 buffer[HDMI_INFOFRAME_SIZE(AUDIO)];
+ int ret;
+
+ ret = hdmi_audio_infoframe_init(&infofame);
+ if (ret < 0) {
+ DRM_ERROR("failed to setup audio infoframe: %d\n", ret);
+ return ret;
+ }
+
+ infofame.channels = 2;
+
+ ret = hdmi_audio_infoframe_pack(&infofame, buffer, sizeof(buffer));
+ if (ret < 0) {
+ DRM_ERROR("failed to pack audio infoframe: %d\n", ret);
+ return ret;
+ }
+
+ hdmi_infoframe_write_infopack(hdmi, buffer);
return 0;
}
@@ -427,6 +518,10 @@ static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
if (hdmi_avi_infoframe_config(hdmi))
DRM_ERROR("Unable to configure AVI infoframe\n");
+ /* Program AUDIO infoframe */
+ if (hdmi_audio_infoframe_config(hdmi))
+ DRM_ERROR("Unable to configure AUDIO infoframe\n");
+
/* Sw reset */
hdmi_swreset(hdmi);
}
@@ -463,19 +558,12 @@ static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
/* do nothing */
}
-static void sti_hdmi_brigde_destroy(struct drm_bridge *bridge)
-{
- drm_bridge_cleanup(bridge);
- kfree(bridge);
-}
-
static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
.pre_enable = sti_hdmi_pre_enable,
.enable = sti_hdmi_bridge_nope,
.disable = sti_hdmi_disable,
.post_disable = sti_hdmi_bridge_nope,
.mode_set = sti_hdmi_set_mode,
- .destroy = sti_hdmi_brigde_destroy,
};
static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -635,7 +723,8 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
goto err_adapt;
bridge->driver_private = hdmi;
- drm_bridge_init(drm_dev, bridge, &sti_hdmi_bridge_funcs);
+ bridge->funcs = &sti_hdmi_bridge_funcs;
+ drm_bridge_attach(drm_dev, bridge);
encoder->bridge = bridge;
connector->encoder = encoder;
@@ -667,7 +756,6 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
err_sysfs:
drm_connector_unregister(drm_connector);
err_connector:
- drm_bridge_cleanup(bridge);
drm_connector_cleanup(drm_connector);
err_adapt:
put_device(&hdmi->ddc_adapt->dev);
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
index f3db05dab0ab..b0eb62de1b2e 100644
--- a/drivers/gpu/drm/sti/sti_hqvdp.c
+++ b/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -1025,7 +1025,7 @@ static int sti_hqvdp_probe(struct platform_device *pdev)
/* Get clock resources */
hqvdp->clk = devm_clk_get(dev, "hqvdp");
hqvdp->clk_pix_main = devm_clk_get(dev, "pix_main");
- if (IS_ERR(hqvdp->clk) || IS_ERR(hqvdp->clk)) {
+ if (IS_ERR(hqvdp->clk) || IS_ERR(hqvdp->clk_pix_main)) {
DRM_ERROR("Cannot get clocks\n");
return -ENXIO;
}
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c
index cb924aa2b321..5cc53116508e 100644
--- a/drivers/gpu/drm/sti/sti_tvout.c
+++ b/drivers/gpu/drm/sti/sti_tvout.c
@@ -48,6 +48,9 @@
#define TVO_HDMI_CLIP_VALUE_R_CR 0x514
#define TVO_HDMI_SYNC_SEL 0x518
#define TVO_HDMI_DFV_OBS 0x540
+#define TVO_VIP_DVO 0x600
+#define TVO_DVO_SYNC_SEL 0x618
+#define TVO_DVO_CONFIG 0x620
#define TVO_IN_FMT_SIGNED BIT(0)
#define TVO_SYNC_EXT BIT(4)
@@ -98,6 +101,9 @@
#define TVO_SYNC_HD_DCS_SHIFT 8
+#define TVO_SYNC_DVO_PAD_HSYNC_SHIFT 8
+#define TVO_SYNC_DVO_PAD_VSYNC_SHIFT 16
+
#define ENCODER_CRTC_MASK (BIT(0) | BIT(1))
/* enum listing the supported output data format */
@@ -113,6 +119,7 @@ struct sti_tvout {
struct reset_control *reset;
struct drm_encoder *hdmi;
struct drm_encoder *hda;
+ struct drm_encoder *dvo;
};
struct sti_tvout_encoder {
@@ -262,6 +269,66 @@ static void tvout_vip_set_in_vid_fmt(struct sti_tvout *tvout,
}
/**
+ * Start VIP block for DVO output
+ *
+ * @tvout: pointer on tvout structure
+ * @main_path: true if main path has to be used in the vip configuration
+ * else aux path is used.
+ */
+static void tvout_dvo_start(struct sti_tvout *tvout, bool main_path)
+{
+ struct device_node *node = tvout->dev->of_node;
+ bool sel_input_logic_inverted = false;
+ u32 tvo_in_vid_format;
+ int val;
+
+ dev_dbg(tvout->dev, "%s\n", __func__);
+
+ if (main_path) {
+ DRM_DEBUG_DRIVER("main vip for DVO\n");
+ /* Select the input sync for dvo = VTG set 4 */
+ val = TVO_SYNC_MAIN_VTG_SET_4 << TVO_SYNC_DVO_PAD_VSYNC_SHIFT;
+ val |= TVO_SYNC_MAIN_VTG_SET_4 << TVO_SYNC_DVO_PAD_HSYNC_SHIFT;
+ val |= TVO_SYNC_MAIN_VTG_SET_4;
+ tvout_write(tvout, val, TVO_DVO_SYNC_SEL);
+ tvo_in_vid_format = TVO_MAIN_IN_VID_FORMAT;
+ } else {
+ DRM_DEBUG_DRIVER("aux vip for DVO\n");
+ /* Select the input sync for dvo = VTG set 4 */
+ val = TVO_SYNC_AUX_VTG_SET_4 << TVO_SYNC_DVO_PAD_VSYNC_SHIFT;
+ val |= TVO_SYNC_AUX_VTG_SET_4 << TVO_SYNC_DVO_PAD_HSYNC_SHIFT;
+ val |= TVO_SYNC_AUX_VTG_SET_4;
+ tvout_write(tvout, val, TVO_DVO_SYNC_SEL);
+ tvo_in_vid_format = TVO_AUX_IN_VID_FORMAT;
+ }
+
+ /* Set color channel order */
+ tvout_vip_set_color_order(tvout, TVO_VIP_DVO,
+ TVO_VIP_REORDER_CR_R_SEL,
+ TVO_VIP_REORDER_Y_G_SEL,
+ TVO_VIP_REORDER_CB_B_SEL);
+
+ /* Set clipping mode (Limited range RGB/Y) */
+ tvout_vip_set_clip_mode(tvout, TVO_VIP_DVO,
+ TVO_VIP_CLIP_LIMITED_RANGE_RGB_Y);
+
+ /* Set round mode (rounded to 8-bit per component) */
+ tvout_vip_set_rnd(tvout, TVO_VIP_DVO, TVO_VIP_RND_8BIT_ROUNDED);
+
+ if (of_device_is_compatible(node, "st,stih407-tvout")) {
+ /* Set input video format */
+ tvout_vip_set_in_vid_fmt(tvout, tvo_in_vid_format,
+ TVO_IN_FMT_SIGNED);
+ sel_input_logic_inverted = true;
+ }
+
+ /* Input selection */
+ tvout_vip_set_sel_input(tvout, TVO_VIP_DVO, main_path,
+ sel_input_logic_inverted,
+ STI_TVOUT_VIDEO_OUT_RGB);
+}
+
+/**
* Start VIP block for HDMI output
*
* @tvout: pointer on tvout structure
@@ -402,6 +469,56 @@ static const struct drm_encoder_funcs sti_tvout_encoder_funcs = {
.destroy = sti_tvout_encoder_destroy,
};
+static void sti_dvo_encoder_commit(struct drm_encoder *encoder)
+{
+ struct sti_tvout *tvout = to_sti_tvout(encoder);
+
+ tvout_dvo_start(tvout, sti_drm_crtc_is_main(encoder->crtc));
+}
+
+static void sti_dvo_encoder_disable(struct drm_encoder *encoder)
+{
+ struct sti_tvout *tvout = to_sti_tvout(encoder);
+
+ /* Reset VIP register */
+ tvout_write(tvout, 0x0, TVO_VIP_DVO);
+}
+
+static const struct drm_encoder_helper_funcs sti_dvo_encoder_helper_funcs = {
+ .dpms = sti_tvout_encoder_dpms,
+ .mode_fixup = sti_tvout_encoder_mode_fixup,
+ .mode_set = sti_tvout_encoder_mode_set,
+ .prepare = sti_tvout_encoder_prepare,
+ .commit = sti_dvo_encoder_commit,
+ .disable = sti_dvo_encoder_disable,
+};
+
+static struct drm_encoder *
+sti_tvout_create_dvo_encoder(struct drm_device *dev,
+ struct sti_tvout *tvout)
+{
+ struct sti_tvout_encoder *encoder;
+ struct drm_encoder *drm_encoder;
+
+ encoder = devm_kzalloc(tvout->dev, sizeof(*encoder), GFP_KERNEL);
+ if (!encoder)
+ return NULL;
+
+ encoder->tvout = tvout;
+
+ drm_encoder = (struct drm_encoder *)encoder;
+
+ drm_encoder->possible_crtcs = ENCODER_CRTC_MASK;
+ drm_encoder->possible_clones = 1 << 0;
+
+ drm_encoder_init(dev, drm_encoder,
+ &sti_tvout_encoder_funcs, DRM_MODE_ENCODER_LVDS);
+
+ drm_encoder_helper_add(drm_encoder, &sti_dvo_encoder_helper_funcs);
+
+ return drm_encoder;
+}
+
static void sti_hda_encoder_commit(struct drm_encoder *encoder)
{
struct sti_tvout *tvout = to_sti_tvout(encoder);
@@ -508,6 +625,7 @@ static void sti_tvout_create_encoders(struct drm_device *dev,
{
tvout->hdmi = sti_tvout_create_hdmi_encoder(dev, tvout);
tvout->hda = sti_tvout_create_hda_encoder(dev, tvout);
+ tvout->dvo = sti_tvout_create_dvo_encoder(dev, tvout);
}
static void sti_tvout_destroy_encoders(struct sti_tvout *tvout)
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 978993fa3a36..3aaa84ae2681 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -18,9 +18,12 @@
#include "drm.h"
#include "gem.h"
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h>
struct tegra_dc_soc_info {
+ bool supports_border_color;
bool supports_interlacing;
bool supports_cursor;
bool supports_block_linear;
@@ -38,63 +41,122 @@ static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
return container_of(plane, struct tegra_plane, base);
}
-static void tegra_dc_window_commit(struct tegra_dc *dc, unsigned int index)
+struct tegra_dc_state {
+ struct drm_crtc_state base;
+
+ struct clk *clk;
+ unsigned long pclk;
+ unsigned int div;
+
+ u32 planes;
+};
+
+static inline struct tegra_dc_state *to_dc_state(struct drm_crtc_state *state)
{
- u32 value = WIN_A_ACT_REQ << index;
+ if (state)
+ return container_of(state, struct tegra_dc_state, base);
- tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
+ return NULL;
}
-static void tegra_dc_cursor_commit(struct tegra_dc *dc)
+struct tegra_plane_state {
+ struct drm_plane_state base;
+
+ struct tegra_bo_tiling tiling;
+ u32 format;
+ u32 swap;
+};
+
+static inline struct tegra_plane_state *
+to_tegra_plane_state(struct drm_plane_state *state)
{
- tegra_dc_writel(dc, CURSOR_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL);
+ if (state)
+ return container_of(state, struct tegra_plane_state, base);
+
+ return NULL;
}
-static void tegra_dc_commit(struct tegra_dc *dc)
+/*
+ * Reads the active copy of a register. This takes the dc->lock spinlock to
+ * prevent races with the VBLANK processing which also needs access to the
+ * active copy of some registers.
+ */
+static u32 tegra_dc_readl_active(struct tegra_dc *dc, unsigned long offset)
+{
+ unsigned long flags;
+ u32 value;
+
+ spin_lock_irqsave(&dc->lock, flags);
+
+ tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
+ value = tegra_dc_readl(dc, offset);
+ tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
+
+ spin_unlock_irqrestore(&dc->lock, flags);
+ return value;
+}
+
+/*
+ * Double-buffered registers have two copies: ASSEMBLY and ACTIVE. When the
+ * *_ACT_REQ bits are set the ASSEMBLY copy is latched into the ACTIVE copy.
+ * Latching happens mmediately if the display controller is in STOP mode or
+ * on the next frame boundary otherwise.
+ *
+ * Triple-buffered registers have three copies: ASSEMBLY, ARM and ACTIVE. The
+ * ASSEMBLY copy is latched into the ARM copy immediately after *_UPDATE bits
+ * are written. When the *_ACT_REQ bits are written, the ARM copy is latched
+ * into the ACTIVE copy, either immediately if the display controller is in
+ * STOP mode, or at the next frame boundary otherwise.
+ */
+void tegra_dc_commit(struct tegra_dc *dc)
{
tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
}
-static unsigned int tegra_dc_format(uint32_t format, uint32_t *swap)
+static int tegra_dc_format(u32 fourcc, u32 *format, u32 *swap)
{
/* assume no swapping of fetched data */
if (swap)
*swap = BYTE_SWAP_NOSWAP;
- switch (format) {
+ switch (fourcc) {
case DRM_FORMAT_XBGR8888:
- return WIN_COLOR_DEPTH_R8G8B8A8;
+ *format = WIN_COLOR_DEPTH_R8G8B8A8;
+ break;
case DRM_FORMAT_XRGB8888:
- return WIN_COLOR_DEPTH_B8G8R8A8;
+ *format = WIN_COLOR_DEPTH_B8G8R8A8;
+ break;
case DRM_FORMAT_RGB565:
- return WIN_COLOR_DEPTH_B5G6R5;
+ *format = WIN_COLOR_DEPTH_B5G6R5;
+ break;
case DRM_FORMAT_UYVY:
- return WIN_COLOR_DEPTH_YCbCr422;
+ *format = WIN_COLOR_DEPTH_YCbCr422;
+ break;
case DRM_FORMAT_YUYV:
if (swap)
*swap = BYTE_SWAP_SWAP2;
- return WIN_COLOR_DEPTH_YCbCr422;
+ *format = WIN_COLOR_DEPTH_YCbCr422;
+ break;
case DRM_FORMAT_YUV420:
- return WIN_COLOR_DEPTH_YCbCr420P;
+ *format = WIN_COLOR_DEPTH_YCbCr420P;
+ break;
case DRM_FORMAT_YUV422:
- return WIN_COLOR_DEPTH_YCbCr422P;
+ *format = WIN_COLOR_DEPTH_YCbCr422P;
+ break;
default:
- break;
+ return -EINVAL;
}
- WARN(1, "unsupported pixel format %u, using default\n", format);
- return WIN_COLOR_DEPTH_B8G8R8A8;
+ return 0;
}
static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
@@ -121,6 +183,9 @@ static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
return true;
}
+ if (planar)
+ *planar = false;
+
return false;
}
@@ -164,8 +229,8 @@ static inline u32 compute_initial_dda(unsigned int in)
return dfixed_frac(inf);
}
-static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
- const struct tegra_dc_window *window)
+static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
+ const struct tegra_dc_window *window)
{
unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
unsigned long value, flags;
@@ -274,9 +339,11 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
break;
case TEGRA_BO_TILING_MODE_BLOCK:
- DRM_ERROR("hardware doesn't support block linear mode\n");
- spin_unlock_irqrestore(&dc->lock, flags);
- return -EINVAL;
+ /*
+ * No need to handle this here because ->atomic_check
+ * will already have filtered it out.
+ */
+ break;
}
tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
@@ -332,109 +399,245 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
break;
}
- tegra_dc_window_commit(dc, index);
-
spin_unlock_irqrestore(&dc->lock, flags);
-
- return 0;
}
-static int tegra_window_plane_disable(struct drm_plane *plane)
+static void tegra_plane_destroy(struct drm_plane *plane)
{
- struct tegra_dc *dc = to_tegra_dc(plane->crtc);
struct tegra_plane *p = to_tegra_plane(plane);
- unsigned long flags;
- u32 value;
- if (!plane->crtc)
- return 0;
+ drm_plane_cleanup(plane);
+ kfree(p);
+}
- spin_lock_irqsave(&dc->lock, flags);
+static const u32 tegra_primary_plane_formats[] = {
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB565,
+};
- value = WINDOW_A_SELECT << p->index;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
+static void tegra_primary_plane_destroy(struct drm_plane *plane)
+{
+ tegra_plane_destroy(plane);
+}
- value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
- value &= ~WIN_ENABLE;
- tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
+static void tegra_plane_reset(struct drm_plane *plane)
+{
+ struct tegra_plane_state *state;
- tegra_dc_window_commit(dc, p->index);
+ if (plane->state && plane->state->fb)
+ drm_framebuffer_unreference(plane->state->fb);
- spin_unlock_irqrestore(&dc->lock, flags);
+ kfree(plane->state);
+ plane->state = NULL;
- return 0;
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state) {
+ plane->state = &state->base;
+ plane->state->plane = plane;
+ }
}
-static void tegra_plane_destroy(struct drm_plane *plane)
+static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
{
- struct tegra_plane *p = to_tegra_plane(plane);
+ struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
+ struct tegra_plane_state *copy;
- drm_plane_cleanup(plane);
- kfree(p);
+ copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
+ if (!copy)
+ return NULL;
+
+ if (copy->base.fb)
+ drm_framebuffer_reference(copy->base.fb);
+
+ return &copy->base;
}
-static const u32 tegra_primary_plane_formats[] = {
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB565,
+static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ if (state->fb)
+ drm_framebuffer_unreference(state->fb);
+
+ kfree(state);
+}
+
+static const struct drm_plane_funcs tegra_primary_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = tegra_primary_plane_destroy,
+ .reset = tegra_plane_reset,
+ .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
+ .atomic_destroy_state = tegra_plane_atomic_destroy_state,
};
-static int tegra_primary_plane_update(struct drm_plane *plane,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x,
- int crtc_y, unsigned int crtc_w,
- unsigned int crtc_h, uint32_t src_x,
- uint32_t src_y, uint32_t src_w,
- uint32_t src_h)
+static int tegra_plane_prepare_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb)
{
- struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
- struct tegra_plane *p = to_tegra_plane(plane);
- struct tegra_dc *dc = to_tegra_dc(crtc);
- struct tegra_dc_window window;
+ return 0;
+}
+
+static void tegra_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb)
+{
+}
+
+static int tegra_plane_state_add(struct tegra_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct drm_crtc_state *crtc_state;
+ struct tegra_dc_state *tegra;
+
+ /* Propagate errors from allocation or locking failures. */
+ crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ tegra = to_dc_state(crtc_state);
+
+ tegra->planes |= WIN_A_ACT_REQ << plane->index;
+
+ return 0;
+}
+
+static int tegra_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
+ struct tegra_bo_tiling *tiling = &plane_state->tiling;
+ struct tegra_plane *tegra = to_tegra_plane(plane);
+ struct tegra_dc *dc = to_tegra_dc(state->crtc);
int err;
- memset(&window, 0, sizeof(window));
- window.src.x = src_x >> 16;
- window.src.y = src_y >> 16;
- window.src.w = src_w >> 16;
- window.src.h = src_h >> 16;
- window.dst.x = crtc_x;
- window.dst.y = crtc_y;
- window.dst.w = crtc_w;
- window.dst.h = crtc_h;
- window.format = tegra_dc_format(fb->pixel_format, &window.swap);
- window.bits_per_pixel = fb->bits_per_pixel;
- window.bottom_up = tegra_fb_is_bottom_up(fb);
+ /* no need for further checks if the plane is being disabled */
+ if (!state->crtc)
+ return 0;
- err = tegra_fb_get_tiling(fb, &window.tiling);
+ err = tegra_dc_format(state->fb->pixel_format, &plane_state->format,
+ &plane_state->swap);
if (err < 0)
return err;
- window.base[0] = bo->paddr + fb->offsets[0];
- window.stride[0] = fb->pitches[0];
+ err = tegra_fb_get_tiling(state->fb, tiling);
+ if (err < 0)
+ return err;
+
+ if (tiling->mode == TEGRA_BO_TILING_MODE_BLOCK &&
+ !dc->soc->supports_block_linear) {
+ DRM_ERROR("hardware doesn't support block linear mode\n");
+ return -EINVAL;
+ }
- err = tegra_dc_setup_window(dc, p->index, &window);
+ /*
+ * Tegra doesn't support different strides for U and V planes so we
+ * error out if the user tries to display a framebuffer with such a
+ * configuration.
+ */
+ if (drm_format_num_planes(state->fb->pixel_format) > 2) {
+ if (state->fb->pitches[2] != state->fb->pitches[1]) {
+ DRM_ERROR("unsupported UV-plane configuration\n");
+ return -EINVAL;
+ }
+ }
+
+ err = tegra_plane_state_add(tegra, state);
if (err < 0)
return err;
return 0;
}
-static void tegra_primary_plane_destroy(struct drm_plane *plane)
+static void tegra_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
- tegra_window_plane_disable(plane);
- tegra_plane_destroy(plane);
+ struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
+ struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
+ struct drm_framebuffer *fb = plane->state->fb;
+ struct tegra_plane *p = to_tegra_plane(plane);
+ struct tegra_dc_window window;
+ unsigned int i;
+
+ /* rien ne va plus */
+ if (!plane->state->crtc || !plane->state->fb)
+ return;
+
+ memset(&window, 0, sizeof(window));
+ window.src.x = plane->state->src_x >> 16;
+ window.src.y = plane->state->src_y >> 16;
+ window.src.w = plane->state->src_w >> 16;
+ window.src.h = plane->state->src_h >> 16;
+ window.dst.x = plane->state->crtc_x;
+ window.dst.y = plane->state->crtc_y;
+ window.dst.w = plane->state->crtc_w;
+ window.dst.h = plane->state->crtc_h;
+ window.bits_per_pixel = fb->bits_per_pixel;
+ window.bottom_up = tegra_fb_is_bottom_up(fb);
+
+ /* copy from state */
+ window.tiling = state->tiling;
+ window.format = state->format;
+ window.swap = state->swap;
+
+ for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
+ struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
+
+ window.base[i] = bo->paddr + fb->offsets[i];
+ window.stride[i] = fb->pitches[i];
+ }
+
+ tegra_dc_setup_window(dc, p->index, &window);
}
-static const struct drm_plane_funcs tegra_primary_plane_funcs = {
- .update_plane = tegra_primary_plane_update,
- .disable_plane = tegra_window_plane_disable,
- .destroy = tegra_primary_plane_destroy,
+static void tegra_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct tegra_plane *p = to_tegra_plane(plane);
+ struct tegra_dc *dc;
+ unsigned long flags;
+ u32 value;
+
+ /* rien ne va plus */
+ if (!old_state || !old_state->crtc)
+ return;
+
+ dc = to_tegra_dc(old_state->crtc);
+
+ spin_lock_irqsave(&dc->lock, flags);
+
+ value = WINDOW_A_SELECT << p->index;
+ tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
+
+ value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
+ value &= ~WIN_ENABLE;
+ tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
+
+ spin_unlock_irqrestore(&dc->lock, flags);
+}
+
+static const struct drm_plane_helper_funcs tegra_primary_plane_helper_funcs = {
+ .prepare_fb = tegra_plane_prepare_fb,
+ .cleanup_fb = tegra_plane_cleanup_fb,
+ .atomic_check = tegra_plane_atomic_check,
+ .atomic_update = tegra_plane_atomic_update,
+ .atomic_disable = tegra_plane_atomic_disable,
};
static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
struct tegra_dc *dc)
{
+ /*
+ * Ideally this would use drm_crtc_mask(), but that would require the
+ * CRTC to already be in the mode_config's list of CRTCs. However, it
+ * will only be added to that list in the drm_crtc_init_with_planes()
+ * (in tegra_dc_init()), which in turn requires registration of these
+ * planes. So we have ourselves a nice little chicken and egg problem
+ * here.
+ *
+ * We work around this by manually creating the mask from the number
+ * of CRTCs that have been registered, and should therefore always be
+ * the same as drm_crtc_index() after registration.
+ */
+ unsigned long possible_crtcs = 1 << drm->mode_config.num_crtc;
struct tegra_plane *plane;
unsigned int num_formats;
const u32 *formats;
@@ -447,7 +650,7 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
num_formats = ARRAY_SIZE(tegra_primary_plane_formats);
formats = tegra_primary_plane_formats;
- err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
+ err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
&tegra_primary_plane_funcs, formats,
num_formats, DRM_PLANE_TYPE_PRIMARY);
if (err < 0) {
@@ -455,6 +658,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
return ERR_PTR(err);
}
+ drm_plane_helper_add(&plane->base, &tegra_primary_plane_helper_funcs);
+
return &plane->base;
}
@@ -462,27 +667,49 @@ static const u32 tegra_cursor_plane_formats[] = {
DRM_FORMAT_RGBA8888,
};
-static int tegra_cursor_plane_update(struct drm_plane *plane,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x,
- int crtc_y, unsigned int crtc_w,
- unsigned int crtc_h, uint32_t src_x,
- uint32_t src_y, uint32_t src_w,
- uint32_t src_h)
+static int tegra_cursor_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
{
- struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
- struct tegra_dc *dc = to_tegra_dc(crtc);
- u32 value = CURSOR_CLIP_DISPLAY;
+ struct tegra_plane *tegra = to_tegra_plane(plane);
+ int err;
+
+ /* no need for further checks if the plane is being disabled */
+ if (!state->crtc)
+ return 0;
/* scaling not supported for cursor */
- if ((src_w >> 16 != crtc_w) || (src_h >> 16 != crtc_h))
+ if ((state->src_w >> 16 != state->crtc_w) ||
+ (state->src_h >> 16 != state->crtc_h))
return -EINVAL;
/* only square cursors supported */
- if (src_w != src_h)
+ if (state->src_w != state->src_h)
return -EINVAL;
- switch (crtc_w) {
+ if (state->crtc_w != 32 && state->crtc_w != 64 &&
+ state->crtc_w != 128 && state->crtc_w != 256)
+ return -EINVAL;
+
+ err = tegra_plane_state_add(tegra, state);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static void tegra_cursor_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct tegra_bo *bo = tegra_fb_get_plane(plane->state->fb, 0);
+ struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
+ struct drm_plane_state *state = plane->state;
+ u32 value = CURSOR_CLIP_DISPLAY;
+
+ /* rien ne va plus */
+ if (!plane->state->crtc || !plane->state->fb)
+ return;
+
+ switch (state->crtc_w) {
case 32:
value |= CURSOR_SIZE_32x32;
break;
@@ -500,7 +727,9 @@ static int tegra_cursor_plane_update(struct drm_plane *plane,
break;
default:
- return -EINVAL;
+ WARN(1, "cursor size %ux%u not supported\n", state->crtc_w,
+ state->crtc_h);
+ return;
}
value |= (bo->paddr >> 10) & 0x3fffff;
@@ -526,38 +755,43 @@ static int tegra_cursor_plane_update(struct drm_plane *plane,
tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL);
/* position the cursor */
- value = (crtc_y & 0x3fff) << 16 | (crtc_x & 0x3fff);
+ value = (state->crtc_y & 0x3fff) << 16 | (state->crtc_x & 0x3fff);
tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
- /* apply changes */
- tegra_dc_cursor_commit(dc);
- tegra_dc_commit(dc);
-
- return 0;
}
-static int tegra_cursor_plane_disable(struct drm_plane *plane)
+static void tegra_cursor_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
- struct tegra_dc *dc = to_tegra_dc(plane->crtc);
+ struct tegra_dc *dc;
u32 value;
- if (!plane->crtc)
- return 0;
+ /* rien ne va plus */
+ if (!old_state || !old_state->crtc)
+ return;
+
+ dc = to_tegra_dc(old_state->crtc);
value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
value &= ~CURSOR_ENABLE;
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
-
- tegra_dc_cursor_commit(dc);
- tegra_dc_commit(dc);
-
- return 0;
}
static const struct drm_plane_funcs tegra_cursor_plane_funcs = {
- .update_plane = tegra_cursor_plane_update,
- .disable_plane = tegra_cursor_plane_disable,
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
.destroy = tegra_plane_destroy,
+ .reset = tegra_plane_reset,
+ .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
+ .atomic_destroy_state = tegra_plane_atomic_destroy_state,
+};
+
+static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs = {
+ .prepare_fb = tegra_plane_prepare_fb,
+ .cleanup_fb = tegra_plane_cleanup_fb,
+ .atomic_check = tegra_cursor_atomic_check,
+ .atomic_update = tegra_cursor_atomic_update,
+ .atomic_disable = tegra_cursor_atomic_disable,
};
static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
@@ -572,6 +806,13 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
if (!plane)
return ERR_PTR(-ENOMEM);
+ /*
+ * We'll treat the cursor as an overlay plane with index 6 here so
+ * that the update and activation request bits in DC_CMD_STATE_CONTROL
+ * match up.
+ */
+ plane->index = 6;
+
num_formats = ARRAY_SIZE(tegra_cursor_plane_formats);
formats = tegra_cursor_plane_formats;
@@ -583,71 +824,23 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
return ERR_PTR(err);
}
- return &plane->base;
-}
-
-static int tegra_overlay_plane_update(struct drm_plane *plane,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x,
- int crtc_y, unsigned int crtc_w,
- unsigned int crtc_h, uint32_t src_x,
- uint32_t src_y, uint32_t src_w,
- uint32_t src_h)
-{
- struct tegra_plane *p = to_tegra_plane(plane);
- struct tegra_dc *dc = to_tegra_dc(crtc);
- struct tegra_dc_window window;
- unsigned int i;
- int err;
-
- memset(&window, 0, sizeof(window));
- window.src.x = src_x >> 16;
- window.src.y = src_y >> 16;
- window.src.w = src_w >> 16;
- window.src.h = src_h >> 16;
- window.dst.x = crtc_x;
- window.dst.y = crtc_y;
- window.dst.w = crtc_w;
- window.dst.h = crtc_h;
- window.format = tegra_dc_format(fb->pixel_format, &window.swap);
- window.bits_per_pixel = fb->bits_per_pixel;
- window.bottom_up = tegra_fb_is_bottom_up(fb);
-
- err = tegra_fb_get_tiling(fb, &window.tiling);
- if (err < 0)
- return err;
-
- for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
- struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
-
- window.base[i] = bo->paddr + fb->offsets[i];
-
- /*
- * Tegra doesn't support different strides for U and V planes
- * so we display a warning if the user tries to display a
- * framebuffer with such a configuration.
- */
- if (i >= 2) {
- if (fb->pitches[i] != window.stride[1])
- DRM_ERROR("unsupported UV-plane configuration\n");
- } else {
- window.stride[i] = fb->pitches[i];
- }
- }
+ drm_plane_helper_add(&plane->base, &tegra_cursor_plane_helper_funcs);
- return tegra_dc_setup_window(dc, p->index, &window);
+ return &plane->base;
}
static void tegra_overlay_plane_destroy(struct drm_plane *plane)
{
- tegra_window_plane_disable(plane);
tegra_plane_destroy(plane);
}
static const struct drm_plane_funcs tegra_overlay_plane_funcs = {
- .update_plane = tegra_overlay_plane_update,
- .disable_plane = tegra_window_plane_disable,
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
.destroy = tegra_overlay_plane_destroy,
+ .reset = tegra_plane_reset,
+ .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
+ .atomic_destroy_state = tegra_plane_atomic_destroy_state,
};
static const uint32_t tegra_overlay_plane_formats[] = {
@@ -660,6 +853,14 @@ static const uint32_t tegra_overlay_plane_formats[] = {
DRM_FORMAT_YUV422,
};
+static const struct drm_plane_helper_funcs tegra_overlay_plane_helper_funcs = {
+ .prepare_fb = tegra_plane_prepare_fb,
+ .cleanup_fb = tegra_plane_cleanup_fb,
+ .atomic_check = tegra_plane_atomic_check,
+ .atomic_update = tegra_plane_atomic_update,
+ .atomic_disable = tegra_plane_atomic_disable,
+};
+
static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
struct tegra_dc *dc,
unsigned int index)
@@ -686,6 +887,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
return ERR_PTR(err);
}
+ drm_plane_helper_add(&plane->base, &tegra_overlay_plane_helper_funcs);
+
return &plane->base;
}
@@ -703,99 +906,6 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
return 0;
}
-static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
- struct drm_framebuffer *fb)
-{
- struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
- unsigned int h_offset = 0, v_offset = 0;
- struct tegra_bo_tiling tiling;
- unsigned long value, flags;
- unsigned int format, swap;
- int err;
-
- err = tegra_fb_get_tiling(fb, &tiling);
- if (err < 0)
- return err;
-
- spin_lock_irqsave(&dc->lock, flags);
-
- tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
-
- value = fb->offsets[0] + y * fb->pitches[0] +
- x * fb->bits_per_pixel / 8;
-
- tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
- tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
-
- format = tegra_dc_format(fb->pixel_format, &swap);
- tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);
- tegra_dc_writel(dc, swap, DC_WIN_BYTE_SWAP);
-
- if (dc->soc->supports_block_linear) {
- unsigned long height = tiling.value;
-
- switch (tiling.mode) {
- case TEGRA_BO_TILING_MODE_PITCH:
- value = DC_WINBUF_SURFACE_KIND_PITCH;
- break;
-
- case TEGRA_BO_TILING_MODE_TILED:
- value = DC_WINBUF_SURFACE_KIND_TILED;
- break;
-
- case TEGRA_BO_TILING_MODE_BLOCK:
- value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height) |
- DC_WINBUF_SURFACE_KIND_BLOCK;
- break;
- }
-
- tegra_dc_writel(dc, value, DC_WINBUF_SURFACE_KIND);
- } else {
- switch (tiling.mode) {
- case TEGRA_BO_TILING_MODE_PITCH:
- value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
- DC_WIN_BUFFER_ADDR_MODE_LINEAR;
- break;
-
- case TEGRA_BO_TILING_MODE_TILED:
- value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
- DC_WIN_BUFFER_ADDR_MODE_TILE;
- break;
-
- case TEGRA_BO_TILING_MODE_BLOCK:
- DRM_ERROR("hardware doesn't support block linear mode\n");
- spin_unlock_irqrestore(&dc->lock, flags);
- return -EINVAL;
- }
-
- tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
- }
-
- /* make sure bottom-up buffers are properly displayed */
- if (tegra_fb_is_bottom_up(fb)) {
- value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
- value |= V_DIRECTION;
- tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
-
- v_offset += fb->height - 1;
- } else {
- value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
- value &= ~V_DIRECTION;
- tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
- }
-
- tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
- tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
-
- value = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
- tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
-
- spin_unlock_irqrestore(&dc->lock, flags);
-
- return 0;
-}
-
void tegra_dc_enable_vblank(struct tegra_dc *dc)
{
unsigned long value, flags;
@@ -838,7 +948,7 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
bo = tegra_fb_get_plane(crtc->primary->fb, 0);
- spin_lock_irqsave(&dc->lock, flags);
+ spin_lock(&dc->lock);
/* check if new start address has been latched */
tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -846,7 +956,7 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
- spin_unlock_irqrestore(&dc->lock, flags);
+ spin_unlock(&dc->lock);
if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
drm_crtc_send_vblank_event(crtc, dc->event);
@@ -874,64 +984,130 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
spin_unlock_irqrestore(&drm->event_lock, flags);
}
-static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
+static void tegra_dc_destroy(struct drm_crtc *crtc)
{
- unsigned int pipe = drm_crtc_index(crtc);
- struct tegra_dc *dc = to_tegra_dc(crtc);
-
- if (dc->event)
- return -EBUSY;
+ drm_crtc_cleanup(crtc);
+}
- if (event) {
- event->pipe = pipe;
- dc->event = event;
- drm_crtc_vblank_get(crtc);
- }
+static void tegra_crtc_reset(struct drm_crtc *crtc)
+{
+ struct tegra_dc_state *state;
- tegra_dc_set_base(dc, 0, 0, fb);
- crtc->primary->fb = fb;
+ kfree(crtc->state);
+ crtc->state = NULL;
- return 0;
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state)
+ crtc->state = &state->base;
}
-static void drm_crtc_clear(struct drm_crtc *crtc)
+static struct drm_crtc_state *
+tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
{
- memset(crtc, 0, sizeof(*crtc));
+ struct tegra_dc_state *state = to_dc_state(crtc->state);
+ struct tegra_dc_state *copy;
+
+ copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
+ if (!copy)
+ return NULL;
+
+ copy->base.mode_changed = false;
+ copy->base.planes_changed = false;
+ copy->base.event = NULL;
+
+ return &copy->base;
}
-static void tegra_dc_destroy(struct drm_crtc *crtc)
+static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
{
- drm_crtc_cleanup(crtc);
- drm_crtc_clear(crtc);
+ kfree(state);
}
static const struct drm_crtc_funcs tegra_crtc_funcs = {
- .page_flip = tegra_dc_page_flip,
- .set_config = drm_crtc_helper_set_config,
+ .page_flip = drm_atomic_helper_page_flip,
+ .set_config = drm_atomic_helper_set_config,
.destroy = tegra_dc_destroy,
+ .reset = tegra_crtc_reset,
+ .atomic_duplicate_state = tegra_crtc_atomic_duplicate_state,
+ .atomic_destroy_state = tegra_crtc_atomic_destroy_state,
};
+static void tegra_dc_stop(struct tegra_dc *dc)
+{
+ u32 value;
+
+ /* stop the display controller */
+ value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
+ value &= ~DISP_CTRL_MODE_MASK;
+ tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
+
+ tegra_dc_commit(dc);
+}
+
+static bool tegra_dc_idle(struct tegra_dc *dc)
+{
+ u32 value;
+
+ value = tegra_dc_readl_active(dc, DC_CMD_DISPLAY_COMMAND);
+
+ return (value & DISP_CTRL_MODE_MASK) == 0;
+}
+
+static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout)
+{
+ timeout = jiffies + msecs_to_jiffies(timeout);
+
+ while (time_before(jiffies, timeout)) {
+ if (tegra_dc_idle(dc))
+ return 0;
+
+ usleep_range(1000, 2000);
+ }
+
+ dev_dbg(dc->dev, "timeout waiting for DC to become idle\n");
+ return -ETIMEDOUT;
+}
+
static void tegra_crtc_disable(struct drm_crtc *crtc)
{
struct tegra_dc *dc = to_tegra_dc(crtc);
- struct drm_device *drm = crtc->dev;
- struct drm_plane *plane;
+ u32 value;
- drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) {
- if (plane->crtc == crtc) {
- tegra_window_plane_disable(plane);
- plane->crtc = NULL;
+ if (!tegra_dc_idle(dc)) {
+ tegra_dc_stop(dc);
- if (plane->fb) {
- drm_framebuffer_unreference(plane->fb);
- plane->fb = NULL;
- }
- }
+ /*
+ * Ignore the return value, there isn't anything useful to do
+ * in case this fails.
+ */
+ tegra_dc_wait_idle(dc, 100);
+ }
+
+ /*
+ * This should really be part of the RGB encoder driver, but clearing
+ * these bits has the side-effect of stopping the display controller.
+ * When that happens no VBLANK interrupts will be raised. At the same
+ * time the encoder is disabled before the display controller, so the
+ * above code is always going to timeout waiting for the controller
+ * to go idle.
+ *
+ * Given the close coupling between the RGB encoder and the display
+ * controller doing it here is still kind of okay. None of the other
+ * encoder drivers require these bits to be cleared.
+ *
+ * XXX: Perhaps given that the display controller is switched off at
+ * this point anyway maybe clearing these bits isn't even useful for
+ * the RGB encoder?
+ */
+ if (dc->rgb) {
+ value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
+ value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
+ PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
+ tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
}
drm_crtc_vblank_off(crtc);
- tegra_dc_commit(dc);
}
static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -971,33 +1147,15 @@ static int tegra_dc_set_timings(struct tegra_dc *dc,
return 0;
}
-static int tegra_crtc_setup_clk(struct drm_crtc *crtc,
- struct drm_display_mode *mode)
+int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent,
+ unsigned long pclk, unsigned int div)
{
- unsigned long pclk = mode->clock * 1000;
- struct tegra_dc *dc = to_tegra_dc(crtc);
- struct tegra_output *output = NULL;
- struct drm_encoder *encoder;
- unsigned int div;
u32 value;
- long err;
-
- list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head)
- if (encoder->crtc == crtc) {
- output = encoder_to_output(encoder);
- break;
- }
-
- if (!output)
- return -ENODEV;
+ int err;
- /*
- * This assumes that the parent clock is pll_d_out0 or pll_d2_out
- * respectively, each of which divides the base pll_d by 2.
- */
- err = tegra_output_setup_clock(output, dc->clk, pclk, &div);
+ err = clk_set_parent(dc->clk, parent);
if (err < 0) {
- dev_err(dc->dev, "failed to setup clock: %ld\n", err);
+ dev_err(dc->dev, "failed to set parent clock: %d\n", err);
return err;
}
@@ -1009,26 +1167,69 @@ static int tegra_crtc_setup_clk(struct drm_crtc *crtc,
return 0;
}
-static int tegra_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted,
- int x, int y, struct drm_framebuffer *old_fb)
+int tegra_dc_state_setup_clock(struct tegra_dc *dc,
+ struct drm_crtc_state *crtc_state,
+ struct clk *clk, unsigned long pclk,
+ unsigned int div)
+{
+ struct tegra_dc_state *state = to_dc_state(crtc_state);
+
+ state->clk = clk;
+ state->pclk = pclk;
+ state->div = div;
+
+ return 0;
+}
+
+static void tegra_dc_commit_state(struct tegra_dc *dc,
+ struct tegra_dc_state *state)
{
- struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0);
- struct tegra_dc *dc = to_tegra_dc(crtc);
- struct tegra_dc_window window;
u32 value;
int err;
- err = tegra_crtc_setup_clk(crtc, mode);
- if (err) {
- dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err);
- return err;
+ err = clk_set_parent(dc->clk, state->clk);
+ if (err < 0)
+ dev_err(dc->dev, "failed to set parent clock: %d\n", err);
+
+ /*
+ * Outputs may not want to change the parent clock rate. This is only
+ * relevant to Tegra20 where only a single display PLL is available.
+ * Since that PLL would typically be used for HDMI, an internal LVDS
+ * panel would need to be driven by some other clock such as PLL_P
+ * which is shared with other peripherals. Changing the clock rate
+ * should therefore be avoided.
+ */
+ if (state->pclk > 0) {
+ err = clk_set_rate(state->clk, state->pclk);
+ if (err < 0)
+ dev_err(dc->dev,
+ "failed to set clock rate to %lu Hz\n",
+ state->pclk);
}
+ DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk),
+ state->div);
+ DRM_DEBUG_KMS("pclk: %lu\n", state->pclk);
+
+ value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1;
+ tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
+}
+
+static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+ struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+ struct tegra_dc_state *state = to_dc_state(crtc->state);
+ struct tegra_dc *dc = to_tegra_dc(crtc);
+ u32 value;
+
+ tegra_dc_commit_state(dc, state);
+
/* program display mode */
tegra_dc_set_timings(dc, mode);
+ if (dc->soc->supports_border_color)
+ tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
+
/* interlacing isn't supported yet, so disable it */
if (dc->soc->supports_interlacing) {
value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL);
@@ -1036,35 +1237,17 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
}
- /* setup window parameters */
- memset(&window, 0, sizeof(window));
- window.src.x = 0;
- window.src.y = 0;
- window.src.w = mode->hdisplay;
- window.src.h = mode->vdisplay;
- window.dst.x = 0;
- window.dst.y = 0;
- window.dst.w = mode->hdisplay;
- window.dst.h = mode->vdisplay;
- window.format = tegra_dc_format(crtc->primary->fb->pixel_format,
- &window.swap);
- window.bits_per_pixel = crtc->primary->fb->bits_per_pixel;
- window.stride[0] = crtc->primary->fb->pitches[0];
- window.base[0] = bo->paddr;
-
- err = tegra_dc_setup_window(dc, 0, &window);
- if (err < 0)
- dev_err(dc->dev, "failed to enable root plane\n");
+ value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
+ value &= ~DISP_CTRL_MODE_MASK;
+ value |= DISP_CTRL_MODE_C_DISPLAY;
+ tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
- return 0;
-}
+ value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
+ value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
+ PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
+ tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
-static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
-{
- struct tegra_dc *dc = to_tegra_dc(crtc);
-
- return tegra_dc_set_base(dc, x, y, crtc->primary->fb);
+ tegra_dc_commit(dc);
}
static void tegra_crtc_prepare(struct drm_crtc *crtc)
@@ -1075,10 +1258,6 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
drm_crtc_vblank_off(crtc);
- /* hardware initialization */
- reset_control_deassert(dc->rst);
- usleep_range(10000, 20000);
-
if (dc->pipe)
syncpt = SYNCPT_VBLANK1;
else
@@ -1113,24 +1292,49 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
static void tegra_crtc_commit(struct drm_crtc *crtc)
{
+ drm_crtc_vblank_on(crtc);
+}
+
+static int tegra_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ return 0;
+}
+
+static void tegra_crtc_atomic_begin(struct drm_crtc *crtc)
+{
struct tegra_dc *dc = to_tegra_dc(crtc);
- drm_crtc_vblank_on(crtc);
- tegra_dc_commit(dc);
+ if (crtc->state->event) {
+ crtc->state->event->pipe = drm_crtc_index(crtc);
+
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+ dc->event = crtc->state->event;
+ crtc->state->event = NULL;
+ }
}
-static void tegra_crtc_load_lut(struct drm_crtc *crtc)
+static void tegra_crtc_atomic_flush(struct drm_crtc *crtc)
{
+ struct tegra_dc_state *state = to_dc_state(crtc->state);
+ struct tegra_dc *dc = to_tegra_dc(crtc);
+
+ tegra_dc_writel(dc, state->planes << 8, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, state->planes, DC_CMD_STATE_CONTROL);
}
static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
.disable = tegra_crtc_disable,
.mode_fixup = tegra_crtc_mode_fixup,
- .mode_set = tegra_crtc_mode_set,
- .mode_set_base = tegra_crtc_mode_set_base,
+ .mode_set = drm_helper_crtc_mode_set,
+ .mode_set_nofb = tegra_crtc_mode_set_nofb,
+ .mode_set_base = drm_helper_crtc_mode_set_base,
.prepare = tegra_crtc_prepare,
.commit = tegra_crtc_commit,
- .load_lut = tegra_crtc_load_lut,
+ .atomic_check = tegra_crtc_atomic_check,
+ .atomic_begin = tegra_crtc_atomic_begin,
+ .atomic_flush = tegra_crtc_atomic_flush,
};
static irqreturn_t tegra_dc_irq(int irq, void *data)
@@ -1576,6 +1780,7 @@ static const struct host1x_client_ops dc_client_ops = {
};
static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
+ .supports_border_color = true,
.supports_interlacing = false,
.supports_cursor = false,
.supports_block_linear = false,
@@ -1584,6 +1789,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
};
static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
+ .supports_border_color = true,
.supports_interlacing = false,
.supports_cursor = false,
.supports_block_linear = false,
@@ -1592,6 +1798,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
};
static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
+ .supports_border_color = true,
.supports_interlacing = false,
.supports_cursor = false,
.supports_block_linear = false,
@@ -1600,6 +1807,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
};
static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
+ .supports_border_color = false,
.supports_interlacing = true,
.supports_cursor = true,
.supports_block_linear = true,
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index d4f827593dfa..7dd328d77996 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -10,6 +10,9 @@
#include <linux/host1x.h>
#include <linux/iommu.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+
#include "drm.h"
#include "gem.h"
@@ -24,6 +27,92 @@ struct tegra_drm_file {
struct list_head contexts;
};
+static void tegra_atomic_schedule(struct tegra_drm *tegra,
+ struct drm_atomic_state *state)
+{
+ tegra->commit.state = state;
+ schedule_work(&tegra->commit.work);
+}
+
+static void tegra_atomic_complete(struct tegra_drm *tegra,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *drm = tegra->drm;
+
+ /*
+ * Everything below can be run asynchronously without the need to grab
+ * any modeset locks at all under one condition: It must be guaranteed
+ * that the asynchronous work has either been cancelled (if the driver
+ * supports it, which at least requires that the framebuffers get
+ * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
+ * before the new state gets committed on the software side with
+ * drm_atomic_helper_swap_state().
+ *
+ * This scheme allows new atomic state updates to be prepared and
+ * checked in parallel to the asynchronous completion of the previous
+ * update. Which is important since compositors need to figure out the
+ * composition of the next frame right after having submitted the
+ * current layout.
+ */
+
+ drm_atomic_helper_commit_pre_planes(drm, state);
+ drm_atomic_helper_commit_planes(drm, state);
+ drm_atomic_helper_commit_post_planes(drm, state);
+
+ drm_atomic_helper_wait_for_vblanks(drm, state);
+
+ drm_atomic_helper_cleanup_planes(drm, state);
+ drm_atomic_state_free(state);
+}
+
+static void tegra_atomic_work(struct work_struct *work)
+{
+ struct tegra_drm *tegra = container_of(work, struct tegra_drm,
+ commit.work);
+
+ tegra_atomic_complete(tegra, tegra->commit.state);
+}
+
+static int tegra_atomic_commit(struct drm_device *drm,
+ struct drm_atomic_state *state, bool async)
+{
+ struct tegra_drm *tegra = drm->dev_private;
+ int err;
+
+ err = drm_atomic_helper_prepare_planes(drm, state);
+ if (err)
+ return err;
+
+ /* serialize outstanding asynchronous commits */
+ mutex_lock(&tegra->commit.lock);
+ flush_work(&tegra->commit.work);
+
+ /*
+ * This is the point of no return - everything below never fails except
+ * when the hw goes bonghits. Which means we can commit the new state on
+ * the software side now.
+ */
+
+ drm_atomic_helper_swap_state(drm, state);
+
+ if (async)
+ tegra_atomic_schedule(tegra, state);
+ else
+ tegra_atomic_complete(tegra, state);
+
+ mutex_unlock(&tegra->commit.lock);
+ return 0;
+}
+
+static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
+ .fb_create = tegra_fb_create,
+#ifdef CONFIG_DRM_TEGRA_FBDEV
+ .output_poll_changed = tegra_fb_output_poll_changed,
+#endif
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = tegra_atomic_commit,
+};
+
static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
{
struct host1x_device *device = to_host1x_device(drm->dev);
@@ -36,8 +125,8 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
if (iommu_present(&platform_bus_type)) {
tegra->domain = iommu_domain_alloc(&platform_bus_type);
- if (IS_ERR(tegra->domain)) {
- err = PTR_ERR(tegra->domain);
+ if (!tegra->domain) {
+ err = -ENOMEM;
goto free;
}
@@ -47,11 +136,23 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
mutex_init(&tegra->clients_lock);
INIT_LIST_HEAD(&tegra->clients);
+
+ mutex_init(&tegra->commit.lock);
+ INIT_WORK(&tegra->commit.work, tegra_atomic_work);
+
drm->dev_private = tegra;
tegra->drm = drm;
drm_mode_config_init(drm);
+ drm->mode_config.min_width = 0;
+ drm->mode_config.min_height = 0;
+
+ drm->mode_config.max_width = 4096;
+ drm->mode_config.max_height = 4096;
+
+ drm->mode_config.funcs = &tegra_drm_mode_funcs;
+
err = tegra_drm_fb_prepare(drm);
if (err < 0)
goto config;
@@ -62,6 +163,8 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
if (err < 0)
goto fbdev;
+ drm_mode_config_reset(drm);
+
/*
* We don't use the drm_irq_install() helpers provided by the DRM
* core, so we need to set this manually in order to allow the
@@ -106,8 +209,8 @@ static int tegra_drm_unload(struct drm_device *drm)
drm_kms_helper_poll_fini(drm);
tegra_drm_fb_exit(drm);
- drm_vblank_cleanup(drm);
drm_mode_config_cleanup(drm);
+ drm_vblank_cleanup(drm);
err = host1x_device_exit(device);
if (err < 0)
@@ -190,7 +293,7 @@ static int host1x_reloc_copy_from_user(struct host1x_reloc *dest,
if (err < 0)
return err;
- err = get_user(dest->target.offset, &src->cmdbuf.offset);
+ err = get_user(dest->target.offset, &src->target.offset);
if (err < 0)
return err;
@@ -893,6 +996,30 @@ static int host1x_drm_remove(struct host1x_device *dev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int host1x_drm_suspend(struct device *dev)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+
+ drm_kms_helper_poll_disable(drm);
+
+ return 0;
+}
+
+static int host1x_drm_resume(struct device *dev)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+
+ drm_kms_helper_poll_enable(drm);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops host1x_drm_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(host1x_drm_suspend, host1x_drm_resume)
+};
+
static const struct of_device_id host1x_drm_subdevs[] = {
{ .compatible = "nvidia,tegra20-dc", },
{ .compatible = "nvidia,tegra20-hdmi", },
@@ -912,7 +1039,10 @@ static const struct of_device_id host1x_drm_subdevs[] = {
};
static struct host1x_driver host1x_drm_driver = {
- .name = "drm",
+ .driver = {
+ .name = "drm",
+ .pm = &host1x_drm_pm_ops,
+ },
.probe = host1x_drm_probe,
.remove = host1x_drm_remove,
.subdevs = host1x_drm_subdevs,
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 3a3b2e7b5b3f..8cb2dfeaa957 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -50,6 +50,12 @@ struct tegra_drm {
#endif
unsigned int pitch_align;
+
+ struct {
+ struct drm_atomic_state *state;
+ struct work_struct work;
+ struct mutex lock;
+ } commit;
};
struct tegra_drm_client;
@@ -164,45 +170,31 @@ struct tegra_dc_window {
unsigned int h;
} dst;
unsigned int bits_per_pixel;
- unsigned int format;
- unsigned int swap;
unsigned int stride[2];
unsigned long base[3];
bool bottom_up;
struct tegra_bo_tiling tiling;
+ u32 format;
+ u32 swap;
};
/* from dc.c */
void tegra_dc_enable_vblank(struct tegra_dc *dc);
void tegra_dc_disable_vblank(struct tegra_dc *dc);
void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
-
-struct tegra_output_ops {
- int (*enable)(struct tegra_output *output);
- int (*disable)(struct tegra_output *output);
- int (*setup_clock)(struct tegra_output *output, struct clk *clk,
- unsigned long pclk, unsigned int *div);
- int (*check_mode)(struct tegra_output *output,
- struct drm_display_mode *mode,
- enum drm_mode_status *status);
- enum drm_connector_status (*detect)(struct tegra_output *output);
-};
-
-enum tegra_output_type {
- TEGRA_OUTPUT_RGB,
- TEGRA_OUTPUT_HDMI,
- TEGRA_OUTPUT_DSI,
- TEGRA_OUTPUT_EDP,
-};
+void tegra_dc_commit(struct tegra_dc *dc);
+int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent,
+ unsigned long pclk, unsigned int div);
+int tegra_dc_state_setup_clock(struct tegra_dc *dc,
+ struct drm_crtc_state *crtc_state,
+ struct clk *clk, unsigned long pclk,
+ unsigned int div);
struct tegra_output {
struct device_node *of_node;
struct device *dev;
- const struct tegra_output_ops *ops;
- enum tegra_output_type type;
-
struct drm_panel *panel;
struct i2c_adapter *ddc;
const struct edid *edid;
@@ -223,42 +215,6 @@ static inline struct tegra_output *connector_to_output(struct drm_connector *c)
return container_of(c, struct tegra_output, connector);
}
-static inline int tegra_output_enable(struct tegra_output *output)
-{
- if (output && output->ops && output->ops->enable)
- return output->ops->enable(output);
-
- return output ? -ENOSYS : -EINVAL;
-}
-
-static inline int tegra_output_disable(struct tegra_output *output)
-{
- if (output && output->ops && output->ops->disable)
- return output->ops->disable(output);
-
- return output ? -ENOSYS : -EINVAL;
-}
-
-static inline int tegra_output_setup_clock(struct tegra_output *output,
- struct clk *clk, unsigned long pclk,
- unsigned int *div)
-{
- if (output && output->ops && output->ops->setup_clock)
- return output->ops->setup_clock(output, clk, pclk, div);
-
- return output ? -ENOSYS : -EINVAL;
-}
-
-static inline int tegra_output_check_mode(struct tegra_output *output,
- struct drm_display_mode *mode,
- enum drm_mode_status *status)
-{
- if (output && output->ops && output->ops->check_mode)
- return output->ops->check_mode(output, mode, status);
-
- return output ? -ENOSYS : -EINVAL;
-}
-
/* from rgb.c */
int tegra_dc_rgb_probe(struct tegra_dc *dc);
int tegra_dc_rgb_remove(struct tegra_dc *dc);
@@ -267,9 +223,18 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
/* from output.c */
int tegra_output_probe(struct tegra_output *output);
-int tegra_output_remove(struct tegra_output *output);
+void tegra_output_remove(struct tegra_output *output);
int tegra_output_init(struct drm_device *drm, struct tegra_output *output);
-int tegra_output_exit(struct tegra_output *output);
+void tegra_output_exit(struct tegra_output *output);
+
+int tegra_output_connector_get_modes(struct drm_connector *connector);
+struct drm_encoder *
+tegra_output_connector_best_encoder(struct drm_connector *connector);
+enum drm_connector_status
+tegra_output_connector_detect(struct drm_connector *connector, bool force);
+void tegra_output_connector_destroy(struct drm_connector *connector);
+
+void tegra_output_encoder_destroy(struct drm_encoder *encoder);
/* from dpaux.c */
struct tegra_dpaux;
@@ -291,12 +256,16 @@ struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer,
struct tegra_bo_tiling *tiling);
+struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
+ struct drm_file *file,
+ struct drm_mode_fb_cmd2 *cmd);
int tegra_drm_fb_prepare(struct drm_device *drm);
void tegra_drm_fb_free(struct drm_device *drm);
int tegra_drm_fb_init(struct drm_device *drm);
void tegra_drm_fb_exit(struct drm_device *drm);
#ifdef CONFIG_DRM_TEGRA_FBDEV
void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
+void tegra_fb_output_poll_changed(struct drm_device *drm);
#endif
extern struct platform_driver tegra_dc_driver;
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 33f67fd601c6..ed970f622903 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -17,6 +17,7 @@
#include <linux/regulator/consumer.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
@@ -27,6 +28,28 @@
#include "dsi.h"
#include "mipi-phy.h"
+struct tegra_dsi_state {
+ struct drm_connector_state base;
+
+ struct mipi_dphy_timing timing;
+ unsigned long period;
+
+ unsigned int vrefresh;
+ unsigned int lanes;
+ unsigned long pclk;
+ unsigned long bclk;
+
+ enum tegra_dsi_format format;
+ unsigned int mul;
+ unsigned int div;
+};
+
+static inline struct tegra_dsi_state *
+to_dsi_state(struct drm_connector_state *state)
+{
+ return container_of(state, struct tegra_dsi_state, base);
+}
+
struct tegra_dsi {
struct host1x_client client;
struct tegra_output output;
@@ -51,7 +74,6 @@ struct tegra_dsi {
struct mipi_dsi_host host;
struct regulator *vdd;
- bool enabled;
unsigned int video_fifo_depth;
unsigned int host_fifo_depth;
@@ -77,13 +99,17 @@ static inline struct tegra_dsi *to_dsi(struct tegra_output *output)
return container_of(output, struct tegra_dsi, output);
}
-static inline unsigned long tegra_dsi_readl(struct tegra_dsi *dsi,
- unsigned long reg)
+static struct tegra_dsi_state *tegra_dsi_get_state(struct tegra_dsi *dsi)
+{
+ return to_dsi_state(dsi->output.connector.state);
+}
+
+static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned long reg)
{
return readl(dsi->regs + (reg << 2));
}
-static inline void tegra_dsi_writel(struct tegra_dsi *dsi, unsigned long value,
+static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value,
unsigned long reg)
{
writel(value, dsi->regs + (reg << 2));
@@ -95,7 +121,7 @@ static int tegra_dsi_show_regs(struct seq_file *s, void *data)
struct tegra_dsi *dsi = node->info_ent->data;
#define DUMP_REG(name) \
- seq_printf(s, "%-32s %#05x %08lx\n", #name, name, \
+ seq_printf(s, "%-32s %#05x %08x\n", #name, name, \
tegra_dsi_readl(dsi, name))
DUMP_REG(DSI_INCR_SYNCPT);
@@ -230,7 +256,7 @@ remove:
return err;
}
-static int tegra_dsi_debugfs_exit(struct tegra_dsi *dsi)
+static void tegra_dsi_debugfs_exit(struct tegra_dsi *dsi)
{
drm_debugfs_remove_files(dsi->debugfs_files, ARRAY_SIZE(debugfs_files),
dsi->minor);
@@ -241,8 +267,6 @@ static int tegra_dsi_debugfs_exit(struct tegra_dsi *dsi)
debugfs_remove(dsi->debugfs);
dsi->debugfs = NULL;
-
- return 0;
}
#define PKT_ID0(id) ((((id) & 0x3f) << 3) | (1 << 9))
@@ -338,61 +362,36 @@ static const u32 pkt_seq_command_mode[NUM_PKT_SEQ] = {
[11] = 0,
};
-static int tegra_dsi_set_phy_timing(struct tegra_dsi *dsi)
+static void tegra_dsi_set_phy_timing(struct tegra_dsi *dsi,
+ unsigned long period,
+ const struct mipi_dphy_timing *timing)
{
- struct mipi_dphy_timing timing;
- unsigned long value, period;
- long rate;
- int err;
-
- rate = clk_get_rate(dsi->clk);
- if (rate < 0)
- return rate;
-
- period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, rate * 2);
-
- err = mipi_dphy_timing_get_default(&timing, period);
- if (err < 0)
- return err;
-
- err = mipi_dphy_timing_validate(&timing, period);
- if (err < 0) {
- dev_err(dsi->dev, "failed to validate D-PHY timing: %d\n", err);
- return err;
- }
-
- /*
- * The D-PHY timing fields below are expressed in byte-clock cycles,
- * so multiply the period by 8.
- */
- period *= 8;
+ u32 value;
- value = DSI_TIMING_FIELD(timing.hsexit, period, 1) << 24 |
- DSI_TIMING_FIELD(timing.hstrail, period, 0) << 16 |
- DSI_TIMING_FIELD(timing.hszero, period, 3) << 8 |
- DSI_TIMING_FIELD(timing.hsprepare, period, 1);
+ value = DSI_TIMING_FIELD(timing->hsexit, period, 1) << 24 |
+ DSI_TIMING_FIELD(timing->hstrail, period, 0) << 16 |
+ DSI_TIMING_FIELD(timing->hszero, period, 3) << 8 |
+ DSI_TIMING_FIELD(timing->hsprepare, period, 1);
tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_0);
- value = DSI_TIMING_FIELD(timing.clktrail, period, 1) << 24 |
- DSI_TIMING_FIELD(timing.clkpost, period, 1) << 16 |
- DSI_TIMING_FIELD(timing.clkzero, period, 1) << 8 |
- DSI_TIMING_FIELD(timing.lpx, period, 1);
+ value = DSI_TIMING_FIELD(timing->clktrail, period, 1) << 24 |
+ DSI_TIMING_FIELD(timing->clkpost, period, 1) << 16 |
+ DSI_TIMING_FIELD(timing->clkzero, period, 1) << 8 |
+ DSI_TIMING_FIELD(timing->lpx, period, 1);
tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_1);
- value = DSI_TIMING_FIELD(timing.clkprepare, period, 1) << 16 |
- DSI_TIMING_FIELD(timing.clkpre, period, 1) << 8 |
+ value = DSI_TIMING_FIELD(timing->clkprepare, period, 1) << 16 |
+ DSI_TIMING_FIELD(timing->clkpre, period, 1) << 8 |
DSI_TIMING_FIELD(0xff * period, period, 0) << 0;
tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_2);
- value = DSI_TIMING_FIELD(timing.taget, period, 1) << 16 |
- DSI_TIMING_FIELD(timing.tasure, period, 1) << 8 |
- DSI_TIMING_FIELD(timing.tago, period, 1);
+ value = DSI_TIMING_FIELD(timing->taget, period, 1) << 16 |
+ DSI_TIMING_FIELD(timing->tasure, period, 1) << 8 |
+ DSI_TIMING_FIELD(timing->tago, period, 1);
tegra_dsi_writel(dsi, value, DSI_BTA_TIMING);
if (dsi->slave)
- return tegra_dsi_set_phy_timing(dsi->slave);
-
- return 0;
+ tegra_dsi_set_phy_timing(dsi->slave, period, timing);
}
static int tegra_dsi_get_muldiv(enum mipi_dsi_pixel_format format,
@@ -484,14 +483,22 @@ static unsigned int tegra_dsi_get_lanes(struct tegra_dsi *dsi)
return dsi->lanes;
}
-static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
- const struct drm_display_mode *mode)
+static void tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
+ const struct drm_display_mode *mode)
{
unsigned int hact, hsw, hbp, hfp, i, mul, div;
- enum tegra_dsi_format format;
+ struct tegra_dsi_state *state;
const u32 *pkt_seq;
u32 value;
- int err;
+
+ /* XXX: pass in state into this function? */
+ if (dsi->master)
+ state = tegra_dsi_get_state(dsi->master);
+ else
+ state = tegra_dsi_get_state(dsi);
+
+ mul = state->mul;
+ div = state->div;
if (dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
DRM_DEBUG_KMS("Non-burst video mode with sync pulses\n");
@@ -504,15 +511,8 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
pkt_seq = pkt_seq_command_mode;
}
- err = tegra_dsi_get_muldiv(dsi->format, &mul, &div);
- if (err < 0)
- return err;
-
- err = tegra_dsi_get_format(dsi->format, &format);
- if (err < 0)
- return err;
-
- value = DSI_CONTROL_CHANNEL(0) | DSI_CONTROL_FORMAT(format) |
+ value = DSI_CONTROL_CHANNEL(0) |
+ DSI_CONTROL_FORMAT(state->format) |
DSI_CONTROL_LANES(dsi->lanes - 1) |
DSI_CONTROL_SOURCE(pipe);
tegra_dsi_writel(dsi, value, DSI_CONTROL);
@@ -591,8 +591,8 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
/* set SOL delay */
if (dsi->master || dsi->slave) {
- unsigned int lanes = tegra_dsi_get_lanes(dsi);
unsigned long delay, bclk, bclk_ganged;
+ unsigned int lanes = state->lanes;
/* SOL to valid, valid to FIFO and FIFO write delay */
delay = 4 + 4 + 2;
@@ -612,9 +612,7 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
}
if (dsi->slave) {
- err = tegra_dsi_configure(dsi->slave, pipe, mode);
- if (err < 0)
- return err;
+ tegra_dsi_configure(dsi->slave, pipe, mode);
/*
* TODO: Support modes other than symmetrical left-right
@@ -624,49 +622,6 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
tegra_dsi_ganged_enable(dsi->slave, mode->hdisplay / 2,
mode->hdisplay / 2);
}
-
- return 0;
-}
-
-static int tegra_output_dsi_enable(struct tegra_output *output)
-{
- struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
- const struct drm_display_mode *mode = &dc->base.mode;
- struct tegra_dsi *dsi = to_dsi(output);
- u32 value;
- int err;
-
- if (dsi->enabled)
- return 0;
-
- err = tegra_dsi_configure(dsi, dc->pipe, mode);
- if (err < 0)
- return err;
-
- /* enable display controller */
- value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
- value |= DSI_ENABLE;
- tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
-
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
- value &= ~DISP_CTRL_MODE_MASK;
- value |= DISP_CTRL_MODE_C_DISPLAY;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
-
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
-
- tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
-
- /* enable DSI controller */
- tegra_dsi_enable(dsi);
-
- dsi->enabled = true;
-
- return 0;
}
static int tegra_dsi_wait_idle(struct tegra_dsi *dsi, unsigned long timeout)
@@ -705,6 +660,29 @@ static void tegra_dsi_ganged_disable(struct tegra_dsi *dsi)
tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL);
}
+static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,
+ unsigned int vrefresh)
+{
+ unsigned int timeout;
+ u32 value;
+
+ /* one frame high-speed transmission timeout */
+ timeout = (bclk / vrefresh) / 512;
+ value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout);
+ tegra_dsi_writel(dsi, value, DSI_TIMEOUT_0);
+
+ /* 2 ms peripheral timeout for panel */
+ timeout = 2 * bclk / 512 * 1000;
+ value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000);
+ tegra_dsi_writel(dsi, value, DSI_TIMEOUT_1);
+
+ value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0);
+ tegra_dsi_writel(dsi, value, DSI_TO_TALLY);
+
+ if (dsi->slave)
+ tegra_dsi_set_timeout(dsi->slave, bclk, vrefresh);
+}
+
static void tegra_dsi_disable(struct tegra_dsi *dsi)
{
u32 value;
@@ -724,15 +702,149 @@ static void tegra_dsi_disable(struct tegra_dsi *dsi)
usleep_range(5000, 10000);
}
-static int tegra_output_dsi_disable(struct tegra_output *output)
+static void tegra_dsi_soft_reset(struct tegra_dsi *dsi)
+{
+ u32 value;
+
+ value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
+ value &= ~DSI_POWER_CONTROL_ENABLE;
+ tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);
+
+ usleep_range(300, 1000);
+
+ value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
+ value |= DSI_POWER_CONTROL_ENABLE;
+ tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);
+
+ usleep_range(300, 1000);
+
+ value = tegra_dsi_readl(dsi, DSI_TRIGGER);
+ if (value)
+ tegra_dsi_writel(dsi, 0, DSI_TRIGGER);
+
+ if (dsi->slave)
+ tegra_dsi_soft_reset(dsi->slave);
+}
+
+static void tegra_dsi_connector_dpms(struct drm_connector *connector, int mode)
+{
+}
+
+static void tegra_dsi_connector_reset(struct drm_connector *connector)
+{
+ struct tegra_dsi_state *state;
+
+ kfree(connector->state);
+ connector->state = NULL;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state)
+ connector->state = &state->base;
+}
+
+static struct drm_connector_state *
+tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
+{
+ struct tegra_dsi_state *state = to_dsi_state(connector->state);
+ struct tegra_dsi_state *copy;
+
+ copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
+ if (!copy)
+ return NULL;
+
+ return &copy->base;
+}
+
+static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
+ .dpms = tegra_dsi_connector_dpms,
+ .reset = tegra_dsi_connector_reset,
+ .detect = tegra_output_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = tegra_output_connector_destroy,
+ .atomic_duplicate_state = tegra_dsi_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static enum drm_mode_status
+tegra_dsi_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs tegra_dsi_connector_helper_funcs = {
+ .get_modes = tegra_output_connector_get_modes,
+ .mode_valid = tegra_dsi_connector_mode_valid,
+ .best_encoder = tegra_output_connector_best_encoder,
+};
+
+static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = {
+ .destroy = tegra_output_encoder_destroy,
+};
+
+static void tegra_dsi_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static void tegra_dsi_encoder_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void tegra_dsi_encoder_commit(struct drm_encoder *encoder)
{
- struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
+}
+
+static void tegra_dsi_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
+ struct tegra_dsi *dsi = to_dsi(output);
+ struct tegra_dsi_state *state;
+ u32 value;
+
+ state = tegra_dsi_get_state(dsi);
+
+ tegra_dsi_set_timeout(dsi, state->bclk, state->vrefresh);
+
+ /*
+ * The D-PHY timing fields are expressed in byte-clock cycles, so
+ * multiply the period by 8.
+ */
+ tegra_dsi_set_phy_timing(dsi, state->period * 8, &state->timing);
+
+ if (output->panel)
+ drm_panel_prepare(output->panel);
+
+ tegra_dsi_configure(dsi, dc->pipe, mode);
+
+ /* enable display controller */
+ value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
+ value |= DSI_ENABLE;
+ tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
+
+ tegra_dc_commit(dc);
+
+ /* enable DSI controller */
+ tegra_dsi_enable(dsi);
+
+ if (output->panel)
+ drm_panel_enable(output->panel);
+
+ return;
+}
+
+static void tegra_dsi_encoder_disable(struct drm_encoder *encoder)
+{
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
struct tegra_dsi *dsi = to_dsi(output);
- unsigned long value;
+ u32 value;
int err;
- if (!dsi->enabled)
- return 0;
+ if (output->panel)
+ drm_panel_disable(output->panel);
tegra_dsi_video_disable(dsi);
@@ -741,85 +853,78 @@ static int tegra_output_dsi_disable(struct tegra_output *output)
* sure it's only executed when the output is attached to one.
*/
if (dc) {
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
-
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
- value &= ~DISP_CTRL_MODE_MASK;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
-
value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
value &= ~DSI_ENABLE;
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
- tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+ tegra_dc_commit(dc);
}
err = tegra_dsi_wait_idle(dsi, 100);
if (err < 0)
dev_dbg(dsi->dev, "failed to idle DSI: %d\n", err);
- tegra_dsi_disable(dsi);
+ tegra_dsi_soft_reset(dsi);
- dsi->enabled = false;
+ if (output->panel)
+ drm_panel_unprepare(output->panel);
- return 0;
-}
-
-static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,
- unsigned int vrefresh)
-{
- unsigned int timeout;
- u32 value;
-
- /* one frame high-speed transmission timeout */
- timeout = (bclk / vrefresh) / 512;
- value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout);
- tegra_dsi_writel(dsi, value, DSI_TIMEOUT_0);
-
- /* 2 ms peripheral timeout for panel */
- timeout = 2 * bclk / 512 * 1000;
- value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000);
- tegra_dsi_writel(dsi, value, DSI_TIMEOUT_1);
-
- value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0);
- tegra_dsi_writel(dsi, value, DSI_TO_TALLY);
+ tegra_dsi_disable(dsi);
- if (dsi->slave)
- tegra_dsi_set_timeout(dsi->slave, bclk, vrefresh);
+ return;
}
-static int tegra_output_dsi_setup_clock(struct tegra_output *output,
- struct clk *clk, unsigned long pclk,
- unsigned int *divp)
+static int
+tegra_dsi_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
- struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
- struct drm_display_mode *mode = &dc->base.mode;
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dsi_state *state = to_dsi_state(conn_state);
+ struct tegra_dc *dc = to_tegra_dc(conn_state->crtc);
struct tegra_dsi *dsi = to_dsi(output);
- unsigned int mul, div, vrefresh, lanes;
- unsigned long bclk, plld;
+ unsigned int scdiv;
+ unsigned long plld;
int err;
- lanes = tegra_dsi_get_lanes(dsi);
+ state->pclk = crtc_state->mode.clock * 1000;
+
+ err = tegra_dsi_get_muldiv(dsi->format, &state->mul, &state->div);
+ if (err < 0)
+ return err;
+
+ state->lanes = tegra_dsi_get_lanes(dsi);
- err = tegra_dsi_get_muldiv(dsi->format, &mul, &div);
+ err = tegra_dsi_get_format(dsi->format, &state->format);
if (err < 0)
return err;
- DRM_DEBUG_KMS("mul: %u, div: %u, lanes: %u\n", mul, div, lanes);
- vrefresh = drm_mode_vrefresh(mode);
- DRM_DEBUG_KMS("vrefresh: %u\n", vrefresh);
+ state->vrefresh = drm_mode_vrefresh(&crtc_state->mode);
/* compute byte clock */
- bclk = (pclk * mul) / (div * lanes);
+ state->bclk = (state->pclk * state->mul) / (state->div * state->lanes);
+
+ DRM_DEBUG_KMS("mul: %u, div: %u, lanes: %u\n", state->mul, state->div,
+ state->lanes);
+ DRM_DEBUG_KMS("format: %u, vrefresh: %u\n", state->format,
+ state->vrefresh);
+ DRM_DEBUG_KMS("bclk: %lu\n", state->bclk);
/*
* Compute bit clock and round up to the next MHz.
*/
- plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC) * USEC_PER_SEC;
+ plld = DIV_ROUND_UP(state->bclk * 8, USEC_PER_SEC) * USEC_PER_SEC;
+ state->period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, plld);
+
+ err = mipi_dphy_timing_get_default(&state->timing, state->period);
+ if (err < 0)
+ return err;
+
+ err = mipi_dphy_timing_validate(&state->timing, state->period);
+ if (err < 0) {
+ dev_err(dsi->dev, "failed to validate D-PHY timing: %d\n", err);
+ return err;
+ }
/*
* We divide the frequency by two here, but we make up for that by
@@ -828,19 +933,6 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output,
*/
plld /= 2;
- err = clk_set_parent(clk, dsi->clk_parent);
- if (err < 0) {
- dev_err(dsi->dev, "failed to set parent clock: %d\n", err);
- return err;
- }
-
- err = clk_set_rate(dsi->clk_parent, plld);
- if (err < 0) {
- dev_err(dsi->dev, "failed to set base clock rate to %lu Hz\n",
- plld);
- return err;
- }
-
/*
* Derive pixel clock from bit clock using the shift clock divider.
* Note that this is only half of what we would expect, but we need
@@ -851,44 +943,30 @@ static int tegra_output_dsi_setup_clock(struct tegra_output *output,
* not working properly otherwise. Perhaps the PLLs cannot generate
* frequencies sufficiently high.
*/
- *divp = ((8 * mul) / (div * lanes)) - 2;
+ scdiv = ((8 * state->mul) / (state->div * state->lanes)) - 2;
- /*
- * XXX: Move the below somewhere else so that we don't need to have
- * access to the vrefresh in this function?
- */
- tegra_dsi_set_timeout(dsi, bclk, vrefresh);
-
- err = tegra_dsi_set_phy_timing(dsi);
- if (err < 0)
+ err = tegra_dc_state_setup_clock(dc, crtc_state, dsi->clk_parent,
+ plld, scdiv);
+ if (err < 0) {
+ dev_err(output->dev, "failed to setup CRTC state: %d\n", err);
return err;
+ }
- return 0;
-}
-
-static int tegra_output_dsi_check_mode(struct tegra_output *output,
- struct drm_display_mode *mode,
- enum drm_mode_status *status)
-{
- /*
- * FIXME: For now, always assume that the mode is okay.
- */
-
- *status = MODE_OK;
-
- return 0;
+ return err;
}
-static const struct tegra_output_ops dsi_ops = {
- .enable = tegra_output_dsi_enable,
- .disable = tegra_output_dsi_disable,
- .setup_clock = tegra_output_dsi_setup_clock,
- .check_mode = tegra_output_dsi_check_mode,
+static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = {
+ .dpms = tegra_dsi_encoder_dpms,
+ .prepare = tegra_dsi_encoder_prepare,
+ .commit = tegra_dsi_encoder_commit,
+ .mode_set = tegra_dsi_encoder_mode_set,
+ .disable = tegra_dsi_encoder_disable,
+ .atomic_check = tegra_dsi_encoder_atomic_check,
};
static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
{
- unsigned long value;
+ u32 value;
value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
@@ -923,17 +1001,44 @@ static int tegra_dsi_init(struct host1x_client *client)
struct tegra_dsi *dsi = host1x_client_to_dsi(client);
int err;
+ reset_control_deassert(dsi->rst);
+
+ err = tegra_dsi_pad_calibrate(dsi);
+ if (err < 0) {
+ dev_err(dsi->dev, "MIPI calibration failed: %d\n", err);
+ goto reset;
+ }
+
/* Gangsters must not register their own outputs. */
if (!dsi->master) {
- dsi->output.type = TEGRA_OUTPUT_DSI;
dsi->output.dev = client->dev;
- dsi->output.ops = &dsi_ops;
+
+ drm_connector_init(drm, &dsi->output.connector,
+ &tegra_dsi_connector_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ drm_connector_helper_add(&dsi->output.connector,
+ &tegra_dsi_connector_helper_funcs);
+ dsi->output.connector.dpms = DRM_MODE_DPMS_OFF;
+
+ drm_encoder_init(drm, &dsi->output.encoder,
+ &tegra_dsi_encoder_funcs,
+ DRM_MODE_ENCODER_DSI);
+ drm_encoder_helper_add(&dsi->output.encoder,
+ &tegra_dsi_encoder_helper_funcs);
+
+ drm_mode_connector_attach_encoder(&dsi->output.connector,
+ &dsi->output.encoder);
+ drm_connector_register(&dsi->output.connector);
err = tegra_output_init(drm, &dsi->output);
if (err < 0) {
- dev_err(client->dev, "output setup failed: %d\n", err);
- return err;
+ dev_err(client->dev,
+ "failed to initialize output: %d\n",
+ err);
+ goto reset;
}
+
+ dsi->output.encoder.possible_crtcs = 0x3;
}
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
@@ -943,34 +1048,22 @@ static int tegra_dsi_init(struct host1x_client *client)
}
return 0;
+
+reset:
+ reset_control_assert(dsi->rst);
+ return err;
}
static int tegra_dsi_exit(struct host1x_client *client)
{
struct tegra_dsi *dsi = host1x_client_to_dsi(client);
- int err;
- if (IS_ENABLED(CONFIG_DEBUG_FS)) {
- err = tegra_dsi_debugfs_exit(dsi);
- if (err < 0)
- dev_err(dsi->dev, "debugfs cleanup failed: %d\n", err);
- }
+ tegra_output_exit(&dsi->output);
- if (!dsi->master) {
- err = tegra_output_disable(&dsi->output);
- if (err < 0) {
- dev_err(client->dev, "output failed to disable: %d\n",
- err);
- return err;
- }
+ if (IS_ENABLED(CONFIG_DEBUG_FS))
+ tegra_dsi_debugfs_exit(dsi);
- err = tegra_output_exit(&dsi->output);
- if (err < 0) {
- dev_err(client->dev, "output cleanup failed: %d\n",
- err);
- return err;
- }
- }
+ reset_control_assert(dsi->rst);
return 0;
}
@@ -1398,13 +1491,6 @@ static int tegra_dsi_probe(struct platform_device *pdev)
if (IS_ERR(dsi->rst))
return PTR_ERR(dsi->rst);
- err = reset_control_deassert(dsi->rst);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to bring DSI out of reset: %d\n",
- err);
- return err;
- }
-
dsi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(dsi->clk)) {
dev_err(&pdev->dev, "cannot get DSI clock\n");
@@ -1470,12 +1556,6 @@ static int tegra_dsi_probe(struct platform_device *pdev)
goto disable_vdd;
}
- err = tegra_dsi_pad_calibrate(dsi);
- if (err < 0) {
- dev_err(dsi->dev, "MIPI calibration failed: %d\n", err);
- goto mipi_free;
- }
-
dsi->host.ops = &tegra_dsi_host_ops;
dsi->host.dev = &pdev->dev;
@@ -1527,6 +1607,8 @@ static int tegra_dsi_remove(struct platform_device *pdev)
return err;
}
+ tegra_output_remove(&dsi->output);
+
mipi_dsi_host_unregister(&dsi->host);
tegra_mipi_free(dsi->mipi);
@@ -1535,12 +1617,6 @@ static int tegra_dsi_remove(struct platform_device *pdev)
clk_disable_unprepare(dsi->clk);
reset_control_assert(dsi->rst);
- err = tegra_output_remove(&dsi->output);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to remove output: %d\n", err);
- return err;
- }
-
return 0;
}
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index e9c715d89261..397fb34d5d5b 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -129,9 +129,9 @@ static struct tegra_fb *tegra_fb_alloc(struct drm_device *drm,
return fb;
}
-static struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
- struct drm_file *file,
- struct drm_mode_fb_cmd2 *cmd)
+struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
+ struct drm_file *file,
+ struct drm_mode_fb_cmd2 *cmd)
{
unsigned int hsub, vsub, i;
struct tegra_bo *planes[4];
@@ -377,7 +377,7 @@ void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev)
drm_fb_helper_restore_fbdev_mode_unlocked(&fbdev->base);
}
-static void tegra_fb_output_poll_changed(struct drm_device *drm)
+void tegra_fb_output_poll_changed(struct drm_device *drm)
{
struct tegra_drm *tegra = drm->dev_private;
@@ -386,28 +386,11 @@ static void tegra_fb_output_poll_changed(struct drm_device *drm)
}
#endif
-static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
- .fb_create = tegra_fb_create,
-#ifdef CONFIG_DRM_TEGRA_FBDEV
- .output_poll_changed = tegra_fb_output_poll_changed,
-#endif
-};
-
int tegra_drm_fb_prepare(struct drm_device *drm)
{
#ifdef CONFIG_DRM_TEGRA_FBDEV
struct tegra_drm *tegra = drm->dev_private;
-#endif
- drm->mode_config.min_width = 0;
- drm->mode_config.min_height = 0;
-
- drm->mode_config.max_width = 4096;
- drm->mode_config.max_height = 4096;
-
- drm->mode_config.funcs = &tegra_drm_mode_funcs;
-
-#ifdef CONFIG_DRM_TEGRA_FBDEV
tegra->fbdev = tegra_fbdev_create(drm);
if (IS_ERR(tegra->fbdev))
return PTR_ERR(tegra->fbdev);
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 8777b7f75791..cfb481943b6b 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -92,36 +92,6 @@ static const struct host1x_bo_ops tegra_bo_ops = {
.kunmap = tegra_bo_kunmap,
};
-/*
- * A generic iommu_map_sg() function is being reviewed and will hopefully be
- * merged soon. At that point this function can be dropped in favour of the
- * one provided by the IOMMU API.
- */
-static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
- struct scatterlist *sg, unsigned int nents,
- int prot)
-{
- struct scatterlist *s;
- size_t offset = 0;
- unsigned int i;
- int err;
-
- for_each_sg(sg, s, nents, i) {
- phys_addr_t phys = page_to_phys(sg_page(s));
- size_t length = s->offset + s->length;
-
- err = iommu_map(domain, iova + offset, phys, length, prot);
- if (err < 0) {
- iommu_unmap(domain, iova, offset);
- return err;
- }
-
- offset += length;
- }
-
- return offset;
-}
-
static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
{
int prot = IOMMU_READ | IOMMU_WRITE;
@@ -144,8 +114,8 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
bo->paddr = bo->mm->start;
- err = __iommu_map_sg(tegra->domain, bo->paddr, bo->sgt->sgl,
- bo->sgt->nents, prot);
+ err = iommu_map_sg(tegra->domain, bo->paddr, bo->sgt->sgl,
+ bo->sgt->nents, prot);
if (err < 0) {
dev_err(tegra->drm->dev, "failed to map buffer: %zd\n", err);
goto remove;
@@ -244,10 +214,8 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
for_each_sg(sgt->sgl, s, sgt->nents, i)
sg_dma_address(s) = sg_phys(s);
- if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0) {
- sgt = ERR_PTR(-ENOMEM);
+ if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0)
goto release_sgt;
- }
bo->sgt = sgt;
@@ -256,6 +224,7 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
release_sgt:
sg_free_table(sgt);
kfree(sgt);
+ sgt = ERR_PTR(-ENOMEM);
put_pages:
drm_gem_put_pages(&bo->gem, bo->pages, false, false);
return PTR_ERR(sgt);
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index ffe26547328d..7e06657ae58b 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -9,10 +9,15 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
+#include <linux/gpio.h>
#include <linux/hdmi.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+
#include "hdmi.h"
#include "drm.h"
#include "dc.h"
@@ -31,7 +36,7 @@ struct tegra_hdmi_config {
unsigned int num_tmds;
unsigned long fuse_override_offset;
- unsigned long fuse_override_value;
+ u32 fuse_override_value;
bool has_sor_io_peak_current;
};
@@ -40,7 +45,6 @@ struct tegra_hdmi {
struct host1x_client client;
struct tegra_output output;
struct device *dev;
- bool enabled;
struct regulator *hdmi;
struct regulator *pll;
@@ -85,16 +89,16 @@ enum {
HDA,
};
-static inline unsigned long tegra_hdmi_readl(struct tegra_hdmi *hdmi,
- unsigned long reg)
+static inline u32 tegra_hdmi_readl(struct tegra_hdmi *hdmi,
+ unsigned long offset)
{
- return readl(hdmi->regs + (reg << 2));
+ return readl(hdmi->regs + (offset << 2));
}
-static inline void tegra_hdmi_writel(struct tegra_hdmi *hdmi, unsigned long val,
- unsigned long reg)
+static inline void tegra_hdmi_writel(struct tegra_hdmi *hdmi, u32 value,
+ unsigned long offset)
{
- writel(val, hdmi->regs + (reg << 2));
+ writel(value, hdmi->regs + (offset << 2));
}
struct tegra_hdmi_audio_config {
@@ -455,8 +459,8 @@ static void tegra_hdmi_setup_audio_fs_tables(struct tegra_hdmi *hdmi)
for (i = 0; i < ARRAY_SIZE(freqs); i++) {
unsigned int f = freqs[i];
unsigned int eight_half;
- unsigned long value;
unsigned int delta;
+ u32 value;
if (f > 96000)
delta = 2;
@@ -477,7 +481,7 @@ static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi, unsigned int pclk)
struct device_node *node = hdmi->dev->of_node;
const struct tegra_hdmi_audio_config *config;
unsigned int offset = 0;
- unsigned long value;
+ u32 value;
switch (hdmi->audio_source) {
case HDA:
@@ -571,9 +575,9 @@ static int tegra_hdmi_setup_audio(struct tegra_hdmi *hdmi, unsigned int pclk)
return 0;
}
-static inline unsigned long tegra_hdmi_subpack(const u8 *ptr, size_t size)
+static inline u32 tegra_hdmi_subpack(const u8 *ptr, size_t size)
{
- unsigned long value = 0;
+ u32 value = 0;
size_t i;
for (i = size; i > 0; i--)
@@ -587,8 +591,8 @@ static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi, const void *data,
{
const u8 *ptr = data;
unsigned long offset;
- unsigned long value;
size_t i, j;
+ u32 value;
switch (ptr[0]) {
case HDMI_INFOFRAME_TYPE_AVI:
@@ -707,9 +711,9 @@ static void tegra_hdmi_setup_audio_infoframe(struct tegra_hdmi *hdmi)
static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi)
{
struct hdmi_vendor_infoframe frame;
- unsigned long value;
u8 buffer[10];
ssize_t err;
+ u32 value;
if (!hdmi->stereo) {
value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
@@ -738,7 +742,7 @@ static void tegra_hdmi_setup_stereo_infoframe(struct tegra_hdmi *hdmi)
static void tegra_hdmi_setup_tmds(struct tegra_hdmi *hdmi,
const struct tmds_config *tmds)
{
- unsigned long value;
+ u32 value;
tegra_hdmi_writel(hdmi, tmds->pll0, HDMI_NV_PDISP_SOR_PLL0);
tegra_hdmi_writel(hdmi, tmds->pll1, HDMI_NV_PDISP_SOR_PLL1);
@@ -768,21 +772,78 @@ static bool tegra_output_is_hdmi(struct tegra_output *output)
return drm_detect_hdmi_monitor(edid);
}
-static int tegra_output_hdmi_enable(struct tegra_output *output)
+static void tegra_hdmi_connector_dpms(struct drm_connector *connector,
+ int mode)
+{
+}
+
+static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
+ .dpms = tegra_hdmi_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
+ .detect = tegra_output_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = tegra_output_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static enum drm_mode_status
+tegra_hdmi_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct tegra_output *output = connector_to_output(connector);
+ struct tegra_hdmi *hdmi = to_hdmi(output);
+ unsigned long pclk = mode->clock * 1000;
+ enum drm_mode_status status = MODE_OK;
+ struct clk *parent;
+ long err;
+
+ parent = clk_get_parent(hdmi->clk_parent);
+
+ err = clk_round_rate(parent, pclk * 4);
+ if (err <= 0)
+ status = MODE_NOCLOCK;
+
+ return status;
+}
+
+static const struct drm_connector_helper_funcs
+tegra_hdmi_connector_helper_funcs = {
+ .get_modes = tegra_output_connector_get_modes,
+ .mode_valid = tegra_hdmi_connector_mode_valid,
+ .best_encoder = tegra_output_connector_best_encoder,
+};
+
+static const struct drm_encoder_funcs tegra_hdmi_encoder_funcs = {
+ .destroy = tegra_output_encoder_destroy,
+};
+
+static void tegra_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static void tegra_hdmi_encoder_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void tegra_hdmi_encoder_commit(struct drm_encoder *encoder)
+{
+}
+
+static void tegra_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
{
unsigned int h_sync_width, h_front_porch, h_back_porch, i, rekey;
- struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
- struct drm_display_mode *mode = &dc->base.mode;
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
+ struct device_node *node = output->dev->of_node;
struct tegra_hdmi *hdmi = to_hdmi(output);
- struct device_node *node = hdmi->dev->of_node;
unsigned int pulse_start, div82, pclk;
- unsigned long value;
int retries = 1000;
+ u32 value;
int err;
- if (hdmi->enabled)
- return 0;
-
hdmi->dvi = !tegra_output_is_hdmi(output);
pclk = mode->clock * 1000;
@@ -790,32 +851,6 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
h_back_porch = mode->htotal - mode->hsync_end;
h_front_porch = mode->hsync_start - mode->hdisplay;
- err = regulator_enable(hdmi->pll);
- if (err < 0) {
- dev_err(hdmi->dev, "failed to enable PLL regulator: %d\n", err);
- return err;
- }
-
- err = regulator_enable(hdmi->vdd);
- if (err < 0) {
- dev_err(hdmi->dev, "failed to enable VDD regulator: %d\n", err);
- return err;
- }
-
- err = clk_set_rate(hdmi->clk, pclk);
- if (err < 0)
- return err;
-
- err = clk_prepare_enable(hdmi->clk);
- if (err < 0) {
- dev_err(hdmi->dev, "failed to enable clock: %d\n", err);
- return err;
- }
-
- reset_control_assert(hdmi->rst);
- usleep_range(1000, 2000);
- reset_control_deassert(hdmi->rst);
-
/* power up sequence */
value = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_SOR_PLL0);
value &= ~SOR_PLL_PDBG;
@@ -987,123 +1022,57 @@ static int tegra_output_hdmi_enable(struct tegra_output *output)
value |= HDMI_ENABLE;
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
- value &= ~DISP_CTRL_MODE_MASK;
- value |= DISP_CTRL_MODE_C_DISPLAY;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
-
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
-
- tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+ tegra_dc_commit(dc);
/* TODO: add HDCP support */
-
- hdmi->enabled = true;
-
- return 0;
}
-static int tegra_output_hdmi_disable(struct tegra_output *output)
+static void tegra_hdmi_encoder_disable(struct drm_encoder *encoder)
{
- struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
- struct tegra_hdmi *hdmi = to_hdmi(output);
- unsigned long value;
-
- if (!hdmi->enabled)
- return 0;
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
+ u32 value;
/*
* The following accesses registers of the display controller, so make
* sure it's only executed when the output is attached to one.
*/
if (dc) {
- /*
- * XXX: We can't do this here because it causes HDMI to go
- * into an erroneous state with the result that HDMI won't
- * properly work once disabled. See also a similar symptom
- * for the SOR output.
- */
- /*
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
- */
-
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
- value &= ~DISP_CTRL_MODE_MASK;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
-
value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
value &= ~HDMI_ENABLE;
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
- tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+ tegra_dc_commit(dc);
}
-
- clk_disable_unprepare(hdmi->clk);
- reset_control_assert(hdmi->rst);
- regulator_disable(hdmi->vdd);
- regulator_disable(hdmi->pll);
-
- hdmi->enabled = false;
-
- return 0;
}
-static int tegra_output_hdmi_setup_clock(struct tegra_output *output,
- struct clk *clk, unsigned long pclk,
- unsigned int *div)
+static int
+tegra_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(conn_state->crtc);
+ unsigned long pclk = crtc_state->mode.clock * 1000;
struct tegra_hdmi *hdmi = to_hdmi(output);
int err;
- err = clk_set_parent(clk, hdmi->clk_parent);
+ err = tegra_dc_state_setup_clock(dc, crtc_state, hdmi->clk_parent,
+ pclk, 0);
if (err < 0) {
- dev_err(output->dev, "failed to set parent: %d\n", err);
+ dev_err(output->dev, "failed to setup CRTC state: %d\n", err);
return err;
}
- err = clk_set_rate(hdmi->clk_parent, pclk);
- if (err < 0)
- dev_err(output->dev, "failed to set clock rate to %lu Hz\n",
- pclk);
-
- *div = 0;
-
- return 0;
-}
-
-static int tegra_output_hdmi_check_mode(struct tegra_output *output,
- struct drm_display_mode *mode,
- enum drm_mode_status *status)
-{
- struct tegra_hdmi *hdmi = to_hdmi(output);
- unsigned long pclk = mode->clock * 1000;
- struct clk *parent;
- long err;
-
- parent = clk_get_parent(hdmi->clk_parent);
-
- err = clk_round_rate(parent, pclk * 4);
- if (err <= 0)
- *status = MODE_NOCLOCK;
- else
- *status = MODE_OK;
-
- return 0;
+ return err;
}
-static const struct tegra_output_ops hdmi_ops = {
- .enable = tegra_output_hdmi_enable,
- .disable = tegra_output_hdmi_disable,
- .setup_clock = tegra_output_hdmi_setup_clock,
- .check_mode = tegra_output_hdmi_check_mode,
+static const struct drm_encoder_helper_funcs tegra_hdmi_encoder_helper_funcs = {
+ .dpms = tegra_hdmi_encoder_dpms,
+ .prepare = tegra_hdmi_encoder_prepare,
+ .commit = tegra_hdmi_encoder_commit,
+ .mode_set = tegra_hdmi_encoder_mode_set,
+ .disable = tegra_hdmi_encoder_disable,
+ .atomic_check = tegra_hdmi_encoder_atomic_check,
};
static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
@@ -1117,8 +1086,8 @@ static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
return err;
#define DUMP_REG(name) \
- seq_printf(s, "%-56s %#05x %08lx\n", #name, name, \
- tegra_hdmi_readl(hdmi, name))
+ seq_printf(s, "%-56s %#05x %08x\n", #name, name, \
+ tegra_hdmi_readl(hdmi, name))
DUMP_REG(HDMI_CTXSW);
DUMP_REG(HDMI_NV_PDISP_SOR_STATE0);
@@ -1330,7 +1299,7 @@ remove:
return err;
}
-static int tegra_hdmi_debugfs_exit(struct tegra_hdmi *hdmi)
+static void tegra_hdmi_debugfs_exit(struct tegra_hdmi *hdmi)
{
drm_debugfs_remove_files(hdmi->debugfs_files, ARRAY_SIZE(debugfs_files),
hdmi->minor);
@@ -1341,8 +1310,6 @@ static int tegra_hdmi_debugfs_exit(struct tegra_hdmi *hdmi)
debugfs_remove(hdmi->debugfs);
hdmi->debugfs = NULL;
-
- return 0;
}
static int tegra_hdmi_init(struct host1x_client *client)
@@ -1351,16 +1318,32 @@ static int tegra_hdmi_init(struct host1x_client *client)
struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
int err;
- hdmi->output.type = TEGRA_OUTPUT_HDMI;
hdmi->output.dev = client->dev;
- hdmi->output.ops = &hdmi_ops;
+
+ drm_connector_init(drm, &hdmi->output.connector,
+ &tegra_hdmi_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA);
+ drm_connector_helper_add(&hdmi->output.connector,
+ &tegra_hdmi_connector_helper_funcs);
+ hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF;
+
+ drm_encoder_init(drm, &hdmi->output.encoder, &tegra_hdmi_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+ drm_encoder_helper_add(&hdmi->output.encoder,
+ &tegra_hdmi_encoder_helper_funcs);
+
+ drm_mode_connector_attach_encoder(&hdmi->output.connector,
+ &hdmi->output.encoder);
+ drm_connector_register(&hdmi->output.connector);
err = tegra_output_init(drm, &hdmi->output);
if (err < 0) {
- dev_err(client->dev, "output setup failed: %d\n", err);
+ dev_err(client->dev, "failed to initialize output: %d\n", err);
return err;
}
+ hdmi->output.encoder.possible_crtcs = 0x3;
+
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
err = tegra_hdmi_debugfs_init(hdmi, drm->primary);
if (err < 0)
@@ -1374,34 +1357,44 @@ static int tegra_hdmi_init(struct host1x_client *client)
return err;
}
+ err = regulator_enable(hdmi->pll);
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to enable PLL regulator: %d\n", err);
+ return err;
+ }
+
+ err = regulator_enable(hdmi->vdd);
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to enable VDD regulator: %d\n", err);
+ return err;
+ }
+
+ err = clk_prepare_enable(hdmi->clk);
+ if (err < 0) {
+ dev_err(hdmi->dev, "failed to enable clock: %d\n", err);
+ return err;
+ }
+
+ reset_control_deassert(hdmi->rst);
+
return 0;
}
static int tegra_hdmi_exit(struct host1x_client *client)
{
struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
- int err;
- regulator_disable(hdmi->hdmi);
+ tegra_output_exit(&hdmi->output);
- if (IS_ENABLED(CONFIG_DEBUG_FS)) {
- err = tegra_hdmi_debugfs_exit(hdmi);
- if (err < 0)
- dev_err(client->dev, "debugfs cleanup failed: %d\n",
- err);
- }
+ clk_disable_unprepare(hdmi->clk);
+ reset_control_assert(hdmi->rst);
- err = tegra_output_disable(&hdmi->output);
- if (err < 0) {
- dev_err(client->dev, "output failed to disable: %d\n", err);
- return err;
- }
+ regulator_disable(hdmi->vdd);
+ regulator_disable(hdmi->pll);
+ regulator_disable(hdmi->hdmi);
- err = tegra_output_exit(&hdmi->output);
- if (err < 0) {
- dev_err(client->dev, "output cleanup failed: %d\n", err);
- return err;
- }
+ if (IS_ENABLED(CONFIG_DEBUG_FS))
+ tegra_hdmi_debugfs_exit(hdmi);
return 0;
}
@@ -1559,11 +1552,7 @@ static int tegra_hdmi_remove(struct platform_device *pdev)
return err;
}
- err = tegra_output_remove(&hdmi->output);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to remove output: %d\n", err);
- return err;
- }
+ tegra_output_remove(&hdmi->output);
clk_disable_unprepare(hdmi->clk_parent);
clk_disable_unprepare(hdmi->clk);
diff --git a/drivers/gpu/drm/tegra/mipi-phy.c b/drivers/gpu/drm/tegra/mipi-phy.c
index 486d19d589c8..ba2ae6511957 100644
--- a/drivers/gpu/drm/tegra/mipi-phy.c
+++ b/drivers/gpu/drm/tegra/mipi-phy.c
@@ -12,9 +12,9 @@
#include "mipi-phy.h"
/*
- * Default D-PHY timings based on MIPI D-PHY specification. Derived from
- * the valid ranges specified in Section 5.9 of the D-PHY specification
- * with minor adjustments.
+ * Default D-PHY timings based on MIPI D-PHY specification. Derived from the
+ * valid ranges specified in Section 6.9, Table 14, Page 40 of the D-PHY
+ * specification (v1.2) with minor adjustments.
*/
int mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
unsigned long period)
@@ -34,7 +34,20 @@ int mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
timing->hszero = 145 + 5 * period;
timing->hssettle = 85 + 6 * period;
timing->hsskip = 40;
- timing->hstrail = max(8 * period, 60 + 4 * period);
+
+ /*
+ * The MIPI D-PHY specification (Section 6.9, v1.2, Table 14, Page 40)
+ * contains this formula as:
+ *
+ * T_HS-TRAIL = max(n * 8 * period, 60 + n * 4 * period)
+ *
+ * where n = 1 for forward-direction HS mode and n = 4 for reverse-
+ * direction HS mode. There's only one setting and this function does
+ * not parameterize on anything other that period, so this code will
+ * assumes that reverse-direction HS mode is supported and uses n = 4.
+ */
+ timing->hstrail = max(4 * 8 * period, 60 + 4 * 4 * period);
+
timing->init = 100000;
timing->lpx = 60;
timing->taget = 5 * timing->lpx;
@@ -46,8 +59,8 @@ int mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
}
/*
- * Validate D-PHY timing according to MIPI Alliance Specification for D-PHY,
- * Section 5.9 "Global Operation Timing Parameters".
+ * Validate D-PHY timing according to MIPI D-PHY specification (v1.2, Section
+ * Section 6.9 "Global Operation Timing Parameters").
*/
int mipi_dphy_timing_validate(struct mipi_dphy_timing *timing,
unsigned long period)
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index 6a5c7b81fbc5..37db47975d48 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -9,10 +9,11 @@
#include <linux/of_gpio.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_panel.h>
#include "drm.h"
-static int tegra_connector_get_modes(struct drm_connector *connector)
+int tegra_output_connector_get_modes(struct drm_connector *connector)
{
struct tegra_output *output = connector_to_output(connector);
struct edid *edid = NULL;
@@ -43,43 +44,20 @@ static int tegra_connector_get_modes(struct drm_connector *connector)
return err;
}
-static int tegra_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- struct tegra_output *output = connector_to_output(connector);
- enum drm_mode_status status = MODE_OK;
- int err;
-
- err = tegra_output_check_mode(output, mode, &status);
- if (err < 0)
- return MODE_ERROR;
-
- return status;
-}
-
-static struct drm_encoder *
-tegra_connector_best_encoder(struct drm_connector *connector)
+struct drm_encoder *
+tegra_output_connector_best_encoder(struct drm_connector *connector)
{
struct tegra_output *output = connector_to_output(connector);
return &output->encoder;
}
-static const struct drm_connector_helper_funcs connector_helper_funcs = {
- .get_modes = tegra_connector_get_modes,
- .mode_valid = tegra_connector_mode_valid,
- .best_encoder = tegra_connector_best_encoder,
-};
-
-static enum drm_connector_status
-tegra_connector_detect(struct drm_connector *connector, bool force)
+enum drm_connector_status
+tegra_output_connector_detect(struct drm_connector *connector, bool force)
{
struct tegra_output *output = connector_to_output(connector);
enum drm_connector_status status = connector_status_unknown;
- if (output->ops->detect)
- return output->ops->detect(output);
-
if (gpio_is_valid(output->hpd_gpio)) {
if (gpio_get_value(output->hpd_gpio) == 0)
status = connector_status_disconnected;
@@ -90,95 +68,22 @@ tegra_connector_detect(struct drm_connector *connector, bool force)
status = connector_status_disconnected;
else
status = connector_status_connected;
-
- if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
- status = connector_status_connected;
}
return status;
}
-static void drm_connector_clear(struct drm_connector *connector)
-{
- memset(connector, 0, sizeof(*connector));
-}
-
-static void tegra_connector_destroy(struct drm_connector *connector)
+void tegra_output_connector_destroy(struct drm_connector *connector)
{
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
- drm_connector_clear(connector);
}
-static const struct drm_connector_funcs connector_funcs = {
- .dpms = drm_helper_connector_dpms,
- .detect = tegra_connector_detect,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = tegra_connector_destroy,
-};
-
-static void drm_encoder_clear(struct drm_encoder *encoder)
-{
- memset(encoder, 0, sizeof(*encoder));
-}
-
-static void tegra_encoder_destroy(struct drm_encoder *encoder)
+void tegra_output_encoder_destroy(struct drm_encoder *encoder)
{
drm_encoder_cleanup(encoder);
- drm_encoder_clear(encoder);
}
-static const struct drm_encoder_funcs encoder_funcs = {
- .destroy = tegra_encoder_destroy,
-};
-
-static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct tegra_output *output = encoder_to_output(encoder);
- struct drm_panel *panel = output->panel;
-
- if (mode != DRM_MODE_DPMS_ON) {
- drm_panel_disable(panel);
- tegra_output_disable(output);
- drm_panel_unprepare(panel);
- } else {
- drm_panel_prepare(panel);
- tegra_output_enable(output);
- drm_panel_enable(panel);
- }
-}
-
-static bool tegra_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted)
-{
- return true;
-}
-
-static void tegra_encoder_prepare(struct drm_encoder *encoder)
-{
- tegra_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-static void tegra_encoder_commit(struct drm_encoder *encoder)
-{
- tegra_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static void tegra_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted)
-{
-}
-
-static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
- .dpms = tegra_encoder_dpms,
- .mode_fixup = tegra_encoder_mode_fixup,
- .prepare = tegra_encoder_prepare,
- .commit = tegra_encoder_commit,
- .mode_set = tegra_encoder_mode_set,
-};
-
static irqreturn_t hpd_irq(int irq, void *data)
{
struct tegra_output *output = data;
@@ -268,7 +173,7 @@ int tegra_output_probe(struct tegra_output *output)
return 0;
}
-int tegra_output_remove(struct tegra_output *output)
+void tegra_output_remove(struct tegra_output *output)
{
if (gpio_is_valid(output->hpd_gpio)) {
free_irq(output->hpd_irq, output);
@@ -277,56 +182,17 @@ int tegra_output_remove(struct tegra_output *output)
if (output->ddc)
put_device(&output->ddc->dev);
-
- return 0;
}
int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
{
- int connector, encoder;
-
- switch (output->type) {
- case TEGRA_OUTPUT_RGB:
- connector = DRM_MODE_CONNECTOR_LVDS;
- encoder = DRM_MODE_ENCODER_LVDS;
- break;
-
- case TEGRA_OUTPUT_HDMI:
- connector = DRM_MODE_CONNECTOR_HDMIA;
- encoder = DRM_MODE_ENCODER_TMDS;
- break;
-
- case TEGRA_OUTPUT_DSI:
- connector = DRM_MODE_CONNECTOR_DSI;
- encoder = DRM_MODE_ENCODER_DSI;
- break;
-
- case TEGRA_OUTPUT_EDP:
- connector = DRM_MODE_CONNECTOR_eDP;
- encoder = DRM_MODE_ENCODER_TMDS;
- break;
-
- default:
- connector = DRM_MODE_CONNECTOR_Unknown;
- encoder = DRM_MODE_ENCODER_NONE;
- break;
- }
-
- drm_connector_init(drm, &output->connector, &connector_funcs,
- connector);
- drm_connector_helper_add(&output->connector, &connector_helper_funcs);
- output->connector.dpms = DRM_MODE_DPMS_OFF;
-
- if (output->panel)
- drm_panel_attach(output->panel, &output->connector);
-
- drm_encoder_init(drm, &output->encoder, &encoder_funcs, encoder);
- drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs);
-
- drm_mode_connector_attach_encoder(&output->connector, &output->encoder);
- drm_connector_register(&output->connector);
+ int err;
- output->encoder.possible_crtcs = 0x3;
+ if (output->panel) {
+ err = drm_panel_attach(output->panel, &output->connector);
+ if (err < 0)
+ return err;
+ }
/*
* The connector is now registered and ready to receive hotplug events
@@ -338,7 +204,7 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
return 0;
}
-int tegra_output_exit(struct tegra_output *output)
+void tegra_output_exit(struct tegra_output *output)
{
/*
* The connector is going away, so the interrupt must be disabled to
@@ -349,6 +215,4 @@ int tegra_output_exit(struct tegra_output *output)
if (output->panel)
drm_panel_detach(output->panel);
-
- return 0;
}
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index d6af9be48f42..7cd833f5b5b5 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -9,6 +9,9 @@
#include <linux/clk.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_panel.h>
+
#include "drm.h"
#include "dc.h"
@@ -85,13 +88,65 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
tegra_dc_writel(dc, table[i].value, table[i].offset);
}
-static int tegra_output_rgb_enable(struct tegra_output *output)
+static void tegra_rgb_connector_dpms(struct drm_connector *connector,
+ int mode)
+{
+}
+
+static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
+ .dpms = tegra_rgb_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
+ .detect = tegra_output_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = tegra_output_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static enum drm_mode_status
+tegra_rgb_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ /*
+ * FIXME: For now, always assume that the mode is okay. There are
+ * unresolved issues with clk_round_rate(), which doesn't always
+ * reliably report whether a frequency can be set or not.
+ */
+ return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs tegra_rgb_connector_helper_funcs = {
+ .get_modes = tegra_output_connector_get_modes,
+ .mode_valid = tegra_rgb_connector_mode_valid,
+ .best_encoder = tegra_output_connector_best_encoder,
+};
+
+static const struct drm_encoder_funcs tegra_rgb_encoder_funcs = {
+ .destroy = tegra_output_encoder_destroy,
+};
+
+static void tegra_rgb_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static void tegra_rgb_encoder_prepare(struct drm_encoder *encoder)
{
+}
+
+static void tegra_rgb_encoder_commit(struct drm_encoder *encoder)
+{
+}
+
+static void tegra_rgb_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct tegra_output *output = encoder_to_output(encoder);
struct tegra_rgb *rgb = to_rgb(output);
- unsigned long value;
+ u32 value;
- if (rgb->enabled)
- return 0;
+ if (output->panel)
+ drm_panel_prepare(output->panel);
tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));
@@ -113,64 +168,39 @@ static int tegra_output_rgb_enable(struct tegra_output *output)
value = SC0_H_QUALIFIER_NONE | SC1_H_QUALIFIER_NONE;
tegra_dc_writel(rgb->dc, value, DC_DISP_SHIFT_CLOCK_OPTIONS);
- value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_COMMAND);
- value &= ~DISP_CTRL_MODE_MASK;
- value |= DISP_CTRL_MODE_C_DISPLAY;
- tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_COMMAND);
+ tegra_dc_commit(rgb->dc);
- value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
- tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
-
- tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
-
- rgb->enabled = true;
-
- return 0;
+ if (output->panel)
+ drm_panel_enable(output->panel);
}
-static int tegra_output_rgb_disable(struct tegra_output *output)
+static void tegra_rgb_encoder_disable(struct drm_encoder *encoder)
{
+ struct tegra_output *output = encoder_to_output(encoder);
struct tegra_rgb *rgb = to_rgb(output);
- unsigned long value;
-
- if (!rgb->enabled)
- return 0;
-
- value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
- tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
-
- value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_COMMAND);
- value &= ~DISP_CTRL_MODE_MASK;
- tegra_dc_writel(rgb->dc, value, DC_CMD_DISPLAY_COMMAND);
- tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+ if (output->panel)
+ drm_panel_disable(output->panel);
tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable));
+ tegra_dc_commit(rgb->dc);
- rgb->enabled = false;
-
- return 0;
+ if (output->panel)
+ drm_panel_unprepare(output->panel);
}
-static int tegra_output_rgb_setup_clock(struct tegra_output *output,
- struct clk *clk, unsigned long pclk,
- unsigned int *div)
+static int
+tegra_rgb_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(conn_state->crtc);
+ unsigned long pclk = crtc_state->mode.clock * 1000;
struct tegra_rgb *rgb = to_rgb(output);
+ unsigned int div;
int err;
- err = clk_set_parent(clk, rgb->clk_parent);
- if (err < 0) {
- dev_err(output->dev, "failed to set parent: %d\n", err);
- return err;
- }
-
/*
* We may not want to change the frequency of the parent clock, since
* it may be a parent for other peripherals. This is due to the fact
@@ -187,32 +217,26 @@ static int tegra_output_rgb_setup_clock(struct tegra_output *output,
* and hope that the desired frequency can be matched (or at least
* matched sufficiently close that the panel will still work).
*/
+ div = ((clk_get_rate(rgb->clk) * 2) / pclk) - 2;
+ pclk = 0;
- *div = ((clk_get_rate(clk) * 2) / pclk) - 2;
-
- return 0;
-}
-
-static int tegra_output_rgb_check_mode(struct tegra_output *output,
- struct drm_display_mode *mode,
- enum drm_mode_status *status)
-{
- /*
- * FIXME: For now, always assume that the mode is okay. There are
- * unresolved issues with clk_round_rate(), which doesn't always
- * reliably report whether a frequency can be set or not.
- */
-
- *status = MODE_OK;
+ err = tegra_dc_state_setup_clock(dc, crtc_state, rgb->clk_parent,
+ pclk, div);
+ if (err < 0) {
+ dev_err(output->dev, "failed to setup CRTC state: %d\n", err);
+ return err;
+ }
- return 0;
+ return err;
}
-static const struct tegra_output_ops rgb_ops = {
- .enable = tegra_output_rgb_enable,
- .disable = tegra_output_rgb_disable,
- .setup_clock = tegra_output_rgb_setup_clock,
- .check_mode = tegra_output_rgb_check_mode,
+static const struct drm_encoder_helper_funcs tegra_rgb_encoder_helper_funcs = {
+ .dpms = tegra_rgb_encoder_dpms,
+ .prepare = tegra_rgb_encoder_prepare,
+ .commit = tegra_rgb_encoder_commit,
+ .mode_set = tegra_rgb_encoder_mode_set,
+ .disable = tegra_rgb_encoder_disable,
+ .atomic_check = tegra_rgb_encoder_atomic_check,
};
int tegra_dc_rgb_probe(struct tegra_dc *dc)
@@ -262,64 +286,58 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
int tegra_dc_rgb_remove(struct tegra_dc *dc)
{
- int err;
-
if (!dc->rgb)
return 0;
- err = tegra_output_remove(dc->rgb);
- if (err < 0)
- return err;
+ tegra_output_remove(dc->rgb);
+ dc->rgb = NULL;
return 0;
}
int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
{
- struct tegra_rgb *rgb = to_rgb(dc->rgb);
+ struct tegra_output *output = dc->rgb;
int err;
if (!dc->rgb)
return -ENODEV;
- rgb->output.type = TEGRA_OUTPUT_RGB;
- rgb->output.ops = &rgb_ops;
+ drm_connector_init(drm, &output->connector, &tegra_rgb_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+ drm_connector_helper_add(&output->connector,
+ &tegra_rgb_connector_helper_funcs);
+ output->connector.dpms = DRM_MODE_DPMS_OFF;
+
+ drm_encoder_init(drm, &output->encoder, &tegra_rgb_encoder_funcs,
+ DRM_MODE_ENCODER_LVDS);
+ drm_encoder_helper_add(&output->encoder,
+ &tegra_rgb_encoder_helper_funcs);
- err = tegra_output_init(dc->base.dev, &rgb->output);
+ drm_mode_connector_attach_encoder(&output->connector,
+ &output->encoder);
+ drm_connector_register(&output->connector);
+
+ err = tegra_output_init(drm, output);
if (err < 0) {
- dev_err(dc->dev, "output setup failed: %d\n", err);
+ dev_err(output->dev, "failed to initialize output: %d\n", err);
return err;
}
/*
- * By default, outputs can be associated with each display controller.
- * RGB outputs are an exception, so we make sure they can be attached
- * to only their parent display controller.
+ * Other outputs can be attached to either display controller. The RGB
+ * outputs are an exception and work only with their parent display
+ * controller.
*/
- rgb->output.encoder.possible_crtcs = drm_crtc_mask(&dc->base);
+ output->encoder.possible_crtcs = drm_crtc_mask(&dc->base);
return 0;
}
int tegra_dc_rgb_exit(struct tegra_dc *dc)
{
- if (dc->rgb) {
- int err;
-
- err = tegra_output_disable(dc->rgb);
- if (err < 0) {
- dev_err(dc->dev, "output failed to disable: %d\n", err);
- return err;
- }
-
- err = tegra_output_exit(dc->rgb);
- if (err < 0) {
- dev_err(dc->dev, "output cleanup failed: %d\n", err);
- return err;
- }
-
- dc->rgb = NULL;
- }
+ if (dc->rgb)
+ tegra_output_exit(dc->rgb);
return 0;
}
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 7829e81f065d..2afe478ded3b 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -8,13 +8,16 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
+#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <soc/tegra/pmc.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_dp_helper.h>
+#include <drm/drm_panel.h>
#include "dc.h"
#include "drm.h"
@@ -258,18 +261,8 @@ static int tegra_sor_attach(struct tegra_sor *sor)
static int tegra_sor_wakeup(struct tegra_sor *sor)
{
- struct tegra_dc *dc = to_tegra_dc(sor->output.encoder.crtc);
unsigned long value, timeout;
- /* enable display controller outputs */
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
-
- tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
-
timeout = jiffies + msecs_to_jiffies(250);
/* wait for head to wake up */
@@ -482,10 +475,317 @@ static int tegra_sor_calc_config(struct tegra_sor *sor,
return 0;
}
-static int tegra_output_sor_enable(struct tegra_output *output)
+static int tegra_sor_detach(struct tegra_sor *sor)
+{
+ unsigned long value, timeout;
+
+ /* switch to safe mode */
+ value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
+ value &= ~SOR_SUPER_STATE_MODE_NORMAL;
+ tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
+ tegra_sor_super_update(sor);
+
+ timeout = jiffies + msecs_to_jiffies(250);
+
+ while (time_before(jiffies, timeout)) {
+ value = tegra_sor_readl(sor, SOR_PWR);
+ if (value & SOR_PWR_MODE_SAFE)
+ break;
+ }
+
+ if ((value & SOR_PWR_MODE_SAFE) == 0)
+ return -ETIMEDOUT;
+
+ /* go to sleep */
+ value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
+ value &= ~SOR_SUPER_STATE_HEAD_MODE_MASK;
+ tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
+ tegra_sor_super_update(sor);
+
+ /* detach */
+ value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
+ value &= ~SOR_SUPER_STATE_ATTACHED;
+ tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
+ tegra_sor_super_update(sor);
+
+ timeout = jiffies + msecs_to_jiffies(250);
+
+ while (time_before(jiffies, timeout)) {
+ value = tegra_sor_readl(sor, SOR_TEST);
+ if ((value & SOR_TEST_ATTACHED) == 0)
+ break;
+
+ usleep_range(25, 100);
+ }
+
+ if ((value & SOR_TEST_ATTACHED) != 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int tegra_sor_power_down(struct tegra_sor *sor)
+{
+ unsigned long value, timeout;
+ int err;
+
+ value = tegra_sor_readl(sor, SOR_PWR);
+ value &= ~SOR_PWR_NORMAL_STATE_PU;
+ value |= SOR_PWR_TRIGGER;
+ tegra_sor_writel(sor, value, SOR_PWR);
+
+ timeout = jiffies + msecs_to_jiffies(250);
+
+ while (time_before(jiffies, timeout)) {
+ value = tegra_sor_readl(sor, SOR_PWR);
+ if ((value & SOR_PWR_TRIGGER) == 0)
+ return 0;
+
+ usleep_range(25, 100);
+ }
+
+ if ((value & SOR_PWR_TRIGGER) != 0)
+ return -ETIMEDOUT;
+
+ err = clk_set_parent(sor->clk, sor->clk_safe);
+ if (err < 0)
+ dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
+
+ value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
+ value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
+ SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2);
+ tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
+
+ /* stop lane sequencer */
+ value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_UP |
+ SOR_LANE_SEQ_CTL_POWER_STATE_DOWN;
+ tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
+
+ timeout = jiffies + msecs_to_jiffies(250);
+
+ while (time_before(jiffies, timeout)) {
+ value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
+ if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
+ break;
+
+ usleep_range(25, 100);
+ }
+
+ if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)
+ return -ETIMEDOUT;
+
+ value = tegra_sor_readl(sor, SOR_PLL_2);
+ value |= SOR_PLL_2_PORT_POWERDOWN;
+ tegra_sor_writel(sor, value, SOR_PLL_2);
+
+ usleep_range(20, 100);
+
+ value = tegra_sor_readl(sor, SOR_PLL_0);
+ value |= SOR_PLL_0_POWER_OFF;
+ value |= SOR_PLL_0_VCOPD;
+ tegra_sor_writel(sor, value, SOR_PLL_0);
+
+ value = tegra_sor_readl(sor, SOR_PLL_2);
+ value |= SOR_PLL_2_SEQ_PLLCAPPD;
+ value |= SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
+ tegra_sor_writel(sor, value, SOR_PLL_2);
+
+ usleep_range(20, 100);
+
+ return 0;
+}
+
+static int tegra_sor_crc_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+
+ return 0;
+}
+
+static int tegra_sor_crc_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int tegra_sor_crc_wait(struct tegra_sor *sor, unsigned long timeout)
+{
+ u32 value;
+
+ timeout = jiffies + msecs_to_jiffies(timeout);
+
+ while (time_before(jiffies, timeout)) {
+ value = tegra_sor_readl(sor, SOR_CRC_A);
+ if (value & SOR_CRC_A_VALID)
+ return 0;
+
+ usleep_range(100, 200);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static ssize_t tegra_sor_crc_read(struct file *file, char __user *buffer,
+ size_t size, loff_t *ppos)
+{
+ struct tegra_sor *sor = file->private_data;
+ ssize_t num, err;
+ char buf[10];
+ u32 value;
+
+ mutex_lock(&sor->lock);
+
+ if (!sor->enabled) {
+ err = -EAGAIN;
+ goto unlock;
+ }
+
+ value = tegra_sor_readl(sor, SOR_STATE_1);
+ value &= ~SOR_STATE_ASY_CRC_MODE_MASK;
+ tegra_sor_writel(sor, value, SOR_STATE_1);
+
+ value = tegra_sor_readl(sor, SOR_CRC_CNTRL);
+ value |= SOR_CRC_CNTRL_ENABLE;
+ tegra_sor_writel(sor, value, SOR_CRC_CNTRL);
+
+ value = tegra_sor_readl(sor, SOR_TEST);
+ value &= ~SOR_TEST_CRC_POST_SERIALIZE;
+ tegra_sor_writel(sor, value, SOR_TEST);
+
+ err = tegra_sor_crc_wait(sor, 100);
+ if (err < 0)
+ goto unlock;
+
+ tegra_sor_writel(sor, SOR_CRC_A_RESET, SOR_CRC_A);
+ value = tegra_sor_readl(sor, SOR_CRC_B);
+
+ num = scnprintf(buf, sizeof(buf), "%08x\n", value);
+
+ err = simple_read_from_buffer(buffer, size, ppos, buf, num);
+
+unlock:
+ mutex_unlock(&sor->lock);
+ return err;
+}
+
+static const struct file_operations tegra_sor_crc_fops = {
+ .owner = THIS_MODULE,
+ .open = tegra_sor_crc_open,
+ .read = tegra_sor_crc_read,
+ .release = tegra_sor_crc_release,
+};
+
+static int tegra_sor_debugfs_init(struct tegra_sor *sor,
+ struct drm_minor *minor)
+{
+ struct dentry *entry;
+ int err = 0;
+
+ sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root);
+ if (!sor->debugfs)
+ return -ENOMEM;
+
+ entry = debugfs_create_file("crc", 0644, sor->debugfs, sor,
+ &tegra_sor_crc_fops);
+ if (!entry) {
+ dev_err(sor->dev,
+ "cannot create /sys/kernel/debug/dri/%s/sor/crc\n",
+ minor->debugfs_root->d_name.name);
+ err = -ENOMEM;
+ goto remove;
+ }
+
+ return err;
+
+remove:
+ debugfs_remove(sor->debugfs);
+ sor->debugfs = NULL;
+ return err;
+}
+
+static void tegra_sor_debugfs_exit(struct tegra_sor *sor)
+{
+ debugfs_remove_recursive(sor->debugfs);
+ sor->debugfs = NULL;
+}
+
+static void tegra_sor_connector_dpms(struct drm_connector *connector, int mode)
+{
+}
+
+static enum drm_connector_status
+tegra_sor_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct tegra_output *output = connector_to_output(connector);
+ struct tegra_sor *sor = to_sor(output);
+
+ if (sor->dpaux)
+ return tegra_dpaux_detect(sor->dpaux);
+
+ return connector_status_unknown;
+}
+
+static const struct drm_connector_funcs tegra_sor_connector_funcs = {
+ .dpms = tegra_sor_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
+ .detect = tegra_sor_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = tegra_output_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int tegra_sor_connector_get_modes(struct drm_connector *connector)
{
- struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
- struct drm_display_mode *mode = &dc->base.mode;
+ struct tegra_output *output = connector_to_output(connector);
+ struct tegra_sor *sor = to_sor(output);
+ int err;
+
+ if (sor->dpaux)
+ tegra_dpaux_enable(sor->dpaux);
+
+ err = tegra_output_connector_get_modes(connector);
+
+ if (sor->dpaux)
+ tegra_dpaux_disable(sor->dpaux);
+
+ return err;
+}
+
+static enum drm_mode_status
+tegra_sor_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs tegra_sor_connector_helper_funcs = {
+ .get_modes = tegra_sor_connector_get_modes,
+ .mode_valid = tegra_sor_connector_mode_valid,
+ .best_encoder = tegra_output_connector_best_encoder,
+};
+
+static const struct drm_encoder_funcs tegra_sor_encoder_funcs = {
+ .destroy = tegra_output_encoder_destroy,
+};
+
+static void tegra_sor_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static void tegra_sor_encoder_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void tegra_sor_encoder_commit(struct drm_encoder *encoder)
+{
+}
+
+static void tegra_sor_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted)
+{
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
unsigned int vbe, vse, hbe, hse, vbs, hbs, i;
struct tegra_sor *sor = to_sor(output);
struct tegra_sor_config config;
@@ -505,6 +805,9 @@ static int tegra_output_sor_enable(struct tegra_output *output)
reset_control_deassert(sor->rst);
+ if (output->panel)
+ drm_panel_prepare(output->panel);
+
/* FIXME: properly convert to struct drm_dp_aux */
aux = (struct drm_dp_aux *)sor->dpaux;
@@ -800,18 +1103,6 @@ static int tegra_output_sor_enable(struct tegra_output *output)
goto unlock;
}
- /* start display controller in continuous mode */
- value = tegra_dc_readl(dc, DC_CMD_STATE_ACCESS);
- value |= WRITE_MUX;
- tegra_dc_writel(dc, value, DC_CMD_STATE_ACCESS);
-
- tegra_dc_writel(dc, VSYNC_H_POSITION(1), DC_DISP_DISP_TIMING_OPTIONS);
- tegra_dc_writel(dc, DISP_CTRL_MODE_C_DISPLAY, DC_CMD_DISPLAY_COMMAND);
-
- value = tegra_dc_readl(dc, DC_CMD_STATE_ACCESS);
- value &= ~WRITE_MUX;
- tegra_dc_writel(dc, value, DC_CMD_STATE_ACCESS);
-
/*
* configure panel (24bpp, vsync-, hsync-, DP-A protocol, complete
* raster, associate with display controller)
@@ -886,11 +1177,13 @@ static int tegra_output_sor_enable(struct tegra_output *output)
goto unlock;
}
+ tegra_sor_update(sor);
+
value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
value |= SOR_ENABLE;
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
- tegra_sor_update(sor);
+ tegra_dc_commit(dc);
err = tegra_sor_attach(sor);
if (err < 0) {
@@ -904,145 +1197,31 @@ static int tegra_output_sor_enable(struct tegra_output *output)
goto unlock;
}
+ if (output->panel)
+ drm_panel_enable(output->panel);
+
sor->enabled = true;
unlock:
mutex_unlock(&sor->lock);
- return err;
}
-static int tegra_sor_detach(struct tegra_sor *sor)
+static void tegra_sor_encoder_disable(struct drm_encoder *encoder)
{
- unsigned long value, timeout;
-
- /* switch to safe mode */
- value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
- value &= ~SOR_SUPER_STATE_MODE_NORMAL;
- tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
- tegra_sor_super_update(sor);
-
- timeout = jiffies + msecs_to_jiffies(250);
-
- while (time_before(jiffies, timeout)) {
- value = tegra_sor_readl(sor, SOR_PWR);
- if (value & SOR_PWR_MODE_SAFE)
- break;
- }
-
- if ((value & SOR_PWR_MODE_SAFE) == 0)
- return -ETIMEDOUT;
-
- /* go to sleep */
- value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
- value &= ~SOR_SUPER_STATE_HEAD_MODE_MASK;
- tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
- tegra_sor_super_update(sor);
-
- /* detach */
- value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
- value &= ~SOR_SUPER_STATE_ATTACHED;
- tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
- tegra_sor_super_update(sor);
-
- timeout = jiffies + msecs_to_jiffies(250);
-
- while (time_before(jiffies, timeout)) {
- value = tegra_sor_readl(sor, SOR_TEST);
- if ((value & SOR_TEST_ATTACHED) == 0)
- break;
-
- usleep_range(25, 100);
- }
-
- if ((value & SOR_TEST_ATTACHED) != 0)
- return -ETIMEDOUT;
-
- return 0;
-}
-
-static int tegra_sor_power_down(struct tegra_sor *sor)
-{
- unsigned long value, timeout;
- int err;
-
- value = tegra_sor_readl(sor, SOR_PWR);
- value &= ~SOR_PWR_NORMAL_STATE_PU;
- value |= SOR_PWR_TRIGGER;
- tegra_sor_writel(sor, value, SOR_PWR);
-
- timeout = jiffies + msecs_to_jiffies(250);
-
- while (time_before(jiffies, timeout)) {
- value = tegra_sor_readl(sor, SOR_PWR);
- if ((value & SOR_PWR_TRIGGER) == 0)
- return 0;
-
- usleep_range(25, 100);
- }
-
- if ((value & SOR_PWR_TRIGGER) != 0)
- return -ETIMEDOUT;
-
- err = clk_set_parent(sor->clk, sor->clk_safe);
- if (err < 0)
- dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
-
- value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
- value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
- SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2);
- tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
-
- /* stop lane sequencer */
- value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_UP |
- SOR_LANE_SEQ_CTL_POWER_STATE_DOWN;
- tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
-
- timeout = jiffies + msecs_to_jiffies(250);
-
- while (time_before(jiffies, timeout)) {
- value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
- if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
- break;
-
- usleep_range(25, 100);
- }
-
- if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)
- return -ETIMEDOUT;
-
- value = tegra_sor_readl(sor, SOR_PLL_2);
- value |= SOR_PLL_2_PORT_POWERDOWN;
- tegra_sor_writel(sor, value, SOR_PLL_2);
-
- usleep_range(20, 100);
-
- value = tegra_sor_readl(sor, SOR_PLL_0);
- value |= SOR_PLL_0_POWER_OFF;
- value |= SOR_PLL_0_VCOPD;
- tegra_sor_writel(sor, value, SOR_PLL_0);
-
- value = tegra_sor_readl(sor, SOR_PLL_2);
- value |= SOR_PLL_2_SEQ_PLLCAPPD;
- value |= SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
- tegra_sor_writel(sor, value, SOR_PLL_2);
-
- usleep_range(20, 100);
-
- return 0;
-}
-
-static int tegra_output_sor_disable(struct tegra_output *output)
-{
- struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
struct tegra_sor *sor = to_sor(output);
- unsigned long value;
- int err = 0;
+ u32 value;
+ int err;
mutex_lock(&sor->lock);
if (!sor->enabled)
goto unlock;
+ if (output->panel)
+ drm_panel_disable(output->panel);
+
err = tegra_sor_detach(sor);
if (err < 0) {
dev_err(sor->dev, "failed to detach SOR: %d\n", err);
@@ -1057,31 +1236,11 @@ static int tegra_output_sor_disable(struct tegra_output *output)
* sure it's only executed when the output is attached to one.
*/
if (dc) {
- /*
- * XXX: We can't do this here because it causes the SOR to go
- * into an erroneous state and the output will look scrambled
- * the next time it is enabled. Presumably this is because we
- * should be doing this only on the next VBLANK. A possible
- * solution would be to queue a "power-off" event to trigger
- * this code to be run during the next VBLANK.
- */
- /*
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
- value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
- PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
- */
-
- value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
- value &= ~DISP_CTRL_MODE_MASK;
- tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
-
value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
value &= ~SOR_ENABLE;
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
- tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+ tegra_dc_commit(dc);
}
err = tegra_sor_power_down(sor);
@@ -1104,187 +1263,48 @@ static int tegra_output_sor_disable(struct tegra_output *output)
goto unlock;
}
- reset_control_assert(sor->rst);
+ if (output->panel)
+ drm_panel_unprepare(output->panel);
+
clk_disable_unprepare(sor->clk);
+ reset_control_assert(sor->rst);
sor->enabled = false;
unlock:
mutex_unlock(&sor->lock);
- return err;
}
-static int tegra_output_sor_setup_clock(struct tegra_output *output,
- struct clk *clk, unsigned long pclk,
- unsigned int *div)
+static int
+tegra_sor_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
+ struct tegra_output *output = encoder_to_output(encoder);
+ struct tegra_dc *dc = to_tegra_dc(conn_state->crtc);
+ unsigned long pclk = crtc_state->mode.clock * 1000;
struct tegra_sor *sor = to_sor(output);
int err;
- err = clk_set_parent(clk, sor->clk_parent);
- if (err < 0) {
- dev_err(sor->dev, "failed to set parent clock: %d\n", err);
- return err;
- }
-
- err = clk_set_rate(sor->clk_parent, pclk);
+ err = tegra_dc_state_setup_clock(dc, crtc_state, sor->clk_parent,
+ pclk, 0);
if (err < 0) {
- dev_err(sor->dev, "failed to set clock rate to %lu Hz\n", pclk);
+ dev_err(output->dev, "failed to setup CRTC state: %d\n", err);
return err;
}
- *div = 0;
-
return 0;
}
-static int tegra_output_sor_check_mode(struct tegra_output *output,
- struct drm_display_mode *mode,
- enum drm_mode_status *status)
-{
- /*
- * FIXME: For now, always assume that the mode is okay.
- */
-
- *status = MODE_OK;
-
- return 0;
-}
-
-static enum drm_connector_status
-tegra_output_sor_detect(struct tegra_output *output)
-{
- struct tegra_sor *sor = to_sor(output);
-
- if (sor->dpaux)
- return tegra_dpaux_detect(sor->dpaux);
-
- return connector_status_unknown;
-}
-
-static const struct tegra_output_ops sor_ops = {
- .enable = tegra_output_sor_enable,
- .disable = tegra_output_sor_disable,
- .setup_clock = tegra_output_sor_setup_clock,
- .check_mode = tegra_output_sor_check_mode,
- .detect = tegra_output_sor_detect,
+static const struct drm_encoder_helper_funcs tegra_sor_encoder_helper_funcs = {
+ .dpms = tegra_sor_encoder_dpms,
+ .prepare = tegra_sor_encoder_prepare,
+ .commit = tegra_sor_encoder_commit,
+ .mode_set = tegra_sor_encoder_mode_set,
+ .disable = tegra_sor_encoder_disable,
+ .atomic_check = tegra_sor_encoder_atomic_check,
};
-static int tegra_sor_crc_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
-
- return 0;
-}
-
-static int tegra_sor_crc_release(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static int tegra_sor_crc_wait(struct tegra_sor *sor, unsigned long timeout)
-{
- u32 value;
-
- timeout = jiffies + msecs_to_jiffies(timeout);
-
- while (time_before(jiffies, timeout)) {
- value = tegra_sor_readl(sor, SOR_CRC_A);
- if (value & SOR_CRC_A_VALID)
- return 0;
-
- usleep_range(100, 200);
- }
-
- return -ETIMEDOUT;
-}
-
-static ssize_t tegra_sor_crc_read(struct file *file, char __user *buffer,
- size_t size, loff_t *ppos)
-{
- struct tegra_sor *sor = file->private_data;
- ssize_t num, err;
- char buf[10];
- u32 value;
-
- mutex_lock(&sor->lock);
-
- if (!sor->enabled) {
- err = -EAGAIN;
- goto unlock;
- }
-
- value = tegra_sor_readl(sor, SOR_STATE_1);
- value &= ~SOR_STATE_ASY_CRC_MODE_MASK;
- tegra_sor_writel(sor, value, SOR_STATE_1);
-
- value = tegra_sor_readl(sor, SOR_CRC_CNTRL);
- value |= SOR_CRC_CNTRL_ENABLE;
- tegra_sor_writel(sor, value, SOR_CRC_CNTRL);
-
- value = tegra_sor_readl(sor, SOR_TEST);
- value &= ~SOR_TEST_CRC_POST_SERIALIZE;
- tegra_sor_writel(sor, value, SOR_TEST);
-
- err = tegra_sor_crc_wait(sor, 100);
- if (err < 0)
- goto unlock;
-
- tegra_sor_writel(sor, SOR_CRC_A_RESET, SOR_CRC_A);
- value = tegra_sor_readl(sor, SOR_CRC_B);
-
- num = scnprintf(buf, sizeof(buf), "%08x\n", value);
-
- err = simple_read_from_buffer(buffer, size, ppos, buf, num);
-
-unlock:
- mutex_unlock(&sor->lock);
- return err;
-}
-
-static const struct file_operations tegra_sor_crc_fops = {
- .owner = THIS_MODULE,
- .open = tegra_sor_crc_open,
- .read = tegra_sor_crc_read,
- .release = tegra_sor_crc_release,
-};
-
-static int tegra_sor_debugfs_init(struct tegra_sor *sor,
- struct drm_minor *minor)
-{
- struct dentry *entry;
- int err = 0;
-
- sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root);
- if (!sor->debugfs)
- return -ENOMEM;
-
- entry = debugfs_create_file("crc", 0644, sor->debugfs, sor,
- &tegra_sor_crc_fops);
- if (!entry) {
- dev_err(sor->dev,
- "cannot create /sys/kernel/debug/dri/%s/sor/crc\n",
- minor->debugfs_root->d_name.name);
- err = -ENOMEM;
- goto remove;
- }
-
- return err;
-
-remove:
- debugfs_remove(sor->debugfs);
- sor->debugfs = NULL;
- return err;
-}
-
-static int tegra_sor_debugfs_exit(struct tegra_sor *sor)
-{
- debugfs_remove_recursive(sor->debugfs);
- sor->debugfs = NULL;
-
- return 0;
-}
-
static int tegra_sor_init(struct host1x_client *client)
{
struct drm_device *drm = dev_get_drvdata(client->parent);
@@ -1294,17 +1314,32 @@ static int tegra_sor_init(struct host1x_client *client)
if (!sor->dpaux)
return -ENODEV;
- sor->output.type = TEGRA_OUTPUT_EDP;
-
sor->output.dev = sor->dev;
- sor->output.ops = &sor_ops;
+
+ drm_connector_init(drm, &sor->output.connector,
+ &tegra_sor_connector_funcs,
+ DRM_MODE_CONNECTOR_eDP);
+ drm_connector_helper_add(&sor->output.connector,
+ &tegra_sor_connector_helper_funcs);
+ sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
+
+ drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+ drm_encoder_helper_add(&sor->output.encoder,
+ &tegra_sor_encoder_helper_funcs);
+
+ drm_mode_connector_attach_encoder(&sor->output.connector,
+ &sor->output.encoder);
+ drm_connector_register(&sor->output.connector);
err = tegra_output_init(drm, &sor->output);
if (err < 0) {
- dev_err(sor->dev, "output setup failed: %d\n", err);
+ dev_err(client->dev, "failed to initialize output: %d\n", err);
return err;
}
+ sor->output.encoder.possible_crtcs = 0x3;
+
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
err = tegra_sor_debugfs_init(sor, drm->primary);
if (err < 0)
@@ -1319,6 +1354,20 @@ static int tegra_sor_init(struct host1x_client *client)
}
}
+ err = clk_prepare_enable(sor->clk);
+ if (err < 0) {
+ dev_err(sor->dev, "failed to enable clock: %d\n", err);
+ return err;
+ }
+
+ err = clk_prepare_enable(sor->clk_safe);
+ if (err < 0)
+ return err;
+
+ err = clk_prepare_enable(sor->clk_dp);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -1327,11 +1376,7 @@ static int tegra_sor_exit(struct host1x_client *client)
struct tegra_sor *sor = host1x_client_to_sor(client);
int err;
- err = tegra_output_disable(&sor->output);
- if (err < 0) {
- dev_err(sor->dev, "output failed to disable: %d\n", err);
- return err;
- }
+ tegra_output_exit(&sor->output);
if (sor->dpaux) {
err = tegra_dpaux_detach(sor->dpaux);
@@ -1341,17 +1386,12 @@ static int tegra_sor_exit(struct host1x_client *client)
}
}
- if (IS_ENABLED(CONFIG_DEBUG_FS)) {
- err = tegra_sor_debugfs_exit(sor);
- if (err < 0)
- dev_err(sor->dev, "debugfs cleanup failed: %d\n", err);
- }
+ clk_disable_unprepare(sor->clk_safe);
+ clk_disable_unprepare(sor->clk_dp);
+ clk_disable_unprepare(sor->clk);
- err = tegra_output_exit(&sor->output);
- if (err < 0) {
- dev_err(sor->dev, "output cleanup failed: %d\n", err);
- return err;
- }
+ if (IS_ENABLED(CONFIG_DEBUG_FS))
+ tegra_sor_debugfs_exit(sor);
return 0;
}
@@ -1404,26 +1444,14 @@ static int tegra_sor_probe(struct platform_device *pdev)
if (IS_ERR(sor->clk_parent))
return PTR_ERR(sor->clk_parent);
- err = clk_prepare_enable(sor->clk_parent);
- if (err < 0)
- return err;
-
sor->clk_safe = devm_clk_get(&pdev->dev, "safe");
if (IS_ERR(sor->clk_safe))
return PTR_ERR(sor->clk_safe);
- err = clk_prepare_enable(sor->clk_safe);
- if (err < 0)
- return err;
-
sor->clk_dp = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(sor->clk_dp))
return PTR_ERR(sor->clk_dp);
- err = clk_prepare_enable(sor->clk_dp);
- if (err < 0)
- return err;
-
INIT_LIST_HEAD(&sor->client.list);
sor->client.ops = &sor_client_ops;
sor->client.dev = &pdev->dev;
@@ -1454,10 +1482,7 @@ static int tegra_sor_remove(struct platform_device *pdev)
return err;
}
- clk_disable_unprepare(sor->clk_parent);
- clk_disable_unprepare(sor->clk_safe);
- clk_disable_unprepare(sor->clk_dp);
- clk_disable_unprepare(sor->clk);
+ tegra_output_remove(&sor->output);
return 0;
}
diff --git a/drivers/gpu/drm/tilcdc/Kconfig b/drivers/gpu/drm/tilcdc/Kconfig
index 7c3ef79fcb37..8394a0b3993e 100644
--- a/drivers/gpu/drm/tilcdc/Kconfig
+++ b/drivers/gpu/drm/tilcdc/Kconfig
@@ -1,6 +1,6 @@
config DRM_TILCDC
tristate "DRM Support for TI LCDC Display Controller"
- depends on DRM && OF && ARM
+ depends on DRM && OF && ARM && HAVE_DMA_ATTRS
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select DRM_KMS_CMA_HELPER
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 8cbcb4589bd3..5fc16cecd3ba 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -589,19 +589,27 @@ int udl_fbdev_init(struct drm_device *dev)
ret = drm_fb_helper_init(dev, &ufbdev->helper,
1, 1);
- if (ret) {
- kfree(ufbdev);
- return ret;
-
- }
+ if (ret)
+ goto free;
- drm_fb_helper_single_add_all_connectors(&ufbdev->helper);
+ ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper);
+ if (ret)
+ goto fini;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);
- drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel);
+ ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel);
+ if (ret)
+ goto fini;
+
return 0;
+
+fini:
+ drm_fb_helper_fini(&ufbdev->helper);
+free:
+ kfree(ufbdev);
+ return ret;
}
void udl_fbdev_cleanup(struct drm_device *dev)
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 1701f1dfb23f..677190a65e82 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -340,11 +340,11 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,
wrptr = udl_dummy_render(wrptr);
- ufb->active_16 = true;
if (old_fb) {
struct udl_framebuffer *uold_fb = to_udl_fb(old_fb);
uold_fb->active_16 = false;
}
+ ufb->active_16 = true;
udl->mode_buf_len = wrptr - buf;
/* damage all of it */
@@ -373,6 +373,13 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
unsigned long flags;
+ struct drm_framebuffer *old_fb = crtc->primary->fb;
+ if (old_fb) {
+ struct udl_framebuffer *uold_fb = to_udl_fb(old_fb);
+ uold_fb->active_16 = false;
+ }
+ ufb->active_16 = true;
+
udl_handle_damage(ufb, 0, 0, fb->width, fb->height);
spin_lock_irqsave(&dev->event_lock, flags);
diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
index f343db73e095..917dcb978c2c 100644
--- a/drivers/gpu/drm/udl/udl_transfer.c
+++ b/drivers/gpu/drm/udl/udl_transfer.c
@@ -82,12 +82,14 @@ static inline u16 pixel32_to_be16(const uint32_t pixel)
((pixel >> 8) & 0xf800));
}
-static bool pixel_repeats(const void *pixel, const uint32_t repeat, int bpp)
+static inline u16 get_pixel_val16(const uint8_t *pixel, int bpp)
{
+ u16 pixel_val16 = 0;
if (bpp == 2)
- return *(const uint16_t *)pixel == repeat;
- else
- return *(const uint32_t *)pixel == repeat;
+ pixel_val16 = *(const uint16_t *)pixel;
+ else if (bpp == 4)
+ pixel_val16 = pixel32_to_be16(*(const uint32_t *)pixel);
+ return pixel_val16;
}
/*
@@ -134,6 +136,7 @@ static void udl_compress_hline16(
uint8_t *cmd_pixels_count_byte = NULL;
const u8 *raw_pixel_start = NULL;
const u8 *cmd_pixel_start, *cmd_pixel_end = NULL;
+ uint16_t pixel_val16;
prefetchw((void *) cmd); /* pull in one cache line at least */
@@ -154,33 +157,29 @@ static void udl_compress_hline16(
(int)(cmd_buffer_end - cmd) / 2))) * bpp;
prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
+ pixel_val16 = get_pixel_val16(pixel, bpp);
while (pixel < cmd_pixel_end) {
const u8 *const start = pixel;
- u32 repeating_pixel;
-
- if (bpp == 2) {
- repeating_pixel = *(uint16_t *)pixel;
- *(uint16_t *)cmd = cpu_to_be16(repeating_pixel);
- } else {
- repeating_pixel = *(uint32_t *)pixel;
- *(uint16_t *)cmd = cpu_to_be16(pixel32_to_be16(repeating_pixel));
- }
+ const uint16_t repeating_pixel_val16 = pixel_val16;
+
+ *(uint16_t *)cmd = cpu_to_be16(pixel_val16);
cmd += 2;
pixel += bpp;
- if (unlikely((pixel < cmd_pixel_end) &&
- (pixel_repeats(pixel, repeating_pixel, bpp)))) {
+ while (pixel < cmd_pixel_end) {
+ pixel_val16 = get_pixel_val16(pixel, bpp);
+ if (pixel_val16 != repeating_pixel_val16)
+ break;
+ pixel += bpp;
+ }
+
+ if (unlikely(pixel > start + bpp)) {
/* go back and fill in raw pixel count */
*raw_pixels_count_byte = (((start -
raw_pixel_start) / bpp) + 1) & 0xFF;
- while ((pixel < cmd_pixel_end) &&
- (pixel_repeats(pixel, repeating_pixel, bpp))) {
- pixel += bpp;
- }
-
/* immediately after raw data is repeat byte */
*cmd++ = (((pixel - start) / bpp) - 1) & 0xFF;
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index aaf54859adb0..4a99c6416e6a 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -72,13 +72,14 @@ static void host1x_subdev_del(struct host1x_subdev *subdev)
/**
* host1x_device_parse_dt() - scan device tree and add matching subdevices
*/
-static int host1x_device_parse_dt(struct host1x_device *device)
+static int host1x_device_parse_dt(struct host1x_device *device,
+ struct host1x_driver *driver)
{
struct device_node *np;
int err;
for_each_child_of_node(device->dev.parent->of_node, np) {
- if (of_match_node(device->driver->subdevs, np) &&
+ if (of_match_node(driver->subdevs, np) &&
of_device_is_available(np)) {
err = host1x_subdev_add(device, np);
if (err < 0)
@@ -109,14 +110,12 @@ static void host1x_subdev_register(struct host1x_device *device,
mutex_unlock(&device->clients_lock);
mutex_unlock(&device->subdevs_lock);
- /*
- * When all subdevices have been registered, the composite device is
- * ready to be probed.
- */
if (list_empty(&device->subdevs)) {
- err = device->driver->probe(device);
+ err = device_add(&device->dev);
if (err < 0)
- dev_err(&device->dev, "probe failed: %d\n", err);
+ dev_err(&device->dev, "failed to add: %d\n", err);
+ else
+ device->registered = true;
}
}
@@ -124,16 +123,16 @@ static void __host1x_subdev_unregister(struct host1x_device *device,
struct host1x_subdev *subdev)
{
struct host1x_client *client = subdev->client;
- int err;
/*
* If all subdevices have been activated, we're about to remove the
* first active subdevice, so unload the driver first.
*/
if (list_empty(&device->subdevs)) {
- err = device->driver->remove(device);
- if (err < 0)
- dev_err(&device->dev, "remove failed: %d\n", err);
+ if (device->registered) {
+ device->registered = false;
+ device_del(&device->dev);
+ }
}
/*
@@ -260,24 +259,113 @@ static int host1x_del_client(struct host1x *host1x,
return -ENODEV;
}
-static struct bus_type host1x_bus_type = {
- .name = "host1x",
-};
+static int host1x_device_match(struct device *dev, struct device_driver *drv)
+{
+ return strcmp(dev_name(dev), drv->name) == 0;
+}
+
+static int host1x_device_probe(struct device *dev)
+{
+ struct host1x_driver *driver = to_host1x_driver(dev->driver);
+ struct host1x_device *device = to_host1x_device(dev);
+
+ if (driver->probe)
+ return driver->probe(device);
+
+ return 0;
+}
-int host1x_bus_init(void)
+static int host1x_device_remove(struct device *dev)
{
- return bus_register(&host1x_bus_type);
+ struct host1x_driver *driver = to_host1x_driver(dev->driver);
+ struct host1x_device *device = to_host1x_device(dev);
+
+ if (driver->remove)
+ return driver->remove(device);
+
+ return 0;
+}
+
+static void host1x_device_shutdown(struct device *dev)
+{
+ struct host1x_driver *driver = to_host1x_driver(dev->driver);
+ struct host1x_device *device = to_host1x_device(dev);
+
+ if (driver->shutdown)
+ driver->shutdown(device);
}
-void host1x_bus_exit(void)
+static const struct dev_pm_ops host1x_device_pm_ops = {
+ .suspend = pm_generic_suspend,
+ .resume = pm_generic_resume,
+ .freeze = pm_generic_freeze,
+ .thaw = pm_generic_thaw,
+ .poweroff = pm_generic_poweroff,
+ .restore = pm_generic_restore,
+};
+
+struct bus_type host1x_bus_type = {
+ .name = "host1x",
+ .match = host1x_device_match,
+ .probe = host1x_device_probe,
+ .remove = host1x_device_remove,
+ .shutdown = host1x_device_shutdown,
+ .pm = &host1x_device_pm_ops,
+};
+
+static void __host1x_device_del(struct host1x_device *device)
{
- bus_unregister(&host1x_bus_type);
+ struct host1x_subdev *subdev, *sd;
+ struct host1x_client *client, *cl;
+
+ mutex_lock(&device->subdevs_lock);
+
+ /* unregister subdevices */
+ list_for_each_entry_safe(subdev, sd, &device->active, list) {
+ /*
+ * host1x_subdev_unregister() will remove the client from
+ * any lists, so we'll need to manually add it back to the
+ * list of idle clients.
+ *
+ * XXX: Alternatively, perhaps don't remove the client from
+ * any lists in host1x_subdev_unregister() and instead do
+ * that explicitly from host1x_unregister_client()?
+ */
+ client = subdev->client;
+
+ __host1x_subdev_unregister(device, subdev);
+
+ /* add the client to the list of idle clients */
+ mutex_lock(&clients_lock);
+ list_add_tail(&client->list, &clients);
+ mutex_unlock(&clients_lock);
+ }
+
+ /* remove subdevices */
+ list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
+ host1x_subdev_del(subdev);
+
+ mutex_unlock(&device->subdevs_lock);
+
+ /* move clients to idle list */
+ mutex_lock(&clients_lock);
+ mutex_lock(&device->clients_lock);
+
+ list_for_each_entry_safe(client, cl, &device->clients, list)
+ list_move_tail(&client->list, &clients);
+
+ mutex_unlock(&device->clients_lock);
+ mutex_unlock(&clients_lock);
+
+ /* finally remove the device */
+ list_del_init(&device->list);
}
static void host1x_device_release(struct device *dev)
{
struct host1x_device *device = to_host1x_device(dev);
+ __host1x_device_del(device);
kfree(device);
}
@@ -293,6 +381,8 @@ static int host1x_device_add(struct host1x *host1x,
if (!device)
return -ENOMEM;
+ device_initialize(&device->dev);
+
mutex_init(&device->subdevs_lock);
INIT_LIST_HEAD(&device->subdevs);
INIT_LIST_HEAD(&device->active);
@@ -303,24 +393,18 @@ static int host1x_device_add(struct host1x *host1x,
device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
device->dev.dma_mask = &device->dev.coherent_dma_mask;
+ dev_set_name(&device->dev, "%s", driver->driver.name);
device->dev.release = host1x_device_release;
- dev_set_name(&device->dev, "%s", driver->name);
device->dev.bus = &host1x_bus_type;
device->dev.parent = host1x->dev;
- err = device_register(&device->dev);
- if (err < 0)
- return err;
-
- err = host1x_device_parse_dt(device);
+ err = host1x_device_parse_dt(device, driver);
if (err < 0) {
- device_unregister(&device->dev);
+ kfree(device);
return err;
}
- mutex_lock(&host1x->devices_lock);
list_add_tail(&device->list, &host1x->devices);
- mutex_unlock(&host1x->devices_lock);
mutex_lock(&clients_lock);
@@ -347,51 +431,12 @@ static int host1x_device_add(struct host1x *host1x,
static void host1x_device_del(struct host1x *host1x,
struct host1x_device *device)
{
- struct host1x_subdev *subdev, *sd;
- struct host1x_client *client, *cl;
-
- mutex_lock(&device->subdevs_lock);
-
- /* unregister subdevices */
- list_for_each_entry_safe(subdev, sd, &device->active, list) {
- /*
- * host1x_subdev_unregister() will remove the client from
- * any lists, so we'll need to manually add it back to the
- * list of idle clients.
- *
- * XXX: Alternatively, perhaps don't remove the client from
- * any lists in host1x_subdev_unregister() and instead do
- * that explicitly from host1x_unregister_client()?
- */
- client = subdev->client;
-
- __host1x_subdev_unregister(device, subdev);
-
- /* add the client to the list of idle clients */
- mutex_lock(&clients_lock);
- list_add_tail(&client->list, &clients);
- mutex_unlock(&clients_lock);
+ if (device->registered) {
+ device->registered = false;
+ device_del(&device->dev);
}
- /* remove subdevices */
- list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
- host1x_subdev_del(subdev);
-
- mutex_unlock(&device->subdevs_lock);
-
- /* move clients to idle list */
- mutex_lock(&clients_lock);
- mutex_lock(&device->clients_lock);
-
- list_for_each_entry_safe(client, cl, &device->clients, list)
- list_move_tail(&client->list, &clients);
-
- mutex_unlock(&device->clients_lock);
- mutex_unlock(&clients_lock);
-
- /* finally remove the device */
- list_del_init(&device->list);
- device_unregister(&device->dev);
+ put_device(&device->dev);
}
static void host1x_attach_driver(struct host1x *host1x,
@@ -409,11 +454,11 @@ static void host1x_attach_driver(struct host1x *host1x,
}
}
- mutex_unlock(&host1x->devices_lock);
-
err = host1x_device_add(host1x, driver);
if (err < 0)
dev_err(host1x->dev, "failed to allocate device: %d\n", err);
+
+ mutex_unlock(&host1x->devices_lock);
}
static void host1x_detach_driver(struct host1x *host1x,
@@ -466,7 +511,8 @@ int host1x_unregister(struct host1x *host1x)
return 0;
}
-int host1x_driver_register(struct host1x_driver *driver)
+int host1x_driver_register_full(struct host1x_driver *driver,
+ struct module *owner)
{
struct host1x *host1x;
@@ -483,9 +529,12 @@ int host1x_driver_register(struct host1x_driver *driver)
mutex_unlock(&devices_lock);
- return 0;
+ driver->driver.bus = &host1x_bus_type;
+ driver->driver.owner = owner;
+
+ return driver_register(&driver->driver);
}
-EXPORT_SYMBOL(host1x_driver_register);
+EXPORT_SYMBOL(host1x_driver_register_full);
void host1x_driver_unregister(struct host1x_driver *driver)
{
diff --git a/drivers/gpu/host1x/bus.h b/drivers/gpu/host1x/bus.h
index 4099e99212c8..88fb1c4aac68 100644
--- a/drivers/gpu/host1x/bus.h
+++ b/drivers/gpu/host1x/bus.h
@@ -18,10 +18,10 @@
#ifndef HOST1X_BUS_H
#define HOST1X_BUS_H
+struct bus_type;
struct host1x;
-int host1x_bus_init(void);
-void host1x_bus_exit(void);
+extern struct bus_type host1x_bus_type;
int host1x_register(struct host1x *host1x);
int host1x_unregister(struct host1x *host1x);
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 2529908d304b..53d3d1d45b48 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -216,7 +216,7 @@ static int __init tegra_host1x_init(void)
{
int err;
- err = host1x_bus_init();
+ err = bus_register(&host1x_bus_type);
if (err < 0)
return err;
@@ -233,7 +233,7 @@ static int __init tegra_host1x_init(void)
unregister_host1x:
platform_driver_unregister(&tegra_host1x_driver);
unregister_bus:
- host1x_bus_exit();
+ bus_unregister(&host1x_bus_type);
return err;
}
module_init(tegra_host1x_init);
@@ -242,7 +242,7 @@ static void __exit tegra_host1x_exit(void)
{
platform_driver_unregister(&tegra_mipi_driver);
platform_driver_unregister(&tegra_host1x_driver);
- host1x_bus_exit();
+ bus_unregister(&host1x_bus_type);
}
module_exit(tegra_host1x_exit);
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index f707d25ae78f..67bab5c36056 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -742,7 +742,7 @@ static struct ipu_devtype ipu_type_imx51 = {
.tpm_ofs = 0x1f060000,
.csi0_ofs = 0x1f030000,
.csi1_ofs = 0x1f038000,
- .ic_ofs = 0x1f020000,
+ .ic_ofs = 0x1e020000,
.disp0_ofs = 0x1e040000,
.disp1_ofs = 0x1e048000,
.dc_tmpl_ofs = 0x1f080000,
@@ -758,7 +758,7 @@ static struct ipu_devtype ipu_type_imx53 = {
.tpm_ofs = 0x07060000,
.csi0_ofs = 0x07030000,
.csi1_ofs = 0x07038000,
- .ic_ofs = 0x07020000,
+ .ic_ofs = 0x06020000,
.disp0_ofs = 0x06040000,
.disp1_ofs = 0x06048000,
.dc_tmpl_ofs = 0x07080000,
diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
index 2326c752d89b..4864f8300797 100644
--- a/drivers/gpu/ipu-v3/ipu-dc.c
+++ b/drivers/gpu/ipu-v3/ipu-dc.c
@@ -114,6 +114,7 @@ struct ipu_dc_priv {
struct completion comp;
int dc_irq;
int dp_irq;
+ int use_count;
};
static void dc_link_event(struct ipu_dc *dc, int event, int addr, int priority)
@@ -232,7 +233,16 @@ EXPORT_SYMBOL_GPL(ipu_dc_init_sync);
void ipu_dc_enable(struct ipu_soc *ipu)
{
- ipu_module_enable(ipu, IPU_CONF_DC_EN);
+ struct ipu_dc_priv *priv = ipu->dc_priv;
+
+ mutex_lock(&priv->mutex);
+
+ if (!priv->use_count)
+ ipu_module_enable(priv->ipu, IPU_CONF_DC_EN);
+
+ priv->use_count++;
+
+ mutex_unlock(&priv->mutex);
}
EXPORT_SYMBOL_GPL(ipu_dc_enable);
@@ -267,7 +277,8 @@ static irqreturn_t dc_irq_handler(int irq, void *dev_id)
void ipu_dc_disable_channel(struct ipu_dc *dc)
{
struct ipu_dc_priv *priv = dc->priv;
- int irq, ret;
+ int irq;
+ unsigned long ret;
u32 val;
/* TODO: Handle MEM_FG_SYNC differently from MEM_BG_SYNC */
@@ -282,7 +293,7 @@ void ipu_dc_disable_channel(struct ipu_dc *dc)
enable_irq(irq);
ret = wait_for_completion_timeout(&priv->comp, msecs_to_jiffies(50));
disable_irq(irq);
- if (ret <= 0) {
+ if (ret == 0) {
dev_warn(priv->dev, "DC stop timeout after 50 ms\n");
val = readl(dc->base + DC_WR_CH_CONF);
@@ -294,7 +305,18 @@ EXPORT_SYMBOL_GPL(ipu_dc_disable_channel);
void ipu_dc_disable(struct ipu_soc *ipu)
{
- ipu_module_disable(ipu, IPU_CONF_DC_EN);
+ struct ipu_dc_priv *priv = ipu->dc_priv;
+
+ mutex_lock(&priv->mutex);
+
+ priv->use_count--;
+ if (!priv->use_count)
+ ipu_module_disable(priv->ipu, IPU_CONF_DC_EN);
+
+ if (priv->use_count < 0)
+ priv->use_count = 0;
+
+ mutex_unlock(&priv->mutex);
}
EXPORT_SYMBOL_GPL(ipu_dc_disable);
diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c
index c490ba4384fc..b61d6be97602 100644
--- a/drivers/gpu/ipu-v3/ipu-di.c
+++ b/drivers/gpu/ipu-v3/ipu-di.c
@@ -207,10 +207,10 @@ static void ipu_di_sync_config(struct ipu_di *di, struct di_sync_config *config,
static void ipu_di_sync_config_interlaced(struct ipu_di *di,
struct ipu_di_signal_cfg *sig)
{
- u32 h_total = sig->width + sig->h_sync_width +
- sig->h_start_width + sig->h_end_width;
- u32 v_total = sig->height + sig->v_sync_width +
- sig->v_start_width + sig->v_end_width;
+ u32 h_total = sig->mode.hactive + sig->mode.hsync_len +
+ sig->mode.hback_porch + sig->mode.hfront_porch;
+ u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
+ sig->mode.vback_porch + sig->mode.vfront_porch;
u32 reg;
struct di_sync_config cfg[] = {
{
@@ -229,13 +229,13 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
}, {
.run_count = v_total / 2 - 1,
.run_src = DI_SYNC_HSYNC,
- .offset_count = sig->v_start_width,
+ .offset_count = sig->mode.vback_porch,
.offset_src = DI_SYNC_HSYNC,
.repeat_count = 2,
.cnt_clr_src = DI_SYNC_VSYNC,
}, {
.run_src = DI_SYNC_HSYNC,
- .repeat_count = sig->height / 2,
+ .repeat_count = sig->mode.vactive / 2,
.cnt_clr_src = 4,
}, {
.run_count = v_total - 1,
@@ -249,9 +249,9 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
.cnt_clr_src = DI_SYNC_VSYNC,
}, {
.run_src = DI_SYNC_CLK,
- .offset_count = sig->h_start_width,
+ .offset_count = sig->mode.hback_porch,
.offset_src = DI_SYNC_CLK,
- .repeat_count = sig->width,
+ .repeat_count = sig->mode.hactive,
.cnt_clr_src = 5,
}, {
.run_count = v_total - 1,
@@ -277,10 +277,10 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
struct ipu_di_signal_cfg *sig, int div)
{
- u32 h_total = sig->width + sig->h_sync_width + sig->h_start_width +
- sig->h_end_width;
- u32 v_total = sig->height + sig->v_sync_width + sig->v_start_width +
- sig->v_end_width;
+ u32 h_total = sig->mode.hactive + sig->mode.hsync_len +
+ sig->mode.hback_porch + sig->mode.hfront_porch;
+ u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
+ sig->mode.vback_porch + sig->mode.vfront_porch;
struct di_sync_config cfg[] = {
{
/* 1: INT_HSYNC */
@@ -294,27 +294,29 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
.offset_src = DI_SYNC_CLK,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_CLK,
- .cnt_down = sig->h_sync_width * 2,
+ .cnt_down = sig->mode.hsync_len * 2,
} , {
/* PIN3: VSYNC */
.run_count = v_total - 1,
.run_src = DI_SYNC_INT_HSYNC,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_INT_HSYNC,
- .cnt_down = sig->v_sync_width * 2,
+ .cnt_down = sig->mode.vsync_len * 2,
} , {
/* 4: Line Active */
.run_src = DI_SYNC_HSYNC,
- .offset_count = sig->v_sync_width + sig->v_start_width,
+ .offset_count = sig->mode.vsync_len +
+ sig->mode.vback_porch,
.offset_src = DI_SYNC_HSYNC,
- .repeat_count = sig->height,
+ .repeat_count = sig->mode.vactive,
.cnt_clr_src = DI_SYNC_VSYNC,
} , {
/* 5: Pixel Active, referenced by DC */
.run_src = DI_SYNC_CLK,
- .offset_count = sig->h_sync_width + sig->h_start_width,
+ .offset_count = sig->mode.hsync_len +
+ sig->mode.hback_porch,
.offset_src = DI_SYNC_CLK,
- .repeat_count = sig->width,
+ .repeat_count = sig->mode.hactive,
.cnt_clr_src = 5, /* Line Active */
} , {
/* unused */
@@ -339,9 +341,10 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
} , {
/* 3: Line Active */
.run_src = DI_SYNC_INT_HSYNC,
- .offset_count = sig->v_sync_width + sig->v_start_width,
+ .offset_count = sig->mode.vsync_len +
+ sig->mode.vback_porch,
.offset_src = DI_SYNC_INT_HSYNC,
- .repeat_count = sig->height,
+ .repeat_count = sig->mode.vactive,
.cnt_clr_src = 3 /* VSYNC */,
} , {
/* PIN4: HSYNC for VGA via TVEv2 on TQ MBa53 */
@@ -351,13 +354,14 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
.offset_src = DI_SYNC_CLK,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_CLK,
- .cnt_down = sig->h_sync_width * 2,
+ .cnt_down = sig->mode.hsync_len * 2,
} , {
/* 5: Pixel Active signal to DC */
.run_src = DI_SYNC_CLK,
- .offset_count = sig->h_sync_width + sig->h_start_width,
+ .offset_count = sig->mode.hsync_len +
+ sig->mode.hback_porch,
.offset_src = DI_SYNC_CLK,
- .repeat_count = sig->width,
+ .repeat_count = sig->mode.hactive,
.cnt_clr_src = 4, /* Line Active */
} , {
/* PIN6: VSYNC for VGA via TVEv2 on TQ MBa53 */
@@ -367,7 +371,7 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
.offset_src = DI_SYNC_INT_HSYNC,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_INT_HSYNC,
- .cnt_down = sig->v_sync_width * 2,
+ .cnt_down = sig->mode.vsync_len * 2,
} , {
/* PIN4: HSYNC for VGA via TVEv2 on i.MX53-QSB */
.run_count = h_total - 1,
@@ -376,7 +380,7 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
.offset_src = DI_SYNC_CLK,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_CLK,
- .cnt_down = sig->h_sync_width * 2,
+ .cnt_down = sig->mode.hsync_len * 2,
} , {
/* PIN6: VSYNC for VGA via TVEv2 on i.MX53-QSB */
.run_count = v_total - 1,
@@ -385,7 +389,7 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
.offset_src = DI_SYNC_INT_HSYNC,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_INT_HSYNC,
- .cnt_down = sig->v_sync_width * 2,
+ .cnt_down = sig->mode.vsync_len * 2,
} , {
/* unused */
},
@@ -433,10 +437,10 @@ static void ipu_di_config_clock(struct ipu_di *di,
unsigned long in_rate;
unsigned div;
- clk_set_rate(clk, sig->pixelclock);
+ clk_set_rate(clk, sig->mode.pixelclock);
in_rate = clk_get_rate(clk);
- div = (in_rate + sig->pixelclock / 2) / sig->pixelclock;
+ div = DIV_ROUND_CLOSEST(in_rate, sig->mode.pixelclock);
if (div == 0)
div = 1;
@@ -454,10 +458,10 @@ static void ipu_di_config_clock(struct ipu_di *di,
unsigned div, error;
clkrate = clk_get_rate(di->clk_ipu);
- div = (clkrate + sig->pixelclock / 2) / sig->pixelclock;
+ div = DIV_ROUND_CLOSEST(clkrate, sig->mode.pixelclock);
rate = clkrate / div;
- error = rate / (sig->pixelclock / 1000);
+ error = rate / (sig->mode.pixelclock / 1000);
dev_dbg(di->ipu->dev, " IPU clock can give %lu with divider %u, error %d.%u%%\n",
rate, div, (signed)(error - 1000) / 10, error % 10);
@@ -473,10 +477,10 @@ static void ipu_di_config_clock(struct ipu_di *di,
clk = di->clk_di;
- clk_set_rate(clk, sig->pixelclock);
+ clk_set_rate(clk, sig->mode.pixelclock);
in_rate = clk_get_rate(clk);
- div = (in_rate + sig->pixelclock / 2) / sig->pixelclock;
+ div = DIV_ROUND_CLOSEST(in_rate, sig->mode.pixelclock);
if (div == 0)
div = 1;
@@ -504,35 +508,58 @@ static void ipu_di_config_clock(struct ipu_di *di,
ipu_di_write(di, val, DI_GENERAL);
dev_dbg(di->ipu->dev, "Want %luHz IPU %luHz DI %luHz using %s, %luHz\n",
- sig->pixelclock,
+ sig->mode.pixelclock,
clk_get_rate(di->clk_ipu),
clk_get_rate(di->clk_di),
clk == di->clk_di ? "DI" : "IPU",
clk_get_rate(di->clk_di_pixel) / (clkgen0 >> 4));
}
+/*
+ * This function is called to adjust a video mode to IPU restrictions.
+ * It is meant to be called from drm crtc mode_fixup() methods.
+ */
+int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode)
+{
+ u32 diff;
+
+ if (mode->vfront_porch >= 2)
+ return 0;
+
+ diff = 2 - mode->vfront_porch;
+
+ if (mode->vback_porch >= diff) {
+ mode->vfront_porch = 2;
+ mode->vback_porch -= diff;
+ } else if (mode->vsync_len > diff) {
+ mode->vfront_porch = 2;
+ mode->vsync_len = mode->vsync_len - diff;
+ } else {
+ dev_warn(di->ipu->dev, "failed to adjust videomode\n");
+ return -EINVAL;
+ }
+
+ dev_warn(di->ipu->dev, "videomode adapted for IPU restrictions\n");
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_di_adjust_videomode);
+
int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
{
u32 reg;
u32 di_gen, vsync_cnt;
u32 div;
- u32 h_total, v_total;
dev_dbg(di->ipu->dev, "disp %d: panel size = %d x %d\n",
- di->id, sig->width, sig->height);
+ di->id, sig->mode.hactive, sig->mode.vactive);
- if ((sig->v_sync_width == 0) || (sig->h_sync_width == 0))
+ if ((sig->mode.vsync_len == 0) || (sig->mode.hsync_len == 0))
return -EINVAL;
- h_total = sig->width + sig->h_sync_width + sig->h_start_width +
- sig->h_end_width;
- v_total = sig->height + sig->v_sync_width + sig->v_start_width +
- sig->v_end_width;
-
dev_dbg(di->ipu->dev, "Clocks: IPU %luHz DI %luHz Needed %luHz\n",
clk_get_rate(di->clk_ipu),
clk_get_rate(di->clk_di),
- sig->pixelclock);
+ sig->mode.pixelclock);
mutex_lock(&di_mutex);
@@ -551,7 +578,7 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
di_gen = ipu_di_read(di, DI_GENERAL) & DI_GEN_DI_CLK_EXT;
di_gen |= DI_GEN_DI_VSYNC_EXT;
- if (sig->interlaced) {
+ if (sig->mode.flags & DISPLAY_FLAGS_INTERLACED) {
ipu_di_sync_config_interlaced(di, sig);
/* set y_sel = 1 */
@@ -561,9 +588,9 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
vsync_cnt = 7;
- if (sig->Hsync_pol)
+ if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH)
di_gen |= DI_GEN_POLARITY_3;
- if (sig->Vsync_pol)
+ if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH)
di_gen |= DI_GEN_POLARITY_2;
} else {
ipu_di_sync_config_noninterlaced(di, sig, div);
@@ -577,7 +604,7 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
if (!(sig->hsync_pin == 2 && sig->vsync_pin == 3))
vsync_cnt = 6;
- if (sig->Hsync_pol) {
+ if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH) {
if (sig->hsync_pin == 2)
di_gen |= DI_GEN_POLARITY_2;
else if (sig->hsync_pin == 4)
@@ -585,7 +612,7 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
else if (sig->hsync_pin == 7)
di_gen |= DI_GEN_POLARITY_7;
}
- if (sig->Vsync_pol) {
+ if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH) {
if (sig->vsync_pin == 3)
di_gen |= DI_GEN_POLARITY_3;
else if (sig->vsync_pin == 6)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 1bc0c170f12a..b0e58522780d 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -97,6 +97,8 @@ static const struct idle_cpu *icpu;
static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
static int intel_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index);
+static void intel_idle_freeze(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index);
static int intel_idle_cpu_init(int cpu);
static struct cpuidle_state *cpuidle_state_table;
@@ -131,28 +133,32 @@ static struct cpuidle_state nehalem_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 3,
.target_residency = 6,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-NHM",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-NHM",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 20,
.target_residency = 80,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-NHM",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 200,
.target_residency = 800,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -164,35 +170,40 @@ static struct cpuidle_state snb_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 2,
.target_residency = 2,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-SNB",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-SNB",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 80,
.target_residency = 211,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-SNB",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 104,
.target_residency = 345,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C7-SNB",
.desc = "MWAIT 0x30",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 109,
.target_residency = 345,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -204,42 +215,48 @@ static struct cpuidle_state byt_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-BYT",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 15,
.target_residency = 30,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6N-BYT",
.desc = "MWAIT 0x58",
.flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 40,
.target_residency = 275,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6S-BYT",
.desc = "MWAIT 0x52",
.flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 140,
.target_residency = 560,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C7-BYT",
.desc = "MWAIT 0x60",
.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 1200,
.target_residency = 1500,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C7S-BYT",
.desc = "MWAIT 0x64",
.flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 10000,
.target_residency = 20000,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -251,35 +268,40 @@ static struct cpuidle_state ivb_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-IVB",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-IVB",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 156,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-IVB",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 80,
.target_residency = 300,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C7-IVB",
.desc = "MWAIT 0x30",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 87,
.target_residency = 300,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -291,28 +313,32 @@ static struct cpuidle_state ivt_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-IVT",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 80,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-IVT",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 156,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-IVT",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 82,
.target_residency = 300,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -324,28 +350,32 @@ static struct cpuidle_state ivt_cstates_4s[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-IVT-4S",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 250,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-IVT-4S",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 300,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-IVT-4S",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 84,
.target_residency = 400,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -357,28 +387,32 @@ static struct cpuidle_state ivt_cstates_8s[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-IVT-8S",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 500,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-IVT-8S",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 600,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-IVT-8S",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 88,
.target_residency = 700,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -390,56 +424,64 @@ static struct cpuidle_state hsw_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 2,
.target_residency = 2,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-HSW",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-HSW",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 33,
.target_residency = 100,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-HSW",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 133,
.target_residency = 400,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C7s-HSW",
.desc = "MWAIT 0x32",
.flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 166,
.target_residency = 500,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C8-HSW",
.desc = "MWAIT 0x40",
.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 300,
.target_residency = 900,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C9-HSW",
.desc = "MWAIT 0x50",
.flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 600,
.target_residency = 1800,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C10-HSW",
.desc = "MWAIT 0x60",
.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 2600,
.target_residency = 7700,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -450,56 +492,64 @@ static struct cpuidle_state bdw_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 2,
.target_residency = 2,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C1E-BDW",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C3-BDW",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 40,
.target_residency = 100,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-BDW",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 133,
.target_residency = 400,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C7s-BDW",
.desc = "MWAIT 0x32",
.flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 166,
.target_residency = 500,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C8-BDW",
.desc = "MWAIT 0x40",
.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 300,
.target_residency = 900,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C9-BDW",
.desc = "MWAIT 0x50",
.flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 600,
.target_residency = 1800,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C10-BDW",
.desc = "MWAIT 0x60",
.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 2600,
.target_residency = 7700,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -511,28 +561,32 @@ static struct cpuidle_state atom_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 10,
.target_residency = 20,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C2-ATM",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10),
.exit_latency = 20,
.target_residency = 80,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C4-ATM",
.desc = "MWAIT 0x30",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 100,
.target_residency = 400,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-ATM",
.desc = "MWAIT 0x52",
.flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 140,
.target_residency = 560,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -543,14 +597,16 @@ static struct cpuidle_state avn_cstates[] = {
.flags = MWAIT2flg(0x00),
.exit_latency = 2,
.target_residency = 2,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.name = "C6-AVN",
.desc = "MWAIT 0x51",
.flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 15,
.target_residency = 45,
- .enter = &intel_idle },
+ .enter = &intel_idle,
+ .enter_freeze = intel_idle_freeze, },
{
.enter = NULL }
};
@@ -592,6 +648,21 @@ static int intel_idle(struct cpuidle_device *dev,
return index;
}
+/**
+ * intel_idle_freeze - simplified "enter" callback routine for suspend-to-idle
+ * @dev: cpuidle_device
+ * @drv: cpuidle driver
+ * @index: state index
+ */
+static void intel_idle_freeze(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ unsigned long ecx = 1; /* break on interrupt flag */
+ unsigned long eax = flg2MWAIT(drv->states[index].flags);
+
+ mwait_idle_with_hints(eax, ecx);
+}
+
static void __setup_broadcast_timer(void *arg)
{
unsigned long reason = (unsigned long)arg;
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index aafdbcd84fc4..8fb295e4a9ab 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -700,37 +700,24 @@ static const struct file_operations ep_debugfs_fops = {
static int setup_debugfs(struct c4iw_dev *devp)
{
- struct dentry *de;
-
if (!devp->debugfs_root)
return -1;
- de = debugfs_create_file("qps", S_IWUSR, devp->debugfs_root,
- (void *)devp, &qp_debugfs_fops);
- if (de && de->d_inode)
- de->d_inode->i_size = 4096;
+ debugfs_create_file_size("qps", S_IWUSR, devp->debugfs_root,
+ (void *)devp, &qp_debugfs_fops, 4096);
- de = debugfs_create_file("stags", S_IWUSR, devp->debugfs_root,
- (void *)devp, &stag_debugfs_fops);
- if (de && de->d_inode)
- de->d_inode->i_size = 4096;
+ debugfs_create_file_size("stags", S_IWUSR, devp->debugfs_root,
+ (void *)devp, &stag_debugfs_fops, 4096);
- de = debugfs_create_file("stats", S_IWUSR, devp->debugfs_root,
- (void *)devp, &stats_debugfs_fops);
- if (de && de->d_inode)
- de->d_inode->i_size = 4096;
+ debugfs_create_file_size("stats", S_IWUSR, devp->debugfs_root,
+ (void *)devp, &stats_debugfs_fops, 4096);
- de = debugfs_create_file("eps", S_IWUSR, devp->debugfs_root,
- (void *)devp, &ep_debugfs_fops);
- if (de && de->d_inode)
- de->d_inode->i_size = 4096;
+ debugfs_create_file_size("eps", S_IWUSR, devp->debugfs_root,
+ (void *)devp, &ep_debugfs_fops, 4096);
- if (c4iw_wr_log) {
- de = debugfs_create_file("wr_log", S_IWUSR, devp->debugfs_root,
- (void *)devp, &wr_log_debugfs_fops);
- if (de && de->d_inode)
- de->d_inode->i_size = 4096;
- }
+ if (c4iw_wr_log)
+ debugfs_create_file_size("wr_log", S_IWUSR, devp->debugfs_root,
+ (void *)devp, &wr_log_debugfs_fops, 4096);
return 0;
}
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 9516a324be6d..42965d2476bb 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o
obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o
+obj-$(CONFIG_ARCH_DIGICOLOR) += irq-digicolor.o
diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c
new file mode 100644
index 000000000000..930a2a2fac7f
--- /dev/null
+++ b/drivers/irqchip/irq-digicolor.c
@@ -0,0 +1,120 @@
+/*
+ * Conexant Digicolor SoCs IRQ chip driver
+ *
+ * Author: Baruch Siach <baruch@tkos.co.il>
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define UC_IRQ_CONTROL 0x04
+
+#define IC_FLAG_CLEAR_LO 0x00
+#define IC_FLAG_CLEAR_XLO 0x04
+#define IC_INT0ENABLE_LO 0x10
+#define IC_INT0ENABLE_XLO 0x14
+#define IC_INT0STATUS_LO 0x18
+#define IC_INT0STATUS_XLO 0x1c
+
+static struct irq_domain *digicolor_irq_domain;
+
+static void __exception_irq_entry digicolor_handle_irq(struct pt_regs *regs)
+{
+ struct irq_domain_chip_generic *dgc = digicolor_irq_domain->gc;
+ struct irq_chip_generic *gc = dgc->gc[0];
+ u32 status, hwirq;
+
+ do {
+ status = irq_reg_readl(gc, IC_INT0STATUS_LO);
+ if (status) {
+ hwirq = ffs(status) - 1;
+ } else {
+ status = irq_reg_readl(gc, IC_INT0STATUS_XLO);
+ if (status)
+ hwirq = ffs(status) - 1 + 32;
+ else
+ return;
+ }
+
+ handle_domain_irq(digicolor_irq_domain, hwirq, regs);
+ } while (1);
+}
+
+static void digicolor_set_gc(void __iomem *reg_base, unsigned irq_base,
+ unsigned en_reg, unsigned ack_reg)
+{
+ struct irq_chip_generic *gc;
+
+ gc = irq_get_domain_generic_chip(digicolor_irq_domain, irq_base);
+ gc->reg_base = reg_base;
+ gc->chip_types[0].regs.ack = ack_reg;
+ gc->chip_types[0].regs.mask = en_reg;
+ gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+ gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+}
+
+static int __init digicolor_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ static void __iomem *reg_base;
+ unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+ struct regmap *ucregs;
+ int ret;
+
+ reg_base = of_iomap(node, 0);
+ if (!reg_base) {
+ pr_err("%s: unable to map IC registers\n", node->full_name);
+ return -ENXIO;
+ }
+
+ /* disable all interrupts */
+ writel(0, reg_base + IC_INT0ENABLE_LO);
+ writel(0, reg_base + IC_INT0ENABLE_XLO);
+
+ ucregs = syscon_regmap_lookup_by_phandle(node, "syscon");
+ if (IS_ERR(ucregs)) {
+ pr_err("%s: unable to map UC registers\n", node->full_name);
+ return PTR_ERR(ucregs);
+ }
+ /* channel 1, regular IRQs */
+ regmap_write(ucregs, UC_IRQ_CONTROL, 1);
+
+ digicolor_irq_domain =
+ irq_domain_add_linear(node, 64, &irq_generic_chip_ops, NULL);
+ if (!digicolor_irq_domain) {
+ pr_err("%s: unable to create IRQ domain\n", node->full_name);
+ return -ENOMEM;
+ }
+
+ ret = irq_alloc_domain_generic_chips(digicolor_irq_domain, 32, 1,
+ "digicolor_irq", handle_level_irq,
+ clr, 0, 0);
+ if (ret) {
+ pr_err("%s: unable to allocate IRQ gc\n", node->full_name);
+ return ret;
+ }
+
+ digicolor_set_gc(reg_base, 0, IC_INT0ENABLE_LO, IC_FLAG_CLEAR_LO);
+ digicolor_set_gc(reg_base, 32, IC_INT0ENABLE_XLO, IC_FLAG_CLEAR_XLO);
+
+ set_handle_irq(digicolor_handle_irq);
+
+ return 0;
+}
+IRQCHIP_DECLARE(conexant_digicolor_ic, "cnxt,cx92755-ic", digicolor_of_init);
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index 61541ff24397..ad96ebb0c7ab 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -21,7 +21,7 @@
#include "irq-gic-common.h"
-void gic_configure_irq(unsigned int irq, unsigned int type,
+int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void))
{
u32 enablemask = 1 << (irq % 32);
@@ -29,16 +29,17 @@ void gic_configure_irq(unsigned int irq, unsigned int type,
u32 confmask = 0x2 << ((irq % 16) * 2);
u32 confoff = (irq / 16) * 4;
bool enabled = false;
- u32 val;
+ u32 val, oldval;
+ int ret = 0;
/*
* Read current configuration register, and insert the config
* for "irq", depending on "type".
*/
- val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
- if (type == IRQ_TYPE_LEVEL_HIGH)
+ val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
+ if (type & IRQ_TYPE_LEVEL_MASK)
val &= ~confmask;
- else if (type == IRQ_TYPE_EDGE_RISING)
+ else if (type & IRQ_TYPE_EDGE_BOTH)
val |= confmask;
/*
@@ -54,15 +55,20 @@ void gic_configure_irq(unsigned int irq, unsigned int type,
/*
* Write back the new configuration, and possibly re-enable
- * the interrupt.
+ * the interrupt. If we tried to write a new configuration and failed,
+ * return an error.
*/
writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
+ if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval)
+ ret = -EINVAL;
if (enabled)
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
if (sync_access)
sync_access();
+
+ return ret;
}
void __init gic_dist_config(void __iomem *base, int gic_irqs,
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index b41f02481c3a..35a9884778bd 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -20,7 +20,7 @@
#include <linux/of.h>
#include <linux/irqdomain.h>
-void gic_configure_irq(unsigned int irq, unsigned int type,
+int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void));
void gic_dist_config(void __iomem *base, int gic_irqs,
void (*sync_access)(void));
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 2ab290bec655..1c6dea2fbc34 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -238,7 +238,9 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
if (irq < 16)
return -EINVAL;
- if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+ /* SPIs have restrictions on the supported types */
+ if (irq >= 32 && type != IRQ_TYPE_LEVEL_HIGH &&
+ type != IRQ_TYPE_EDGE_RISING)
return -EINVAL;
if (gic_irq_in_rdist(d)) {
@@ -249,9 +251,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
rwp_wait = gic_dist_wait_for_rwp;
}
- gic_configure_irq(irq, type, base, rwp_wait);
-
- return 0;
+ return gic_configure_irq(irq, type, base, rwp_wait);
}
static u64 gic_mpidr_to_affinity(u64 mpidr)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index d617ee5a3d8a..4634cf7d0ec3 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -188,12 +188,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
{
void __iomem *base = gic_dist_base(d);
unsigned int gicirq = gic_irq(d);
+ int ret;
/* Interrupt configuration for SGIs can't be changed */
if (gicirq < 16)
return -EINVAL;
- if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+ /* SPIs have restrictions on the supported types */
+ if (gicirq >= 32 && type != IRQ_TYPE_LEVEL_HIGH &&
+ type != IRQ_TYPE_EDGE_RISING)
return -EINVAL;
raw_spin_lock(&irq_controller_lock);
@@ -201,11 +204,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
if (gic_arch_extn.irq_set_type)
gic_arch_extn.irq_set_type(d, type);
- gic_configure_irq(gicirq, type, base, NULL);
+ ret = gic_configure_irq(gicirq, type, base, NULL);
raw_spin_unlock(&irq_controller_lock);
- return 0;
+ return ret;
}
static int gic_retrigger(struct irq_data *d)
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index 6bc2deb73d53..7d6ffb5de84f 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -120,21 +120,24 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type)
{
void __iomem *base = hip04_dist_base(d);
unsigned int irq = hip04_irq(d);
+ int ret;
/* Interrupt configuration for SGIs can't be changed */
if (irq < 16)
return -EINVAL;
- if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+ /* SPIs have restrictions on the supported types */
+ if (irq >= 32 && type != IRQ_TYPE_LEVEL_HIGH &&
+ type != IRQ_TYPE_EDGE_RISING)
return -EINVAL;
raw_spin_lock(&irq_controller_lock);
- gic_configure_irq(irq, type, base, NULL);
+ ret = gic_configure_irq(irq, type, base, NULL);
raw_spin_unlock(&irq_controller_lock);
- return 0;
+ return ret;
}
#ifdef CONFIG_SMP
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 56b96c63dc4b..1daa7ca04577 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -235,9 +235,9 @@ int gic_get_c0_perfcount_int(void)
GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_PERFCTR));
}
-static unsigned int gic_get_int(void)
+static void gic_handle_shared_int(void)
{
- unsigned int i;
+ unsigned int i, intr, virq;
unsigned long *pcpu_mask;
unsigned long pending_reg, intrmask_reg;
DECLARE_BITMAP(pending, GIC_MAX_INTRS);
@@ -259,7 +259,16 @@ static unsigned int gic_get_int(void)
bitmap_and(pending, pending, intrmask, gic_shared_intrs);
bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
- return find_first_bit(pending, gic_shared_intrs);
+ intr = find_first_bit(pending, gic_shared_intrs);
+ while (intr != gic_shared_intrs) {
+ virq = irq_linear_revmap(gic_irq_domain,
+ GIC_SHARED_TO_HWIRQ(intr));
+ do_IRQ(virq);
+
+ /* go to next pending bit */
+ bitmap_clear(pending, intr, 1);
+ intr = find_first_bit(pending, gic_shared_intrs);
+ }
}
static void gic_mask_irq(struct irq_data *d)
@@ -386,16 +395,26 @@ static struct irq_chip gic_edge_irq_controller = {
#endif
};
-static unsigned int gic_get_local_int(void)
+static void gic_handle_local_int(void)
{
unsigned long pending, masked;
+ unsigned int intr, virq;
pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));
bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
- return find_first_bit(&pending, GIC_NUM_LOCAL_INTRS);
+ intr = find_first_bit(&pending, GIC_NUM_LOCAL_INTRS);
+ while (intr != GIC_NUM_LOCAL_INTRS) {
+ virq = irq_linear_revmap(gic_irq_domain,
+ GIC_LOCAL_TO_HWIRQ(intr));
+ do_IRQ(virq);
+
+ /* go to next pending bit */
+ bitmap_clear(&pending, intr, 1);
+ intr = find_first_bit(&pending, GIC_NUM_LOCAL_INTRS);
+ }
}
static void gic_mask_local_irq(struct irq_data *d)
@@ -454,19 +473,8 @@ static struct irq_chip gic_all_vpes_local_irq_controller = {
static void __gic_irq_dispatch(void)
{
- unsigned int intr, virq;
-
- while ((intr = gic_get_local_int()) != GIC_NUM_LOCAL_INTRS) {
- virq = irq_linear_revmap(gic_irq_domain,
- GIC_LOCAL_TO_HWIRQ(intr));
- do_IRQ(virq);
- }
-
- while ((intr = gic_get_int()) != gic_shared_intrs) {
- virq = irq_linear_revmap(gic_irq_domain,
- GIC_SHARED_TO_HWIRQ(intr));
- do_IRQ(virq);
- }
+ gic_handle_local_int();
+ gic_handle_shared_int();
}
static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc)
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index 0b0d2c00a2df..eaf0a710e98a 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -23,8 +23,6 @@
#include "irqchip.h"
-#define MT6577_SYS_INTPOL_NUM (224)
-
struct mtk_sysirq_chip_data {
spinlock_t lock;
void __iomem *intpol_base;
@@ -124,7 +122,8 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
{
struct irq_domain *domain, *domain_parent;
struct mtk_sysirq_chip_data *chip_data;
- int ret = 0;
+ int ret, size, intpol_num;
+ struct resource res;
domain_parent = irq_find_host(parent);
if (!domain_parent) {
@@ -132,19 +131,24 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
return -EINVAL;
}
+ ret = of_address_to_resource(node, 0, &res);
+ if (ret)
+ return ret;
+
chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
if (!chip_data)
return -ENOMEM;
- chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol");
- if (IS_ERR(chip_data->intpol_base)) {
+ size = resource_size(&res);
+ intpol_num = size * 8;
+ chip_data->intpol_base = ioremap(res.start, size);
+ if (!chip_data->intpol_base) {
pr_err("mtk_sysirq: unable to map sysirq register\n");
ret = PTR_ERR(chip_data->intpol_base);
goto out_free;
}
- domain = irq_domain_add_hierarchy(domain_parent, 0,
- MT6577_SYS_INTPOL_NUM, node,
+ domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
&sysirq_domain_ops, chip_data);
if (!domain) {
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c
index c03f140acbae..a569c6dbd1d1 100644
--- a/drivers/irqchip/irq-omap-intc.c
+++ b/drivers/irqchip/irq-omap-intc.c
@@ -364,14 +364,6 @@ out:
omap_ack_irq(NULL);
}
-void __init omap2_init_irq(void)
-{
- omap_nr_irqs = 96;
- omap_nr_pending = 3;
- omap_init_irq(OMAP24XX_IC_BASE, NULL);
- set_handle_irq(omap_intc_handle_irq);
-}
-
void __init omap3_init_irq(void)
{
omap_nr_irqs = 96;
@@ -380,14 +372,6 @@ void __init omap3_init_irq(void)
set_handle_irq(omap_intc_handle_irq);
}
-void __init ti81xx_init_irq(void)
-{
- omap_nr_irqs = 96;
- omap_nr_pending = 4;
- omap_init_irq(OMAP34XX_IC_BASE, NULL);
- set_handle_irq(omap_intc_handle_irq);
-}
-
static int __init intc_of_init(struct device_node *node,
struct device_node *parent)
{
@@ -399,7 +383,9 @@ static int __init intc_of_init(struct device_node *node,
if (WARN_ON(!node))
return -ENODEV;
- if (of_device_is_compatible(node, "ti,am33xx-intc")) {
+ if (of_device_is_compatible(node, "ti,dm814-intc") ||
+ of_device_is_compatible(node, "ti,dm816-intc") ||
+ of_device_is_compatible(node, "ti,am33xx-intc")) {
omap_nr_irqs = 128;
omap_nr_pending = 4;
}
@@ -415,4 +401,6 @@ static int __init intc_of_init(struct device_node *node,
IRQCHIP_DECLARE(omap2_intc, "ti,omap2-intc", intc_of_init);
IRQCHIP_DECLARE(omap3_intc, "ti,omap3-intc", intc_of_init);
+IRQCHIP_DECLARE(dm814x_intc, "ti,dm814-intc", intc_of_init);
+IRQCHIP_DECLARE(dm816x_intc, "ti,dm816-intc", intc_of_init);
IRQCHIP_DECLARE(am33xx_intc, "ti,am33xx-intc", intc_of_init);
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 078cac5e2d08..9a0767b9c89d 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -30,6 +30,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/of_device.h>
#include <linux/platform_data/irq-renesas-intc-irqpin.h>
#include <linux/pm_runtime.h>
@@ -40,7 +41,9 @@
#define INTC_IRQPIN_REG_SOURCE 2 /* INTREQnn */
#define INTC_IRQPIN_REG_MASK 3 /* INTMSKnn */
#define INTC_IRQPIN_REG_CLEAR 4 /* INTMSKCLRnn */
-#define INTC_IRQPIN_REG_NR 5
+#define INTC_IRQPIN_REG_NR_MANDATORY 5
+#define INTC_IRQPIN_REG_IRLM 5 /* ICR0 with IRLM bit (optional) */
+#define INTC_IRQPIN_REG_NR 6
/* INTC external IRQ PIN hardware register access:
*
@@ -82,6 +85,10 @@ struct intc_irqpin_priv {
u8 shared_irq_mask;
};
+struct intc_irqpin_irlm_config {
+ unsigned int irlm_bit;
+};
+
static unsigned long intc_irqpin_read32(void __iomem *iomem)
{
return ioread32(iomem);
@@ -345,10 +352,23 @@ static struct irq_domain_ops intc_irqpin_irq_domain_ops = {
.xlate = irq_domain_xlate_twocell,
};
+static const struct intc_irqpin_irlm_config intc_irqpin_irlm_r8a7779 = {
+ .irlm_bit = 23, /* ICR0.IRLM0 */
+};
+
+static const struct of_device_id intc_irqpin_dt_ids[] = {
+ { .compatible = "renesas,intc-irqpin", },
+ { .compatible = "renesas,intc-irqpin-r8a7779",
+ .data = &intc_irqpin_irlm_r8a7779 },
+ {},
+};
+MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids);
+
static int intc_irqpin_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct renesas_intc_irqpin_config *pdata = dev->platform_data;
+ const struct of_device_id *of_id;
struct intc_irqpin_priv *p;
struct intc_irqpin_iomem *i;
struct resource *io[INTC_IRQPIN_REG_NR];
@@ -391,10 +411,11 @@ static int intc_irqpin_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
- /* get hold of manadatory IOMEM */
+ /* get hold of register banks */
+ memset(io, 0, sizeof(io));
for (k = 0; k < INTC_IRQPIN_REG_NR; k++) {
io[k] = platform_get_resource(pdev, IORESOURCE_MEM, k);
- if (!io[k]) {
+ if (!io[k] && k < INTC_IRQPIN_REG_NR_MANDATORY) {
dev_err(dev, "not enough IOMEM resources\n");
ret = -EINVAL;
goto err0;
@@ -422,6 +443,10 @@ static int intc_irqpin_probe(struct platform_device *pdev)
for (k = 0; k < INTC_IRQPIN_REG_NR; k++) {
i = &p->iomem[k];
+ /* handle optional registers */
+ if (!io[k])
+ continue;
+
switch (resource_size(io[k])) {
case 1:
i->width = 8;
@@ -448,6 +473,19 @@ static int intc_irqpin_probe(struct platform_device *pdev)
}
}
+ /* configure "individual IRQ mode" where needed */
+ of_id = of_match_device(intc_irqpin_dt_ids, dev);
+ if (of_id && of_id->data) {
+ const struct intc_irqpin_irlm_config *irlm_config = of_id->data;
+
+ if (io[INTC_IRQPIN_REG_IRLM])
+ intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_IRLM,
+ irlm_config->irlm_bit,
+ 1, 1);
+ else
+ dev_warn(dev, "unable to select IRLM mode\n");
+ }
+
/* mask all interrupts using priority */
for (k = 0; k < p->number_of_irqs; k++)
intc_irqpin_mask_unmask_prio(p, k, 1);
@@ -550,12 +588,6 @@ static int intc_irqpin_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id intc_irqpin_dt_ids[] = {
- { .compatible = "renesas,intc-irqpin", },
- {},
-};
-MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids);
-
static struct platform_driver intc_irqpin_device_driver = {
.probe = intc_irqpin_probe,
.remove = intc_irqpin_remove,
diff --git a/drivers/lguest/Makefile b/drivers/lguest/Makefile
index c4197503900e..16f52ee73994 100644
--- a/drivers/lguest/Makefile
+++ b/drivers/lguest/Makefile
@@ -1,6 +1,3 @@
-# Guest requires the device configuration and probing code.
-obj-$(CONFIG_LGUEST_GUEST) += lguest_device.o
-
# Host requires the other files, which can be a module.
obj-$(CONFIG_LGUEST) += lg.o
lg-y = core.o hypercalls.o page_tables.o interrupts_and_traps.o \
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 6590558d1d31..7dc93aa004c8 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -208,6 +208,14 @@ void __lgwrite(struct lg_cpu *cpu, unsigned long addr, const void *b,
*/
int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
{
+ /* If the launcher asked for a register with LHREQ_GETREG */
+ if (cpu->reg_read) {
+ if (put_user(*cpu->reg_read, user))
+ return -EFAULT;
+ cpu->reg_read = NULL;
+ return sizeof(*cpu->reg_read);
+ }
+
/* We stop running once the Guest is dead. */
while (!cpu->lg->dead) {
unsigned int irq;
@@ -217,21 +225,12 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
if (cpu->hcall)
do_hypercalls(cpu);
- /*
- * It's possible the Guest did a NOTIFY hypercall to the
- * Launcher.
- */
- if (cpu->pending_notify) {
- /*
- * Does it just needs to write to a registered
- * eventfd (ie. the appropriate virtqueue thread)?
- */
- if (!send_notify_to_eventfd(cpu)) {
- /* OK, we tell the main Launcher. */
- if (put_user(cpu->pending_notify, user))
- return -EFAULT;
- return sizeof(cpu->pending_notify);
- }
+ /* Do we have to tell the Launcher about a trap? */
+ if (cpu->pending.trap) {
+ if (copy_to_user(user, &cpu->pending,
+ sizeof(cpu->pending)))
+ return -EFAULT;
+ return sizeof(cpu->pending);
}
/*
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 83511eb0923d..1219af493c0f 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -117,9 +117,6 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
/* Similarly, this sets the halted flag for run_guest(). */
cpu->halted = 1;
break;
- case LHCALL_NOTIFY:
- cpu->pending_notify = args->arg1;
- break;
default:
/* It should be an architecture-specific hypercall. */
if (lguest_arch_do_hcall(cpu, args))
@@ -189,7 +186,7 @@ static void do_async_hcalls(struct lg_cpu *cpu)
* Stop doing hypercalls if they want to notify the Launcher:
* it needs to service this first.
*/
- if (cpu->pending_notify)
+ if (cpu->pending.trap)
break;
}
}
@@ -280,7 +277,7 @@ void do_hypercalls(struct lg_cpu *cpu)
* NOTIFY to the Launcher, we want to return now. Otherwise we do
* the hypercall.
*/
- if (!cpu->pending_notify) {
+ if (!cpu->pending.trap) {
do_hcall(cpu, cpu->hcall);
/*
* Tricky point: we reset the hcall pointer to mark the
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 2eef40be4c04..307e8b39e7d1 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -50,7 +50,10 @@ struct lg_cpu {
/* Bitmap of what has changed: see CHANGED_* above. */
int changed;
- unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
+ /* Pending operation. */
+ struct lguest_pending pending;
+
+ unsigned long *reg_read; /* register from LHREQ_GETREG */
/* At end of a page shared mapped over lguest_pages in guest. */
unsigned long regs_page;
@@ -78,24 +81,18 @@ struct lg_cpu {
struct lg_cpu_arch arch;
};
-struct lg_eventfd {
- unsigned long addr;
- struct eventfd_ctx *event;
-};
-
-struct lg_eventfd_map {
- unsigned int num;
- struct lg_eventfd map[];
-};
-
/* The private info the thread maintains about the guest. */
struct lguest {
struct lguest_data __user *lguest_data;
struct lg_cpu cpus[NR_CPUS];
unsigned int nr_cpus;
+ /* Valid guest memory pages must be < this. */
u32 pfn_limit;
+ /* Device memory is >= pfn_limit and < device_limit. */
+ u32 device_limit;
+
/*
* This provides the offset to the base of guest-physical memory in the
* Launcher.
@@ -110,8 +107,6 @@ struct lguest {
unsigned int stack_pages;
u32 tsc_khz;
- struct lg_eventfd_map *eventfds;
-
/* Dead? */
const char *dead;
};
@@ -197,8 +192,10 @@ void guest_pagetable_flush_user(struct lg_cpu *cpu);
void guest_set_pte(struct lg_cpu *cpu, unsigned long gpgdir,
unsigned long vaddr, pte_t val);
void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages);
-bool demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode);
+bool demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode,
+ unsigned long *iomem);
void pin_page(struct lg_cpu *cpu, unsigned long vaddr);
+bool __guest_pa(struct lg_cpu *cpu, unsigned long vaddr, unsigned long *paddr);
unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr);
void page_table_guest_data_init(struct lg_cpu *cpu);
@@ -210,6 +207,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu);
int lguest_arch_init_hypercalls(struct lg_cpu *cpu);
int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args);
void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start);
+unsigned long *lguest_arch_regptr(struct lg_cpu *cpu, size_t reg_off, bool any);
/* <arch>/switcher.S: */
extern char start_switcher_text[], end_switcher_text[], switch_to_guest[];
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
deleted file mode 100644
index 89088d6538fd..000000000000
--- a/drivers/lguest/lguest_device.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*P:050
- * Lguest guests use a very simple method to describe devices. It's a
- * series of device descriptors contained just above the top of normal Guest
- * memory.
- *
- * We use the standard "virtio" device infrastructure, which provides us with a
- * console, a network and a block driver. Each one expects some configuration
- * information and a "virtqueue" or two to send and receive data.
-:*/
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/lguest_launcher.h>
-#include <linux/virtio.h>
-#include <linux/virtio_config.h>
-#include <linux/interrupt.h>
-#include <linux/virtio_ring.h>
-#include <linux/err.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/paravirt.h>
-#include <asm/lguest_hcall.h>
-
-/* The pointer to our (page) of device descriptions. */
-static void *lguest_devices;
-
-/*
- * For Guests, device memory can be used as normal memory, so we cast away the
- * __iomem to quieten sparse.
- */
-static inline void *lguest_map(unsigned long phys_addr, unsigned long pages)
-{
- return (__force void *)ioremap_cache(phys_addr, PAGE_SIZE*pages);
-}
-
-static inline void lguest_unmap(void *addr)
-{
- iounmap((__force void __iomem *)addr);
-}
-
-/*D:100
- * Each lguest device is just a virtio device plus a pointer to its entry
- * in the lguest_devices page.
- */
-struct lguest_device {
- struct virtio_device vdev;
-
- /* The entry in the lguest_devices page for this device. */
- struct lguest_device_desc *desc;
-};
-
-/*
- * Since the virtio infrastructure hands us a pointer to the virtio_device all
- * the time, it helps to have a curt macro to get a pointer to the struct
- * lguest_device it's enclosed in.
- */
-#define to_lgdev(vd) container_of(vd, struct lguest_device, vdev)
-
-/*D:130
- * Device configurations
- *
- * The configuration information for a device consists of one or more
- * virtqueues, a feature bitmap, and some configuration bytes. The
- * configuration bytes don't really matter to us: the Launcher sets them up, and
- * the driver will look at them during setup.
- *
- * A convenient routine to return the device's virtqueue config array:
- * immediately after the descriptor.
- */
-static struct lguest_vqconfig *lg_vq(const struct lguest_device_desc *desc)
-{
- return (void *)(desc + 1);
-}
-
-/* The features come immediately after the virtqueues. */
-static u8 *lg_features(const struct lguest_device_desc *desc)
-{
- return (void *)(lg_vq(desc) + desc->num_vq);
-}
-
-/* The config space comes after the two feature bitmasks. */
-static u8 *lg_config(const struct lguest_device_desc *desc)
-{
- return lg_features(desc) + desc->feature_len * 2;
-}
-
-/* The total size of the config page used by this device (incl. desc) */
-static unsigned desc_size(const struct lguest_device_desc *desc)
-{
- return sizeof(*desc)
- + desc->num_vq * sizeof(struct lguest_vqconfig)
- + desc->feature_len * 2
- + desc->config_len;
-}
-
-/* This gets the device's feature bits. */
-static u64 lg_get_features(struct virtio_device *vdev)
-{
- unsigned int i;
- u32 features = 0;
- struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
- u8 *in_features = lg_features(desc);
-
- /* We do this the slow but generic way. */
- for (i = 0; i < min(desc->feature_len * 8, 32); i++)
- if (in_features[i / 8] & (1 << (i % 8)))
- features |= (1 << i);
-
- return features;
-}
-
-/*
- * To notify on reset or feature finalization, we (ab)use the NOTIFY
- * hypercall, with the descriptor address of the device.
- */
-static void status_notify(struct virtio_device *vdev)
-{
- unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices;
-
- hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0);
-}
-
-/*
- * The virtio core takes the features the Host offers, and copies the ones
- * supported by the driver into the vdev->features array. Once that's all
- * sorted out, this routine is called so we can tell the Host which features we
- * understand and accept.
- */
-static int lg_finalize_features(struct virtio_device *vdev)
-{
- unsigned int i, bits;
- struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
- /* Second half of bitmap is features we accept. */
- u8 *out_features = lg_features(desc) + desc->feature_len;
-
- /* Give virtio_ring a chance to accept features. */
- vring_transport_features(vdev);
-
- /* Make sure we don't have any features > 32 bits! */
- BUG_ON((u32)vdev->features != vdev->features);
-
- /*
- * Since lguest is currently x86-only, we're little-endian. That
- * means we could just memcpy. But it's not time critical, and in
- * case someone copies this code, we do it the slow, obvious way.
- */
- memset(out_features, 0, desc->feature_len);
- bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
- for (i = 0; i < bits; i++) {
- if (__virtio_test_bit(vdev, i))
- out_features[i / 8] |= (1 << (i % 8));
- }
-
- /* Tell Host we've finished with this device's feature negotiation */
- status_notify(vdev);
-
- return 0;
-}
-
-/* Once they've found a field, getting a copy of it is easy. */
-static void lg_get(struct virtio_device *vdev, unsigned int offset,
- void *buf, unsigned len)
-{
- struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
-
- /* Check they didn't ask for more than the length of the config! */
- BUG_ON(offset + len > desc->config_len);
- memcpy(buf, lg_config(desc) + offset, len);
-}
-
-/* Setting the contents is also trivial. */
-static void lg_set(struct virtio_device *vdev, unsigned int offset,
- const void *buf, unsigned len)
-{
- struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
-
- /* Check they didn't ask for more than the length of the config! */
- BUG_ON(offset + len > desc->config_len);
- memcpy(lg_config(desc) + offset, buf, len);
-}
-
-/*
- * The operations to get and set the status word just access the status field
- * of the device descriptor.
- */
-static u8 lg_get_status(struct virtio_device *vdev)
-{
- return to_lgdev(vdev)->desc->status;
-}
-
-static void lg_set_status(struct virtio_device *vdev, u8 status)
-{
- BUG_ON(!status);
- to_lgdev(vdev)->desc->status = status;
-
- /* Tell Host immediately if we failed. */
- if (status & VIRTIO_CONFIG_S_FAILED)
- status_notify(vdev);
-}
-
-static void lg_reset(struct virtio_device *vdev)
-{
- /* 0 status means "reset" */
- to_lgdev(vdev)->desc->status = 0;
- status_notify(vdev);
-}
-
-/*
- * Virtqueues
- *
- * The other piece of infrastructure virtio needs is a "virtqueue": a way of
- * the Guest device registering buffers for the other side to read from or
- * write into (ie. send and receive buffers). Each device can have multiple
- * virtqueues: for example the console driver uses one queue for sending and
- * another for receiving.
- *
- * Fortunately for us, a very fast shared-memory-plus-descriptors virtqueue
- * already exists in virtio_ring.c. We just need to connect it up.
- *
- * We start with the information we need to keep about each virtqueue.
- */
-
-/*D:140 This is the information we remember about each virtqueue. */
-struct lguest_vq_info {
- /* A copy of the information contained in the device config. */
- struct lguest_vqconfig config;
-
- /* The address where we mapped the virtio ring, so we can unmap it. */
- void *pages;
-};
-
-/*
- * When the virtio_ring code wants to prod the Host, it calls us here and we
- * make a hypercall. We hand the physical address of the virtqueue so the Host
- * knows which virtqueue we're talking about.
- */
-static bool lg_notify(struct virtqueue *vq)
-{
- /*
- * We store our virtqueue information in the "priv" pointer of the
- * virtqueue structure.
- */
- struct lguest_vq_info *lvq = vq->priv;
-
- hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0);
- return true;
-}
-
-/* An extern declaration inside a C file is bad form. Don't do it. */
-extern int lguest_setup_irq(unsigned int irq);
-
-/*
- * This routine finds the Nth virtqueue described in the configuration of
- * this device and sets it up.
- *
- * This is kind of an ugly duckling. It'd be nicer to have a standard
- * representation of a virtqueue in the configuration space, but it seems that
- * everyone wants to do it differently. The KVM coders want the Guest to
- * allocate its own pages and tell the Host where they are, but for lguest it's
- * simpler for the Host to simply tell us where the pages are.
- */
-static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
- unsigned index,
- void (*callback)(struct virtqueue *vq),
- const char *name)
-{
- struct lguest_device *ldev = to_lgdev(vdev);
- struct lguest_vq_info *lvq;
- struct virtqueue *vq;
- int err;
-
- if (!name)
- return NULL;
-
- /* We must have this many virtqueues. */
- if (index >= ldev->desc->num_vq)
- return ERR_PTR(-ENOENT);
-
- lvq = kmalloc(sizeof(*lvq), GFP_KERNEL);
- if (!lvq)
- return ERR_PTR(-ENOMEM);
-
- /*
- * Make a copy of the "struct lguest_vqconfig" entry, which sits after
- * the descriptor. We need a copy because the config space might not
- * be aligned correctly.
- */
- memcpy(&lvq->config, lg_vq(ldev->desc)+index, sizeof(lvq->config));
-
- printk("Mapping virtqueue %i addr %lx\n", index,
- (unsigned long)lvq->config.pfn << PAGE_SHIFT);
- /* Figure out how many pages the ring will take, and map that memory */
- lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
- DIV_ROUND_UP(vring_size(lvq->config.num,
- LGUEST_VRING_ALIGN),
- PAGE_SIZE));
- if (!lvq->pages) {
- err = -ENOMEM;
- goto free_lvq;
- }
-
- /*
- * OK, tell virtio_ring.c to set up a virtqueue now we know its size
- * and we've got a pointer to its pages. Note that we set weak_barriers
- * to 'true': the host just a(nother) SMP CPU, so we only need inter-cpu
- * barriers.
- */
- vq = vring_new_virtqueue(index, lvq->config.num, LGUEST_VRING_ALIGN, vdev,
- true, lvq->pages, lg_notify, callback, name);
- if (!vq) {
- err = -ENOMEM;
- goto unmap;
- }
-
- /* Make sure the interrupt is allocated. */
- err = lguest_setup_irq(lvq->config.irq);
- if (err)
- goto destroy_vring;
-
- /*
- * Tell the interrupt for this virtqueue to go to the virtio_ring
- * interrupt handler.
- *
- * FIXME: We used to have a flag for the Host to tell us we could use
- * the interrupt as a source of randomness: it'd be nice to have that
- * back.
- */
- err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED,
- dev_name(&vdev->dev), vq);
- if (err)
- goto free_desc;
-
- /*
- * Last of all we hook up our 'struct lguest_vq_info" to the
- * virtqueue's priv pointer.
- */
- vq->priv = lvq;
- return vq;
-
-free_desc:
- irq_free_desc(lvq->config.irq);
-destroy_vring:
- vring_del_virtqueue(vq);
-unmap:
- lguest_unmap(lvq->pages);
-free_lvq:
- kfree(lvq);
- return ERR_PTR(err);
-}
-/*:*/
-
-/* Cleaning up a virtqueue is easy */
-static void lg_del_vq(struct virtqueue *vq)
-{
- struct lguest_vq_info *lvq = vq->priv;
-
- /* Release the interrupt */
- free_irq(lvq->config.irq, vq);
- /* Tell virtio_ring.c to free the virtqueue. */
- vring_del_virtqueue(vq);
- /* Unmap the pages containing the ring. */
- lguest_unmap(lvq->pages);
- /* Free our own queue information. */
- kfree(lvq);
-}
-
-static void lg_del_vqs(struct virtio_device *vdev)
-{
- struct virtqueue *vq, *n;
-
- list_for_each_entry_safe(vq, n, &vdev->vqs, list)
- lg_del_vq(vq);
-}
-
-static int lg_find_vqs(struct virtio_device *vdev, unsigned nvqs,
- struct virtqueue *vqs[],
- vq_callback_t *callbacks[],
- const char *names[])
-{
- struct lguest_device *ldev = to_lgdev(vdev);
- int i;
-
- /* We must have this many virtqueues. */
- if (nvqs > ldev->desc->num_vq)
- return -ENOENT;
-
- for (i = 0; i < nvqs; ++i) {
- vqs[i] = lg_find_vq(vdev, i, callbacks[i], names[i]);
- if (IS_ERR(vqs[i]))
- goto error;
- }
- return 0;
-
-error:
- lg_del_vqs(vdev);
- return PTR_ERR(vqs[i]);
-}
-
-static const char *lg_bus_name(struct virtio_device *vdev)
-{
- return "";
-}
-
-/* The ops structure which hooks everything together. */
-static const struct virtio_config_ops lguest_config_ops = {
- .get_features = lg_get_features,
- .finalize_features = lg_finalize_features,
- .get = lg_get,
- .set = lg_set,
- .get_status = lg_get_status,
- .set_status = lg_set_status,
- .reset = lg_reset,
- .find_vqs = lg_find_vqs,
- .del_vqs = lg_del_vqs,
- .bus_name = lg_bus_name,
-};
-
-/*
- * The root device for the lguest virtio devices. This makes them appear as
- * /sys/devices/lguest/0,1,2 not /sys/devices/0,1,2.
- */
-static struct device *lguest_root;
-
-/*D:120
- * This is the core of the lguest bus: actually adding a new device.
- * It's a separate function because it's neater that way, and because an
- * earlier version of the code supported hotplug and unplug. They were removed
- * early on because they were never used.
- *
- * As Andrew Tridgell says, "Untested code is buggy code".
- *
- * It's worth reading this carefully: we start with a pointer to the new device
- * descriptor in the "lguest_devices" page, and the offset into the device
- * descriptor page so we can uniquely identify it if things go badly wrong.
- */
-static void add_lguest_device(struct lguest_device_desc *d,
- unsigned int offset)
-{
- struct lguest_device *ldev;
-
- /* Start with zeroed memory; Linux's device layer counts on it. */
- ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
- if (!ldev) {
- printk(KERN_EMERG "Cannot allocate lguest dev %u type %u\n",
- offset, d->type);
- return;
- }
-
- /* This devices' parent is the lguest/ dir. */
- ldev->vdev.dev.parent = lguest_root;
- /*
- * The device type comes straight from the descriptor. There's also a
- * device vendor field in the virtio_device struct, which we leave as
- * 0.
- */
- ldev->vdev.id.device = d->type;
- /*
- * We have a simple set of routines for querying the device's
- * configuration information and setting its status.
- */
- ldev->vdev.config = &lguest_config_ops;
- /* And we remember the device's descriptor for lguest_config_ops. */
- ldev->desc = d;
-
- /*
- * register_virtio_device() sets up the generic fields for the struct
- * virtio_device and calls device_register(). This makes the bus
- * infrastructure look for a matching driver.
- */
- if (register_virtio_device(&ldev->vdev) != 0) {
- printk(KERN_ERR "Failed to register lguest dev %u type %u\n",
- offset, d->type);
- kfree(ldev);
- }
-}
-
-/*D:110
- * scan_devices() simply iterates through the device page. The type 0 is
- * reserved to mean "end of devices".
- */
-static void scan_devices(void)
-{
- unsigned int i;
- struct lguest_device_desc *d;
-
- /* We start at the page beginning, and skip over each entry. */
- for (i = 0; i < PAGE_SIZE; i += desc_size(d)) {
- d = lguest_devices + i;
-
- /* Once we hit a zero, stop. */
- if (d->type == 0)
- break;
-
- printk("Device at %i has size %u\n", i, desc_size(d));
- add_lguest_device(d, i);
- }
-}
-
-/*D:105
- * Fairly early in boot, lguest_devices_init() is called to set up the
- * lguest device infrastructure. We check that we are a Guest by checking
- * pv_info.name: there are other ways of checking, but this seems most
- * obvious to me.
- *
- * So we can access the "struct lguest_device_desc"s easily, we map that memory
- * and store the pointer in the global "lguest_devices". Then we register a
- * root device from which all our devices will hang (this seems to be the
- * correct sysfs incantation).
- *
- * Finally we call scan_devices() which adds all the devices found in the
- * lguest_devices page.
- */
-static int __init lguest_devices_init(void)
-{
- if (strcmp(pv_info.name, "lguest") != 0)
- return 0;
-
- lguest_root = root_device_register("lguest");
- if (IS_ERR(lguest_root))
- panic("Could not register lguest root");
-
- /* Devices are in a single page above top of "normal" mem */
- lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1);
-
- scan_devices();
- return 0;
-}
-/* We do this after core stuff, but before the drivers. */
-postcore_initcall(lguest_devices_init);
-
-/*D:150
- * At this point in the journey we used to now wade through the lguest
- * devices themselves: net, block and console. Since they're all now virtio
- * devices rather than lguest-specific, I've decided to ignore them. Mostly,
- * they're kind of boring. But this does mean you'll never experience the
- * thrill of reading the forbidden love scene buried deep in the block driver.
- *
- * "make Launcher" beckons, where we answer questions like "Where do Guests
- * come from?", and "What do you do when someone asks for optimization?".
- */
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 4263f4cc8c55..c4c6113eb9a6 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -2,175 +2,62 @@
* launcher controls and communicates with the Guest. For example,
* the first write will tell us the Guest's memory layout and entry
* point. A read will run the Guest until something happens, such as
- * a signal or the Guest doing a NOTIFY out to the Launcher. There is
- * also a way for the Launcher to attach eventfds to particular NOTIFY
- * values instead of returning from the read() call.
+ * a signal or the Guest accessing a device.
:*/
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/sched.h>
-#include <linux/eventfd.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/export.h>
#include "lg.h"
-/*L:056
- * Before we move on, let's jump ahead and look at what the kernel does when
- * it needs to look up the eventfds. That will complete our picture of how we
- * use RCU.
- *
- * The notification value is in cpu->pending_notify: we return true if it went
- * to an eventfd.
- */
-bool send_notify_to_eventfd(struct lg_cpu *cpu)
-{
- unsigned int i;
- struct lg_eventfd_map *map;
-
- /*
- * This "rcu_read_lock()" helps track when someone is still looking at
- * the (RCU-using) eventfds array. It's not actually a lock at all;
- * indeed it's a noop in many configurations. (You didn't expect me to
- * explain all the RCU secrets here, did you?)
- */
- rcu_read_lock();
- /*
- * rcu_dereference is the counter-side of rcu_assign_pointer(); it
- * makes sure we don't access the memory pointed to by
- * cpu->lg->eventfds before cpu->lg->eventfds is set. Sounds crazy,
- * but Alpha allows this! Paul McKenney points out that a really
- * aggressive compiler could have the same effect:
- * http://lists.ozlabs.org/pipermail/lguest/2009-July/001560.html
- *
- * So play safe, use rcu_dereference to get the rcu-protected pointer:
- */
- map = rcu_dereference(cpu->lg->eventfds);
- /*
- * Simple array search: even if they add an eventfd while we do this,
- * we'll continue to use the old array and just won't see the new one.
- */
- for (i = 0; i < map->num; i++) {
- if (map->map[i].addr == cpu->pending_notify) {
- eventfd_signal(map->map[i].event, 1);
- cpu->pending_notify = 0;
- break;
- }
- }
- /* We're done with the rcu-protected variable cpu->lg->eventfds. */
- rcu_read_unlock();
-
- /* If we cleared the notification, it's because we found a match. */
- return cpu->pending_notify == 0;
-}
-
-/*L:055
- * One of the more tricksy tricks in the Linux Kernel is a technique called
- * Read Copy Update. Since one point of lguest is to teach lguest journeyers
- * about kernel coding, I use it here. (In case you're curious, other purposes
- * include learning about virtualization and instilling a deep appreciation for
- * simplicity and puppies).
- *
- * We keep a simple array which maps LHCALL_NOTIFY values to eventfds, but we
- * add new eventfds without ever blocking readers from accessing the array.
- * The current Launcher only does this during boot, so that never happens. But
- * Read Copy Update is cool, and adding a lock risks damaging even more puppies
- * than this code does.
- *
- * We allocate a brand new one-larger array, copy the old one and add our new
- * element. Then we make the lg eventfd pointer point to the new array.
- * That's the easy part: now we need to free the old one, but we need to make
- * sure no slow CPU somewhere is still looking at it. That's what
- * synchronize_rcu does for us: waits until every CPU has indicated that it has
- * moved on to know it's no longer using the old one.
- *
- * If that's unclear, see http://en.wikipedia.org/wiki/Read-copy-update.
- */
-static int add_eventfd(struct lguest *lg, unsigned long addr, int fd)
+/*L:052
+ The Launcher can get the registers, and also set some of them.
+*/
+static int getreg_setup(struct lg_cpu *cpu, const unsigned long __user *input)
{
- struct lg_eventfd_map *new, *old = lg->eventfds;
-
- /*
- * We don't allow notifications on value 0 anyway (pending_notify of
- * 0 means "nothing pending").
- */
- if (!addr)
- return -EINVAL;
-
- /*
- * Replace the old array with the new one, carefully: others can
- * be accessing it at the same time.
- */
- new = kmalloc(sizeof(*new) + sizeof(new->map[0]) * (old->num + 1),
- GFP_KERNEL);
- if (!new)
- return -ENOMEM;
+ unsigned long which;
- /* First make identical copy. */
- memcpy(new->map, old->map, sizeof(old->map[0]) * old->num);
- new->num = old->num;
-
- /* Now append new entry. */
- new->map[new->num].addr = addr;
- new->map[new->num].event = eventfd_ctx_fdget(fd);
- if (IS_ERR(new->map[new->num].event)) {
- int err = PTR_ERR(new->map[new->num].event);
- kfree(new);
- return err;
- }
- new->num++;
+ /* We re-use the ptrace structure to specify which register to read. */
+ if (get_user(which, input) != 0)
+ return -EFAULT;
/*
- * Now put new one in place: rcu_assign_pointer() is a fancy way of
- * doing "lg->eventfds = new", but it uses memory barriers to make
- * absolutely sure that the contents of "new" written above is nailed
- * down before we actually do the assignment.
+ * We set up the cpu register pointer, and their next read will
+ * actually get the value (instead of running the guest).
*
- * We have to think about these kinds of things when we're operating on
- * live data without locks.
+ * The last argument 'true' says we can access any register.
*/
- rcu_assign_pointer(lg->eventfds, new);
+ cpu->reg_read = lguest_arch_regptr(cpu, which, true);
+ if (!cpu->reg_read)
+ return -ENOENT;
- /*
- * We're not in a big hurry. Wait until no one's looking at old
- * version, then free it.
- */
- synchronize_rcu();
- kfree(old);
-
- return 0;
+ /* And because this is a write() call, we return the length used. */
+ return sizeof(unsigned long) * 2;
}
-/*L:052
- * Receiving notifications from the Guest is usually done by attaching a
- * particular LHCALL_NOTIFY value to an event filedescriptor. The eventfd will
- * become readable when the Guest does an LHCALL_NOTIFY with that value.
- *
- * This is really convenient for processing each virtqueue in a separate
- * thread.
- */
-static int attach_eventfd(struct lguest *lg, const unsigned long __user *input)
+static int setreg(struct lg_cpu *cpu, const unsigned long __user *input)
{
- unsigned long addr, fd;
- int err;
+ unsigned long which, value, *reg;
- if (get_user(addr, input) != 0)
+ /* We re-use the ptrace structure to specify which register to read. */
+ if (get_user(which, input) != 0)
return -EFAULT;
input++;
- if (get_user(fd, input) != 0)
+ if (get_user(value, input) != 0)
return -EFAULT;
- /*
- * Just make sure two callers don't add eventfds at once. We really
- * only need to lock against callers adding to the same Guest, so using
- * the Big Lguest Lock is overkill. But this is setup, not a fast path.
- */
- mutex_lock(&lguest_lock);
- err = add_eventfd(lg, addr, fd);
- mutex_unlock(&lguest_lock);
+ /* The last argument 'false' means we can't access all registers. */
+ reg = lguest_arch_regptr(cpu, which, false);
+ if (!reg)
+ return -ENOENT;
- return err;
+ *reg = value;
+
+ /* And because this is a write() call, we return the length used. */
+ return sizeof(unsigned long) * 3;
}
/*L:050
@@ -194,6 +81,23 @@ static int user_send_irq(struct lg_cpu *cpu, const unsigned long __user *input)
return 0;
}
+/*L:053
+ * Deliver a trap: this is used by the Launcher if it can't emulate
+ * an instruction.
+ */
+static int trap(struct lg_cpu *cpu, const unsigned long __user *input)
+{
+ unsigned long trapnum;
+
+ if (get_user(trapnum, input) != 0)
+ return -EFAULT;
+
+ if (!deliver_trap(cpu, trapnum))
+ return -EINVAL;
+
+ return 0;
+}
+
/*L:040
* Once our Guest is initialized, the Launcher makes it run by reading
* from /dev/lguest.
@@ -237,8 +141,8 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
* If we returned from read() last time because the Guest sent I/O,
* clear the flag.
*/
- if (cpu->pending_notify)
- cpu->pending_notify = 0;
+ if (cpu->pending.trap)
+ cpu->pending.trap = 0;
/* Run the Guest until something interesting happens. */
return run_guest(cpu, (unsigned long __user *)user);
@@ -319,7 +223,7 @@ static int initialize(struct file *file, const unsigned long __user *input)
/* "struct lguest" contains all we (the Host) know about a Guest. */
struct lguest *lg;
int err;
- unsigned long args[3];
+ unsigned long args[4];
/*
* We grab the Big Lguest lock, which protects against multiple
@@ -343,21 +247,15 @@ static int initialize(struct file *file, const unsigned long __user *input)
goto unlock;
}
- lg->eventfds = kmalloc(sizeof(*lg->eventfds), GFP_KERNEL);
- if (!lg->eventfds) {
- err = -ENOMEM;
- goto free_lg;
- }
- lg->eventfds->num = 0;
-
/* Populate the easy fields of our "struct lguest" */
lg->mem_base = (void __user *)args[0];
lg->pfn_limit = args[1];
+ lg->device_limit = args[3];
/* This is the first cpu (cpu 0) and it will start booting at args[2] */
err = lg_cpu_start(&lg->cpus[0], 0, args[2]);
if (err)
- goto free_eventfds;
+ goto free_lg;
/*
* Initialize the Guest's shadow page tables. This allocates
@@ -378,8 +276,6 @@ static int initialize(struct file *file, const unsigned long __user *input)
free_regs:
/* FIXME: This should be in free_vcpu */
free_page(lg->cpus[0].regs_page);
-free_eventfds:
- kfree(lg->eventfds);
free_lg:
kfree(lg);
unlock:
@@ -432,8 +328,12 @@ static ssize_t write(struct file *file, const char __user *in,
return initialize(file, input);
case LHREQ_IRQ:
return user_send_irq(cpu, input);
- case LHREQ_EVENTFD:
- return attach_eventfd(lg, input);
+ case LHREQ_GETREG:
+ return getreg_setup(cpu, input);
+ case LHREQ_SETREG:
+ return setreg(cpu, input);
+ case LHREQ_TRAP:
+ return trap(cpu, input);
default:
return -EINVAL;
}
@@ -478,11 +378,6 @@ static int close(struct inode *inode, struct file *file)
mmput(lg->cpus[i].mm);
}
- /* Release any eventfds they registered. */
- for (i = 0; i < lg->eventfds->num; i++)
- eventfd_ctx_put(lg->eventfds->map[i].event);
- kfree(lg->eventfds);
-
/*
* If lg->dead doesn't contain an error code it will be NULL or a
* kmalloc()ed string, either of which is ok to hand to kfree().
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index e8b55c3a6170..e3abebc912c0 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -250,6 +250,16 @@ static void release_pte(pte_t pte)
}
/*:*/
+static bool gpte_in_iomem(struct lg_cpu *cpu, pte_t gpte)
+{
+ /* We don't handle large pages. */
+ if (pte_flags(gpte) & _PAGE_PSE)
+ return false;
+
+ return (pte_pfn(gpte) >= cpu->lg->pfn_limit
+ && pte_pfn(gpte) < cpu->lg->device_limit);
+}
+
static bool check_gpte(struct lg_cpu *cpu, pte_t gpte)
{
if ((pte_flags(gpte) & _PAGE_PSE) ||
@@ -374,8 +384,14 @@ static pte_t *find_spte(struct lg_cpu *cpu, unsigned long vaddr, bool allocate,
*
* If we fixed up the fault (ie. we mapped the address), this routine returns
* true. Otherwise, it was a real fault and we need to tell the Guest.
+ *
+ * There's a corner case: they're trying to access memory between
+ * pfn_limit and device_limit, which is I/O memory. In this case, we
+ * return false and set @iomem to the physical address, so the the
+ * Launcher can handle the instruction manually.
*/
-bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
+bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode,
+ unsigned long *iomem)
{
unsigned long gpte_ptr;
pte_t gpte;
@@ -383,6 +399,8 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
pmd_t gpmd;
pgd_t gpgd;
+ *iomem = 0;
+
/* We never demand page the Switcher, so trying is a mistake. */
if (vaddr >= switcher_addr)
return false;
@@ -459,6 +477,12 @@ bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
return false;
+ /* If they're accessing io memory, we expect a fault. */
+ if (gpte_in_iomem(cpu, gpte)) {
+ *iomem = (pte_pfn(gpte) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
+ return false;
+ }
+
/*
* Check that the Guest PTE flags are OK, and the page number is below
* the pfn_limit (ie. not mapping the Launcher binary).
@@ -553,7 +577,9 @@ static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr)
*/
void pin_page(struct lg_cpu *cpu, unsigned long vaddr)
{
- if (!page_writable(cpu, vaddr) && !demand_page(cpu, vaddr, 2))
+ unsigned long iomem;
+
+ if (!page_writable(cpu, vaddr) && !demand_page(cpu, vaddr, 2, &iomem))
kill_guest(cpu, "bad stack page %#lx", vaddr);
}
/*:*/
@@ -647,7 +673,7 @@ void guest_pagetable_flush_user(struct lg_cpu *cpu)
/*:*/
/* We walk down the guest page tables to get a guest-physical address */
-unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr)
+bool __guest_pa(struct lg_cpu *cpu, unsigned long vaddr, unsigned long *paddr)
{
pgd_t gpgd;
pte_t gpte;
@@ -656,31 +682,47 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr)
#endif
/* Still not set up? Just map 1:1. */
- if (unlikely(cpu->linear_pages))
- return vaddr;
+ if (unlikely(cpu->linear_pages)) {
+ *paddr = vaddr;
+ return true;
+ }
/* First step: get the top-level Guest page table entry. */
gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
/* Toplevel not present? We can't map it in. */
- if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) {
- kill_guest(cpu, "Bad address %#lx", vaddr);
- return -1UL;
- }
+ if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
+ goto fail;
#ifdef CONFIG_X86_PAE
gpmd = lgread(cpu, gpmd_addr(gpgd, vaddr), pmd_t);
- if (!(pmd_flags(gpmd) & _PAGE_PRESENT)) {
- kill_guest(cpu, "Bad address %#lx", vaddr);
- return -1UL;
- }
+ if (!(pmd_flags(gpmd) & _PAGE_PRESENT))
+ goto fail;
gpte = lgread(cpu, gpte_addr(cpu, gpmd, vaddr), pte_t);
#else
gpte = lgread(cpu, gpte_addr(cpu, gpgd, vaddr), pte_t);
#endif
if (!(pte_flags(gpte) & _PAGE_PRESENT))
- kill_guest(cpu, "Bad address %#lx", vaddr);
+ goto fail;
+
+ *paddr = pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK);
+ return true;
+
+fail:
+ *paddr = -1UL;
+ return false;
+}
- return pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK);
+/*
+ * This is the version we normally use: kills the Guest if it uses a
+ * bad address
+ */
+unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr)
+{
+ unsigned long paddr;
+
+ if (!__guest_pa(cpu, vaddr, &paddr))
+ kill_guest(cpu, "Bad address %#lx", vaddr);
+ return paddr;
}
/*
@@ -912,7 +954,8 @@ static void __guest_set_pte(struct lg_cpu *cpu, int idx,
* now. This shaves 10% off a copy-on-write
* micro-benchmark.
*/
- if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) {
+ if ((pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED))
+ && !gpte_in_iomem(cpu, gpte)) {
if (!check_gpte(cpu, gpte))
return;
set_pte(spte,
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 922a1acbf652..30f2aef69d78 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -47,6 +47,7 @@
#include <asm/lguest.h>
#include <asm/uaccess.h>
#include <asm/i387.h>
+#include <asm/tlbflush.h>
#include "../lg.h"
static int cpu_had_pge;
@@ -181,6 +182,52 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
}
/*:*/
+unsigned long *lguest_arch_regptr(struct lg_cpu *cpu, size_t reg_off, bool any)
+{
+ switch (reg_off) {
+ case offsetof(struct pt_regs, bx):
+ return &cpu->regs->ebx;
+ case offsetof(struct pt_regs, cx):
+ return &cpu->regs->ecx;
+ case offsetof(struct pt_regs, dx):
+ return &cpu->regs->edx;
+ case offsetof(struct pt_regs, si):
+ return &cpu->regs->esi;
+ case offsetof(struct pt_regs, di):
+ return &cpu->regs->edi;
+ case offsetof(struct pt_regs, bp):
+ return &cpu->regs->ebp;
+ case offsetof(struct pt_regs, ax):
+ return &cpu->regs->eax;
+ case offsetof(struct pt_regs, ip):
+ return &cpu->regs->eip;
+ case offsetof(struct pt_regs, sp):
+ return &cpu->regs->esp;
+ }
+
+ /* Launcher can read these, but we don't allow any setting. */
+ if (any) {
+ switch (reg_off) {
+ case offsetof(struct pt_regs, ds):
+ return &cpu->regs->ds;
+ case offsetof(struct pt_regs, es):
+ return &cpu->regs->es;
+ case offsetof(struct pt_regs, fs):
+ return &cpu->regs->fs;
+ case offsetof(struct pt_regs, gs):
+ return &cpu->regs->gs;
+ case offsetof(struct pt_regs, cs):
+ return &cpu->regs->cs;
+ case offsetof(struct pt_regs, flags):
+ return &cpu->regs->eflags;
+ case offsetof(struct pt_regs, ss):
+ return &cpu->regs->ss;
+ }
+ }
+
+ return NULL;
+}
+
/*M:002
* There are hooks in the scheduler which we can register to tell when we
* get kicked off the CPU (preempt_notifier_register()). This would allow us
@@ -268,110 +315,73 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
* usually attached to a PC.
*
* When the Guest uses one of these instructions, we get a trap (General
- * Protection Fault) and come here. We see if it's one of those troublesome
- * instructions and skip over it. We return true if we did.
+ * Protection Fault) and come here. We queue this to be sent out to the
+ * Launcher to handle.
*/
-static int emulate_insn(struct lg_cpu *cpu)
-{
- u8 insn;
- unsigned int insnlen = 0, in = 0, small_operand = 0;
- /*
- * The eip contains the *virtual* address of the Guest's instruction:
- * walk the Guest's page tables to find the "physical" address.
- */
- unsigned long physaddr = guest_pa(cpu, cpu->regs->eip);
-
- /*
- * This must be the Guest kernel trying to do something, not userspace!
- * The bottom two bits of the CS segment register are the privilege
- * level.
- */
- if ((cpu->regs->cs & 3) != GUEST_PL)
- return 0;
-
- /* Decoding x86 instructions is icky. */
- insn = lgread(cpu, physaddr, u8);
- /*
- * Around 2.6.33, the kernel started using an emulation for the
- * cmpxchg8b instruction in early boot on many configurations. This
- * code isn't paravirtualized, and it tries to disable interrupts.
- * Ignore it, which will Mostly Work.
- */
- if (insn == 0xfa) {
- /* "cli", or Clear Interrupt Enable instruction. Skip it. */
- cpu->regs->eip++;
- return 1;
+/*
+ * The eip contains the *virtual* address of the Guest's instruction:
+ * we copy the instruction here so the Launcher doesn't have to walk
+ * the page tables to decode it. We handle the case (eg. in a kernel
+ * module) where the instruction is over two pages, and the pages are
+ * virtually but not physically contiguous.
+ *
+ * The longest possible x86 instruction is 15 bytes, but we don't handle
+ * anything that strange.
+ */
+static void copy_from_guest(struct lg_cpu *cpu,
+ void *dst, unsigned long vaddr, size_t len)
+{
+ size_t to_page_end = PAGE_SIZE - (vaddr % PAGE_SIZE);
+ unsigned long paddr;
+
+ BUG_ON(len > PAGE_SIZE);
+
+ /* If it goes over a page, copy in two parts. */
+ if (len > to_page_end) {
+ /* But make sure the next page is mapped! */
+ if (__guest_pa(cpu, vaddr + to_page_end, &paddr))
+ copy_from_guest(cpu, dst + to_page_end,
+ vaddr + to_page_end,
+ len - to_page_end);
+ else
+ /* Otherwise fill with zeroes. */
+ memset(dst + to_page_end, 0, len - to_page_end);
+ len = to_page_end;
}
- /*
- * 0x66 is an "operand prefix". It means a 16, not 32 bit in/out.
- */
- if (insn == 0x66) {
- small_operand = 1;
- /* The instruction is 1 byte so far, read the next byte. */
- insnlen = 1;
- insn = lgread(cpu, physaddr + insnlen, u8);
- }
+ /* This will kill the guest if it isn't mapped, but that
+ * shouldn't happen. */
+ __lgread(cpu, dst, guest_pa(cpu, vaddr), len);
+}
- /*
- * We can ignore the lower bit for the moment and decode the 4 opcodes
- * we need to emulate.
- */
- switch (insn & 0xFE) {
- case 0xE4: /* in <next byte>,%al */
- insnlen += 2;
- in = 1;
- break;
- case 0xEC: /* in (%dx),%al */
- insnlen += 1;
- in = 1;
- break;
- case 0xE6: /* out %al,<next byte> */
- insnlen += 2;
- break;
- case 0xEE: /* out %al,(%dx) */
- insnlen += 1;
- break;
- default:
- /* OK, we don't know what this is, can't emulate. */
- return 0;
- }
- /*
- * If it was an "IN" instruction, they expect the result to be read
- * into %eax, so we change %eax. We always return all-ones, which
- * traditionally means "there's nothing there".
- */
- if (in) {
- /* Lower bit tells means it's a 32/16 bit access */
- if (insn & 0x1) {
- if (small_operand)
- cpu->regs->eax |= 0xFFFF;
- else
- cpu->regs->eax = 0xFFFFFFFF;
- } else
- cpu->regs->eax |= 0xFF;
- }
- /* Finally, we've "done" the instruction, so move past it. */
- cpu->regs->eip += insnlen;
- /* Success! */
- return 1;
+static void setup_emulate_insn(struct lg_cpu *cpu)
+{
+ cpu->pending.trap = 13;
+ copy_from_guest(cpu, cpu->pending.insn, cpu->regs->eip,
+ sizeof(cpu->pending.insn));
+}
+
+static void setup_iomem_insn(struct lg_cpu *cpu, unsigned long iomem_addr)
+{
+ cpu->pending.trap = 14;
+ cpu->pending.addr = iomem_addr;
+ copy_from_guest(cpu, cpu->pending.insn, cpu->regs->eip,
+ sizeof(cpu->pending.insn));
}
/*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
void lguest_arch_handle_trap(struct lg_cpu *cpu)
{
+ unsigned long iomem_addr;
+
switch (cpu->regs->trapnum) {
case 13: /* We've intercepted a General Protection Fault. */
- /*
- * Check if this was one of those annoying IN or OUT
- * instructions which we need to emulate. If so, we just go
- * back into the Guest after we've done it.
- */
+ /* Hand to Launcher to emulate those pesky IN and OUT insns */
if (cpu->regs->errcode == 0) {
- if (emulate_insn(cpu))
- return;
+ setup_emulate_insn(cpu);
+ return;
}
break;
case 14: /* We've intercepted a Page Fault. */
@@ -386,9 +396,16 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
* whether kernel or userspace code.
*/
if (demand_page(cpu, cpu->arch.last_pagefault,
- cpu->regs->errcode))
+ cpu->regs->errcode, &iomem_addr))
return;
+ /* Was this an access to memory mapped IO? */
+ if (iomem_addr) {
+ /* Tell Launcher, let it handle it. */
+ setup_iomem_insn(cpu, iomem_addr);
+ return;
+ }
+
/*
* OK, it's really not there (or not OK): the Guest needs to
* know. We write out the cr2 value so it knows where the
@@ -452,9 +469,9 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
static void adjust_pge(void *on)
{
if (on)
- write_cr4(read_cr4() | X86_CR4_PGE);
+ cr4_set_bits(X86_CR4_PGE);
else
- write_cr4(read_cr4() & ~X86_CR4_PGE);
+ cr4_clear_bits(X86_CR4_PGE);
}
/*H:020
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 5dd0c2e59ab9..4153da5d4011 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2196,7 +2196,8 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
if (rdev->badblocks.shift < 0)
return 0;
- block_sectors = 1 << rdev->badblocks.shift;
+ block_sectors = roundup(1 << rdev->badblocks.shift,
+ bdev_logical_block_size(rdev->bdev) >> 9);
sector = r1_bio->sector;
sectors = ((sector + block_sectors)
& ~(sector_t)(block_sectors - 1))
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index b8d76b1fba64..a7196c49d15d 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2572,7 +2572,8 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
if (rdev->badblocks.shift < 0)
return 0;
- block_sectors = 1 << rdev->badblocks.shift;
+ block_sectors = roundup(1 << rdev->badblocks.shift,
+ bdev_logical_block_size(rdev->bdev) >> 9);
sector = r10_bio->sector;
sectors = ((r10_bio->sector + block_sectors)
& ~(sector_t)(block_sectors - 1))
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index aa76865b804b..e75d48c0421a 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3170,7 +3170,8 @@ static void handle_stripe_dirtying(struct r5conf *conf,
* generate correct data from the parity.
*/
if (conf->max_degraded == 2 ||
- (recovery_cp < MaxSector && sh->sector >= recovery_cp)) {
+ (recovery_cp < MaxSector && sh->sector >= recovery_cp &&
+ s->failed == 0)) {
/* Calculate the real rcw later - for now make it
* look like rcw is cheaper
*/
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 3a2604580164..d2a85cde68da 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -1111,7 +1111,7 @@ static int verify_addr(struct i2c_client *i2c)
return 0;
}
-static struct regmap_config pm860x_regmap_config = {
+static const struct regmap_config pm860x_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2e6b7311fabc..38356e39adba 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -195,6 +195,18 @@ config MFD_DA9063
Additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_DA9150
+ tristate "Dialog Semiconductor DA9150 Charger Fuel-Gauge chip"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ help
+ This adds support for the DA9150 integrated charger and fuel-gauge
+ chip. This driver provides common support for accessing the device.
+ Additional drivers must be enabled in order to use the specific
+ features of the device.
+
config MFD_DLN2
tristate "Diolan DLN2 support"
select MFD_CORE
@@ -417,6 +429,7 @@ config MFD_MAX14577
config MFD_MAX77686
bool "Maxim Semiconductor MAX77686/802 PMIC Support"
depends on I2C=y
+ depends on OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -589,6 +602,20 @@ config MFD_PM8921_CORE
Say M here if you want to include support for PM8921 chip as a module.
This will build a module called "pm8921-core".
+config MFD_QCOM_RPM
+ tristate "Qualcomm Resource Power Manager (RPM)"
+ depends on ARCH_QCOM && OF
+ help
+ If you say yes to this option, support will be included for the
+ Resource Power Manager system found in the Qualcomm 8660, 8960 and
+ 8064 based devices.
+
+ This is required to access many regulators, clocks and bus
+ frequencies controlled by the RPM on these devices.
+
+ Say M here if you want to include support for the Qualcomm RPM as a
+ module. This will build a module called "qcom_rpm".
+
config MFD_SPMI_PMIC
tristate "Qualcomm SPMI PMICs"
depends on ARCH_QCOM || COMPILE_TEST
@@ -623,6 +650,18 @@ config MFD_RTSX_PCI
types of memory cards, such as Memory Stick, Memory Stick Pro,
Secure Digital and MultiMediaCard.
+config MFD_RT5033
+ tristate "Richtek RT5033 Power Management IC"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ help
+ This driver provides for the Richtek RT5033 Power Management IC,
+ which includes the I2C driver and the Core APIs. This driver provides
+ common support for accessing the device. The device supports multiple
+ sub-devices like charger, fuel gauge, flash LED, current source,
+ LDO and Buck.
+
config MFD_RTSX_USB
tristate "Realtek USB card reader"
depends on USB
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 53467e211381..19f3d744e3bd 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -113,7 +113,7 @@ obj-$(CONFIG_MFD_DA9055) += da9055.o
da9063-objs := da9063-core.o da9063-irq.o da9063-i2c.o
obj-$(CONFIG_MFD_DA9063) += da9063.o
-
+obj-$(CONFIG_MFD_DA9150) += da9150-core.o
obj-$(CONFIG_MFD_MAX14577) += max14577.o
obj-$(CONFIG_MFD_MAX77686) += max77686.o
obj-$(CONFIG_MFD_MAX77693) += max77693.o
@@ -153,6 +153,7 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o
obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o
+obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o
obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
@@ -176,6 +177,7 @@ obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o
obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o
obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o
obj-$(CONFIG_MFD_DLN2) += dln2.o
+obj-$(CONFIG_MFD_RT5033) += rt5033.o
intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c
index f38bc98a3c57..facd3610ac77 100644
--- a/drivers/mfd/da9063-core.c
+++ b/drivers/mfd/da9063-core.c
@@ -86,6 +86,7 @@ static const struct mfd_cell da9063_devs[] = {
},
{
.name = DA9063_DRVNAME_WATCHDOG,
+ .of_compatible = "dlg,da9063-watchdog",
},
{
.name = DA9063_DRVNAME_HWMON,
@@ -101,6 +102,7 @@ static const struct mfd_cell da9063_devs[] = {
.name = DA9063_DRVNAME_RTC,
.num_resources = ARRAY_SIZE(da9063_rtc_resources),
.resources = da9063_rtc_resources,
+ .of_compatible = "dlg,da9063-rtc",
},
{
.name = DA9063_DRVNAME_VIBRATION,
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index 21fd8d9a217b..6f3a7c0001f9 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -25,6 +25,9 @@
#include <linux/mfd/da9063/pdata.h>
#include <linux/mfd/da9063/registers.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
+
static const struct regmap_range da9063_ad_readable_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
@@ -203,6 +206,11 @@ static struct regmap_config da9063_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
+static const struct of_device_id da9063_dt_ids[] = {
+ { .compatible = "dlg,da9063", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, da9063_dt_ids);
static int da9063_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
@@ -257,6 +265,7 @@ static struct i2c_driver da9063_i2c_driver = {
.driver = {
.name = "da9063",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(da9063_dt_ids),
},
.probe = da9063_i2c_probe,
.remove = da9063_i2c_remove,
diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c
new file mode 100644
index 000000000000..4d757b97ef9a
--- /dev/null
+++ b/drivers/mfd/da9150-core.c
@@ -0,0 +1,413 @@
+/*
+ * DA9150 Core MFD Driver
+ *
+ * Copyright (c) 2014 Dialog Semiconductor
+ *
+ * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/da9150/core.h>
+#include <linux/mfd/da9150/registers.h>
+
+static bool da9150_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case DA9150_PAGE_CON:
+ case DA9150_STATUS_A:
+ case DA9150_STATUS_B:
+ case DA9150_STATUS_C:
+ case DA9150_STATUS_D:
+ case DA9150_STATUS_E:
+ case DA9150_STATUS_F:
+ case DA9150_STATUS_G:
+ case DA9150_STATUS_H:
+ case DA9150_STATUS_I:
+ case DA9150_STATUS_J:
+ case DA9150_STATUS_K:
+ case DA9150_STATUS_L:
+ case DA9150_STATUS_N:
+ case DA9150_FAULT_LOG_A:
+ case DA9150_FAULT_LOG_B:
+ case DA9150_EVENT_E:
+ case DA9150_EVENT_F:
+ case DA9150_EVENT_G:
+ case DA9150_EVENT_H:
+ case DA9150_CONTROL_B:
+ case DA9150_CONTROL_C:
+ case DA9150_GPADC_MAN:
+ case DA9150_GPADC_RES_A:
+ case DA9150_GPADC_RES_B:
+ case DA9150_ADETVB_CFG_C:
+ case DA9150_ADETD_STAT:
+ case DA9150_ADET_CMPSTAT:
+ case DA9150_ADET_CTRL_A:
+ case DA9150_PPR_TCTR_B:
+ case DA9150_COREBTLD_STAT_A:
+ case DA9150_CORE_DATA_A:
+ case DA9150_CORE_DATA_B:
+ case DA9150_CORE_DATA_C:
+ case DA9150_CORE_DATA_D:
+ case DA9150_CORE2WIRE_STAT_A:
+ case DA9150_FW_CTRL_C:
+ case DA9150_FG_CTRL_B:
+ case DA9150_FW_CTRL_B:
+ case DA9150_GPADC_CMAN:
+ case DA9150_GPADC_CRES_A:
+ case DA9150_GPADC_CRES_B:
+ case DA9150_CC_ICHG_RES_A:
+ case DA9150_CC_ICHG_RES_B:
+ case DA9150_CC_IAVG_RES_A:
+ case DA9150_CC_IAVG_RES_B:
+ case DA9150_TAUX_CTRL_A:
+ case DA9150_TAUX_VALUE_H:
+ case DA9150_TAUX_VALUE_L:
+ case DA9150_TBAT_RES_A:
+ case DA9150_TBAT_RES_B:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_range_cfg da9150_range_cfg[] = {
+ {
+ .range_min = DA9150_PAGE_CON,
+ .range_max = DA9150_TBAT_RES_B,
+ .selector_reg = DA9150_PAGE_CON,
+ .selector_mask = DA9150_I2C_PAGE_MASK,
+ .selector_shift = DA9150_I2C_PAGE_SHIFT,
+ .window_start = 0,
+ .window_len = 256,
+ },
+};
+
+static struct regmap_config da9150_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .ranges = da9150_range_cfg,
+ .num_ranges = ARRAY_SIZE(da9150_range_cfg),
+ .max_register = DA9150_TBAT_RES_B,
+
+ .cache_type = REGCACHE_RBTREE,
+
+ .volatile_reg = da9150_volatile_reg,
+};
+
+u8 da9150_reg_read(struct da9150 *da9150, u16 reg)
+{
+ int val, ret;
+
+ ret = regmap_read(da9150->regmap, reg, &val);
+ if (ret)
+ dev_err(da9150->dev, "Failed to read from reg 0x%x: %d\n",
+ reg, ret);
+
+ return (u8) val;
+}
+EXPORT_SYMBOL_GPL(da9150_reg_read);
+
+void da9150_reg_write(struct da9150 *da9150, u16 reg, u8 val)
+{
+ int ret;
+
+ ret = regmap_write(da9150->regmap, reg, val);
+ if (ret)
+ dev_err(da9150->dev, "Failed to write to reg 0x%x: %d\n",
+ reg, ret);
+}
+EXPORT_SYMBOL_GPL(da9150_reg_write);
+
+void da9150_set_bits(struct da9150 *da9150, u16 reg, u8 mask, u8 val)
+{
+ int ret;
+
+ ret = regmap_update_bits(da9150->regmap, reg, mask, val);
+ if (ret)
+ dev_err(da9150->dev, "Failed to set bits in reg 0x%x: %d\n",
+ reg, ret);
+}
+EXPORT_SYMBOL_GPL(da9150_set_bits);
+
+void da9150_bulk_read(struct da9150 *da9150, u16 reg, int count, u8 *buf)
+{
+ int ret;
+
+ ret = regmap_bulk_read(da9150->regmap, reg, buf, count);
+ if (ret)
+ dev_err(da9150->dev, "Failed to bulk read from reg 0x%x: %d\n",
+ reg, ret);
+}
+EXPORT_SYMBOL_GPL(da9150_bulk_read);
+
+void da9150_bulk_write(struct da9150 *da9150, u16 reg, int count, const u8 *buf)
+{
+ int ret;
+
+ ret = regmap_raw_write(da9150->regmap, reg, buf, count);
+ if (ret)
+ dev_err(da9150->dev, "Failed to bulk write to reg 0x%x %d\n",
+ reg, ret);
+}
+EXPORT_SYMBOL_GPL(da9150_bulk_write);
+
+static struct regmap_irq da9150_irqs[] = {
+ [DA9150_IRQ_VBUS] = {
+ .reg_offset = 0,
+ .mask = DA9150_E_VBUS_MASK,
+ },
+ [DA9150_IRQ_CHG] = {
+ .reg_offset = 0,
+ .mask = DA9150_E_CHG_MASK,
+ },
+ [DA9150_IRQ_TCLASS] = {
+ .reg_offset = 0,
+ .mask = DA9150_E_TCLASS_MASK,
+ },
+ [DA9150_IRQ_TJUNC] = {
+ .reg_offset = 0,
+ .mask = DA9150_E_TJUNC_MASK,
+ },
+ [DA9150_IRQ_VFAULT] = {
+ .reg_offset = 0,
+ .mask = DA9150_E_VFAULT_MASK,
+ },
+ [DA9150_IRQ_CONF] = {
+ .reg_offset = 1,
+ .mask = DA9150_E_CONF_MASK,
+ },
+ [DA9150_IRQ_DAT] = {
+ .reg_offset = 1,
+ .mask = DA9150_E_DAT_MASK,
+ },
+ [DA9150_IRQ_DTYPE] = {
+ .reg_offset = 1,
+ .mask = DA9150_E_DTYPE_MASK,
+ },
+ [DA9150_IRQ_ID] = {
+ .reg_offset = 1,
+ .mask = DA9150_E_ID_MASK,
+ },
+ [DA9150_IRQ_ADP] = {
+ .reg_offset = 1,
+ .mask = DA9150_E_ADP_MASK,
+ },
+ [DA9150_IRQ_SESS_END] = {
+ .reg_offset = 1,
+ .mask = DA9150_E_SESS_END_MASK,
+ },
+ [DA9150_IRQ_SESS_VLD] = {
+ .reg_offset = 1,
+ .mask = DA9150_E_SESS_VLD_MASK,
+ },
+ [DA9150_IRQ_FG] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_FG_MASK,
+ },
+ [DA9150_IRQ_GP] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_GP_MASK,
+ },
+ [DA9150_IRQ_TBAT] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_TBAT_MASK,
+ },
+ [DA9150_IRQ_GPIOA] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_GPIOA_MASK,
+ },
+ [DA9150_IRQ_GPIOB] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_GPIOB_MASK,
+ },
+ [DA9150_IRQ_GPIOC] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_GPIOC_MASK,
+ },
+ [DA9150_IRQ_GPIOD] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_GPIOD_MASK,
+ },
+ [DA9150_IRQ_GPADC] = {
+ .reg_offset = 2,
+ .mask = DA9150_E_GPADC_MASK,
+ },
+ [DA9150_IRQ_WKUP] = {
+ .reg_offset = 3,
+ .mask = DA9150_E_WKUP_MASK,
+ },
+};
+
+static struct regmap_irq_chip da9150_regmap_irq_chip = {
+ .name = "da9150_irq",
+ .status_base = DA9150_EVENT_E,
+ .mask_base = DA9150_IRQ_MASK_E,
+ .ack_base = DA9150_EVENT_E,
+ .num_regs = DA9150_NUM_IRQ_REGS,
+ .irqs = da9150_irqs,
+ .num_irqs = ARRAY_SIZE(da9150_irqs),
+};
+
+static struct resource da9150_gpadc_resources[] = {
+ {
+ .name = "GPADC",
+ .start = DA9150_IRQ_GPADC,
+ .end = DA9150_IRQ_GPADC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource da9150_charger_resources[] = {
+ {
+ .name = "CHG_STATUS",
+ .start = DA9150_IRQ_CHG,
+ .end = DA9150_IRQ_CHG,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "CHG_TJUNC",
+ .start = DA9150_IRQ_TJUNC,
+ .end = DA9150_IRQ_TJUNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "CHG_VFAULT",
+ .start = DA9150_IRQ_VFAULT,
+ .end = DA9150_IRQ_VFAULT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "CHG_VBUS",
+ .start = DA9150_IRQ_VBUS,
+ .end = DA9150_IRQ_VBUS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell da9150_devs[] = {
+ {
+ .name = "da9150-gpadc",
+ .of_compatible = "dlg,da9150-gpadc",
+ .resources = da9150_gpadc_resources,
+ .num_resources = ARRAY_SIZE(da9150_gpadc_resources),
+ },
+ {
+ .name = "da9150-charger",
+ .of_compatible = "dlg,da9150-charger",
+ .resources = da9150_charger_resources,
+ .num_resources = ARRAY_SIZE(da9150_charger_resources),
+ },
+};
+
+static int da9150_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct da9150 *da9150;
+ struct da9150_pdata *pdata = dev_get_platdata(&client->dev);
+ int ret;
+
+ da9150 = devm_kzalloc(&client->dev, sizeof(*da9150), GFP_KERNEL);
+ if (!da9150)
+ return -ENOMEM;
+
+ da9150->dev = &client->dev;
+ da9150->irq = client->irq;
+ i2c_set_clientdata(client, da9150);
+
+ da9150->regmap = devm_regmap_init_i2c(client, &da9150_regmap_config);
+ if (IS_ERR(da9150->regmap)) {
+ ret = PTR_ERR(da9150->regmap);
+ dev_err(da9150->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ da9150->irq_base = pdata ? pdata->irq_base : -1;
+
+ ret = regmap_add_irq_chip(da9150->regmap, da9150->irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ da9150->irq_base, &da9150_regmap_irq_chip,
+ &da9150->regmap_irq_data);
+ if (ret)
+ return ret;
+
+ da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data);
+ enable_irq_wake(da9150->irq);
+
+ ret = mfd_add_devices(da9150->dev, -1, da9150_devs,
+ ARRAY_SIZE(da9150_devs), NULL,
+ da9150->irq_base, NULL);
+ if (ret) {
+ dev_err(da9150->dev, "Failed to add child devices: %d\n", ret);
+ regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int da9150_remove(struct i2c_client *client)
+{
+ struct da9150 *da9150 = i2c_get_clientdata(client);
+
+ regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
+ mfd_remove_devices(da9150->dev);
+
+ return 0;
+}
+
+static void da9150_shutdown(struct i2c_client *client)
+{
+ struct da9150 *da9150 = i2c_get_clientdata(client);
+
+ /* Make sure we have a wakup source for the device */
+ da9150_set_bits(da9150, DA9150_CONFIG_D,
+ DA9150_WKUP_PM_EN_MASK,
+ DA9150_WKUP_PM_EN_MASK);
+
+ /* Set device to DISABLED mode */
+ da9150_set_bits(da9150, DA9150_CONTROL_C,
+ DA9150_DISABLE_MASK, DA9150_DISABLE_MASK);
+}
+
+static const struct i2c_device_id da9150_i2c_id[] = {
+ { "da9150", },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, da9150_i2c_id);
+
+static const struct of_device_id da9150_of_match[] = {
+ { .compatible = "dlg,da9150", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, da9150_of_match);
+
+static struct i2c_driver da9150_driver = {
+ .driver = {
+ .name = "da9150",
+ .of_match_table = of_match_ptr(da9150_of_match),
+ },
+ .probe = da9150_probe,
+ .remove = da9150_remove,
+ .shutdown = da9150_shutdown,
+ .id_table = da9150_i2c_id,
+};
+
+module_i2c_driver(da9150_driver);
+
+MODULE_DESCRIPTION("MFD Core Driver for DA9150");
+MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
index c835e85539b2..9bbc642a7b9d 100644
--- a/drivers/mfd/davinci_voicecodec.c
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -33,7 +33,7 @@
#include <linux/mfd/davinci_voicecodec.h>
-static struct regmap_config davinci_vc_regmap = {
+static const struct regmap_config davinci_vc_regmap = {
.reg_bits = 32,
.val_bits = 32,
};
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 16162bf43656..cc1a404328c2 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -675,15 +675,6 @@ bool prcmu_has_arm_maxopp(void)
}
/**
- * prcmu_get_boot_status - PRCMU boot status checking
- * Returns: the current PRCMU boot status
- */
-int prcmu_get_boot_status(void)
-{
- return readb(tcdm_base + PRCM_BOOT_STATUS);
-}
-
-/**
* prcmu_set_rc_a2p - This function is used to run few power state sequences
* @val: Value to be set, i.e. transition requested
* Returns: 0 on success, -EINVAL on invalid argument
diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
index 6d49685d4ee4..1be9bd1c046d 100644
--- a/drivers/mfd/dln2.c
+++ b/drivers/mfd/dln2.c
@@ -587,12 +587,19 @@ static void dln2_free_rx_urbs(struct dln2_dev *dln2)
int i;
for (i = 0; i < DLN2_MAX_URBS; i++) {
- usb_kill_urb(dln2->rx_urb[i]);
usb_free_urb(dln2->rx_urb[i]);
kfree(dln2->rx_buf[i]);
}
}
+static void dln2_stop_rx_urbs(struct dln2_dev *dln2)
+{
+ int i;
+
+ for (i = 0; i < DLN2_MAX_URBS; i++)
+ usb_kill_urb(dln2->rx_urb[i]);
+}
+
static void dln2_free(struct dln2_dev *dln2)
{
dln2_free_rx_urbs(dln2);
@@ -604,9 +611,7 @@ static int dln2_setup_rx_urbs(struct dln2_dev *dln2,
struct usb_host_interface *hostif)
{
int i;
- int ret;
const int rx_max_size = DLN2_RX_BUF_SIZE;
- struct device *dev = &dln2->interface->dev;
for (i = 0; i < DLN2_MAX_URBS; i++) {
dln2->rx_buf[i] = kmalloc(rx_max_size, GFP_KERNEL);
@@ -620,8 +625,19 @@ static int dln2_setup_rx_urbs(struct dln2_dev *dln2,
usb_fill_bulk_urb(dln2->rx_urb[i], dln2->usb_dev,
usb_rcvbulkpipe(dln2->usb_dev, dln2->ep_in),
dln2->rx_buf[i], rx_max_size, dln2_rx, dln2);
+ }
- ret = usb_submit_urb(dln2->rx_urb[i], GFP_KERNEL);
+ return 0;
+}
+
+static int dln2_start_rx_urbs(struct dln2_dev *dln2, gfp_t gfp)
+{
+ struct device *dev = &dln2->interface->dev;
+ int ret;
+ int i;
+
+ for (i = 0; i < DLN2_MAX_URBS; i++) {
+ ret = usb_submit_urb(dln2->rx_urb[i], gfp);
if (ret < 0) {
dev_err(dev, "failed to submit RX URB: %d\n", ret);
return ret;
@@ -665,9 +681,8 @@ static const struct mfd_cell dln2_devs[] = {
},
};
-static void dln2_disconnect(struct usb_interface *interface)
+static void dln2_stop(struct dln2_dev *dln2)
{
- struct dln2_dev *dln2 = usb_get_intfdata(interface);
int i, j;
/* don't allow starting new transfers */
@@ -696,6 +711,15 @@ static void dln2_disconnect(struct usb_interface *interface)
/* wait for transfers to end */
wait_event(dln2->disconnect_wq, !dln2->active_transfers);
+ dln2_stop_rx_urbs(dln2);
+}
+
+static void dln2_disconnect(struct usb_interface *interface)
+{
+ struct dln2_dev *dln2 = usb_get_intfdata(interface);
+
+ dln2_stop(dln2);
+
mfd_remove_devices(&interface->dev);
dln2_free(dln2);
@@ -738,28 +762,53 @@ static int dln2_probe(struct usb_interface *interface,
ret = dln2_setup_rx_urbs(dln2, hostif);
if (ret)
- goto out_cleanup;
+ goto out_free;
+
+ ret = dln2_start_rx_urbs(dln2, GFP_KERNEL);
+ if (ret)
+ goto out_stop_rx;
ret = dln2_hw_init(dln2);
if (ret < 0) {
dev_err(dev, "failed to initialize hardware\n");
- goto out_cleanup;
+ goto out_stop_rx;
}
ret = mfd_add_hotplug_devices(dev, dln2_devs, ARRAY_SIZE(dln2_devs));
if (ret != 0) {
dev_err(dev, "failed to add mfd devices to core\n");
- goto out_cleanup;
+ goto out_stop_rx;
}
return 0;
-out_cleanup:
+out_stop_rx:
+ dln2_stop_rx_urbs(dln2);
+
+out_free:
dln2_free(dln2);
return ret;
}
+static int dln2_suspend(struct usb_interface *iface, pm_message_t message)
+{
+ struct dln2_dev *dln2 = usb_get_intfdata(iface);
+
+ dln2_stop(dln2);
+
+ return 0;
+}
+
+static int dln2_resume(struct usb_interface *iface)
+{
+ struct dln2_dev *dln2 = usb_get_intfdata(iface);
+
+ dln2->disconnect = false;
+
+ return dln2_start_rx_urbs(dln2, GFP_NOIO);
+}
+
static const struct usb_device_id dln2_table[] = {
{ USB_DEVICE(0xa257, 0x2013) },
{ }
@@ -772,6 +821,8 @@ static struct usb_driver dln2_driver = {
.probe = dln2_probe,
.disconnect = dln2_disconnect,
.id_table = dln2_table,
+ .suspend = dln2_suspend,
+ .resume = dln2_resume,
};
module_usb_driver(dln2_driver);
diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c
index 321a2656fd00..7210ae28bf81 100644
--- a/drivers/mfd/hi6421-pmic-core.c
+++ b/drivers/mfd/hi6421-pmic-core.c
@@ -35,7 +35,7 @@ static const struct mfd_cell hi6421_devs[] = {
{ .name = "hi6421-regulator", },
};
-static struct regmap_config hi6421_regmap_config = {
+static const struct regmap_config hi6421_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 8,
diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c
index df7b0642a5b4..80cef048b904 100644
--- a/drivers/mfd/intel_soc_pmic_core.c
+++ b/drivers/mfd/intel_soc_pmic_core.c
@@ -64,6 +64,9 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
config = (struct intel_soc_pmic_config *)id->driver_data;
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
+ if (!pmic)
+ return -ENOMEM;
+
dev_set_drvdata(dev, pmic);
pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config);
diff --git a/drivers/mfd/intel_soc_pmic_core.h b/drivers/mfd/intel_soc_pmic_core.h
index 33aacd9baddc..9498d6719847 100644
--- a/drivers/mfd/intel_soc_pmic_core.h
+++ b/drivers/mfd/intel_soc_pmic_core.h
@@ -23,7 +23,7 @@ struct intel_soc_pmic_config {
unsigned long irq_flags;
struct mfd_cell *cell_dev;
int n_cell_devs;
- struct regmap_config *regmap_config;
+ const struct regmap_config *regmap_config;
struct regmap_irq_chip *irq_chip;
};
diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c
index c85e2ecb868a..4cc1b324e971 100644
--- a/drivers/mfd/intel_soc_pmic_crc.c
+++ b/drivers/mfd/intel_soc_pmic_crc.c
@@ -111,7 +111,7 @@ static struct mfd_cell crystal_cove_dev[] = {
},
};
-static struct regmap_config crystal_cove_regmap_config = {
+static const struct regmap_config crystal_cove_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index 8c29f7b27324..d42fbb667d8c 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -583,7 +583,7 @@ static bool lm3533_precious_register(struct device *dev, unsigned int reg)
}
}
-static struct regmap_config regmap_config = {
+static const struct regmap_config regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = LM3533_REG_MAX,
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
index 5c38df35a84d..a56e4ba5227b 100644
--- a/drivers/mfd/lpc_sch.c
+++ b/drivers/mfd/lpc_sch.c
@@ -75,6 +75,7 @@ static struct lpc_sch_info sch_chipset_info[] = {
[LPC_QUARK_X1000] = {
.io_size_gpio = GPIO_IO_SIZE,
.irq_gpio = GPIO_IRQ_QUARK_X1000,
+ .io_size_wdt = WDT_IO_SIZE,
},
};
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index 929795eae9fc..760d08d7923d 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -111,17 +111,17 @@ static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg)
max77802_rtc_is_volatile_reg(dev, reg));
}
-static struct regmap_config max77686_regmap_config = {
+static const struct regmap_config max77686_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
-static struct regmap_config max77686_rtc_regmap_config = {
+static const struct regmap_config max77686_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
-static struct regmap_config max77802_regmap_config = {
+static const struct regmap_config max77802_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.writeable_reg = max77802_is_accessible_reg,
@@ -205,24 +205,10 @@ static const struct of_device_id max77686_pmic_dt_match[] = {
{ },
};
-static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device
- *dev)
-{
- struct max77686_platform_data *pd;
-
- pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
- if (!pd)
- return NULL;
-
- dev->platform_data = pd;
- return pd;
-}
-
static int max77686_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max77686_dev *max77686 = NULL;
- struct max77686_platform_data *pdata = dev_get_platdata(&i2c->dev);
const struct of_device_id *match;
unsigned int data;
int ret = 0;
@@ -233,14 +219,6 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
const struct mfd_cell *cells;
int n_devs;
- if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node && !pdata)
- pdata = max77686_i2c_parse_dt_pdata(&i2c->dev);
-
- if (!pdata) {
- dev_err(&i2c->dev, "No platform data found.\n");
- return -EINVAL;
- }
-
max77686 = devm_kzalloc(&i2c->dev,
sizeof(struct max77686_dev), GFP_KERNEL);
if (!max77686)
@@ -259,7 +237,6 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
max77686->dev = &i2c->dev;
max77686->i2c = i2c;
- max77686->wakeup = pdata->wakeup;
max77686->irq = i2c->irq;
if (max77686->type == TYPE_MAX77686) {
diff --git a/drivers/mfd/mc13xxx-i2c.c b/drivers/mfd/mc13xxx-i2c.c
index ae3addb153a2..68b844811566 100644
--- a/drivers/mfd/mc13xxx-i2c.c
+++ b/drivers/mfd/mc13xxx-i2c.c
@@ -46,7 +46,7 @@ static const struct of_device_id mc13xxx_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids);
-static struct regmap_config mc13xxx_regmap_i2c_config = {
+static const struct regmap_config mc13xxx_regmap_i2c_config = {
.reg_bits = 8,
.val_bits = 24,
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c
index 702925e242c9..58a170e45d88 100644
--- a/drivers/mfd/mc13xxx-spi.c
+++ b/drivers/mfd/mc13xxx-spi.c
@@ -48,7 +48,7 @@ static const struct of_device_id mc13xxx_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids);
-static struct regmap_config mc13xxx_regmap_spi_config = {
+static const struct regmap_config mc13xxx_regmap_spi_config = {
.reg_bits = 7,
.pad_bits = 1,
.val_bits = 24,
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 04cd54dd507c..1d924d1533c0 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -129,16 +129,6 @@ static inline u32 usbhs_read(void __iomem *base, u32 reg)
return readl_relaxed(base + reg);
}
-static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val)
-{
- writeb_relaxed(val, base + reg);
-}
-
-static inline u8 usbhs_readb(void __iomem *base, u8 reg)
-{
- return readb_relaxed(base + reg);
-}
-
/*-------------------------------------------------------------------------*/
/**
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 43664eb69c93..6155d123a84e 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -183,7 +183,7 @@ static int pcf50633_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
-static struct regmap_config pcf50633_regmap_config = {
+static const struct regmap_config pcf50633_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
new file mode 100644
index 000000000000..f696328c2933
--- /dev/null
+++ b/drivers/mfd/qcom_rpm.c
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2014, Sony Mobile Communications AB.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Author: Bjorn Andersson <bjorn.andersson@sonymobile.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/qcom_rpm.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/mfd/qcom-rpm.h>
+
+struct qcom_rpm_resource {
+ unsigned target_id;
+ unsigned status_id;
+ unsigned select_id;
+ unsigned size;
+};
+
+struct qcom_rpm_data {
+ u32 version;
+ const struct qcom_rpm_resource *resource_table;
+ unsigned n_resources;
+};
+
+struct qcom_rpm {
+ struct device *dev;
+ struct regmap *ipc_regmap;
+ unsigned ipc_offset;
+ unsigned ipc_bit;
+
+ struct completion ack;
+ struct mutex lock;
+
+ void __iomem *status_regs;
+ void __iomem *ctrl_regs;
+ void __iomem *req_regs;
+
+ u32 ack_status;
+
+ const struct qcom_rpm_data *data;
+};
+
+#define RPM_STATUS_REG(rpm, i) ((rpm)->status_regs + (i) * 4)
+#define RPM_CTRL_REG(rpm, i) ((rpm)->ctrl_regs + (i) * 4)
+#define RPM_REQ_REG(rpm, i) ((rpm)->req_regs + (i) * 4)
+
+#define RPM_REQUEST_TIMEOUT (5 * HZ)
+
+#define RPM_REQUEST_CONTEXT 3
+#define RPM_REQ_SELECT 11
+#define RPM_ACK_CONTEXT 15
+#define RPM_ACK_SELECTOR 23
+#define RPM_SELECT_SIZE 7
+
+#define RPM_NOTIFICATION BIT(30)
+#define RPM_REJECTED BIT(31)
+
+#define RPM_SIGNAL BIT(2)
+
+static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = {
+ [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
+ [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 },
+ [QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 },
+ [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 },
+ [QCOM_RPM_MM_FABRIC_CLK] = { 29, 13, 10, 1 },
+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 },
+ [QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 },
+ [QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 },
+ [QCOM_RPM_MMFPB_CLK] = { 33, 17, 14, 1 },
+ [QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 },
+ [QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 1 },
+ [QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 1 },
+ [QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 },
+ [QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 },
+ [QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 1 },
+ [QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 1 },
+ [QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 },
+ [QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 30 },
+ [QCOM_RPM_MM_FABRIC_HALT] = { 89, 27, 26, 1 },
+ [QCOM_RPM_MM_FABRIC_MODE] = { 91, 28, 27, 1 },
+ [QCOM_RPM_MM_FABRIC_IOCTL] = { 94, 29, 28, 1 },
+ [QCOM_RPM_MM_FABRIC_ARB] = { 95, 30, 29, 21 },
+ [QCOM_RPM_PM8921_SMPS1] = { 116, 31, 30, 2 },
+ [QCOM_RPM_PM8921_SMPS2] = { 118, 33, 31, 2 },
+ [QCOM_RPM_PM8921_SMPS3] = { 120, 35, 32, 2 },
+ [QCOM_RPM_PM8921_SMPS4] = { 122, 37, 33, 2 },
+ [QCOM_RPM_PM8921_SMPS5] = { 124, 39, 34, 2 },
+ [QCOM_RPM_PM8921_SMPS6] = { 126, 41, 35, 2 },
+ [QCOM_RPM_PM8921_SMPS7] = { 128, 43, 36, 2 },
+ [QCOM_RPM_PM8921_SMPS8] = { 130, 45, 37, 2 },
+ [QCOM_RPM_PM8921_LDO1] = { 132, 47, 38, 2 },
+ [QCOM_RPM_PM8921_LDO2] = { 134, 49, 39, 2 },
+ [QCOM_RPM_PM8921_LDO3] = { 136, 51, 40, 2 },
+ [QCOM_RPM_PM8921_LDO4] = { 138, 53, 41, 2 },
+ [QCOM_RPM_PM8921_LDO5] = { 140, 55, 42, 2 },
+ [QCOM_RPM_PM8921_LDO6] = { 142, 57, 43, 2 },
+ [QCOM_RPM_PM8921_LDO7] = { 144, 59, 44, 2 },
+ [QCOM_RPM_PM8921_LDO8] = { 146, 61, 45, 2 },
+ [QCOM_RPM_PM8921_LDO9] = { 148, 63, 46, 2 },
+ [QCOM_RPM_PM8921_LDO10] = { 150, 65, 47, 2 },
+ [QCOM_RPM_PM8921_LDO11] = { 152, 67, 48, 2 },
+ [QCOM_RPM_PM8921_LDO12] = { 154, 69, 49, 2 },
+ [QCOM_RPM_PM8921_LDO13] = { 156, 71, 50, 2 },
+ [QCOM_RPM_PM8921_LDO14] = { 158, 73, 51, 2 },
+ [QCOM_RPM_PM8921_LDO15] = { 160, 75, 52, 2 },
+ [QCOM_RPM_PM8921_LDO16] = { 162, 77, 53, 2 },
+ [QCOM_RPM_PM8921_LDO17] = { 164, 79, 54, 2 },
+ [QCOM_RPM_PM8921_LDO18] = { 166, 81, 55, 2 },
+ [QCOM_RPM_PM8921_LDO19] = { 168, 83, 56, 2 },
+ [QCOM_RPM_PM8921_LDO20] = { 170, 85, 57, 2 },
+ [QCOM_RPM_PM8921_LDO21] = { 172, 87, 58, 2 },
+ [QCOM_RPM_PM8921_LDO22] = { 174, 89, 59, 2 },
+ [QCOM_RPM_PM8921_LDO23] = { 176, 91, 60, 2 },
+ [QCOM_RPM_PM8921_LDO24] = { 178, 93, 61, 2 },
+ [QCOM_RPM_PM8921_LDO25] = { 180, 95, 62, 2 },
+ [QCOM_RPM_PM8921_LDO26] = { 182, 97, 63, 2 },
+ [QCOM_RPM_PM8921_LDO27] = { 184, 99, 64, 2 },
+ [QCOM_RPM_PM8921_LDO28] = { 186, 101, 65, 2 },
+ [QCOM_RPM_PM8921_LDO29] = { 188, 103, 66, 2 },
+ [QCOM_RPM_PM8921_CLK1] = { 190, 105, 67, 2 },
+ [QCOM_RPM_PM8921_CLK2] = { 192, 107, 68, 2 },
+ [QCOM_RPM_PM8921_LVS1] = { 194, 109, 69, 1 },
+ [QCOM_RPM_PM8921_LVS2] = { 195, 110, 70, 1 },
+ [QCOM_RPM_PM8921_LVS3] = { 196, 111, 71, 1 },
+ [QCOM_RPM_PM8921_LVS4] = { 197, 112, 72, 1 },
+ [QCOM_RPM_PM8921_LVS5] = { 198, 113, 73, 1 },
+ [QCOM_RPM_PM8921_LVS6] = { 199, 114, 74, 1 },
+ [QCOM_RPM_PM8921_LVS7] = { 200, 115, 75, 1 },
+ [QCOM_RPM_PM8821_SMPS1] = { 201, 116, 76, 2 },
+ [QCOM_RPM_PM8821_SMPS2] = { 203, 118, 77, 2 },
+ [QCOM_RPM_PM8821_LDO1] = { 205, 120, 78, 2 },
+ [QCOM_RPM_PM8921_NCP] = { 207, 122, 80, 2 },
+ [QCOM_RPM_CXO_BUFFERS] = { 209, 124, 81, 1 },
+ [QCOM_RPM_USB_OTG_SWITCH] = { 210, 125, 82, 1 },
+ [QCOM_RPM_HDMI_SWITCH] = { 211, 126, 83, 1 },
+ [QCOM_RPM_DDR_DMM] = { 212, 127, 84, 2 },
+ [QCOM_RPM_VDDMIN_GPIO] = { 215, 131, 89, 1 },
+};
+
+static const struct qcom_rpm_data apq8064_template = {
+ .version = 3,
+ .resource_table = apq8064_rpm_resource_table,
+ .n_resources = ARRAY_SIZE(apq8064_rpm_resource_table),
+};
+
+static const struct qcom_rpm_resource msm8660_rpm_resource_table[] = {
+ [QCOM_RPM_CXO_CLK] = { 32, 12, 5, 1 },
+ [QCOM_RPM_PXO_CLK] = { 33, 13, 6, 1 },
+ [QCOM_RPM_PLL_4] = { 34, 14, 7, 1 },
+ [QCOM_RPM_APPS_FABRIC_CLK] = { 35, 15, 8, 1 },
+ [QCOM_RPM_SYS_FABRIC_CLK] = { 36, 16, 9, 1 },
+ [QCOM_RPM_MM_FABRIC_CLK] = { 37, 17, 10, 1 },
+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 38, 18, 11, 1 },
+ [QCOM_RPM_SFPB_CLK] = { 39, 19, 12, 1 },
+ [QCOM_RPM_CFPB_CLK] = { 40, 20, 13, 1 },
+ [QCOM_RPM_MMFPB_CLK] = { 41, 21, 14, 1 },
+ [QCOM_RPM_SMI_CLK] = { 42, 22, 15, 1 },
+ [QCOM_RPM_EBI1_CLK] = { 43, 23, 16, 1 },
+ [QCOM_RPM_APPS_L2_CACHE_CTL] = { 44, 24, 17, 1 },
+ [QCOM_RPM_APPS_FABRIC_HALT] = { 45, 25, 18, 2 },
+ [QCOM_RPM_APPS_FABRIC_MODE] = { 47, 26, 19, 3 },
+ [QCOM_RPM_APPS_FABRIC_ARB] = { 51, 28, 21, 6 },
+ [QCOM_RPM_SYS_FABRIC_HALT] = { 63, 29, 22, 2 },
+ [QCOM_RPM_SYS_FABRIC_MODE] = { 65, 30, 23, 3 },
+ [QCOM_RPM_SYS_FABRIC_ARB] = { 69, 32, 25, 22 },
+ [QCOM_RPM_MM_FABRIC_HALT] = { 105, 33, 26, 2 },
+ [QCOM_RPM_MM_FABRIC_MODE] = { 107, 34, 27, 3 },
+ [QCOM_RPM_MM_FABRIC_ARB] = { 111, 36, 29, 23 },
+ [QCOM_RPM_PM8901_SMPS0] = { 134, 37, 30, 2 },
+ [QCOM_RPM_PM8901_SMPS1] = { 136, 39, 31, 2 },
+ [QCOM_RPM_PM8901_SMPS2] = { 138, 41, 32, 2 },
+ [QCOM_RPM_PM8901_SMPS3] = { 140, 43, 33, 2 },
+ [QCOM_RPM_PM8901_SMPS4] = { 142, 45, 34, 2 },
+ [QCOM_RPM_PM8901_LDO0] = { 144, 47, 35, 2 },
+ [QCOM_RPM_PM8901_LDO1] = { 146, 49, 36, 2 },
+ [QCOM_RPM_PM8901_LDO2] = { 148, 51, 37, 2 },
+ [QCOM_RPM_PM8901_LDO3] = { 150, 53, 38, 2 },
+ [QCOM_RPM_PM8901_LDO4] = { 152, 55, 39, 2 },
+ [QCOM_RPM_PM8901_LDO5] = { 154, 57, 40, 2 },
+ [QCOM_RPM_PM8901_LDO6] = { 156, 59, 41, 2 },
+ [QCOM_RPM_PM8901_LVS0] = { 158, 61, 42, 1 },
+ [QCOM_RPM_PM8901_LVS1] = { 159, 62, 43, 1 },
+ [QCOM_RPM_PM8901_LVS2] = { 160, 63, 44, 1 },
+ [QCOM_RPM_PM8901_LVS3] = { 161, 64, 45, 1 },
+ [QCOM_RPM_PM8901_MVS] = { 162, 65, 46, 1 },
+ [QCOM_RPM_PM8058_SMPS0] = { 163, 66, 47, 2 },
+ [QCOM_RPM_PM8058_SMPS1] = { 165, 68, 48, 2 },
+ [QCOM_RPM_PM8058_SMPS2] = { 167, 70, 49, 2 },
+ [QCOM_RPM_PM8058_SMPS3] = { 169, 72, 50, 2 },
+ [QCOM_RPM_PM8058_SMPS4] = { 171, 74, 51, 2 },
+ [QCOM_RPM_PM8058_LDO0] = { 173, 76, 52, 2 },
+ [QCOM_RPM_PM8058_LDO1] = { 175, 78, 53, 2 },
+ [QCOM_RPM_PM8058_LDO2] = { 177, 80, 54, 2 },
+ [QCOM_RPM_PM8058_LDO3] = { 179, 82, 55, 2 },
+ [QCOM_RPM_PM8058_LDO4] = { 181, 84, 56, 2 },
+ [QCOM_RPM_PM8058_LDO5] = { 183, 86, 57, 2 },
+ [QCOM_RPM_PM8058_LDO6] = { 185, 88, 58, 2 },
+ [QCOM_RPM_PM8058_LDO7] = { 187, 90, 59, 2 },
+ [QCOM_RPM_PM8058_LDO8] = { 189, 92, 60, 2 },
+ [QCOM_RPM_PM8058_LDO9] = { 191, 94, 61, 2 },
+ [QCOM_RPM_PM8058_LDO10] = { 193, 96, 62, 2 },
+ [QCOM_RPM_PM8058_LDO11] = { 195, 98, 63, 2 },
+ [QCOM_RPM_PM8058_LDO12] = { 197, 100, 64, 2 },
+ [QCOM_RPM_PM8058_LDO13] = { 199, 102, 65, 2 },
+ [QCOM_RPM_PM8058_LDO14] = { 201, 104, 66, 2 },
+ [QCOM_RPM_PM8058_LDO15] = { 203, 106, 67, 2 },
+ [QCOM_RPM_PM8058_LDO16] = { 205, 108, 68, 2 },
+ [QCOM_RPM_PM8058_LDO17] = { 207, 110, 69, 2 },
+ [QCOM_RPM_PM8058_LDO18] = { 209, 112, 70, 2 },
+ [QCOM_RPM_PM8058_LDO19] = { 211, 114, 71, 2 },
+ [QCOM_RPM_PM8058_LDO20] = { 213, 116, 72, 2 },
+ [QCOM_RPM_PM8058_LDO21] = { 215, 118, 73, 2 },
+ [QCOM_RPM_PM8058_LDO22] = { 217, 120, 74, 2 },
+ [QCOM_RPM_PM8058_LDO23] = { 219, 122, 75, 2 },
+ [QCOM_RPM_PM8058_LDO24] = { 221, 124, 76, 2 },
+ [QCOM_RPM_PM8058_LDO25] = { 223, 126, 77, 2 },
+ [QCOM_RPM_PM8058_LVS0] = { 225, 128, 78, 1 },
+ [QCOM_RPM_PM8058_LVS1] = { 226, 129, 79, 1 },
+ [QCOM_RPM_PM8058_NCP] = { 227, 130, 80, 2 },
+ [QCOM_RPM_CXO_BUFFERS] = { 229, 132, 81, 1 },
+};
+
+static const struct qcom_rpm_data msm8660_template = {
+ .version = 2,
+ .resource_table = msm8660_rpm_resource_table,
+ .n_resources = ARRAY_SIZE(msm8660_rpm_resource_table),
+};
+
+static const struct qcom_rpm_resource msm8960_rpm_resource_table[] = {
+ [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
+ [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 },
+ [QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 },
+ [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 },
+ [QCOM_RPM_MM_FABRIC_CLK] = { 29, 13, 10, 1 },
+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 },
+ [QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 },
+ [QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 },
+ [QCOM_RPM_MMFPB_CLK] = { 33, 17, 14, 1 },
+ [QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 },
+ [QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 1 },
+ [QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 1 },
+ [QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 },
+ [QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 },
+ [QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 1 },
+ [QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 1 },
+ [QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 },
+ [QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 29 },
+ [QCOM_RPM_MM_FABRIC_HALT] = { 88, 27, 26, 1 },
+ [QCOM_RPM_MM_FABRIC_MODE] = { 90, 28, 27, 1 },
+ [QCOM_RPM_MM_FABRIC_IOCTL] = { 93, 29, 28, 1 },
+ [QCOM_RPM_MM_FABRIC_ARB] = { 94, 30, 29, 23 },
+ [QCOM_RPM_PM8921_SMPS1] = { 117, 31, 30, 2 },
+ [QCOM_RPM_PM8921_SMPS2] = { 119, 33, 31, 2 },
+ [QCOM_RPM_PM8921_SMPS3] = { 121, 35, 32, 2 },
+ [QCOM_RPM_PM8921_SMPS4] = { 123, 37, 33, 2 },
+ [QCOM_RPM_PM8921_SMPS5] = { 125, 39, 34, 2 },
+ [QCOM_RPM_PM8921_SMPS6] = { 127, 41, 35, 2 },
+ [QCOM_RPM_PM8921_SMPS7] = { 129, 43, 36, 2 },
+ [QCOM_RPM_PM8921_SMPS8] = { 131, 45, 37, 2 },
+ [QCOM_RPM_PM8921_LDO1] = { 133, 47, 38, 2 },
+ [QCOM_RPM_PM8921_LDO2] = { 135, 49, 39, 2 },
+ [QCOM_RPM_PM8921_LDO3] = { 137, 51, 40, 2 },
+ [QCOM_RPM_PM8921_LDO4] = { 139, 53, 41, 2 },
+ [QCOM_RPM_PM8921_LDO5] = { 141, 55, 42, 2 },
+ [QCOM_RPM_PM8921_LDO6] = { 143, 57, 43, 2 },
+ [QCOM_RPM_PM8921_LDO7] = { 145, 59, 44, 2 },
+ [QCOM_RPM_PM8921_LDO8] = { 147, 61, 45, 2 },
+ [QCOM_RPM_PM8921_LDO9] = { 149, 63, 46, 2 },
+ [QCOM_RPM_PM8921_LDO10] = { 151, 65, 47, 2 },
+ [QCOM_RPM_PM8921_LDO11] = { 153, 67, 48, 2 },
+ [QCOM_RPM_PM8921_LDO12] = { 155, 69, 49, 2 },
+ [QCOM_RPM_PM8921_LDO13] = { 157, 71, 50, 2 },
+ [QCOM_RPM_PM8921_LDO14] = { 159, 73, 51, 2 },
+ [QCOM_RPM_PM8921_LDO15] = { 161, 75, 52, 2 },
+ [QCOM_RPM_PM8921_LDO16] = { 163, 77, 53, 2 },
+ [QCOM_RPM_PM8921_LDO17] = { 165, 79, 54, 2 },
+ [QCOM_RPM_PM8921_LDO18] = { 167, 81, 55, 2 },
+ [QCOM_RPM_PM8921_LDO19] = { 169, 83, 56, 2 },
+ [QCOM_RPM_PM8921_LDO20] = { 171, 85, 57, 2 },
+ [QCOM_RPM_PM8921_LDO21] = { 173, 87, 58, 2 },
+ [QCOM_RPM_PM8921_LDO22] = { 175, 89, 59, 2 },
+ [QCOM_RPM_PM8921_LDO23] = { 177, 91, 60, 2 },
+ [QCOM_RPM_PM8921_LDO24] = { 179, 93, 61, 2 },
+ [QCOM_RPM_PM8921_LDO25] = { 181, 95, 62, 2 },
+ [QCOM_RPM_PM8921_LDO26] = { 183, 97, 63, 2 },
+ [QCOM_RPM_PM8921_LDO27] = { 185, 99, 64, 2 },
+ [QCOM_RPM_PM8921_LDO28] = { 187, 101, 65, 2 },
+ [QCOM_RPM_PM8921_LDO29] = { 189, 103, 66, 2 },
+ [QCOM_RPM_PM8921_CLK1] = { 191, 105, 67, 2 },
+ [QCOM_RPM_PM8921_CLK2] = { 193, 107, 68, 2 },
+ [QCOM_RPM_PM8921_LVS1] = { 195, 109, 69, 1 },
+ [QCOM_RPM_PM8921_LVS2] = { 196, 110, 70, 1 },
+ [QCOM_RPM_PM8921_LVS3] = { 197, 111, 71, 1 },
+ [QCOM_RPM_PM8921_LVS4] = { 198, 112, 72, 1 },
+ [QCOM_RPM_PM8921_LVS5] = { 199, 113, 73, 1 },
+ [QCOM_RPM_PM8921_LVS6] = { 200, 114, 74, 1 },
+ [QCOM_RPM_PM8921_LVS7] = { 201, 115, 75, 1 },
+ [QCOM_RPM_PM8921_NCP] = { 202, 116, 80, 2 },
+ [QCOM_RPM_CXO_BUFFERS] = { 204, 118, 81, 1 },
+ [QCOM_RPM_USB_OTG_SWITCH] = { 205, 119, 82, 1 },
+ [QCOM_RPM_HDMI_SWITCH] = { 206, 120, 83, 1 },
+ [QCOM_RPM_DDR_DMM] = { 207, 121, 84, 2 },
+};
+
+static const struct qcom_rpm_data msm8960_template = {
+ .version = 3,
+ .resource_table = msm8960_rpm_resource_table,
+ .n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
+};
+
+static const struct of_device_id qcom_rpm_of_match[] = {
+ { .compatible = "qcom,rpm-apq8064", .data = &apq8064_template },
+ { .compatible = "qcom,rpm-msm8660", .data = &msm8660_template },
+ { .compatible = "qcom,rpm-msm8960", .data = &msm8960_template },
+ { }
+};
+MODULE_DEVICE_TABLE(of, qcom_rpm_of_match);
+
+int qcom_rpm_write(struct qcom_rpm *rpm,
+ int state,
+ int resource,
+ u32 *buf, size_t count)
+{
+ const struct qcom_rpm_resource *res;
+ const struct qcom_rpm_data *data = rpm->data;
+ u32 sel_mask[RPM_SELECT_SIZE] = { 0 };
+ int left;
+ int ret = 0;
+ int i;
+
+ if (WARN_ON(resource < 0 || resource >= data->n_resources))
+ return -EINVAL;
+
+ res = &data->resource_table[resource];
+ if (WARN_ON(res->size != count))
+ return -EINVAL;
+
+ mutex_lock(&rpm->lock);
+
+ for (i = 0; i < res->size; i++)
+ writel_relaxed(buf[i], RPM_REQ_REG(rpm, res->target_id + i));
+
+ bitmap_set((unsigned long *)sel_mask, res->select_id, 1);
+ for (i = 0; i < ARRAY_SIZE(sel_mask); i++) {
+ writel_relaxed(sel_mask[i],
+ RPM_CTRL_REG(rpm, RPM_REQ_SELECT + i));
+ }
+
+ writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, RPM_REQUEST_CONTEXT));
+
+ reinit_completion(&rpm->ack);
+ regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit));
+
+ left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT);
+ if (!left)
+ ret = -ETIMEDOUT;
+ else if (rpm->ack_status & RPM_REJECTED)
+ ret = -EIO;
+
+ mutex_unlock(&rpm->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(qcom_rpm_write);
+
+static irqreturn_t qcom_rpm_ack_interrupt(int irq, void *dev)
+{
+ struct qcom_rpm *rpm = dev;
+ u32 ack;
+ int i;
+
+ ack = readl_relaxed(RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
+ for (i = 0; i < RPM_SELECT_SIZE; i++)
+ writel_relaxed(0, RPM_CTRL_REG(rpm, RPM_ACK_SELECTOR + i));
+ writel(0, RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
+
+ if (ack & RPM_NOTIFICATION) {
+ dev_warn(rpm->dev, "ignoring notification!\n");
+ } else {
+ rpm->ack_status = ack;
+ complete(&rpm->ack);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t qcom_rpm_err_interrupt(int irq, void *dev)
+{
+ struct qcom_rpm *rpm = dev;
+
+ regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit));
+ dev_err(rpm->dev, "RPM triggered fatal error\n");
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t qcom_rpm_wakeup_interrupt(int irq, void *dev)
+{
+ return IRQ_HANDLED;
+}
+
+static int qcom_rpm_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct device_node *syscon_np;
+ struct resource *res;
+ struct qcom_rpm *rpm;
+ u32 fw_version[3];
+ int irq_wakeup;
+ int irq_ack;
+ int irq_err;
+ int ret;
+
+ rpm = devm_kzalloc(&pdev->dev, sizeof(*rpm), GFP_KERNEL);
+ if (!rpm)
+ return -ENOMEM;
+
+ rpm->dev = &pdev->dev;
+ mutex_init(&rpm->lock);
+ init_completion(&rpm->ack);
+
+ irq_ack = platform_get_irq_byname(pdev, "ack");
+ if (irq_ack < 0) {
+ dev_err(&pdev->dev, "required ack interrupt missing\n");
+ return irq_ack;
+ }
+
+ irq_err = platform_get_irq_byname(pdev, "err");
+ if (irq_err < 0) {
+ dev_err(&pdev->dev, "required err interrupt missing\n");
+ return irq_err;
+ }
+
+ irq_wakeup = platform_get_irq_byname(pdev, "wakeup");
+ if (irq_wakeup < 0) {
+ dev_err(&pdev->dev, "required wakeup interrupt missing\n");
+ return irq_wakeup;
+ }
+
+ match = of_match_device(qcom_rpm_of_match, &pdev->dev);
+ rpm->data = match->data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rpm->status_regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rpm->status_regs))
+ return PTR_ERR(rpm->status_regs);
+ rpm->ctrl_regs = rpm->status_regs + 0x400;
+ rpm->req_regs = rpm->status_regs + 0x600;
+
+ syscon_np = of_parse_phandle(pdev->dev.of_node, "qcom,ipc", 0);
+ if (!syscon_np) {
+ dev_err(&pdev->dev, "no qcom,ipc node\n");
+ return -ENODEV;
+ }
+
+ rpm->ipc_regmap = syscon_node_to_regmap(syscon_np);
+ if (IS_ERR(rpm->ipc_regmap))
+ return PTR_ERR(rpm->ipc_regmap);
+
+ ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,ipc", 1,
+ &rpm->ipc_offset);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "no offset in qcom,ipc\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,ipc", 2,
+ &rpm->ipc_bit);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "no bit in qcom,ipc\n");
+ return -EINVAL;
+ }
+
+ dev_set_drvdata(&pdev->dev, rpm);
+
+ fw_version[0] = readl(RPM_STATUS_REG(rpm, 0));
+ fw_version[1] = readl(RPM_STATUS_REG(rpm, 1));
+ fw_version[2] = readl(RPM_STATUS_REG(rpm, 2));
+ if (fw_version[0] != rpm->data->version) {
+ dev_err(&pdev->dev,
+ "RPM version %u.%u.%u incompatible with driver version %u",
+ fw_version[0],
+ fw_version[1],
+ fw_version[2],
+ rpm->data->version);
+ return -EFAULT;
+ }
+
+ dev_info(&pdev->dev, "RPM firmware %u.%u.%u\n", fw_version[0],
+ fw_version[1],
+ fw_version[2]);
+
+ ret = devm_request_irq(&pdev->dev,
+ irq_ack,
+ qcom_rpm_ack_interrupt,
+ IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
+ "qcom_rpm_ack",
+ rpm);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request ack interrupt\n");
+ return ret;
+ }
+
+ ret = irq_set_irq_wake(irq_ack, 1);
+ if (ret)
+ dev_warn(&pdev->dev, "failed to mark ack irq as wakeup\n");
+
+ ret = devm_request_irq(&pdev->dev,
+ irq_err,
+ qcom_rpm_err_interrupt,
+ IRQF_TRIGGER_RISING,
+ "qcom_rpm_err",
+ rpm);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request err interrupt\n");
+ return ret;
+ }
+
+ ret = devm_request_irq(&pdev->dev,
+ irq_wakeup,
+ qcom_rpm_wakeup_interrupt,
+ IRQF_TRIGGER_RISING,
+ "qcom_rpm_wakeup",
+ rpm);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request wakeup interrupt\n");
+ return ret;
+ }
+
+ ret = irq_set_irq_wake(irq_wakeup, 1);
+ if (ret)
+ dev_warn(&pdev->dev, "failed to mark wakeup irq as wakeup\n");
+
+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+}
+
+static int qcom_rpm_remove(struct platform_device *pdev)
+{
+ of_platform_depopulate(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver qcom_rpm_driver = {
+ .probe = qcom_rpm_probe,
+ .remove = qcom_rpm_remove,
+ .driver = {
+ .name = "qcom_rpm",
+ .of_match_table = qcom_rpm_of_match,
+ },
+};
+
+static int __init qcom_rpm_init(void)
+{
+ return platform_driver_register(&qcom_rpm_driver);
+}
+arch_initcall(qcom_rpm_init);
+
+static void __exit qcom_rpm_exit(void)
+{
+ platform_driver_unregister(&qcom_rpm_driver);
+}
+module_exit(qcom_rpm_exit)
+
+MODULE_DESCRIPTION("Qualcomm Resource Power Manager driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c
index 663f8a37aa6b..2d64430c719b 100644
--- a/drivers/mfd/retu-mfd.c
+++ b/drivers/mfd/retu-mfd.c
@@ -222,7 +222,7 @@ static struct regmap_bus retu_bus = {
.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
};
-static struct regmap_config retu_config = {
+static const struct regmap_config retu_config = {
.reg_bits = 8,
.val_bits = 16,
};
diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c
new file mode 100644
index 000000000000..db395a6c52bc
--- /dev/null
+++ b/drivers/mfd/rt5033.c
@@ -0,0 +1,142 @@
+/*
+ * MFD core driver for the Richtek RT5033.
+ *
+ * RT5033 comprises multiple sub-devices switcing charger, fuel gauge,
+ * flash LED, current source, LDO and BUCK regulators.
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/of_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rt5033.h>
+#include <linux/mfd/rt5033-private.h>
+
+static const struct regmap_irq rt5033_irqs[] = {
+ { .mask = RT5033_PMIC_IRQ_BUCKOCP, },
+ { .mask = RT5033_PMIC_IRQ_BUCKLV, },
+ { .mask = RT5033_PMIC_IRQ_SAFELDOLV, },
+ { .mask = RT5033_PMIC_IRQ_LDOLV, },
+ { .mask = RT5033_PMIC_IRQ_OT, },
+ { .mask = RT5033_PMIC_IRQ_VDDA_UV, },
+};
+
+static const struct regmap_irq_chip rt5033_irq_chip = {
+ .name = "rt5033",
+ .status_base = RT5033_REG_PMIC_IRQ_STAT,
+ .mask_base = RT5033_REG_PMIC_IRQ_CTRL,
+ .mask_invert = true,
+ .num_regs = 1,
+ .irqs = rt5033_irqs,
+ .num_irqs = ARRAY_SIZE(rt5033_irqs),
+};
+
+static const struct mfd_cell rt5033_devs[] = {
+ { .name = "rt5033-regulator", },
+ {
+ .name = "rt5033-charger",
+ .of_compatible = "richtek,rt5033-charger",
+ }, {
+ .name = "rt5033-battery",
+ .of_compatible = "richtek,rt5033-battery",
+ },
+};
+
+static const struct regmap_config rt5033_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = RT5033_REG_END,
+};
+
+static int rt5033_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct rt5033_dev *rt5033;
+ unsigned int dev_id;
+ int ret;
+
+ rt5033 = devm_kzalloc(&i2c->dev, sizeof(*rt5033), GFP_KERNEL);
+ if (!rt5033)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, rt5033);
+ rt5033->dev = &i2c->dev;
+ rt5033->irq = i2c->irq;
+ rt5033->wakeup = true;
+
+ rt5033->regmap = devm_regmap_init_i2c(i2c, &rt5033_regmap_config);
+ if (IS_ERR(rt5033->regmap)) {
+ dev_err(&i2c->dev, "Failed to allocate register map.\n");
+ return PTR_ERR(rt5033->regmap);
+ }
+
+ ret = regmap_read(rt5033->regmap, RT5033_REG_DEVICE_ID, &dev_id);
+ if (ret) {
+ dev_err(&i2c->dev, "Device not found\n");
+ return -ENODEV;
+ }
+ dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id);
+
+ ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ 0, &rt5033_irq_chip, &rt5033->irq_data);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+ rt5033->irq, ret);
+ return ret;
+ }
+
+ ret = mfd_add_devices(rt5033->dev, -1, rt5033_devs,
+ ARRAY_SIZE(rt5033_devs), NULL, 0,
+ regmap_irq_get_domain(rt5033->irq_data));
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to add RT5033 child devices.\n");
+ return ret;
+ }
+
+ device_init_wakeup(rt5033->dev, rt5033->wakeup);
+
+ return 0;
+}
+
+static int rt5033_i2c_remove(struct i2c_client *i2c)
+{
+ mfd_remove_devices(&i2c->dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id rt5033_i2c_id[] = {
+ { "rt5033", },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rt5033_i2c_id);
+
+static const struct of_device_id rt5033_dt_match[] = {
+ { .compatible = "richtek,rt5033", },
+ { }
+};
+
+static struct i2c_driver rt5033_driver = {
+ .driver = {
+ .name = "rt5033",
+ .of_match_table = of_match_ptr(rt5033_dt_match),
+ },
+ .probe = rt5033_i2c_probe,
+ .remove = rt5033_i2c_remove,
+ .id_table = rt5033_i2c_id,
+};
+module_i2c_driver(rt5033_driver);
+
+MODULE_ALIAS("i2c:rt5033");
+MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver");
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index 210d1f85679e..ede50244f265 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -681,9 +681,27 @@ static void rtsx_usb_disconnect(struct usb_interface *intf)
#ifdef CONFIG_PM
static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
+ struct rtsx_ucr *ucr =
+ (struct rtsx_ucr *)usb_get_intfdata(intf);
+ u16 val = 0;
+
dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n",
__func__, message.event);
+ if (PMSG_IS_AUTO(message)) {
+ if (mutex_trylock(&ucr->dev_mutex)) {
+ rtsx_usb_get_card_status(ucr, &val);
+ mutex_unlock(&ucr->dev_mutex);
+
+ /* Defer the autosuspend if card exists */
+ if (val & (SD_CD | MS_CD))
+ return -EAGAIN;
+ } else {
+ /* There is an ongoing operation*/
+ return -EAGAIN;
+ }
+ }
+
return 0;
}
diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c
index 90112d4cc905..03246880d484 100644
--- a/drivers/mfd/smsc-ece1099.c
+++ b/drivers/mfd/smsc-ece1099.c
@@ -24,7 +24,7 @@
#include <linux/mfd/smsc.h>
#include <linux/of_platform.h>
-static struct regmap_config smsc_regmap_config = {
+static const struct regmap_config smsc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = SMSC_VEN_ID_H,
diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
index 2f2e9f062571..191173166d65 100644
--- a/drivers/mfd/sun6i-prcm.c
+++ b/drivers/mfd/sun6i-prcm.c
@@ -41,6 +41,14 @@ static const struct resource sun6i_a31_apb0_gates_clk_res[] = {
},
};
+static const struct resource sun6i_a31_ir_clk_res[] = {
+ {
+ .start = 0x54,
+ .end = 0x57,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
static const struct resource sun6i_a31_apb0_rstc_res[] = {
{
.start = 0xb0,
@@ -69,6 +77,12 @@ static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
.resources = sun6i_a31_apb0_gates_clk_res,
},
{
+ .name = "sun6i-a31-ir-clk",
+ .of_compatible = "allwinner,sun4i-a10-mod0-clk",
+ .num_resources = ARRAY_SIZE(sun6i_a31_ir_clk_res),
+ .resources = sun6i_a31_ir_clk_res,
+ },
+ {
.name = "sun6i-a31-apb0-clock-reset",
.of_compatible = "allwinner,sun6i-a31-clock-reset",
.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 80a919a8ca97..7d1cfc1d3ce0 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -145,7 +145,7 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
}
EXPORT_SYMBOL_GPL(tps65217_clear_bits);
-static struct regmap_config tps65217_regmap_config = {
+static const struct regmap_config tps65217_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c
index d6b764349f9d..7af11a8b9753 100644
--- a/drivers/mfd/tps65218.c
+++ b/drivers/mfd/tps65218.c
@@ -135,7 +135,7 @@ static const struct regmap_access_table tps65218_volatile_table = {
.n_yes_ranges = ARRAY_SIZE(tps65218_yes_ranges),
};
-static struct regmap_config tps65218_regmap_config = {
+static const struct regmap_config tps65218_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index db11b4f40611..489674a2497e 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -207,7 +207,7 @@ static struct twl_mapping twl4030_map[] = {
{ 2, TWL5031_BASEADD_INTERRUPTS },
};
-static struct reg_default twl4030_49_defaults[] = {
+static const struct reg_default twl4030_49_defaults[] = {
/* Audio Registers */
{ 0x01, 0x00}, /* CODEC_MODE */
{ 0x02, 0x00}, /* OPTION */
@@ -306,7 +306,7 @@ static const struct regmap_access_table twl4030_49_volatile_table = {
.n_yes_ranges = ARRAY_SIZE(twl4030_49_volatile_ranges),
};
-static struct regmap_config twl4030_regmap_config[4] = {
+static const struct regmap_config twl4030_regmap_config[4] = {
{
/* Address 0x48 */
.reg_bits = 8,
@@ -369,7 +369,7 @@ static struct twl_mapping twl6030_map[] = {
{ 1, TWL6030_BASEADD_GASGAUGE },
};
-static struct regmap_config twl6030_regmap_config[3] = {
+static const struct regmap_config twl6030_regmap_config[3] = {
{
/* Address 0x48 */
.reg_bits = 8,
@@ -1087,7 +1087,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
struct twl4030_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *node = client->dev.of_node;
struct platform_device *pdev;
- struct regmap_config *twl_regmap_config;
+ const struct regmap_config *twl_regmap_config;
int irq_base = 0;
int status;
unsigned i, num_slaves;
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index 9687645162ae..f71ee3dbc2a2 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -44,7 +44,7 @@
#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
#define TWL6040_NUM_SUPPLIES (2)
-static struct reg_default twl6040_defaults[] = {
+static const struct reg_default twl6040_defaults[] = {
{ 0x01, 0x4B }, /* REG_ASICID (ro) */
{ 0x02, 0x00 }, /* REG_ASICREV (ro) */
{ 0x03, 0x00 }, /* REG_INTID */
@@ -580,7 +580,7 @@ static bool twl6040_writeable_reg(struct device *dev, unsigned int reg)
}
}
-static struct regmap_config twl6040_regmap_config = {
+static const struct regmap_config twl6040_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 6ca9d25cc3f0..53ae5af5d6e4 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -36,12 +36,12 @@
static const struct mfd_cell wm8994_regulator_devs[] = {
{
.name = "wm8994-ldo",
- .id = 1,
+ .id = 0,
.pm_runtime_no_callbacks = true,
},
{
.name = "wm8994-ldo",
- .id = 2,
+ .id = 1,
.pm_runtime_no_callbacks = true,
},
};
@@ -344,7 +344,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
dev_set_drvdata(wm8994->dev, wm8994);
/* Add the on-chip regulators first for bootstrapping */
- ret = mfd_add_devices(wm8994->dev, -1,
+ ret = mfd_add_devices(wm8994->dev, 0,
wm8994_regulator_devs,
ARRAY_SIZE(wm8994_regulator_devs),
NULL, 0, NULL);
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
index cc13ea5ce4d5..c0720c1ee4c9 100644
--- a/drivers/mtd/bcm47xxpart.c
+++ b/drivers/mtd/bcm47xxpart.c
@@ -15,6 +15,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <uapi/linux/magic.h>
+
/*
* NAND flash on Netgear R6250 was verified to contain 15 partitions.
* This will result in allocating too big array for some old devices, but the
@@ -39,7 +41,8 @@
#define ML_MAGIC1 0x39685a42
#define ML_MAGIC2 0x26594131
#define TRX_MAGIC 0x30524448
-#define SQSH_MAGIC 0x71736873 /* shsq */
+#define SHSQ_MAGIC 0x71736873 /* shsq (weird ZTE H218N endianness) */
+#define UBI_EC_MAGIC 0x23494255 /* UBI# */
struct trx_header {
uint32_t magic;
@@ -50,7 +53,7 @@ struct trx_header {
uint32_t offset[3];
} __packed;
-static void bcm47xxpart_add_part(struct mtd_partition *part, char *name,
+static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name,
u64 offset, uint32_t mask_flags)
{
part->name = name;
@@ -58,6 +61,26 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, char *name,
part->mask_flags = mask_flags;
}
+static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
+ size_t offset)
+{
+ uint32_t buf;
+ size_t bytes_read;
+
+ if (mtd_read(master, offset, sizeof(buf), &bytes_read,
+ (uint8_t *)&buf) < 0) {
+ pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
+ offset);
+ goto out_default;
+ }
+
+ if (buf == UBI_EC_MAGIC)
+ return "ubi";
+
+out_default:
+ return "rootfs";
+}
+
static int bcm47xxpart_parse(struct mtd_info *master,
struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
@@ -73,8 +96,12 @@ static int bcm47xxpart_parse(struct mtd_info *master,
int last_trx_part = -1;
int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
- if (blocksize <= 0x10000)
- blocksize = 0x10000;
+ /*
+ * Some really old flashes (like AT45DB*) had smaller erasesize-s, but
+ * partitions were aligned to at least 0x1000 anyway.
+ */
+ if (blocksize < 0x1000)
+ blocksize = 0x1000;
/* Alloc */
parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
@@ -186,8 +213,11 @@ static int bcm47xxpart_parse(struct mtd_info *master,
* we want to have jffs2 (overlay) in the same mtd.
*/
if (trx->offset[i]) {
+ const char *name;
+
+ name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]);
bcm47xxpart_add_part(&parts[curr_part++],
- "rootfs",
+ name,
offset + trx->offset[i],
0);
i++;
@@ -205,7 +235,8 @@ static int bcm47xxpart_parse(struct mtd_info *master,
}
/* Squashfs on devices not using TRX */
- if (buf[0x000 / 4] == SQSH_MAGIC) {
+ if (le32_to_cpu(buf[0x000 / 4]) == SQUASHFS_MAGIC ||
+ buf[0x000 / 4] == SHSQ_MAGIC) {
bcm47xxpart_add_part(&parts[curr_part++], "rootfs",
offset, 0);
continue;
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 991c2a1c05d3..afb43d5e1782 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -68,6 +68,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
mtd->_get_unmapped_area = mapram_unmapped_area;
mtd->_read = mapram_read;
mtd->_write = mapram_write;
+ mtd->_panic_write = mapram_write;
mtd->_sync = mapram_nop;
mtd->flags = MTD_CAP_RAM;
mtd->writesize = 1;
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index 47a43cf7e5c6..e67f73ab44c9 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/of.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -28,6 +29,15 @@ static struct mtd_chip_driver maprom_chipdrv = {
.module = THIS_MODULE
};
+static unsigned int default_erasesize(struct map_info *map)
+{
+ const __be32 *erase_size = NULL;
+
+ erase_size = of_get_property(map->device_node, "erase-size", NULL);
+
+ return !erase_size ? map->size : be32_to_cpu(*erase_size);
+}
+
static struct mtd_info *map_rom_probe(struct map_info *map)
{
struct mtd_info *mtd;
@@ -47,8 +57,9 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
mtd->_sync = maprom_nop;
mtd->_erase = maprom_erase;
mtd->flags = MTD_CAP_ROM;
- mtd->erasesize = map->size;
+ mtd->erasesize = default_erasesize(map);
mtd->writesize = 1;
+ mtd->writebufsize = 1;
__module_get(THIS_MODULE);
return mtd;
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
index 54ffe5223e64..3060025c8af4 100644
--- a/drivers/mtd/devices/st_spi_fsm.c
+++ b/drivers/mtd/devices/st_spi_fsm.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/clk.h>
#include "serial_flash_cmds.h"
@@ -262,6 +263,7 @@ struct stfsm {
struct mtd_info mtd;
struct mutex lock;
struct flash_info *info;
+ struct clk *clk;
uint32_t configuration;
uint32_t fifo_dir_delay;
@@ -663,6 +665,23 @@ static struct stfsm_seq stfsm_seq_write_status = {
SEQ_CFG_STARTSEQ),
};
+/* Dummy sequence to read one byte of data from flash into the FIFO */
+static const struct stfsm_seq stfsm_seq_load_fifo_byte = {
+ .data_size = TRANSFER_SIZE(1),
+ .seq_opc[0] = (SEQ_OPC_PADS_1 |
+ SEQ_OPC_CYCLES(8) |
+ SEQ_OPC_OPCODE(SPINOR_OP_RDID)),
+ .seq = {
+ STFSM_INST_CMD1,
+ STFSM_INST_DATA_READ,
+ STFSM_INST_STOP,
+ },
+ .seq_cfg = (SEQ_CFG_PADS_1 |
+ SEQ_CFG_READNOTWRITE |
+ SEQ_CFG_CSDEASSERT |
+ SEQ_CFG_STARTSEQ),
+};
+
static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
{
seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
@@ -695,22 +714,6 @@ static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
}
-static void stfsm_clear_fifo(struct stfsm *fsm)
-{
- uint32_t avail;
-
- for (;;) {
- avail = stfsm_fifo_available(fsm);
- if (!avail)
- break;
-
- while (avail) {
- readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
- avail--;
- }
- }
-}
-
static inline void stfsm_load_seq(struct stfsm *fsm,
const struct stfsm_seq *seq)
{
@@ -772,6 +775,68 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf, uint32_t size)
}
}
+/*
+ * Clear the data FIFO
+ *
+ * Typically, this is only required during driver initialisation, where no
+ * assumptions can be made regarding the state of the FIFO.
+ *
+ * The process of clearing the FIFO is complicated by fact that while it is
+ * possible for the FIFO to contain an arbitrary number of bytes [1], the
+ * SPI_FAST_SEQ_STA register only reports the number of complete 32-bit words
+ * present. Furthermore, data can only be drained from the FIFO by reading
+ * complete 32-bit words.
+ *
+ * With this in mind, a two stage process is used to the clear the FIFO:
+ *
+ * 1. Read any complete 32-bit words from the FIFO, as reported by the
+ * SPI_FAST_SEQ_STA register.
+ *
+ * 2. Mop up any remaining bytes. At this point, it is not known if there
+ * are 0, 1, 2, or 3 bytes in the FIFO. To handle all cases, a dummy FSM
+ * sequence is used to load one byte at a time, until a complete 32-bit
+ * word is formed; at most, 4 bytes will need to be loaded.
+ *
+ * [1] It is theoretically possible for the FIFO to contain an arbitrary number
+ * of bits. However, since there are no known use-cases that leave
+ * incomplete bytes in the FIFO, only words and bytes are considered here.
+ */
+static void stfsm_clear_fifo(struct stfsm *fsm)
+{
+ const struct stfsm_seq *seq = &stfsm_seq_load_fifo_byte;
+ uint32_t words, i;
+
+ /* 1. Clear any 32-bit words */
+ words = stfsm_fifo_available(fsm);
+ if (words) {
+ for (i = 0; i < words; i++)
+ readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+ dev_dbg(fsm->dev, "cleared %d words from FIFO\n", words);
+ }
+
+ /*
+ * 2. Clear any remaining bytes
+ * - Load the FIFO, one byte at a time, until a complete 32-bit word
+ * is available.
+ */
+ for (i = 0, words = 0; i < 4 && !words; i++) {
+ stfsm_load_seq(fsm, seq);
+ stfsm_wait_seq(fsm);
+ words = stfsm_fifo_available(fsm);
+ }
+
+ /* - A single word must be available now */
+ if (words != 1) {
+ dev_err(fsm->dev, "failed to clear bytes from the data FIFO\n");
+ return;
+ }
+
+ /* - Read the 32-bit word */
+ readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
+
+ dev_dbg(fsm->dev, "cleared %d byte(s) from the data FIFO\n", 4 - i);
+}
+
static int stfsm_write_fifo(struct stfsm *fsm, const uint32_t *buf,
uint32_t size)
{
@@ -1521,11 +1586,11 @@ static int stfsm_write(struct stfsm *fsm, const uint8_t *buf,
uint32_t size_lb;
uint32_t size_mop;
uint32_t tmp[4];
+ uint32_t i;
uint32_t page_buf[FLASH_PAGESIZE_32];
uint8_t *t = (uint8_t *)&tmp;
const uint8_t *p;
int ret;
- int i;
dev_dbg(fsm->dev, "writing %d bytes to 0x%08x\n", size, offset);
@@ -1843,8 +1908,7 @@ static void stfsm_set_freq(struct stfsm *fsm, uint32_t spi_freq)
uint32_t emi_freq;
uint32_t clk_div;
- /* TODO: Make this dynamic */
- emi_freq = STFSM_DEFAULT_EMI_FREQ;
+ emi_freq = clk_get_rate(fsm->clk);
/*
* Calculate clk_div - values between 2 and 128
@@ -1994,6 +2058,18 @@ static int stfsm_probe(struct platform_device *pdev)
return PTR_ERR(fsm->base);
}
+ fsm->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(fsm->clk)) {
+ dev_err(fsm->dev, "Couldn't find EMI clock.\n");
+ return PTR_ERR(fsm->clk);
+ }
+
+ ret = clk_prepare_enable(fsm->clk);
+ if (ret) {
+ dev_err(fsm->dev, "Failed to enable EMI clock.\n");
+ return ret;
+ }
+
mutex_init(&fsm->lock);
ret = stfsm_init(fsm);
@@ -2058,6 +2134,28 @@ static int stfsm_remove(struct platform_device *pdev)
return mtd_device_unregister(&fsm->mtd);
}
+#ifdef CONFIG_PM_SLEEP
+static int stfsmfsm_suspend(struct device *dev)
+{
+ struct stfsm *fsm = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(fsm->clk);
+
+ return 0;
+}
+
+static int stfsmfsm_resume(struct device *dev)
+{
+ struct stfsm *fsm = dev_get_drvdata(dev);
+
+ clk_prepare_enable(fsm->clk);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(stfsm_pm_ops, stfsmfsm_suspend, stfsmfsm_resume);
+
static const struct of_device_id stfsm_match[] = {
{ .compatible = "st,spi-fsm", },
{},
@@ -2070,6 +2168,7 @@ static struct platform_driver stfsm_driver = {
.driver = {
.name = "st-spi-fsm",
.of_match_table = stfsm_match,
+ .pm = &stfsm_pm_ops,
},
};
module_platform_driver(stfsm_driver);
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index f35cd2081314..ff26e979b1a1 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -269,6 +269,16 @@ static int of_flash_probe(struct platform_device *dev)
info->list[i].mtd = obsolete_probe(dev,
&info->list[i].map);
}
+
+ /* Fall back to mapping region as ROM */
+ if (!info->list[i].mtd) {
+ dev_warn(&dev->dev,
+ "do_map_probe() failed for type %s\n",
+ probe_type);
+
+ info->list[i].mtd = do_map_probe("map_rom",
+ &info->list[i].map);
+ }
mtd_list[i] = info->list[i].mtd;
err = -ENXIO;
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 485ea751c7f9..bb4c14f83c75 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -45,8 +45,6 @@ struct mtdblk_dev {
enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
};
-static DEFINE_MUTEX(mtdblks_lock);
-
/*
* Cache stuff...
*
@@ -286,10 +284,8 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
pr_debug("mtdblock_open\n");
- mutex_lock(&mtdblks_lock);
if (mtdblk->count) {
mtdblk->count++;
- mutex_unlock(&mtdblks_lock);
return 0;
}
@@ -302,8 +298,6 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
mtdblk->cache_data = NULL;
}
- mutex_unlock(&mtdblks_lock);
-
pr_debug("ok\n");
return 0;
@@ -315,8 +309,6 @@ static void mtdblock_release(struct mtd_blktrans_dev *mbd)
pr_debug("mtdblock_release\n");
- mutex_lock(&mtdblks_lock);
-
mutex_lock(&mtdblk->cache_mutex);
write_cached_data(mtdblk);
mutex_unlock(&mtdblk->cache_mutex);
@@ -331,8 +323,6 @@ static void mtdblock_release(struct mtd_blktrans_dev *mbd)
vfree(mtdblk->cache_data);
}
- mutex_unlock(&mtdblks_lock);
-
pr_debug("ok\n");
}
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index eacc3aac7327..239a8c806b67 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -311,7 +311,8 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
devops.len = subdev->size - to;
err = mtd_write_oob(subdev, to, &devops);
- ops->retlen += devops.oobretlen;
+ ops->retlen += devops.retlen;
+ ops->oobretlen += devops.oobretlen;
if (err)
return err;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 0ec4d6ea1e4b..11883bd26d9d 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -37,6 +37,7 @@
#include <linux/backing-dev.h>
#include <linux/gfp.h>
#include <linux/slab.h>
+#include <linux/reboot.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -356,6 +357,17 @@ unsigned mtd_mmap_capabilities(struct mtd_info *mtd)
EXPORT_SYMBOL_GPL(mtd_mmap_capabilities);
#endif
+static int mtd_reboot_notifier(struct notifier_block *n, unsigned long state,
+ void *cmd)
+{
+ struct mtd_info *mtd;
+
+ mtd = container_of(n, struct mtd_info, reboot_notifier);
+ mtd->_reboot(mtd);
+
+ return NOTIFY_DONE;
+}
+
/**
* add_mtd_device - register an MTD device
* @mtd: pointer to new MTD device info structure
@@ -544,6 +556,19 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
err = -ENODEV;
}
+ /*
+ * FIXME: some drivers unfortunately call this function more than once.
+ * So we have to check if we've already assigned the reboot notifier.
+ *
+ * Generally, we can make multiple calls work for most cases, but it
+ * does cause problems with parse_mtd_partitions() above (e.g.,
+ * cmdlineparts will register partitions more than once).
+ */
+ if (mtd->_reboot && !mtd->reboot_notifier.notifier_call) {
+ mtd->reboot_notifier.notifier_call = mtd_reboot_notifier;
+ register_reboot_notifier(&mtd->reboot_notifier);
+ }
+
return err;
}
EXPORT_SYMBOL_GPL(mtd_device_parse_register);
@@ -558,6 +583,9 @@ int mtd_device_unregister(struct mtd_info *master)
{
int err;
+ if (master->_reboot)
+ unregister_reboot_notifier(&master->reboot_notifier);
+
err = del_mtd_partitions(master);
if (err)
return err;
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 7d0150d20432..5b76a173cd95 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -421,7 +421,7 @@ config MTD_NAND_ORION
config MTD_NAND_FSL_ELBC
tristate "NAND support for Freescale eLBC controllers"
- depends on PPC_OF
+ depends on PPC
select FSL_LBC
help
Various Freescale chips, including the 8313, include a NAND Flash
@@ -524,4 +524,9 @@ config MTD_NAND_SUNXI
help
Enables support for NAND Flash chips on Allwinner SoCs.
+config MTD_NAND_HISI504
+ tristate "Support for NAND controller on Hisilicon SoC Hip04"
+ help
+ Enables support for NAND controller on Hisilicon SoC Hip04.
+
endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index bd38f21d2e28..582bbd05aff7 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -51,5 +51,6 @@ obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o
obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/
obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o
+obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
nand-objs := nand_base.o nand_bbt.o nand_timings.o
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index f1d555cfb332..842f8fe91b56 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -183,7 +183,7 @@ static int ams_delta_init(struct platform_device *pdev)
return -ENXIO;
/* Allocate memory for MTD device structure and private data */
- ams_delta_mtd = kmalloc(sizeof(struct mtd_info) +
+ ams_delta_mtd = kzalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip), GFP_KERNEL);
if (!ams_delta_mtd) {
printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n");
@@ -196,10 +196,6 @@ static int ams_delta_init(struct platform_device *pdev)
/* Get pointer to private data */
this = (struct nand_chip *) (&ams_delta_mtd[1]);
- /* Initialize structures */
- memset(ams_delta_mtd, 0, sizeof(struct mtd_info));
- memset(this, 0, sizeof(struct nand_chip));
-
/* Link the private data with the MTD structure */
ams_delta_mtd->priv = this;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index a345e7b2463a..d93c849b70b5 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -63,6 +63,10 @@ module_param(on_flash_bbt, int, 0);
#include "atmel_nand_ecc.h" /* Hardware ECC registers */
#include "atmel_nand_nfc.h" /* Nand Flash Controller definition */
+struct atmel_nand_caps {
+ bool pmecc_correct_erase_page;
+};
+
/* oob layout for large page size
* bad block info is on bytes 0 and 1
* the bytes have to be consecutives to avoid
@@ -124,6 +128,7 @@ struct atmel_nand_host {
struct atmel_nfc *nfc;
+ struct atmel_nand_caps *caps;
bool has_pmecc;
u8 pmecc_corr_cap;
u16 pmecc_sector_size;
@@ -847,7 +852,11 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
struct atmel_nand_host *host = nand_chip->priv;
int i, err_nbr;
uint8_t *buf_pos;
- int total_err = 0;
+ int max_bitflips = 0;
+
+ /* If can correct bitfilps from erased page, do the normal check */
+ if (host->caps->pmecc_correct_erase_page)
+ goto normal_check;
for (i = 0; i < nand_chip->ecc.total; i++)
if (ecc[i] != 0xff)
@@ -874,13 +883,13 @@ normal_check:
pmecc_correct_data(mtd, buf_pos, ecc, i,
nand_chip->ecc.bytes, err_nbr);
mtd->ecc_stats.corrected += err_nbr;
- total_err += err_nbr;
+ max_bitflips = max_t(int, max_bitflips, err_nbr);
}
}
pmecc_stat >>= 1;
}
- return total_err;
+ return max_bitflips;
}
static void pmecc_enable(struct atmel_nand_host *host, int ecc_op)
@@ -1474,6 +1483,8 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
ecc_writel(host->ecc, CR, ATMEL_ECC_RST);
}
+static const struct of_device_id atmel_nand_dt_ids[];
+
static int atmel_of_init_port(struct atmel_nand_host *host,
struct device_node *np)
{
@@ -1483,6 +1494,9 @@ static int atmel_of_init_port(struct atmel_nand_host *host,
struct atmel_nand_data *board = &host->board;
enum of_gpio_flags flags = 0;
+ host->caps = (struct atmel_nand_caps *)
+ of_match_device(atmel_nand_dt_ids, host->dev)->data;
+
if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) {
if (val >= 32) {
dev_err(host->dev, "invalid addr-offset %u\n", val);
@@ -2288,8 +2302,17 @@ static int atmel_nand_remove(struct platform_device *pdev)
return 0;
}
+static struct atmel_nand_caps at91rm9200_caps = {
+ .pmecc_correct_erase_page = false,
+};
+
+static struct atmel_nand_caps sama5d4_caps = {
+ .pmecc_correct_erase_page = true,
+};
+
static const struct of_device_id atmel_nand_dt_ids[] = {
- { .compatible = "atmel,at91rm9200-nand" },
+ { .compatible = "atmel,at91rm9200-nand", .data = &at91rm9200_caps },
+ { .compatible = "atmel,sama5d4-nand", .data = &sama5d4_caps },
{ /* sentinel */ }
};
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index b3b7ca1bafb8..f44c6061536a 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1041,7 +1041,7 @@ static void denali_setup_dma(struct denali_nand_info *denali, int op)
index_addr(denali, mode | ((addr >> 16) << 8), 0x2200);
/* 3. set memory low address bits 23:8 */
- index_addr(denali, mode | ((addr & 0xff) << 8), 0x2300);
+ index_addr(denali, mode | ((addr & 0xffff) << 8), 0x2300);
/* 4. interrupt when complete, burst len = 64 bytes */
index_addr(denali, mode | 0x14000, 0x2400);
@@ -1328,35 +1328,6 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
break;
}
}
-
-/* stubs for ECC functions not used by the NAND core */
-static int denali_ecc_calculate(struct mtd_info *mtd, const uint8_t *data,
- uint8_t *ecc_code)
-{
- struct denali_nand_info *denali = mtd_to_denali(mtd);
-
- dev_err(denali->dev, "denali_ecc_calculate called unexpectedly\n");
- BUG();
- return -EIO;
-}
-
-static int denali_ecc_correct(struct mtd_info *mtd, uint8_t *data,
- uint8_t *read_ecc, uint8_t *calc_ecc)
-{
- struct denali_nand_info *denali = mtd_to_denali(mtd);
-
- dev_err(denali->dev, "denali_ecc_correct called unexpectedly\n");
- BUG();
- return -EIO;
-}
-
-static void denali_ecc_hwctl(struct mtd_info *mtd, int mode)
-{
- struct denali_nand_info *denali = mtd_to_denali(mtd);
-
- dev_err(denali->dev, "denali_ecc_hwctl called unexpectedly\n");
- BUG();
-}
/* end NAND core entry points */
/* Initialization code to bring the device up to a known good state */
@@ -1609,15 +1580,6 @@ int denali_init(struct denali_nand_info *denali)
denali->totalblks = denali->mtd.size >> denali->nand.phys_erase_shift;
denali->blksperchip = denali->totalblks / denali->nand.numchips;
- /*
- * These functions are required by the NAND core framework, otherwise,
- * the NAND core will assert. However, we don't need them, so we'll stub
- * them out.
- */
- denali->nand.ecc.calculate = denali_ecc_calculate;
- denali->nand.ecc.correct = denali_ecc_correct;
- denali->nand.ecc.hwctl = denali_ecc_hwctl;
-
/* override the default read operations */
denali->nand.ecc.size = ECC_SECTOR_SIZE * denali->devnum;
denali->nand.ecc.read_page = denali_read_page;
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 4f3851a24bb2..33f3c3c54dbc 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1294,14 +1294,6 @@ exit_auxiliary:
* ecc.read_page or ecc.read_page_raw function. Thus, the fact that MTD wants an
* ECC-based or raw view of the page is implicit in which function it calls
* (there is a similar pair of ECC-based/raw functions for writing).
- *
- * FIXME: The following paragraph is incorrect, now that there exist
- * ecc.read_oob_raw and ecc.write_oob_raw functions.
- *
- * Since MTD assumes the OOB is not covered by ECC, there is no pair of
- * ECC-based/raw functions for reading or or writing the OOB. The fact that the
- * caller wants an ECC-based or raw view of the page is not propagated down to
- * this driver.
*/
static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
int page)
@@ -2029,7 +2021,6 @@ static int gpmi_nand_probe(struct platform_device *pdev)
exit_nfc_init:
release_resources(this);
exit_acquire_resources:
- dev_err(this->dev, "driver registration failed: %d\n", ret);
return ret;
}
diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c
new file mode 100644
index 000000000000..289ad3ac3e80
--- /dev/null
+++ b/drivers/mtd/nand/hisi504_nand.c
@@ -0,0 +1,891 @@
+/*
+ * Hisilicon NAND Flash controller driver
+ *
+ * Copyright © 2012-2014 HiSilicon Technologies Co., Ltd.
+ * http://www.hisilicon.com
+ *
+ * Author: Zhou Wang <wangzhou.bry@gmail.com>
+ * The initial developer of the original code is Zhiyong Cai
+ * <caizhiyong@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/of.h>
+#include <linux/of_mtd.h>
+#include <linux/mtd/mtd.h>
+#include <linux/sizes.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/nand.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+
+#define HINFC504_MAX_CHIP (4)
+#define HINFC504_W_LATCH (5)
+#define HINFC504_R_LATCH (7)
+#define HINFC504_RW_LATCH (3)
+
+#define HINFC504_NFC_TIMEOUT (2 * HZ)
+#define HINFC504_NFC_PM_TIMEOUT (1 * HZ)
+#define HINFC504_NFC_DMA_TIMEOUT (5 * HZ)
+#define HINFC504_CHIP_DELAY (25)
+
+#define HINFC504_REG_BASE_ADDRESS_LEN (0x100)
+#define HINFC504_BUFFER_BASE_ADDRESS_LEN (2048 + 128)
+
+#define HINFC504_ADDR_CYCLE_MASK 0x4
+
+#define HINFC504_CON 0x00
+#define HINFC504_CON_OP_MODE_NORMAL BIT(0)
+#define HINFC504_CON_PAGEISZE_SHIFT (1)
+#define HINFC504_CON_PAGESIZE_MASK (0x07)
+#define HINFC504_CON_BUS_WIDTH BIT(4)
+#define HINFC504_CON_READY_BUSY_SEL BIT(8)
+#define HINFC504_CON_ECCTYPE_SHIFT (9)
+#define HINFC504_CON_ECCTYPE_MASK (0x07)
+
+#define HINFC504_PWIDTH 0x04
+#define SET_HINFC504_PWIDTH(_w_lcnt, _r_lcnt, _rw_hcnt) \
+ ((_w_lcnt) | (((_r_lcnt) & 0x0F) << 4) | (((_rw_hcnt) & 0x0F) << 8))
+
+#define HINFC504_CMD 0x0C
+#define HINFC504_ADDRL 0x10
+#define HINFC504_ADDRH 0x14
+#define HINFC504_DATA_NUM 0x18
+
+#define HINFC504_OP 0x1C
+#define HINFC504_OP_READ_DATA_EN BIT(1)
+#define HINFC504_OP_WAIT_READY_EN BIT(2)
+#define HINFC504_OP_CMD2_EN BIT(3)
+#define HINFC504_OP_WRITE_DATA_EN BIT(4)
+#define HINFC504_OP_ADDR_EN BIT(5)
+#define HINFC504_OP_CMD1_EN BIT(6)
+#define HINFC504_OP_NF_CS_SHIFT (7)
+#define HINFC504_OP_NF_CS_MASK (3)
+#define HINFC504_OP_ADDR_CYCLE_SHIFT (9)
+#define HINFC504_OP_ADDR_CYCLE_MASK (7)
+
+#define HINFC504_STATUS 0x20
+#define HINFC504_READY BIT(0)
+
+#define HINFC504_INTEN 0x24
+#define HINFC504_INTEN_DMA BIT(9)
+#define HINFC504_INTEN_UE BIT(6)
+#define HINFC504_INTEN_CE BIT(5)
+
+#define HINFC504_INTS 0x28
+#define HINFC504_INTS_DMA BIT(9)
+#define HINFC504_INTS_UE BIT(6)
+#define HINFC504_INTS_CE BIT(5)
+
+#define HINFC504_INTCLR 0x2C
+#define HINFC504_INTCLR_DMA BIT(9)
+#define HINFC504_INTCLR_UE BIT(6)
+#define HINFC504_INTCLR_CE BIT(5)
+
+#define HINFC504_ECC_STATUS 0x5C
+#define HINFC504_ECC_16_BIT_SHIFT 12
+
+#define HINFC504_DMA_CTRL 0x60
+#define HINFC504_DMA_CTRL_DMA_START BIT(0)
+#define HINFC504_DMA_CTRL_WE BIT(1)
+#define HINFC504_DMA_CTRL_DATA_AREA_EN BIT(2)
+#define HINFC504_DMA_CTRL_OOB_AREA_EN BIT(3)
+#define HINFC504_DMA_CTRL_BURST4_EN BIT(4)
+#define HINFC504_DMA_CTRL_BURST8_EN BIT(5)
+#define HINFC504_DMA_CTRL_BURST16_EN BIT(6)
+#define HINFC504_DMA_CTRL_ADDR_NUM_SHIFT (7)
+#define HINFC504_DMA_CTRL_ADDR_NUM_MASK (1)
+#define HINFC504_DMA_CTRL_CS_SHIFT (8)
+#define HINFC504_DMA_CTRL_CS_MASK (0x03)
+
+#define HINFC504_DMA_ADDR_DATA 0x64
+#define HINFC504_DMA_ADDR_OOB 0x68
+
+#define HINFC504_DMA_LEN 0x6C
+#define HINFC504_DMA_LEN_OOB_SHIFT (16)
+#define HINFC504_DMA_LEN_OOB_MASK (0xFFF)
+
+#define HINFC504_DMA_PARA 0x70
+#define HINFC504_DMA_PARA_DATA_RW_EN BIT(0)
+#define HINFC504_DMA_PARA_OOB_RW_EN BIT(1)
+#define HINFC504_DMA_PARA_DATA_EDC_EN BIT(2)
+#define HINFC504_DMA_PARA_OOB_EDC_EN BIT(3)
+#define HINFC504_DMA_PARA_DATA_ECC_EN BIT(4)
+#define HINFC504_DMA_PARA_OOB_ECC_EN BIT(5)
+
+#define HINFC_VERSION 0x74
+#define HINFC504_LOG_READ_ADDR 0x7C
+#define HINFC504_LOG_READ_LEN 0x80
+
+#define HINFC504_NANDINFO_LEN 0x10
+
+struct hinfc_host {
+ struct nand_chip chip;
+ struct mtd_info mtd;
+ struct device *dev;
+ void __iomem *iobase;
+ void __iomem *mmio;
+ struct completion cmd_complete;
+ unsigned int offset;
+ unsigned int command;
+ int chipselect;
+ unsigned int addr_cycle;
+ u32 addr_value[2];
+ u32 cache_addr_value[2];
+ char *buffer;
+ dma_addr_t dma_buffer;
+ dma_addr_t dma_oob;
+ int version;
+ unsigned int irq_status; /* interrupt status */
+};
+
+static inline unsigned int hinfc_read(struct hinfc_host *host, unsigned int reg)
+{
+ return readl(host->iobase + reg);
+}
+
+static inline void hinfc_write(struct hinfc_host *host, unsigned int value,
+ unsigned int reg)
+{
+ writel(value, host->iobase + reg);
+}
+
+static void wait_controller_finished(struct hinfc_host *host)
+{
+ unsigned long timeout = jiffies + HINFC504_NFC_TIMEOUT;
+ int val;
+
+ while (time_before(jiffies, timeout)) {
+ val = hinfc_read(host, HINFC504_STATUS);
+ if (host->command == NAND_CMD_ERASE2) {
+ /* nfc is ready */
+ while (!(val & HINFC504_READY)) {
+ usleep_range(500, 1000);
+ val = hinfc_read(host, HINFC504_STATUS);
+ }
+ return;
+ }
+
+ if (val & HINFC504_READY)
+ return;
+ }
+
+ /* wait cmd timeout */
+ dev_err(host->dev, "Wait NAND controller exec cmd timeout.\n");
+}
+
+static void hisi_nfc_dma_transfer(struct hinfc_host *host, int todev)
+{
+ struct mtd_info *mtd = &host->mtd;
+ struct nand_chip *chip = mtd->priv;
+ unsigned long val;
+ int ret;
+
+ hinfc_write(host, host->dma_buffer, HINFC504_DMA_ADDR_DATA);
+ hinfc_write(host, host->dma_oob, HINFC504_DMA_ADDR_OOB);
+
+ if (chip->ecc.mode == NAND_ECC_NONE) {
+ hinfc_write(host, ((mtd->oobsize & HINFC504_DMA_LEN_OOB_MASK)
+ << HINFC504_DMA_LEN_OOB_SHIFT), HINFC504_DMA_LEN);
+
+ hinfc_write(host, HINFC504_DMA_PARA_DATA_RW_EN
+ | HINFC504_DMA_PARA_OOB_RW_EN, HINFC504_DMA_PARA);
+ } else {
+ if (host->command == NAND_CMD_READOOB)
+ hinfc_write(host, HINFC504_DMA_PARA_OOB_RW_EN
+ | HINFC504_DMA_PARA_OOB_EDC_EN
+ | HINFC504_DMA_PARA_OOB_ECC_EN, HINFC504_DMA_PARA);
+ else
+ hinfc_write(host, HINFC504_DMA_PARA_DATA_RW_EN
+ | HINFC504_DMA_PARA_OOB_RW_EN
+ | HINFC504_DMA_PARA_DATA_EDC_EN
+ | HINFC504_DMA_PARA_OOB_EDC_EN
+ | HINFC504_DMA_PARA_DATA_ECC_EN
+ | HINFC504_DMA_PARA_OOB_ECC_EN, HINFC504_DMA_PARA);
+
+ }
+
+ val = (HINFC504_DMA_CTRL_DMA_START | HINFC504_DMA_CTRL_BURST4_EN
+ | HINFC504_DMA_CTRL_BURST8_EN | HINFC504_DMA_CTRL_BURST16_EN
+ | HINFC504_DMA_CTRL_DATA_AREA_EN | HINFC504_DMA_CTRL_OOB_AREA_EN
+ | ((host->addr_cycle == 4 ? 1 : 0)
+ << HINFC504_DMA_CTRL_ADDR_NUM_SHIFT)
+ | ((host->chipselect & HINFC504_DMA_CTRL_CS_MASK)
+ << HINFC504_DMA_CTRL_CS_SHIFT));
+
+ if (todev)
+ val |= HINFC504_DMA_CTRL_WE;
+
+ init_completion(&host->cmd_complete);
+
+ hinfc_write(host, val, HINFC504_DMA_CTRL);
+ ret = wait_for_completion_timeout(&host->cmd_complete,
+ HINFC504_NFC_DMA_TIMEOUT);
+
+ if (!ret) {
+ dev_err(host->dev, "DMA operation(irq) timeout!\n");
+ /* sanity check */
+ val = hinfc_read(host, HINFC504_DMA_CTRL);
+ if (!(val & HINFC504_DMA_CTRL_DMA_START))
+ dev_err(host->dev, "DMA is already done but without irq ACK!\n");
+ else
+ dev_err(host->dev, "DMA is really timeout!\n");
+ }
+}
+
+static int hisi_nfc_send_cmd_pageprog(struct hinfc_host *host)
+{
+ host->addr_value[0] &= 0xffff0000;
+
+ hinfc_write(host, host->addr_value[0], HINFC504_ADDRL);
+ hinfc_write(host, host->addr_value[1], HINFC504_ADDRH);
+ hinfc_write(host, NAND_CMD_PAGEPROG << 8 | NAND_CMD_SEQIN,
+ HINFC504_CMD);
+
+ hisi_nfc_dma_transfer(host, 1);
+
+ return 0;
+}
+
+static int hisi_nfc_send_cmd_readstart(struct hinfc_host *host)
+{
+ struct mtd_info *mtd = &host->mtd;
+
+ if ((host->addr_value[0] == host->cache_addr_value[0]) &&
+ (host->addr_value[1] == host->cache_addr_value[1]))
+ return 0;
+
+ host->addr_value[0] &= 0xffff0000;
+
+ hinfc_write(host, host->addr_value[0], HINFC504_ADDRL);
+ hinfc_write(host, host->addr_value[1], HINFC504_ADDRH);
+ hinfc_write(host, NAND_CMD_READSTART << 8 | NAND_CMD_READ0,
+ HINFC504_CMD);
+
+ hinfc_write(host, 0, HINFC504_LOG_READ_ADDR);
+ hinfc_write(host, mtd->writesize + mtd->oobsize,
+ HINFC504_LOG_READ_LEN);
+
+ hisi_nfc_dma_transfer(host, 0);
+
+ host->cache_addr_value[0] = host->addr_value[0];
+ host->cache_addr_value[1] = host->addr_value[1];
+
+ return 0;
+}
+
+static int hisi_nfc_send_cmd_erase(struct hinfc_host *host)
+{
+ hinfc_write(host, host->addr_value[0], HINFC504_ADDRL);
+ hinfc_write(host, (NAND_CMD_ERASE2 << 8) | NAND_CMD_ERASE1,
+ HINFC504_CMD);
+
+ hinfc_write(host, HINFC504_OP_WAIT_READY_EN
+ | HINFC504_OP_CMD2_EN
+ | HINFC504_OP_CMD1_EN
+ | HINFC504_OP_ADDR_EN
+ | ((host->chipselect & HINFC504_OP_NF_CS_MASK)
+ << HINFC504_OP_NF_CS_SHIFT)
+ | ((host->addr_cycle & HINFC504_OP_ADDR_CYCLE_MASK)
+ << HINFC504_OP_ADDR_CYCLE_SHIFT),
+ HINFC504_OP);
+
+ wait_controller_finished(host);
+
+ return 0;
+}
+
+static int hisi_nfc_send_cmd_readid(struct hinfc_host *host)
+{
+ hinfc_write(host, HINFC504_NANDINFO_LEN, HINFC504_DATA_NUM);
+ hinfc_write(host, NAND_CMD_READID, HINFC504_CMD);
+ hinfc_write(host, 0, HINFC504_ADDRL);
+
+ hinfc_write(host, HINFC504_OP_CMD1_EN | HINFC504_OP_ADDR_EN
+ | HINFC504_OP_READ_DATA_EN
+ | ((host->chipselect & HINFC504_OP_NF_CS_MASK)
+ << HINFC504_OP_NF_CS_SHIFT)
+ | 1 << HINFC504_OP_ADDR_CYCLE_SHIFT, HINFC504_OP);
+
+ wait_controller_finished(host);
+
+ return 0;
+}
+
+static int hisi_nfc_send_cmd_status(struct hinfc_host *host)
+{
+ hinfc_write(host, HINFC504_NANDINFO_LEN, HINFC504_DATA_NUM);
+ hinfc_write(host, NAND_CMD_STATUS, HINFC504_CMD);
+ hinfc_write(host, HINFC504_OP_CMD1_EN
+ | HINFC504_OP_READ_DATA_EN
+ | ((host->chipselect & HINFC504_OP_NF_CS_MASK)
+ << HINFC504_OP_NF_CS_SHIFT),
+ HINFC504_OP);
+
+ wait_controller_finished(host);
+
+ return 0;
+}
+
+static int hisi_nfc_send_cmd_reset(struct hinfc_host *host, int chipselect)
+{
+ hinfc_write(host, NAND_CMD_RESET, HINFC504_CMD);
+
+ hinfc_write(host, HINFC504_OP_CMD1_EN
+ | ((chipselect & HINFC504_OP_NF_CS_MASK)
+ << HINFC504_OP_NF_CS_SHIFT)
+ | HINFC504_OP_WAIT_READY_EN,
+ HINFC504_OP);
+
+ wait_controller_finished(host);
+
+ return 0;
+}
+
+static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct hinfc_host *host = chip->priv;
+
+ if (chipselect < 0)
+ return;
+
+ host->chipselect = chipselect;
+}
+
+static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct hinfc_host *host = chip->priv;
+
+ if (host->command == NAND_CMD_STATUS)
+ return *(uint8_t *)(host->mmio);
+
+ host->offset++;
+
+ if (host->command == NAND_CMD_READID)
+ return *(uint8_t *)(host->mmio + host->offset - 1);
+
+ return *(uint8_t *)(host->buffer + host->offset - 1);
+}
+
+static u16 hisi_nfc_read_word(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct hinfc_host *host = chip->priv;
+
+ host->offset += 2;
+ return *(u16 *)(host->buffer + host->offset - 2);
+}
+
+static void
+hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct hinfc_host *host = chip->priv;
+
+ memcpy(host->buffer + host->offset, buf, len);
+ host->offset += len;
+}
+
+static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct hinfc_host *host = chip->priv;
+
+ memcpy(buf, host->buffer + host->offset, len);
+ host->offset += len;
+}
+
+static void set_addr(struct mtd_info *mtd, int column, int page_addr)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct hinfc_host *host = chip->priv;
+ unsigned int command = host->command;
+
+ host->addr_cycle = 0;
+ host->addr_value[0] = 0;
+ host->addr_value[1] = 0;
+
+ /* Serially input address */
+ if (column != -1) {
+ /* Adjust columns for 16 bit buswidth */
+ if (chip->options & NAND_BUSWIDTH_16 &&
+ !nand_opcode_8bits(command))
+ column >>= 1;
+
+ host->addr_value[0] = column & 0xffff;
+ host->addr_cycle = 2;
+ }
+ if (page_addr != -1) {
+ host->addr_value[0] |= (page_addr & 0xffff)
+ << (host->addr_cycle * 8);
+ host->addr_cycle += 2;
+ /* One more address cycle for devices > 128MiB */
+ if (chip->chipsize > (128 << 20)) {
+ host->addr_cycle += 1;
+ if (host->command == NAND_CMD_ERASE1)
+ host->addr_value[0] |= ((page_addr >> 16) & 0xff) << 16;
+ else
+ host->addr_value[1] |= ((page_addr >> 16) & 0xff);
+ }
+ }
+}
+
+static void hisi_nfc_cmdfunc(struct mtd_info *mtd, unsigned command, int column,
+ int page_addr)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct hinfc_host *host = chip->priv;
+ int is_cache_invalid = 1;
+ unsigned int flag = 0;
+
+ host->command = command;
+
+ switch (command) {
+ case NAND_CMD_READ0:
+ case NAND_CMD_READOOB:
+ if (command == NAND_CMD_READ0)
+ host->offset = column;
+ else
+ host->offset = column + mtd->writesize;
+
+ is_cache_invalid = 0;
+ set_addr(mtd, column, page_addr);
+ hisi_nfc_send_cmd_readstart(host);
+ break;
+
+ case NAND_CMD_SEQIN:
+ host->offset = column;
+ set_addr(mtd, column, page_addr);
+ break;
+
+ case NAND_CMD_ERASE1:
+ set_addr(mtd, column, page_addr);
+ break;
+
+ case NAND_CMD_PAGEPROG:
+ hisi_nfc_send_cmd_pageprog(host);
+ break;
+
+ case NAND_CMD_ERASE2:
+ hisi_nfc_send_cmd_erase(host);
+ break;
+
+ case NAND_CMD_READID:
+ host->offset = column;
+ memset(host->mmio, 0, 0x10);
+ hisi_nfc_send_cmd_readid(host);
+ break;
+
+ case NAND_CMD_STATUS:
+ flag = hinfc_read(host, HINFC504_CON);
+ if (chip->ecc.mode == NAND_ECC_HW)
+ hinfc_write(host,
+ flag & ~(HINFC504_CON_ECCTYPE_MASK <<
+ HINFC504_CON_ECCTYPE_SHIFT), HINFC504_CON);
+
+ host->offset = 0;
+ memset(host->mmio, 0, 0x10);
+ hisi_nfc_send_cmd_status(host);
+ hinfc_write(host, flag, HINFC504_CON);
+ break;
+
+ case NAND_CMD_RESET:
+ hisi_nfc_send_cmd_reset(host, host->chipselect);
+ break;
+
+ default:
+ dev_err(host->dev, "Error: unsupported cmd(cmd=%x, col=%x, page=%x)\n",
+ command, column, page_addr);
+ }
+
+ if (is_cache_invalid) {
+ host->cache_addr_value[0] = ~0;
+ host->cache_addr_value[1] = ~0;
+ }
+}
+
+static irqreturn_t hinfc_irq_handle(int irq, void *devid)
+{
+ struct hinfc_host *host = devid;
+ unsigned int flag;
+
+ flag = hinfc_read(host, HINFC504_INTS);
+ /* store interrupts state */
+ host->irq_status |= flag;
+
+ if (flag & HINFC504_INTS_DMA) {
+ hinfc_write(host, HINFC504_INTCLR_DMA, HINFC504_INTCLR);
+ complete(&host->cmd_complete);
+ } else if (flag & HINFC504_INTS_CE) {
+ hinfc_write(host, HINFC504_INTCLR_CE, HINFC504_INTCLR);
+ } else if (flag & HINFC504_INTS_UE) {
+ hinfc_write(host, HINFC504_INTCLR_UE, HINFC504_INTCLR);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int hisi_nand_read_page_hwecc(struct mtd_info *mtd,
+ struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
+{
+ struct hinfc_host *host = chip->priv;
+ int max_bitflips = 0, stat = 0, stat_max = 0, status_ecc;
+ int stat_1, stat_2;
+
+ chip->read_buf(mtd, buf, mtd->writesize);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ /* errors which can not be corrected by ECC */
+ if (host->irq_status & HINFC504_INTS_UE) {
+ mtd->ecc_stats.failed++;
+ } else if (host->irq_status & HINFC504_INTS_CE) {
+ /* TODO: need add other ECC modes! */
+ switch (chip->ecc.strength) {
+ case 16:
+ status_ecc = hinfc_read(host, HINFC504_ECC_STATUS) >>
+ HINFC504_ECC_16_BIT_SHIFT & 0x0fff;
+ stat_2 = status_ecc & 0x3f;
+ stat_1 = status_ecc >> 6 & 0x3f;
+ stat = stat_1 + stat_2;
+ stat_max = max_t(int, stat_1, stat_2);
+ }
+ mtd->ecc_stats.corrected += stat;
+ max_bitflips = max_t(int, max_bitflips, stat_max);
+ }
+ host->irq_status = 0;
+
+ return max_bitflips;
+}
+
+static int hisi_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ struct hinfc_host *host = chip->priv;
+
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ if (host->irq_status & HINFC504_INTS_UE) {
+ host->irq_status = 0;
+ return -EBADMSG;
+ }
+
+ host->irq_status = 0;
+ return 0;
+}
+
+static int hisi_nand_write_page_hwecc(struct mtd_info *mtd,
+ struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+ chip->write_buf(mtd, buf, mtd->writesize);
+ if (oob_required)
+ chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+ return 0;
+}
+
+static void hisi_nfc_host_init(struct hinfc_host *host)
+{
+ struct nand_chip *chip = &host->chip;
+ unsigned int flag = 0;
+
+ host->version = hinfc_read(host, HINFC_VERSION);
+ host->addr_cycle = 0;
+ host->addr_value[0] = 0;
+ host->addr_value[1] = 0;
+ host->cache_addr_value[0] = ~0;
+ host->cache_addr_value[1] = ~0;
+ host->chipselect = 0;
+
+ /* default page size: 2K, ecc_none. need modify */
+ flag = HINFC504_CON_OP_MODE_NORMAL | HINFC504_CON_READY_BUSY_SEL
+ | ((0x001 & HINFC504_CON_PAGESIZE_MASK)
+ << HINFC504_CON_PAGEISZE_SHIFT)
+ | ((0x0 & HINFC504_CON_ECCTYPE_MASK)
+ << HINFC504_CON_ECCTYPE_SHIFT)
+ | ((chip->options & NAND_BUSWIDTH_16) ?
+ HINFC504_CON_BUS_WIDTH : 0);
+ hinfc_write(host, flag, HINFC504_CON);
+
+ memset(host->mmio, 0xff, HINFC504_BUFFER_BASE_ADDRESS_LEN);
+
+ hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH,
+ HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH);
+
+ /* enable DMA irq */
+ hinfc_write(host, HINFC504_INTEN_DMA, HINFC504_INTEN);
+}
+
+static struct nand_ecclayout nand_ecc_2K_16bits = {
+ .oobavail = 6,
+ .oobfree = { {2, 6} },
+};
+
+static int hisi_nfc_ecc_probe(struct hinfc_host *host)
+{
+ unsigned int flag;
+ int size, strength, ecc_bits;
+ struct device *dev = host->dev;
+ struct nand_chip *chip = &host->chip;
+ struct mtd_info *mtd = &host->mtd;
+ struct device_node *np = host->dev->of_node;
+
+ size = of_get_nand_ecc_step_size(np);
+ strength = of_get_nand_ecc_strength(np);
+ if (size != 1024) {
+ dev_err(dev, "error ecc size: %d\n", size);
+ return -EINVAL;
+ }
+
+ if ((size == 1024) && ((strength != 8) && (strength != 16) &&
+ (strength != 24) && (strength != 40))) {
+ dev_err(dev, "ecc size and strength do not match\n");
+ return -EINVAL;
+ }
+
+ chip->ecc.size = size;
+ chip->ecc.strength = strength;
+
+ chip->ecc.read_page = hisi_nand_read_page_hwecc;
+ chip->ecc.read_oob = hisi_nand_read_oob;
+ chip->ecc.write_page = hisi_nand_write_page_hwecc;
+
+ switch (chip->ecc.strength) {
+ case 16:
+ ecc_bits = 6;
+ if (mtd->writesize == 2048)
+ chip->ecc.layout = &nand_ecc_2K_16bits;
+
+ /* TODO: add more page size support */
+ break;
+
+ /* TODO: add more ecc strength support */
+ default:
+ dev_err(dev, "not support strength: %d\n", chip->ecc.strength);
+ return -EINVAL;
+ }
+
+ flag = hinfc_read(host, HINFC504_CON);
+ /* add ecc type configure */
+ flag |= ((ecc_bits & HINFC504_CON_ECCTYPE_MASK)
+ << HINFC504_CON_ECCTYPE_SHIFT);
+ hinfc_write(host, flag, HINFC504_CON);
+
+ /* enable ecc irq */
+ flag = hinfc_read(host, HINFC504_INTEN) & 0xfff;
+ hinfc_write(host, flag | HINFC504_INTEN_UE | HINFC504_INTEN_CE,
+ HINFC504_INTEN);
+
+ return 0;
+}
+
+static int hisi_nfc_probe(struct platform_device *pdev)
+{
+ int ret = 0, irq, buswidth, flag, max_chips = HINFC504_MAX_CHIP;
+ struct device *dev = &pdev->dev;
+ struct hinfc_host *host;
+ struct nand_chip *chip;
+ struct mtd_info *mtd;
+ struct resource *res;
+ struct device_node *np = dev->of_node;
+ struct mtd_part_parser_data ppdata;
+
+ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+ host->dev = dev;
+
+ platform_set_drvdata(pdev, host);
+ chip = &host->chip;
+ mtd = &host->mtd;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "no IRQ resource defined\n");
+ ret = -ENXIO;
+ goto err_res;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ host->iobase = devm_ioremap_resource(dev, res);
+ if (IS_ERR(host->iobase)) {
+ ret = PTR_ERR(host->iobase);
+ goto err_res;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ host->mmio = devm_ioremap_resource(dev, res);
+ if (IS_ERR(host->mmio)) {
+ ret = PTR_ERR(host->mmio);
+ dev_err(dev, "devm_ioremap_resource[1] fail\n");
+ goto err_res;
+ }
+
+ mtd->priv = chip;
+ mtd->owner = THIS_MODULE;
+ mtd->name = "hisi_nand";
+ mtd->dev.parent = &pdev->dev;
+
+ chip->priv = host;
+ chip->cmdfunc = hisi_nfc_cmdfunc;
+ chip->select_chip = hisi_nfc_select_chip;
+ chip->read_byte = hisi_nfc_read_byte;
+ chip->read_word = hisi_nfc_read_word;
+ chip->write_buf = hisi_nfc_write_buf;
+ chip->read_buf = hisi_nfc_read_buf;
+ chip->chip_delay = HINFC504_CHIP_DELAY;
+
+ chip->ecc.mode = of_get_nand_ecc_mode(np);
+
+ buswidth = of_get_nand_bus_width(np);
+ if (buswidth == 16)
+ chip->options |= NAND_BUSWIDTH_16;
+
+ hisi_nfc_host_init(host);
+
+ ret = devm_request_irq(dev, irq, hinfc_irq_handle, IRQF_DISABLED,
+ "nandc", host);
+ if (ret) {
+ dev_err(dev, "failed to request IRQ\n");
+ goto err_res;
+ }
+
+ ret = nand_scan_ident(mtd, max_chips, NULL);
+ if (ret) {
+ ret = -ENODEV;
+ goto err_res;
+ }
+
+ host->buffer = dmam_alloc_coherent(dev, mtd->writesize + mtd->oobsize,
+ &host->dma_buffer, GFP_KERNEL);
+ if (!host->buffer) {
+ ret = -ENOMEM;
+ goto err_res;
+ }
+
+ host->dma_oob = host->dma_buffer + mtd->writesize;
+ memset(host->buffer, 0xff, mtd->writesize + mtd->oobsize);
+
+ flag = hinfc_read(host, HINFC504_CON);
+ flag &= ~(HINFC504_CON_PAGESIZE_MASK << HINFC504_CON_PAGEISZE_SHIFT);
+ switch (mtd->writesize) {
+ case 2048:
+ flag |= (0x001 << HINFC504_CON_PAGEISZE_SHIFT); break;
+ /*
+ * TODO: add more pagesize support,
+ * default pagesize has been set in hisi_nfc_host_init
+ */
+ default:
+ dev_err(dev, "NON-2KB page size nand flash\n");
+ ret = -EINVAL;
+ goto err_res;
+ }
+ hinfc_write(host, flag, HINFC504_CON);
+
+ if (chip->ecc.mode == NAND_ECC_HW)
+ hisi_nfc_ecc_probe(host);
+
+ ret = nand_scan_tail(mtd);
+ if (ret) {
+ dev_err(dev, "nand_scan_tail failed: %d\n", ret);
+ goto err_res;
+ }
+
+ ppdata.of_node = np;
+ ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+ if (ret) {
+ dev_err(dev, "Err MTD partition=%d\n", ret);
+ goto err_mtd;
+ }
+
+ return 0;
+
+err_mtd:
+ nand_release(mtd);
+err_res:
+ return ret;
+}
+
+static int hisi_nfc_remove(struct platform_device *pdev)
+{
+ struct hinfc_host *host = platform_get_drvdata(pdev);
+ struct mtd_info *mtd = &host->mtd;
+
+ nand_release(mtd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int hisi_nfc_suspend(struct device *dev)
+{
+ struct hinfc_host *host = dev_get_drvdata(dev);
+ unsigned long timeout = jiffies + HINFC504_NFC_PM_TIMEOUT;
+
+ while (time_before(jiffies, timeout)) {
+ if (((hinfc_read(host, HINFC504_STATUS) & 0x1) == 0x0) &&
+ (hinfc_read(host, HINFC504_DMA_CTRL) &
+ HINFC504_DMA_CTRL_DMA_START)) {
+ cond_resched();
+ return 0;
+ }
+ }
+
+ dev_err(host->dev, "nand controller suspend timeout.\n");
+
+ return -EAGAIN;
+}
+
+static int hisi_nfc_resume(struct device *dev)
+{
+ int cs;
+ struct hinfc_host *host = dev_get_drvdata(dev);
+ struct nand_chip *chip = &host->chip;
+
+ for (cs = 0; cs < chip->numchips; cs++)
+ hisi_nfc_send_cmd_reset(host, cs);
+ hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH,
+ HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH);
+
+ return 0;
+}
+#endif
+static SIMPLE_DEV_PM_OPS(hisi_nfc_pm_ops, hisi_nfc_suspend, hisi_nfc_resume);
+
+static const struct of_device_id nfc_id_table[] = {
+ { .compatible = "hisilicon,504-nfc" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, nfc_id_table);
+
+static struct platform_driver hisi_nfc_driver = {
+ .driver = {
+ .name = "hisi_nand",
+ .of_match_table = nfc_id_table,
+ .pm = &hisi_nfc_pm_ops,
+ },
+ .probe = hisi_nfc_probe,
+ .remove = hisi_nfc_remove,
+};
+
+module_platform_driver(hisi_nfc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Zhou Wang");
+MODULE_AUTHOR("Zhiyong Cai");
+MODULE_DESCRIPTION("Hisilicon Nand Flash Controller Driver");
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index 1633ec9c5108..ebf2cce04cba 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -69,7 +69,7 @@ struct jz_nand {
int selected_bank;
- struct jz_nand_platform_data *pdata;
+ struct gpio_desc *busy_gpio;
bool is_reading;
};
@@ -131,7 +131,7 @@ static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
static int jz_nand_dev_ready(struct mtd_info *mtd)
{
struct jz_nand *nand = mtd_to_jz_nand(mtd);
- return gpio_get_value_cansleep(nand->pdata->busy_gpio);
+ return gpiod_get_value_cansleep(nand->busy_gpio);
}
static void jz_nand_hwctl(struct mtd_info *mtd, int mode)
@@ -423,14 +423,12 @@ static int jz_nand_probe(struct platform_device *pdev)
if (ret)
goto err_free;
- if (pdata && gpio_is_valid(pdata->busy_gpio)) {
- ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
- if (ret) {
- dev_err(&pdev->dev,
- "Failed to request busy gpio %d: %d\n",
- pdata->busy_gpio, ret);
- goto err_iounmap_mmio;
- }
+ nand->busy_gpio = devm_gpiod_get_optional(&pdev->dev, "busy", GPIOD_IN);
+ if (IS_ERR(nand->busy_gpio)) {
+ ret = PTR_ERR(nand->busy_gpio);
+ dev_err(&pdev->dev, "Failed to request busy gpio %d\n",
+ ret);
+ goto err_iounmap_mmio;
}
mtd = &nand->mtd;
@@ -454,10 +452,9 @@ static int jz_nand_probe(struct platform_device *pdev)
chip->cmd_ctrl = jz_nand_cmd_ctrl;
chip->select_chip = jz_nand_select_chip;
- if (pdata && gpio_is_valid(pdata->busy_gpio))
+ if (nand->busy_gpio)
chip->dev_ready = jz_nand_dev_ready;
- nand->pdata = pdata;
platform_set_drvdata(pdev, nand);
/* We are going to autodetect NAND chips in the banks specified in the
@@ -496,7 +493,7 @@ static int jz_nand_probe(struct platform_device *pdev)
}
if (chipnr == 0) {
dev_err(&pdev->dev, "No NAND chips found\n");
- goto err_gpio_busy;
+ goto err_iounmap_mmio;
}
if (pdata && pdata->ident_callback) {
@@ -533,9 +530,6 @@ err_unclaim_banks:
nand->bank_base[bank - 1]);
}
writel(0, nand->base + JZ_REG_NAND_CTRL);
-err_gpio_busy:
- if (pdata && gpio_is_valid(pdata->busy_gpio))
- gpio_free(pdata->busy_gpio);
err_iounmap_mmio:
jz_nand_iounmap_resource(nand->mem, nand->base);
err_free:
@@ -546,7 +540,6 @@ err_free:
static int jz_nand_remove(struct platform_device *pdev)
{
struct jz_nand *nand = platform_get_drvdata(pdev);
- struct jz_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
size_t i;
nand_release(&nand->mtd);
@@ -562,8 +555,6 @@ static int jz_nand_remove(struct platform_device *pdev)
gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
}
}
- if (pdata && gpio_is_valid(pdata->busy_gpio))
- gpio_free(pdata->busy_gpio);
jz_nand_iounmap_resource(nand->mem, nand->base);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 41585dfb206f..df7eb4ff07d1 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -157,7 +157,6 @@ static uint8_t nand_read_byte(struct mtd_info *mtd)
/**
* nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
- * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
* @mtd: MTD device structure
*
* Default read function for 16bit buswidth with endianness conversion.
@@ -1751,11 +1750,10 @@ static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
int page)
{
- uint8_t *buf = chip->oob_poi;
int length = mtd->oobsize;
int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
int eccsize = chip->ecc.size;
- uint8_t *bufpoi = buf;
+ uint8_t *bufpoi = chip->oob_poi;
int i, toread, sndrnd = 0, pos;
chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
@@ -2944,6 +2942,16 @@ static void nand_resume(struct mtd_info *mtd)
__func__);
}
+/**
+ * nand_shutdown - [MTD Interface] Finish the current NAND operation and
+ * prevent further operations
+ * @mtd: MTD device structure
+ */
+static void nand_shutdown(struct mtd_info *mtd)
+{
+ nand_get_device(mtd, FL_SHUTDOWN);
+}
+
/* Set default functions */
static void nand_set_defaults(struct nand_chip *chip, int busw)
{
@@ -4028,22 +4036,24 @@ int nand_scan_tail(struct mtd_info *mtd)
ecc->read_oob = nand_read_oob_std;
ecc->write_oob = nand_write_oob_std;
/*
- * Board driver should supply ecc.size and ecc.bytes values to
- * select how many bits are correctable; see nand_bch_init()
- * for details. Otherwise, default to 4 bits for large page
- * devices.
+ * Board driver should supply ecc.size and ecc.strength values
+ * to select how many bits are correctable. Otherwise, default
+ * to 4 bits for large page devices.
*/
if (!ecc->size && (mtd->oobsize >= 64)) {
ecc->size = 512;
- ecc->bytes = DIV_ROUND_UP(13 * ecc->strength, 8);
+ ecc->strength = 4;
}
+
+ /* See nand_bch_init() for details. */
+ ecc->bytes = DIV_ROUND_UP(
+ ecc->strength * fls(8 * ecc->size), 8);
ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes,
&ecc->layout);
if (!ecc->priv) {
pr_warn("BCH ECC initialization failed!\n");
BUG();
}
- ecc->strength = ecc->bytes * 8 / fls(8 * ecc->size);
break;
case NAND_ECC_NONE:
@@ -4146,6 +4156,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->_unlock = NULL;
mtd->_suspend = nand_suspend;
mtd->_resume = nand_resume;
+ mtd->_reboot = nand_shutdown;
mtd->_block_isreserved = nand_block_isreserved;
mtd->_block_isbad = nand_block_isbad;
mtd->_block_markbad = nand_block_markbad;
@@ -4161,7 +4172,7 @@ int nand_scan_tail(struct mtd_info *mtd)
* properly set.
*/
if (!mtd->bitflip_threshold)
- mtd->bitflip_threshold = mtd->ecc_strength;
+ mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4);
/* Check, if we should skip the bad block table scan */
if (chip->options & NAND_SKIP_BBTSCAN)
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index ab5bbf567439..f2324271b94e 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -245,7 +245,6 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should "
#define STATE_DATAOUT 0x00001000 /* waiting for page data output */
#define STATE_DATAOUT_ID 0x00002000 /* waiting for ID bytes output */
#define STATE_DATAOUT_STATUS 0x00003000 /* waiting for status output */
-#define STATE_DATAOUT_STATUS_M 0x00004000 /* waiting for multi-plane status output */
#define STATE_DATAOUT_MASK 0x00007000 /* data output states mask */
/* Previous operation is done, ready to accept new requests */
@@ -269,7 +268,6 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should "
#define OPT_ANY 0xFFFFFFFF /* any chip supports this operation */
#define OPT_PAGE512 0x00000002 /* 512-byte page chips */
#define OPT_PAGE2048 0x00000008 /* 2048-byte page chips */
-#define OPT_SMARTMEDIA 0x00000010 /* SmartMedia technology chips */
#define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */
#define OPT_PAGE4096 0x00000080 /* 4096-byte page chips */
#define OPT_LARGEPAGE (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */
@@ -1096,8 +1094,6 @@ static char *get_state_name(uint32_t state)
return "STATE_DATAOUT_ID";
case STATE_DATAOUT_STATUS:
return "STATE_DATAOUT_STATUS";
- case STATE_DATAOUT_STATUS_M:
- return "STATE_DATAOUT_STATUS_M";
case STATE_READY:
return "STATE_READY";
case STATE_UNKNOWN:
@@ -1865,7 +1861,6 @@ static void switch_state(struct nandsim *ns)
break;
case STATE_DATAOUT_STATUS:
- case STATE_DATAOUT_STATUS_M:
ns->regs.count = ns->regs.num = 0;
break;
@@ -2005,7 +2000,6 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
}
if (NS_STATE(ns->state) == STATE_DATAOUT_STATUS
- || NS_STATE(ns->state) == STATE_DATAOUT_STATUS_M
|| NS_STATE(ns->state) == STATE_DATAOUT) {
int row = ns->regs.row;
@@ -2343,6 +2337,7 @@ static int __init ns_init_module(void)
}
chip->ecc.mode = NAND_ECC_SOFT_BCH;
chip->ecc.size = 512;
+ chip->ecc.strength = bch;
chip->ecc.bytes = eccbytes;
NS_INFO("using %u-bit/%u bytes BCH ECC\n", bch, chip->ecc.size);
}
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 63f858e6bf39..60fa89939c24 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1048,10 +1048,9 @@ static int omap_dev_ready(struct mtd_info *mtd)
* @mtd: MTD device structure
* @mode: Read/Write mode
*
- * When using BCH, sector size is hardcoded to 512 bytes.
- * Using wrapping mode 6 both for reading and writing if ELM module not uses
- * for error correction.
- * On writing,
+ * When using BCH with SW correction (i.e. no ELM), sector size is set
+ * to 512 bytes and we use BCH_WRAPMODE_6 wrapping mode
+ * for both reading and writing with:
* eccsize0 = 0 (no additional protected byte in spare area)
* eccsize1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
*/
@@ -1071,15 +1070,9 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode)
case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
bch_type = 0;
nsectors = 1;
- if (mode == NAND_ECC_READ) {
- wr_mode = BCH_WRAPMODE_6;
- ecc_size0 = BCH_ECC_SIZE0;
- ecc_size1 = BCH_ECC_SIZE1;
- } else {
- wr_mode = BCH_WRAPMODE_6;
- ecc_size0 = BCH_ECC_SIZE0;
- ecc_size1 = BCH_ECC_SIZE1;
- }
+ wr_mode = BCH_WRAPMODE_6;
+ ecc_size0 = BCH_ECC_SIZE0;
+ ecc_size1 = BCH_ECC_SIZE1;
break;
case OMAP_ECC_BCH4_CODE_HW:
bch_type = 0;
@@ -1097,15 +1090,9 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode)
case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
bch_type = 1;
nsectors = 1;
- if (mode == NAND_ECC_READ) {
- wr_mode = BCH_WRAPMODE_6;
- ecc_size0 = BCH_ECC_SIZE0;
- ecc_size1 = BCH_ECC_SIZE1;
- } else {
- wr_mode = BCH_WRAPMODE_6;
- ecc_size0 = BCH_ECC_SIZE0;
- ecc_size1 = BCH_ECC_SIZE1;
- }
+ wr_mode = BCH_WRAPMODE_6;
+ ecc_size0 = BCH_ECC_SIZE0;
+ ecc_size1 = BCH_ECC_SIZE1;
break;
case OMAP_ECC_BCH8_CODE_HW:
bch_type = 1;
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index ccaa8e283388..6f93b2990d25 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1110,8 +1110,6 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
switch (ecc->mode) {
case NAND_ECC_SOFT_BCH:
- ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * ecc->size),
- 8);
break;
case NAND_ECC_HW:
ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np);
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 51b9d6af307f..a5dfbfbebfca 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -89,9 +89,10 @@ static int find_boot_record(struct NFTLrecord *nftl)
}
/* To be safer with BIOS, also use erase mark as discriminant */
- if ((ret = nftl_read_oob(mtd, block * nftl->EraseSize +
+ ret = nftl_read_oob(mtd, block * nftl->EraseSize +
SECTORSIZE + 8, 8, &retlen,
- (char *)&h1) < 0)) {
+ (char *)&h1);
+ if (ret < 0) {
printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
continue;
@@ -109,8 +110,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
}
/* Finally reread to check ECC */
- if ((ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
- &retlen, buf) < 0)) {
+ ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
+ &retlen, buf);
+ if (ret < 0) {
printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
continue;
@@ -228,9 +230,11 @@ device is already correct.
The new DiskOnChip driver already scanned the bad block table. Just query it.
if ((i & (SECTORSIZE - 1)) == 0) {
/* read one sector for every SECTORSIZE of blocks */
- if ((ret = mtd->read(nftl->mbd.mtd, block * nftl->EraseSize +
- i + SECTORSIZE, SECTORSIZE, &retlen,
- buf)) < 0) {
+ ret = mtd->read(nftl->mbd.mtd,
+ block * nftl->EraseSize + i +
+ SECTORSIZE, SECTORSIZE,
+ &retlen, buf);
+ if (ret < 0) {
printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
ret);
kfree(nftl->ReplUnitTable);
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 39763b94f67d..1c7308c2c77d 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -57,7 +57,9 @@
#define QUADSPI_BUF3CR 0x1c
#define QUADSPI_BUF3CR_ALLMST_SHIFT 31
-#define QUADSPI_BUF3CR_ALLMST (1 << QUADSPI_BUF3CR_ALLMST_SHIFT)
+#define QUADSPI_BUF3CR_ALLMST_MASK (1 << QUADSPI_BUF3CR_ALLMST_SHIFT)
+#define QUADSPI_BUF3CR_ADATSZ_SHIFT 8
+#define QUADSPI_BUF3CR_ADATSZ_MASK (0xFF << QUADSPI_BUF3CR_ADATSZ_SHIFT)
#define QUADSPI_BFGENCR 0x20
#define QUADSPI_BFGENCR_PAR_EN_SHIFT 16
@@ -198,18 +200,21 @@ struct fsl_qspi_devtype_data {
enum fsl_qspi_devtype devtype;
int rxfifo;
int txfifo;
+ int ahb_buf_size;
};
static struct fsl_qspi_devtype_data vybrid_data = {
.devtype = FSL_QUADSPI_VYBRID,
.rxfifo = 128,
- .txfifo = 64
+ .txfifo = 64,
+ .ahb_buf_size = 1024
};
static struct fsl_qspi_devtype_data imx6sx_data = {
.devtype = FSL_QUADSPI_IMX6SX,
.rxfifo = 128,
- .txfifo = 512
+ .txfifo = 512,
+ .ahb_buf_size = 1024
};
#define FSL_QSPI_MAX_CHIP 4
@@ -227,6 +232,7 @@ struct fsl_qspi {
u32 nor_num;
u32 clk_rate;
unsigned int chip_base_addr; /* We may support two chips. */
+ bool has_second_chip;
};
static inline int is_vybrid_qspi(struct fsl_qspi *q)
@@ -583,7 +589,12 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
- writel(QUADSPI_BUF3CR_ALLMST, base + QUADSPI_BUF3CR);
+ /*
+ * Set ADATSZ with the maximum AHB buffer size to improve the
+ * read performance.
+ */
+ writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8)
+ << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
/* We only use the buffer3 */
writel(0, base + QUADSPI_BUF0IND);
@@ -783,7 +794,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)
struct spi_nor *nor;
struct mtd_info *mtd;
int ret, i = 0;
- bool has_second_chip = false;
const struct of_device_id *of_id =
of_match_device(fsl_qspi_dt_ids, &pdev->dev);
@@ -798,37 +808,30 @@ static int fsl_qspi_probe(struct platform_device *pdev)
/* find the resources */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI");
q->iobase = devm_ioremap_resource(dev, res);
- if (IS_ERR(q->iobase)) {
- ret = PTR_ERR(q->iobase);
- goto map_failed;
- }
+ if (IS_ERR(q->iobase))
+ return PTR_ERR(q->iobase);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"QuadSPI-memory");
q->ahb_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(q->ahb_base)) {
- ret = PTR_ERR(q->ahb_base);
- goto map_failed;
- }
+ if (IS_ERR(q->ahb_base))
+ return PTR_ERR(q->ahb_base);
+
q->memmap_phy = res->start;
/* find the clocks */
q->clk_en = devm_clk_get(dev, "qspi_en");
- if (IS_ERR(q->clk_en)) {
- ret = PTR_ERR(q->clk_en);
- goto map_failed;
- }
+ if (IS_ERR(q->clk_en))
+ return PTR_ERR(q->clk_en);
q->clk = devm_clk_get(dev, "qspi");
- if (IS_ERR(q->clk)) {
- ret = PTR_ERR(q->clk);
- goto map_failed;
- }
+ if (IS_ERR(q->clk))
+ return PTR_ERR(q->clk);
ret = clk_prepare_enable(q->clk_en);
if (ret) {
dev_err(dev, "can not enable the qspi_en clock\n");
- goto map_failed;
+ return ret;
}
ret = clk_prepare_enable(q->clk);
@@ -860,14 +863,14 @@ static int fsl_qspi_probe(struct platform_device *pdev)
goto irq_failed;
if (of_get_property(np, "fsl,qspi-has-second-chip", NULL))
- has_second_chip = true;
+ q->has_second_chip = true;
/* iterate the subnodes. */
for_each_available_child_of_node(dev->of_node, np) {
char modalias[40];
/* skip the holes */
- if (!has_second_chip)
+ if (!q->has_second_chip)
i *= 2;
nor = &q->nor[i];
@@ -890,24 +893,24 @@ static int fsl_qspi_probe(struct platform_device *pdev)
ret = of_modalias_node(np, modalias, sizeof(modalias));
if (ret < 0)
- goto map_failed;
+ goto irq_failed;
ret = of_property_read_u32(np, "spi-max-frequency",
&q->clk_rate);
if (ret < 0)
- goto map_failed;
+ goto irq_failed;
/* set the chip address for READID */
fsl_qspi_set_base_addr(q, nor);
ret = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
if (ret)
- goto map_failed;
+ goto irq_failed;
ppdata.of_node = np;
ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
if (ret)
- goto map_failed;
+ goto irq_failed;
/* Set the correct NOR size now. */
if (q->nor_size == 0) {
@@ -939,19 +942,19 @@ static int fsl_qspi_probe(struct platform_device *pdev)
clk_disable(q->clk);
clk_disable(q->clk_en);
- dev_info(dev, "QuadSPI SPI NOR flash driver\n");
return 0;
last_init_failed:
- for (i = 0; i < q->nor_num; i++)
+ for (i = 0; i < q->nor_num; i++) {
+ /* skip the holes */
+ if (!q->has_second_chip)
+ i *= 2;
mtd_device_unregister(&q->mtd[i]);
-
+ }
irq_failed:
clk_disable_unprepare(q->clk);
clk_failed:
clk_disable_unprepare(q->clk_en);
-map_failed:
- dev_err(dev, "Freescale QuadSPI probe failed\n");
return ret;
}
@@ -960,8 +963,12 @@ static int fsl_qspi_remove(struct platform_device *pdev)
struct fsl_qspi *q = platform_get_drvdata(pdev);
int i;
- for (i = 0; i < q->nor_num; i++)
+ for (i = 0; i < q->nor_num; i++) {
+ /* skip the holes */
+ if (!q->has_second_chip)
+ i *= 2;
mtd_device_unregister(&q->mtd[i]);
+ }
/* disable the hardware */
writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
@@ -972,6 +979,22 @@ static int fsl_qspi_remove(struct platform_device *pdev)
return 0;
}
+static int fsl_qspi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return 0;
+}
+
+static int fsl_qspi_resume(struct platform_device *pdev)
+{
+ struct fsl_qspi *q = platform_get_drvdata(pdev);
+
+ fsl_qspi_nor_setup(q);
+ fsl_qspi_set_map_addr(q);
+ fsl_qspi_nor_setup_last(q);
+
+ return 0;
+}
+
static struct platform_driver fsl_qspi_driver = {
.driver = {
.name = "fsl-quadspi",
@@ -980,6 +1003,8 @@ static struct platform_driver fsl_qspi_driver = {
},
.probe = fsl_qspi_probe,
.remove = fsl_qspi_remove,
+ .suspend = fsl_qspi_suspend,
+ .resume = fsl_qspi_resume,
};
module_platform_driver(fsl_qspi_driver);
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0f8ec3c2d015..b6a5a0c269e1 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -538,6 +538,7 @@ static const struct spi_device_id spi_nor_ids[] = {
/* GigaDevice */
{ "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) },
{ "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
+ { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) },
/* Intel/Numonyx -- xxxs33b */
{ "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
@@ -560,14 +561,14 @@ static const struct spi_device_id spi_nor_ids[] = {
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
/* Micron */
- { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, 0) },
- { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
- { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
- { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
- { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
- { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
- { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR) },
- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR) },
+ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) },
+ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ) },
+ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
+ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
+ { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
/* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
@@ -891,6 +892,45 @@ static int spansion_quad_enable(struct spi_nor *nor)
return 0;
}
+static int micron_quad_enable(struct spi_nor *nor)
+{
+ int ret;
+ u8 val;
+
+ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
+ if (ret < 0) {
+ dev_err(nor->dev, "error %d reading EVCR\n", ret);
+ return ret;
+ }
+
+ write_enable(nor);
+
+ /* set EVCR, enable quad I/O */
+ nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON;
+ ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1, 0);
+ if (ret < 0) {
+ dev_err(nor->dev, "error while writing EVCR register\n");
+ return ret;
+ }
+
+ ret = spi_nor_wait_till_ready(nor);
+ if (ret)
+ return ret;
+
+ /* read EVCR and check it */
+ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1);
+ if (ret < 0) {
+ dev_err(nor->dev, "error %d reading EVCR\n", ret);
+ return ret;
+ }
+ if (val & EVCR_QUAD_EN_MICRON) {
+ dev_err(nor->dev, "Micron EVCR Quad bit not clear\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
{
int status;
@@ -903,6 +943,13 @@ static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
return -EINVAL;
}
return status;
+ case CFI_MFR_ST:
+ status = micron_quad_enable(nor);
+ if (status) {
+ dev_err(nor->dev, "Micron quad-read not enabled\n");
+ return -EINVAL;
+ }
+ return status;
default:
status = spansion_quad_enable(nor);
if (status) {
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 945f532078e9..96edc1346124 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -214,8 +214,17 @@ static struct com20020_pci_card_info card_info_sohard = {
.flags = ARC_CAN_10MBIT,
};
-static struct com20020_pci_card_info card_info_eae = {
- .name = "EAE PLX-PCI",
+static struct com20020_pci_card_info card_info_eae_arc1 = {
+ .name = "EAE PLX-PCI ARC1",
+ .devcount = 1,
+ .chan_map_tbl = {
+ { 2, 0x00, 0x08 },
+ },
+ .flags = ARC_CAN_10MBIT,
+};
+
+static struct com20020_pci_card_info card_info_eae_ma1 = {
+ .name = "EAE PLX-PCI MA1",
.devcount = 2,
.chan_map_tbl = {
{ 2, 0x00, 0x08 },
@@ -359,9 +368,15 @@ static const struct pci_device_id com20020pci_id_table[] = {
},
{
0x10B5, 0x9050,
+ 0x10B5, 0x3263,
+ 0, 0,
+ (kernel_ulong_t)&card_info_eae_arc1
+ },
+ {
+ 0x10B5, 0x9050,
0x10B5, 0x3292,
0, 0,
- (kernel_ulong_t)&card_info_eae
+ (kernel_ulong_t)&card_info_eae_ma1
},
{
0x14BA, 0x6000,
diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c
index f18647c23559..c5a320507556 100644
--- a/drivers/net/ethernet/3com/3c589_cs.c
+++ b/drivers/net/ethernet/3com/3c589_cs.c
@@ -518,11 +518,8 @@ static int el3_open(struct net_device *dev)
netif_start_queue(dev);
tc589_reset(dev);
- init_timer(&lp->media);
- lp->media.function = media_check;
- lp->media.data = (unsigned long) dev;
- lp->media.expires = jiffies + HZ;
- add_timer(&lp->media);
+ setup_timer(&lp->media, media_check, (unsigned long)dev);
+ mod_timer(&lp->media, jiffies + HZ);
dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
dev->name, inw(dev->base_addr + EL3_STATUS));
diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c
index 384dc163851b..e0f3d197e7f2 100644
--- a/drivers/net/ethernet/agere/et131x.c
+++ b/drivers/net/ethernet/agere/et131x.c
@@ -3127,7 +3127,8 @@ static void et131x_error_timer_handler(unsigned long data)
}
/* This is a periodic timer, so reschedule */
- mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000);
+ mod_timer(&adapter->error_timer, jiffies +
+ msecs_to_jiffies(TX_ERROR_PERIOD));
}
static void et131x_adapter_memory_free(struct et131x_adapter *adapter)
@@ -3647,7 +3648,8 @@ static int et131x_open(struct net_device *netdev)
/* Start the timer to track NIC errors */
init_timer(&adapter->error_timer);
- adapter->error_timer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000;
+ adapter->error_timer.expires = jiffies +
+ msecs_to_jiffies(TX_ERROR_PERIOD);
adapter->error_timer.function = et131x_error_timer_handler;
adapter->error_timer.data = (unsigned long)adapter;
add_timer(&adapter->error_timer);
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 44b15373d6b3..4de62b210c85 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -1030,12 +1030,14 @@ static const struct acpi_device_id xgene_enet_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match);
#endif
+#ifdef CONFIG_OF
static struct of_device_id xgene_enet_of_match[] = {
{.compatible = "apm,xgene-enet",},
{},
};
MODULE_DEVICE_TABLE(of, xgene_enet_of_match);
+#endif
static struct platform_driver xgene_enet_driver = {
.driver = {
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index d86d6baf9681..bd5916a60cb5 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -121,7 +121,7 @@ static struct pci_driver b44_pci_driver = {
static const struct ssb_device_id b44_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_ETHERNET, SSB_ANY_REV),
- SSB_DEVTABLE_END
+ {},
};
MODULE_DEVICE_TABLE(ssb, b44_ssb_tbl);
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 3007d95fbb9f..676ffe093180 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -21,7 +21,7 @@
static const struct bcma_device_id bgmac_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
- BCMA_CORETABLE_END
+ {},
};
MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
@@ -1412,6 +1412,7 @@ static void bgmac_mii_unregister(struct bgmac *bgmac)
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
static int bgmac_probe(struct bcma_device *core)
{
+ struct bcma_chipinfo *ci = &core->bus->chipinfo;
struct net_device *net_dev;
struct bgmac *bgmac;
struct ssb_sprom *sprom = &core->bus->sprom;
@@ -1474,8 +1475,8 @@ static int bgmac_probe(struct bcma_device *core)
bgmac_chip_reset(bgmac);
/* For Northstar, we have to take all GMAC core out of reset */
- if (core->id.id == BCMA_CHIP_ID_BCM4707 ||
- core->id.id == BCMA_CHIP_ID_BCM53018) {
+ if (ci->id == BCMA_CHIP_ID_BCM4707 ||
+ ci->id == BCMA_CHIP_ID_BCM53018) {
struct bcma_device *ns_core;
int ns_gmac;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 615a6dbde047..23a019cee279 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -17855,8 +17855,10 @@ static int tg3_init_one(struct pci_dev *pdev,
*/
if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
+ tg3_full_lock(tp, 0);
tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+ tg3_full_unlock(tp);
}
err = tg3_test_dma(tp);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index d221f6b28fcd..78854ceb0870 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -1950,12 +1950,9 @@ static void set_debugfs_file_size(struct dentry *de, loff_t size)
static void add_debugfs_mem(struct adapter *adap, const char *name,
unsigned int idx, unsigned int size_mb)
{
- struct dentry *de;
-
- de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root,
- (void *)adap + idx, &mem_debugfs_fops);
- if (de && de->d_inode)
- de->d_inode->i_size = size_mb << 20;
+ debugfs_create_file_size(name, S_IRUSR, adap->debugfs_root,
+ (void *)adap + idx, &mem_debugfs_fops,
+ size_mb << 20);
}
/* Add an array of Debug FS files.
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
index b63cfee2d963..8f418ba868bd 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
@@ -55,7 +55,7 @@ static const struct file_operations name##_debugfs_fops = { \
struct t4_debugfs_entry {
const char *name;
const struct file_operations *ops;
- mode_t mode;
+ umode_t mode;
unsigned char data;
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index d6651937d899..5394a8486558 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -291,6 +291,7 @@ static void copy_rw_fields(void *to, struct mlx5_caps *from)
MLX5_SET(cmd_hca_cap, to, log_max_ra_req_dc, from->gen.log_max_ra_req_dc);
MLX5_SET(cmd_hca_cap, to, log_max_ra_res_dc, from->gen.log_max_ra_res_dc);
MLX5_SET(cmd_hca_cap, to, pkey_table_size, to_fw_pkey_sz(from->gen.pkey_table_size));
+ MLX5_SET(cmd_hca_cap, to, log_uar_page_sz, PAGE_SHIFT - 12);
v64 = from->gen.flags & MLX5_CAP_BITS_RW_MASK;
*flags_off = cpu_to_be64(v64);
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index e56c1bb36141..fa4317611fd6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -848,10 +848,17 @@ struct qlcnic_cardrsp_tx_ctx {
#define QLCNIC_MAC_VLAN_ADD 3
#define QLCNIC_MAC_VLAN_DEL 4
+enum qlcnic_mac_type {
+ QLCNIC_UNICAST_MAC,
+ QLCNIC_MULTICAST_MAC,
+ QLCNIC_BROADCAST_MAC,
+};
+
struct qlcnic_mac_vlan_list {
struct list_head list;
uint8_t mac_addr[ETH_ALEN+2];
u16 vlan_id;
+ enum qlcnic_mac_type mac_type;
};
/* MAC Learn */
@@ -1615,7 +1622,9 @@ void qlcnic_watchdog_task(struct work_struct *work);
void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
struct qlcnic_host_rds_ring *rds_ring, u8 ring_id);
void qlcnic_set_multi(struct net_device *netdev);
-int qlcnic_nic_add_mac(struct qlcnic_adapter *, const u8 *, u16);
+void qlcnic_flush_mcast_mac(struct qlcnic_adapter *);
+int qlcnic_nic_add_mac(struct qlcnic_adapter *, const u8 *, u16,
+ enum qlcnic_mac_type);
int qlcnic_nic_del_mac(struct qlcnic_adapter *, const u8 *);
void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter);
int qlcnic_82xx_read_phys_port_id(struct qlcnic_adapter *);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 69b46c051cc0..3e0f705a4311 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -487,7 +487,8 @@ int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr)
return err;
}
-int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan)
+int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan,
+ enum qlcnic_mac_type mac_type)
{
struct qlcnic_mac_vlan_list *cur;
struct list_head *head;
@@ -513,10 +514,29 @@ int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan)
}
cur->vlan_id = vlan;
+ cur->mac_type = mac_type;
+
list_add_tail(&cur->list, &adapter->mac_list);
return 0;
}
+void qlcnic_flush_mcast_mac(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_mac_vlan_list *cur;
+ struct list_head *head, *tmp;
+
+ list_for_each_safe(head, tmp, &adapter->mac_list) {
+ cur = list_entry(head, struct qlcnic_mac_vlan_list, list);
+ if (cur->mac_type != QLCNIC_MULTICAST_MAC)
+ continue;
+
+ qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
+ cur->vlan_id, QLCNIC_MAC_DEL);
+ list_del(&cur->list);
+ kfree(cur);
+ }
+}
+
static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -530,8 +550,9 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
return;
- qlcnic_nic_add_mac(adapter, adapter->mac_addr, vlan);
- qlcnic_nic_add_mac(adapter, bcast_addr, vlan);
+ qlcnic_nic_add_mac(adapter, adapter->mac_addr, vlan,
+ QLCNIC_UNICAST_MAC);
+ qlcnic_nic_add_mac(adapter, bcast_addr, vlan, QLCNIC_BROADCAST_MAC);
if (netdev->flags & IFF_PROMISC) {
if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))
@@ -540,8 +561,10 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
(netdev_mc_count(netdev) > ahw->max_mc_count)) {
mode = VPORT_MISS_MODE_ACCEPT_MULTI;
} else if (!netdev_mc_empty(netdev)) {
+ qlcnic_flush_mcast_mac(adapter);
netdev_for_each_mc_addr(ha, netdev)
- qlcnic_nic_add_mac(adapter, ha->addr, vlan);
+ qlcnic_nic_add_mac(adapter, ha->addr, vlan,
+ QLCNIC_MULTICAST_MAC);
}
/* configure unicast MAC address, if there is not sufficient space
@@ -551,7 +574,8 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
mode = VPORT_MISS_MODE_ACCEPT_ALL;
} else if (!netdev_uc_empty(netdev)) {
netdev_for_each_uc_addr(ha, netdev)
- qlcnic_nic_add_mac(adapter, ha->addr, vlan);
+ qlcnic_nic_add_mac(adapter, ha->addr, vlan,
+ QLCNIC_UNICAST_MAC);
}
if (mode == VPORT_MISS_MODE_ACCEPT_ALL &&
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 1659c804f1d5..e6312465fe45 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -1489,7 +1489,8 @@ out:
return ret;
}
-static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac)
+static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac,
+ enum qlcnic_mac_type mac_type)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_sriov *sriov = adapter->ahw->sriov;
@@ -1500,17 +1501,18 @@ static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac)
vf = &adapter->ahw->sriov->vf_info[0];
if (!qlcnic_sriov_check_any_vlan(vf)) {
- qlcnic_nic_add_mac(adapter, mac, 0);
+ qlcnic_nic_add_mac(adapter, mac, 0, mac_type);
} else {
spin_lock(&vf->vlan_list_lock);
for (i = 0; i < sriov->num_allowed_vlans; i++) {
vlan_id = vf->sriov_vlans[i];
if (vlan_id)
- qlcnic_nic_add_mac(adapter, mac, vlan_id);
+ qlcnic_nic_add_mac(adapter, mac, vlan_id,
+ mac_type);
}
spin_unlock(&vf->vlan_list_lock);
if (qlcnic_84xx_check(adapter))
- qlcnic_nic_add_mac(adapter, mac, 0);
+ qlcnic_nic_add_mac(adapter, mac, 0, mac_type);
}
}
@@ -1549,10 +1551,12 @@ void qlcnic_sriov_vf_set_multi(struct net_device *netdev)
(netdev_mc_count(netdev) > ahw->max_mc_count)) {
mode = VPORT_MISS_MODE_ACCEPT_MULTI;
} else {
- qlcnic_vf_add_mc_list(netdev, bcast_addr);
+ qlcnic_vf_add_mc_list(netdev, bcast_addr, QLCNIC_BROADCAST_MAC);
if (!netdev_mc_empty(netdev)) {
+ qlcnic_flush_mcast_mac(adapter);
netdev_for_each_mc_addr(ha, netdev)
- qlcnic_vf_add_mc_list(netdev, ha->addr);
+ qlcnic_vf_add_mc_list(netdev, ha->addr,
+ QLCNIC_MULTICAST_MAC);
}
}
@@ -1563,7 +1567,8 @@ void qlcnic_sriov_vf_set_multi(struct net_device *netdev)
mode = VPORT_MISS_MODE_ACCEPT_ALL;
} else if (!netdev_uc_empty(netdev)) {
netdev_for_each_uc_addr(ha, netdev)
- qlcnic_vf_add_mc_list(netdev, ha->addr);
+ qlcnic_vf_add_mc_list(netdev, ha->addr,
+ QLCNIC_UNICAST_MAC);
}
if (adapter->pdev->is_virtfn) {
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 2b10b85d8a08..22e0cad1b4b5 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -1192,23 +1192,16 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb)
skb_pull(skb, maclen);
if (port->tso && gso_size < datalen) {
+ if (skb_unclone(skb, GFP_ATOMIC))
+ goto out_dropped;
+
/* segment to TSO size */
skb_shinfo(skb)->gso_size = datalen;
skb_shinfo(skb)->gso_segs = gso_segs;
-
- segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO);
-
- /* restore gso_size & gso_segs */
- skb_shinfo(skb)->gso_size = gso_size;
- skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len - hlen,
- gso_size);
- } else
- segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO);
- if (IS_ERR(segs)) {
- dev->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
}
+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO);
+ if (IS_ERR(segs))
+ goto out_dropped;
skb_push(skb, maclen);
skb_reset_mac_header(skb);
@@ -1246,6 +1239,10 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb)
if (!(status & NETDEV_TX_MASK))
dev_kfree_skb_any(skb);
return status;
+out_dropped:
+ dev->stats.tx_dropped++;
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
}
static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 2729f64b3e7e..924ea98bd531 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -67,7 +67,7 @@ struct ipvl_dev {
struct list_head addrs;
int ipv4cnt;
int ipv6cnt;
- struct ipvl_pcpu_stats *pcpu_stats;
+ struct ipvl_pcpu_stats __percpu *pcpu_stats;
DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE);
netdev_features_t sfeatures;
u32 msg_enable;
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 3ad8ca76196d..1190fd8f0088 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -32,6 +32,7 @@
/* Operation Mode Strap Override */
#define MII_KSZPHY_OMSO 0x16
#define KSZPHY_OMSO_B_CAST_OFF BIT(9)
+#define KSZPHY_OMSO_NAND_TREE_ON BIT(5)
#define KSZPHY_OMSO_RMII_OVERRIDE BIT(1)
#define KSZPHY_OMSO_MII_OVERRIDE BIT(0)
@@ -76,6 +77,7 @@ struct kszphy_type {
u32 led_mode_reg;
u16 interrupt_level_mask;
bool has_broadcast_disable;
+ bool has_nand_tree_disable;
bool has_rmii_ref_clk_sel;
};
@@ -89,6 +91,7 @@ struct kszphy_priv {
static const struct kszphy_type ksz8021_type = {
.led_mode_reg = MII_KSZPHY_CTRL_2,
.has_broadcast_disable = true,
+ .has_nand_tree_disable = true,
.has_rmii_ref_clk_sel = true,
};
@@ -98,11 +101,13 @@ static const struct kszphy_type ksz8041_type = {
static const struct kszphy_type ksz8051_type = {
.led_mode_reg = MII_KSZPHY_CTRL_2,
+ .has_nand_tree_disable = true,
};
static const struct kszphy_type ksz8081_type = {
.led_mode_reg = MII_KSZPHY_CTRL_2,
.has_broadcast_disable = true,
+ .has_nand_tree_disable = true,
.has_rmii_ref_clk_sel = true,
};
@@ -231,6 +236,26 @@ out:
return ret;
}
+static int kszphy_nand_tree_disable(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_read(phydev, MII_KSZPHY_OMSO);
+ if (ret < 0)
+ goto out;
+
+ if (!(ret & KSZPHY_OMSO_NAND_TREE_ON))
+ return 0;
+
+ ret = phy_write(phydev, MII_KSZPHY_OMSO,
+ ret & ~KSZPHY_OMSO_NAND_TREE_ON);
+out:
+ if (ret)
+ dev_err(&phydev->dev, "failed to disable NAND tree mode\n");
+
+ return ret;
+}
+
static int kszphy_config_init(struct phy_device *phydev)
{
struct kszphy_priv *priv = phydev->priv;
@@ -245,6 +270,9 @@ static int kszphy_config_init(struct phy_device *phydev)
if (type->has_broadcast_disable)
kszphy_broadcast_disable(phydev);
+ if (type->has_nand_tree_disable)
+ kszphy_nand_tree_disable(phydev);
+
if (priv->rmii_ref_clk_sel) {
ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
if (ret) {
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 6b8efcabb816..9cdfb3fe9c15 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -914,7 +914,7 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
/* We got no receive buffer. */
D1("could not allocate memory");
odev->rx_parse_state = WAIT_SYNC;
- return;
+ continue;
}
/* Copy what we got so far. make room for iphdr
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 5980ac6c48dd..438fc6bcaef1 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -40,6 +40,7 @@
#define PLA_RXFIFO_CTRL0 0xc0a0
#define PLA_RXFIFO_CTRL1 0xc0a4
#define PLA_RXFIFO_CTRL2 0xc0a8
+#define PLA_DMY_REG0 0xc0b0
#define PLA_FMC 0xc0b4
#define PLA_CFG_WOL 0xc0b6
#define PLA_TEREDO_CFG 0xc0bc
@@ -90,8 +91,14 @@
#define PLA_BP_7 0xfc36
#define PLA_BP_EN 0xfc38
+#define USB_USB2PHY 0xb41e
+#define USB_SSPHYLINK2 0xb428
#define USB_U2P3_CTRL 0xb460
+#define USB_CSR_DUMMY1 0xb464
+#define USB_CSR_DUMMY2 0xb466
#define USB_DEV_STAT 0xb808
+#define USB_CONNECT_TIMER 0xcbf8
+#define USB_BURST_SIZE 0xcfc0
#define USB_USB_CTRL 0xd406
#define USB_PHY_CTRL 0xd408
#define USB_TX_AGG 0xd40a
@@ -170,6 +177,9 @@
#define TXFIFO_THR_NORMAL 0x00400008
#define TXFIFO_THR_NORMAL2 0x01000008
+/* PLA_DMY_REG0 */
+#define ECM_ALDPS 0x0002
+
/* PLA_FMC */
#define FMC_FCR_MCU_EN 0x0001
@@ -289,6 +299,20 @@
/* PLA_BOOT_CTRL */
#define AUTOLOAD_DONE 0x0002
+/* USB_USB2PHY */
+#define USB2PHY_SUSPEND 0x0001
+#define USB2PHY_L1 0x0002
+
+/* USB_SSPHYLINK2 */
+#define pwd_dn_scale_mask 0x3ffe
+#define pwd_dn_scale(x) ((x) << 1)
+
+/* USB_CSR_DUMMY1 */
+#define DYNAMIC_BURST 0x0001
+
+/* USB_CSR_DUMMY2 */
+#define EP4_FULL_FC 0x0001
+
/* USB_DEV_STAT */
#define STAT_SPEED_MASK 0x0006
#define STAT_SPEED_HIGH 0x0000
@@ -334,9 +358,13 @@
#define TIMER11_EN 0x0001
/* USB_LPM_CTRL */
+/* bit 4 ~ 5: fifo empty boundary */
+#define FIFO_EMPTY_1FB 0x30 /* 0x1fb * 64 = 32448 bytes */
+/* bit 2 ~ 3: LMP timer */
#define LPM_TIMER_MASK 0x0c
#define LPM_TIMER_500MS 0x04 /* 500 ms */
#define LPM_TIMER_500US 0x0c /* 500 us */
+#define ROK_EXIT_LPM 0x02
/* USB_AFE_CTRL2 */
#define SEN_VAL_MASK 0xf800
@@ -3230,6 +3258,32 @@ static void r8153_init(struct r8152 *tp)
r8153_u2p3en(tp, false);
+ if (tp->version == RTL_VER_04) {
+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2);
+ ocp_data &= ~pwd_dn_scale_mask;
+ ocp_data |= pwd_dn_scale(96);
+ ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2, ocp_data);
+
+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY);
+ ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND;
+ ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data);
+ } else if (tp->version == RTL_VER_05) {
+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0);
+ ocp_data &= ~ECM_ALDPS;
+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0, ocp_data);
+
+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1);
+ if (ocp_read_word(tp, MCU_TYPE_USB, USB_BURST_SIZE) == 0)
+ ocp_data &= ~DYNAMIC_BURST;
+ else
+ ocp_data |= DYNAMIC_BURST;
+ ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data);
+ }
+
+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2);
+ ocp_data |= EP4_FULL_FC;
+ ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2, ocp_data);
+
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL);
ocp_data &= ~TIMER11_EN;
ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data);
@@ -3238,8 +3292,7 @@ static void r8153_init(struct r8152 *tp)
ocp_data &= ~LED_MODE_MASK;
ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
- ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL);
- ocp_data &= ~LPM_TIMER_MASK;
+ ocp_data = FIFO_EMPTY_1FB | ROK_EXIT_LPM;
if (tp->version == RTL_VER_04 && tp->udev->speed != USB_SPEED_SUPER)
ocp_data |= LPM_TIMER_500MS;
else
@@ -3251,6 +3304,8 @@ static void r8153_init(struct r8152 *tp)
ocp_data |= SEN_VAL_NORMAL | SEL_RXIDLE;
ocp_write_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2, ocp_data);
+ ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001);
+
r8153_power_cut_en(tp, false);
r8153_u1u2en(tp, true);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 110a2cf67244..f1ff3666f090 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1710,6 +1710,12 @@ static int virtnet_probe(struct virtio_device *vdev)
struct virtnet_info *vi;
u16 max_queue_pairs;
+ if (!vdev->config->get) {
+ dev_err(&vdev->dev, "%s failure: config access disabled\n",
+ __func__);
+ return -EINVAL;
+ }
+
if (!virtnet_validate_features(vdev))
return -EINVAL;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 0e57e862c399..1e0a775ea882 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -555,12 +555,13 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
unsigned int off,
struct vxlanhdr *vh, size_t hdrlen,
- u32 data)
+ u32 data, struct gro_remcsum *grc,
+ bool nopartial)
{
size_t start, offset, plen;
if (skb->remcsum_offload)
- return vh;
+ return NULL;
if (!NAPI_GRO_CB(skb)->csum_valid)
return NULL;
@@ -579,7 +580,8 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
return NULL;
}
- skb_gro_remcsum_process(skb, (void *)vh + hdrlen, start, offset);
+ skb_gro_remcsum_process(skb, (void *)vh + hdrlen,
+ start, offset, grc, nopartial);
skb->remcsum_offload = 1;
@@ -597,6 +599,9 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head,
struct vxlan_sock *vs = container_of(uoff, struct vxlan_sock,
udp_offloads);
u32 flags;
+ struct gro_remcsum grc;
+
+ skb_gro_remcsum_init(&grc);
off_vx = skb_gro_offset(skb);
hlen = off_vx + sizeof(*vh);
@@ -614,7 +619,9 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head,
if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) {
vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
- ntohl(vh->vx_vni));
+ ntohl(vh->vx_vni), &grc,
+ !!(vs->flags &
+ VXLAN_F_REMCSUM_NOPARTIAL));
if (!vh)
goto out;
@@ -637,6 +644,7 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head,
pp = eth_gro_receive(head, skb);
out:
+ skb_gro_remcsum_cleanup(skb, &grc);
NAPI_GRO_CB(skb)->flush |= flush;
return pp;
@@ -1150,16 +1158,10 @@ static void vxlan_igmp_leave(struct work_struct *work)
}
static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh,
- size_t hdrlen, u32 data)
+ size_t hdrlen, u32 data, bool nopartial)
{
size_t start, offset, plen;
- if (skb->remcsum_offload) {
- /* Already processed in GRO path */
- skb->remcsum_offload = 0;
- return vh;
- }
-
start = (data & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
offset = start + ((data & VXLAN_RCO_UDP) ?
offsetof(struct udphdr, check) :
@@ -1172,7 +1174,8 @@ static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh,
vh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
- skb_remcsum_process(skb, (void *)vh + hdrlen, start, offset);
+ skb_remcsum_process(skb, (void *)vh + hdrlen, start, offset,
+ nopartial);
return vh;
}
@@ -1209,7 +1212,8 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto drop;
if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) {
- vxh = vxlan_remcsum(skb, vxh, sizeof(struct vxlanhdr), vni);
+ vxh = vxlan_remcsum(skb, vxh, sizeof(struct vxlanhdr), vni,
+ !!(vs->flags & VXLAN_F_REMCSUM_NOPARTIAL));
if (!vxh)
goto drop;
@@ -2438,6 +2442,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
[IFLA_VXLAN_REMCSUM_TX] = { .type = NLA_U8 },
[IFLA_VXLAN_REMCSUM_RX] = { .type = NLA_U8 },
[IFLA_VXLAN_GBP] = { .type = NLA_FLAG, },
+ [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
};
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -2761,6 +2766,9 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
if (data[IFLA_VXLAN_GBP])
vxlan->flags |= VXLAN_F_GBP;
+ if (data[IFLA_VXLAN_REMCSUM_NOPARTIAL])
+ vxlan->flags |= VXLAN_F_REMCSUM_NOPARTIAL;
+
if (vxlan_find_vni(src_net, vni, use_ipv6 ? AF_INET6 : AF_INET,
vxlan->dst_port, vxlan->flags)) {
pr_info("duplicate VNI %u\n", vni);
@@ -2910,6 +2918,10 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
nla_put_flag(skb, IFLA_VXLAN_GBP))
goto nla_put_failure;
+ if (vxlan->flags & VXLAN_F_REMCSUM_NOPARTIAL &&
+ nla_put_flag(skb, IFLA_VXLAN_REMCSUM_NOPARTIAL))
+ goto nla_put_failure;
+
return 0;
nla_put_failure:
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 2c9088633ec6..ccbdb05b28cd 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -127,7 +127,7 @@ static const struct bcma_device_id b43_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1E, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x28, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x2A, BCMA_ANY_CLASS),
- BCMA_CORETABLE_END
+ {},
};
MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
#endif
@@ -144,7 +144,7 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
- SSB_DEVTABLE_END
+ {},
};
MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl);
#endif
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 1aec2146a2bf..4e58c0069830 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -86,7 +86,7 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for the firmware files to load.");
static const struct ssb_device_id b43legacy_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 2),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 4),
- SSB_DEVTABLE_END
+ {},
};
MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index f95b52442281..48135063347e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -99,7 +99,7 @@ static struct bcma_device_id brcms_coreid_table[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
- BCMA_CORETABLE_END
+ {},
};
MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index ec456f0d972e..a62170ea0481 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -822,11 +822,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
/* get a new skb - if fail, old one will be reused */
new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
- if (unlikely(!new_skb)) {
- pr_err("Allocation of new skb failed in %s\n",
- __func__);
+ if (unlikely(!new_skb))
goto no_new;
- }
if (rtlpriv->use_new_trx_flow) {
buffer_desc =
&rtlpci->rx_ring[rxring_idx].buffer_desc
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 110fece2ff53..62426d81a4d6 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -229,7 +229,6 @@ parse_failed:
resource_list_for_each_entry(window, resources)
kfree(window->res);
pci_free_resource_list(resources);
- kfree(bus_range);
return err;
}
EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b0d50d70a8a1..b189733a1539 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -526,6 +526,7 @@ static int of_platform_device_destroy(struct device *dev, void *data)
amba_device_unregister(to_amba_device(dev));
#endif
+ of_dma_deconfigure(dev);
of_node_clear_flag(dev->of_node, OF_POPULATED);
of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
return 0;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 8843a678f200..3bb49252a098 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -279,6 +279,7 @@ config BFIN_CFPCMCIA
config AT91_CF
tristate "AT91 CompactFlash Controller"
depends on PCMCIA && ARCH_AT91
+ depends on !ARCH_MULTIPLATFORM
help
Say Y here to support the CompactFlash controller on AT91 chips.
Or choose M to compile the driver as a module named "at91_cf".
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index a3ecf5809634..b1541f40fd8d 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -53,6 +53,7 @@ config PWM_ATMEL
config PWM_ATMEL_HLCDC_PWM
tristate "Atmel HLCDC PWM support"
depends on MFD_ATMEL_HLCDC
+ depends on HAVE_CLK
help
Generic PWM framework driver for the PWM output of the HLCDC
(Atmel High-end LCD Controller). This PWM output is mainly used
@@ -130,6 +131,19 @@ config PWM_FSL_FTM
To compile this driver as a module, choose M here: the module
will be called pwm-fsl-ftm.
+config PWM_IMG
+ tristate "Imagination Technologies PWM driver"
+ depends on HAS_IOMEM
+ depends on MFD_SYSCON
+ depends on COMMON_CLK
+ depends on MIPS || COMPILE_TEST
+ help
+ Generic PWM framework driver for Imagination Technologies
+ PWM block which supports 4 channels.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-img
+
config PWM_IMX
tristate "i.MX PWM support"
depends on ARCH_MXC
@@ -283,6 +297,16 @@ config PWM_STI
To compile this driver as a module, choose M here: the module
will be called pwm-sti.
+config PWM_SUN4I
+ tristate "Allwinner PWM support"
+ depends on ARCH_SUNXI || COMPILE_TEST
+ depends on HAS_IOMEM && COMMON_CLK
+ help
+ Generic PWM framework driver for Allwinner SoCs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-sun4i.
+
config PWM_TEGRA
tristate "NVIDIA Tegra PWM support"
depends on ARCH_TEGRA
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 65259ac1e8de..ec50eb5b5a8f 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o
obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
+obj-$(CONFIG_PWM_IMG) += pwm-img.o
obj-$(CONFIG_PWM_IMX) += pwm-imx.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o
@@ -26,6 +27,7 @@ obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
obj-$(CONFIG_PWM_STI) += pwm-sti.o
+obj-$(CONFIG_PWM_SUN4I) += pwm-sun4i.o
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 966497d10c6e..810aef3f4c3e 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -192,7 +192,7 @@ static void of_pwmchip_add(struct pwm_chip *chip)
static void of_pwmchip_remove(struct pwm_chip *chip)
{
- if (chip->dev && chip->dev->of_node)
+ if (chip->dev)
of_node_put(chip->dev->of_node);
}
diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
index e7a785fadcdf..522f7075bb1a 100644
--- a/drivers/pwm/pwm-atmel-hlcdc.c
+++ b/drivers/pwm/pwm-atmel-hlcdc.c
@@ -64,6 +64,9 @@ static int atmel_hlcdc_pwm_config(struct pwm_chip *c,
if (!chip->errata || !chip->errata->slow_clk_erratum) {
clk_freq = clk_get_rate(new_clk);
+ if (!clk_freq)
+ return -EINVAL;
+
clk_period_ns = (u64)NSEC_PER_SEC * 256;
do_div(clk_period_ns, clk_freq);
}
@@ -73,6 +76,9 @@ static int atmel_hlcdc_pwm_config(struct pwm_chip *c,
clk_period_ns > period_ns) {
new_clk = hlcdc->sys_clk;
clk_freq = clk_get_rate(new_clk);
+ if (!clk_freq)
+ return -EINVAL;
+
clk_period_ns = (u64)NSEC_PER_SEC * 256;
do_div(clk_period_ns, clk_freq);
}
diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c
new file mode 100644
index 000000000000..476171a768d6
--- /dev/null
+++ b/drivers/pwm/pwm-img.c
@@ -0,0 +1,249 @@
+/*
+ * Imagination Technologies Pulse Width Modulator driver
+ *
+ * Copyright (c) 2014-2015, Imagination Technologies
+ *
+ * Based on drivers/pwm/pwm-tegra.c, Copyright (c) 2010, NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* PWM registers */
+#define PWM_CTRL_CFG 0x0000
+#define PWM_CTRL_CFG_NO_SUB_DIV 0
+#define PWM_CTRL_CFG_SUB_DIV0 1
+#define PWM_CTRL_CFG_SUB_DIV1 2
+#define PWM_CTRL_CFG_SUB_DIV0_DIV1 3
+#define PWM_CTRL_CFG_DIV_SHIFT(ch) ((ch) * 2 + 4)
+#define PWM_CTRL_CFG_DIV_MASK 0x3
+
+#define PWM_CH_CFG(ch) (0x4 + (ch) * 4)
+#define PWM_CH_CFG_TMBASE_SHIFT 0
+#define PWM_CH_CFG_DUTY_SHIFT 16
+
+#define PERIP_PWM_PDM_CONTROL 0x0140
+#define PERIP_PWM_PDM_CONTROL_CH_MASK 0x1
+#define PERIP_PWM_PDM_CONTROL_CH_SHIFT(ch) ((ch) * 4)
+
+#define MAX_TMBASE_STEPS 65536
+
+struct img_pwm_chip {
+ struct device *dev;
+ struct pwm_chip chip;
+ struct clk *pwm_clk;
+ struct clk *sys_clk;
+ void __iomem *base;
+ struct regmap *periph_regs;
+};
+
+static inline struct img_pwm_chip *to_img_pwm_chip(struct pwm_chip *chip)
+{
+ return container_of(chip, struct img_pwm_chip, chip);
+}
+
+static inline void img_pwm_writel(struct img_pwm_chip *chip,
+ u32 reg, u32 val)
+{
+ writel(val, chip->base + reg);
+}
+
+static inline u32 img_pwm_readl(struct img_pwm_chip *chip,
+ u32 reg)
+{
+ return readl(chip->base + reg);
+}
+
+static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ u32 val, div, duty, timebase;
+ unsigned long mul, output_clk_hz, input_clk_hz;
+ struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip);
+
+ input_clk_hz = clk_get_rate(pwm_chip->pwm_clk);
+ output_clk_hz = DIV_ROUND_UP(NSEC_PER_SEC, period_ns);
+
+ mul = DIV_ROUND_UP(input_clk_hz, output_clk_hz);
+ if (mul <= MAX_TMBASE_STEPS) {
+ div = PWM_CTRL_CFG_NO_SUB_DIV;
+ timebase = DIV_ROUND_UP(mul, 1);
+ } else if (mul <= MAX_TMBASE_STEPS * 8) {
+ div = PWM_CTRL_CFG_SUB_DIV0;
+ timebase = DIV_ROUND_UP(mul, 8);
+ } else if (mul <= MAX_TMBASE_STEPS * 64) {
+ div = PWM_CTRL_CFG_SUB_DIV1;
+ timebase = DIV_ROUND_UP(mul, 64);
+ } else if (mul <= MAX_TMBASE_STEPS * 512) {
+ div = PWM_CTRL_CFG_SUB_DIV0_DIV1;
+ timebase = DIV_ROUND_UP(mul, 512);
+ } else if (mul > MAX_TMBASE_STEPS * 512) {
+ dev_err(chip->dev,
+ "failed to configure timebase steps/divider value\n");
+ return -EINVAL;
+ }
+
+ duty = DIV_ROUND_UP(timebase * duty_ns, period_ns);
+
+ val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
+ val &= ~(PWM_CTRL_CFG_DIV_MASK << PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm));
+ val |= (div & PWM_CTRL_CFG_DIV_MASK) <<
+ PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm);
+ img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
+
+ val = (duty << PWM_CH_CFG_DUTY_SHIFT) |
+ (timebase << PWM_CH_CFG_TMBASE_SHIFT);
+ img_pwm_writel(pwm_chip, PWM_CH_CFG(pwm->hwpwm), val);
+
+ return 0;
+}
+
+static int img_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ u32 val;
+ struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip);
+
+ val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
+ val |= BIT(pwm->hwpwm);
+ img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
+
+ regmap_update_bits(pwm_chip->periph_regs, PERIP_PWM_PDM_CONTROL,
+ PERIP_PWM_PDM_CONTROL_CH_MASK <<
+ PERIP_PWM_PDM_CONTROL_CH_SHIFT(pwm->hwpwm), 0);
+
+ return 0;
+}
+
+static void img_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ u32 val;
+ struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip);
+
+ val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
+ val &= ~BIT(pwm->hwpwm);
+ img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
+}
+
+static const struct pwm_ops img_pwm_ops = {
+ .config = img_pwm_config,
+ .enable = img_pwm_enable,
+ .disable = img_pwm_disable,
+ .owner = THIS_MODULE,
+};
+
+static int img_pwm_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *res;
+ struct img_pwm_chip *pwm;
+
+ pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+ if (!pwm)
+ return -ENOMEM;
+
+ pwm->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pwm->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pwm->base))
+ return PTR_ERR(pwm->base);
+
+ pwm->periph_regs = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ "img,cr-periph");
+ if (IS_ERR(pwm->periph_regs))
+ return PTR_ERR(pwm->periph_regs);
+
+ pwm->sys_clk = devm_clk_get(&pdev->dev, "sys");
+ if (IS_ERR(pwm->sys_clk)) {
+ dev_err(&pdev->dev, "failed to get system clock\n");
+ return PTR_ERR(pwm->sys_clk);
+ }
+
+ pwm->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
+ if (IS_ERR(pwm->pwm_clk)) {
+ dev_err(&pdev->dev, "failed to get pwm clock\n");
+ return PTR_ERR(pwm->pwm_clk);
+ }
+
+ ret = clk_prepare_enable(pwm->sys_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not prepare or enable sys clock\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(pwm->pwm_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not prepare or enable pwm clock\n");
+ goto disable_sysclk;
+ }
+
+ pwm->chip.dev = &pdev->dev;
+ pwm->chip.ops = &img_pwm_ops;
+ pwm->chip.base = -1;
+ pwm->chip.npwm = 4;
+
+ ret = pwmchip_add(&pwm->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret);
+ goto disable_pwmclk;
+ }
+
+ platform_set_drvdata(pdev, pwm);
+ return 0;
+
+disable_pwmclk:
+ clk_disable_unprepare(pwm->pwm_clk);
+disable_sysclk:
+ clk_disable_unprepare(pwm->sys_clk);
+ return ret;
+}
+
+static int img_pwm_remove(struct platform_device *pdev)
+{
+ struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev);
+ u32 val;
+ unsigned int i;
+
+ for (i = 0; i < pwm_chip->chip.npwm; i++) {
+ val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
+ val &= ~BIT(i);
+ img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
+ }
+
+ clk_disable_unprepare(pwm_chip->pwm_clk);
+ clk_disable_unprepare(pwm_chip->sys_clk);
+
+ return pwmchip_remove(&pwm_chip->chip);
+}
+
+static const struct of_device_id img_pwm_of_match[] = {
+ { .compatible = "img,pistachio-pwm", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, img_pwm_of_match);
+
+static struct platform_driver img_pwm_driver = {
+ .driver = {
+ .name = "img-pwm",
+ .of_match_table = img_pwm_of_match,
+ },
+ .probe = img_pwm_probe,
+ .remove = img_pwm_remove,
+};
+module_platform_driver(img_pwm_driver);
+
+MODULE_AUTHOR("Sai Masarapu <Sai.Masarapu@imgtec.com>");
+MODULE_DESCRIPTION("Imagination Technologies PWM DAC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
index b95115cdaea7..92abbd56b9f7 100644
--- a/drivers/pwm/pwm-sti.c
+++ b/drivers/pwm/pwm-sti.c
@@ -57,6 +57,7 @@ struct sti_pwm_chip {
struct regmap_field *pwm_int_en;
struct pwm_chip chip;
struct pwm_device *cur;
+ unsigned long configured;
unsigned int en_count;
struct mutex sti_pwm_lock; /* To sync between enable/disable calls */
void __iomem *mmio;
@@ -102,24 +103,6 @@ static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period,
return 0;
}
-/* Calculate the number of PWM devices configured with a period. */
-static unsigned int sti_pwm_count_configured(struct pwm_chip *chip)
-{
- struct pwm_device *pwm;
- unsigned int ncfg = 0;
- unsigned int i;
-
- for (i = 0; i < chip->npwm; i++) {
- pwm = &chip->pwms[i];
- if (test_bit(PWMF_REQUESTED, &pwm->flags)) {
- if (pwm_get_period(pwm))
- ncfg++;
- }
- }
-
- return ncfg;
-}
-
/*
* For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles.
* The only way to change the period (apart from changing the PWM input clock)
@@ -141,7 +124,7 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned int ncfg;
bool period_same = false;
- ncfg = sti_pwm_count_configured(chip);
+ ncfg = hweight_long(pc->configured);
if (ncfg)
period_same = (period_ns == pwm_get_period(cur));
@@ -197,6 +180,7 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
ret = regmap_field_write(pc->pwm_int_en, 0);
+ set_bit(pwm->hwpwm, &pc->configured);
pc->cur = pwm;
dev_dbg(dev, "prescale:%u, period:%i, duty:%i, pwmvalx:%u\n",
@@ -254,10 +238,18 @@ static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
mutex_unlock(&pc->sti_pwm_lock);
}
+static void sti_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
+
+ clear_bit(pwm->hwpwm, &pc->configured);
+}
+
static const struct pwm_ops sti_pwm_ops = {
.config = sti_pwm_config,
.enable = sti_pwm_enable,
.disable = sti_pwm_disable,
+ .free = sti_pwm_free,
.owner = THIS_MODULE,
};
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
new file mode 100644
index 000000000000..cd9dde563018
--- /dev/null
+++ b/drivers/pwm/pwm-sun4i.c
@@ -0,0 +1,366 @@
+/*
+ * Driver for Allwinner sun4i Pulse Width Modulation Controller
+ *
+ * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+#define PWM_CTRL_REG 0x0
+
+#define PWM_CH_PRD_BASE 0x4
+#define PWM_CH_PRD_OFFSET 0x4
+#define PWM_CH_PRD(ch) (PWM_CH_PRD_BASE + PWM_CH_PRD_OFFSET * (ch))
+
+#define PWMCH_OFFSET 15
+#define PWM_PRESCAL_MASK GENMASK(3, 0)
+#define PWM_PRESCAL_OFF 0
+#define PWM_EN BIT(4)
+#define PWM_ACT_STATE BIT(5)
+#define PWM_CLK_GATING BIT(6)
+#define PWM_MODE BIT(7)
+#define PWM_PULSE BIT(8)
+#define PWM_BYPASS BIT(9)
+
+#define PWM_RDY_BASE 28
+#define PWM_RDY_OFFSET 1
+#define PWM_RDY(ch) BIT(PWM_RDY_BASE + PWM_RDY_OFFSET * (ch))
+
+#define PWM_PRD(prd) (((prd) - 1) << 16)
+#define PWM_PRD_MASK GENMASK(15, 0)
+
+#define PWM_DTY_MASK GENMASK(15, 0)
+
+#define BIT_CH(bit, chan) ((bit) << ((chan) * PWMCH_OFFSET))
+
+static const u32 prescaler_table[] = {
+ 120,
+ 180,
+ 240,
+ 360,
+ 480,
+ 0,
+ 0,
+ 0,
+ 12000,
+ 24000,
+ 36000,
+ 48000,
+ 72000,
+ 0,
+ 0,
+ 0, /* Actually 1 but tested separately */
+};
+
+struct sun4i_pwm_data {
+ bool has_prescaler_bypass;
+ bool has_rdy;
+};
+
+struct sun4i_pwm_chip {
+ struct pwm_chip chip;
+ struct clk *clk;
+ void __iomem *base;
+ spinlock_t ctrl_lock;
+ const struct sun4i_pwm_data *data;
+};
+
+static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip)
+{
+ return container_of(chip, struct sun4i_pwm_chip, chip);
+}
+
+static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *chip,
+ unsigned long offset)
+{
+ return readl(chip->base + offset);
+}
+
+static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
+ u32 val, unsigned long offset)
+{
+ writel(val, chip->base + offset);
+}
+
+static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+ u32 prd, dty, val, clk_gate;
+ u64 clk_rate, div = 0;
+ unsigned int prescaler = 0;
+ int err;
+
+ clk_rate = clk_get_rate(sun4i_pwm->clk);
+
+ if (sun4i_pwm->data->has_prescaler_bypass) {
+ /* First, test without any prescaler when available */
+ prescaler = PWM_PRESCAL_MASK;
+ /*
+ * When not using any prescaler, the clock period in nanoseconds
+ * is not an integer so round it half up instead of
+ * truncating to get less surprising values.
+ */
+ div = clk_rate * period_ns + NSEC_PER_SEC/2;
+ do_div(div, NSEC_PER_SEC);
+ if (div - 1 > PWM_PRD_MASK)
+ prescaler = 0;
+ }
+
+ if (prescaler == 0) {
+ /* Go up from the first divider */
+ for (prescaler = 0; prescaler < PWM_PRESCAL_MASK; prescaler++) {
+ if (!prescaler_table[prescaler])
+ continue;
+ div = clk_rate;
+ do_div(div, prescaler_table[prescaler]);
+ div = div * period_ns;
+ do_div(div, NSEC_PER_SEC);
+ if (div - 1 <= PWM_PRD_MASK)
+ break;
+ }
+
+ if (div - 1 > PWM_PRD_MASK) {
+ dev_err(chip->dev, "period exceeds the maximum value\n");
+ return -EINVAL;
+ }
+ }
+
+ prd = div;
+ div *= duty_ns;
+ do_div(div, period_ns);
+ dty = div;
+
+ err = clk_prepare_enable(sun4i_pwm->clk);
+ if (err) {
+ dev_err(chip->dev, "failed to enable PWM clock\n");
+ return err;
+ }
+
+ spin_lock(&sun4i_pwm->ctrl_lock);
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+
+ if (sun4i_pwm->data->has_rdy && (val & PWM_RDY(pwm->hwpwm))) {
+ spin_unlock(&sun4i_pwm->ctrl_lock);
+ clk_disable_unprepare(sun4i_pwm->clk);
+ return -EBUSY;
+ }
+
+ clk_gate = val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+ if (clk_gate) {
+ val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+ }
+
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+ val &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
+ val |= BIT_CH(prescaler, pwm->hwpwm);
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+
+ val = (dty & PWM_DTY_MASK) | PWM_PRD(prd);
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
+
+ if (clk_gate) {
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+ val |= clk_gate;
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+ }
+
+ spin_unlock(&sun4i_pwm->ctrl_lock);
+ clk_disable_unprepare(sun4i_pwm->clk);
+
+ return 0;
+}
+
+static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(sun4i_pwm->clk);
+ if (ret) {
+ dev_err(chip->dev, "failed to enable PWM clock\n");
+ return ret;
+ }
+
+ spin_lock(&sun4i_pwm->ctrl_lock);
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+
+ if (polarity != PWM_POLARITY_NORMAL)
+ val &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+ else
+ val |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+
+ spin_unlock(&sun4i_pwm->ctrl_lock);
+ clk_disable_unprepare(sun4i_pwm->clk);
+
+ return 0;
+}
+
+static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(sun4i_pwm->clk);
+ if (ret) {
+ dev_err(chip->dev, "failed to enable PWM clock\n");
+ return ret;
+ }
+
+ spin_lock(&sun4i_pwm->ctrl_lock);
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+ val |= BIT_CH(PWM_EN, pwm->hwpwm);
+ val |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+ spin_unlock(&sun4i_pwm->ctrl_lock);
+
+ return 0;
+}
+
+static void sun4i_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+ u32 val;
+
+ spin_lock(&sun4i_pwm->ctrl_lock);
+ val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+ val &= ~BIT_CH(PWM_EN, pwm->hwpwm);
+ val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+ sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+ spin_unlock(&sun4i_pwm->ctrl_lock);
+
+ clk_disable_unprepare(sun4i_pwm->clk);
+}
+
+static const struct pwm_ops sun4i_pwm_ops = {
+ .config = sun4i_pwm_config,
+ .set_polarity = sun4i_pwm_set_polarity,
+ .enable = sun4i_pwm_enable,
+ .disable = sun4i_pwm_disable,
+ .owner = THIS_MODULE,
+};
+
+static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
+ .has_prescaler_bypass = false,
+ .has_rdy = false,
+};
+
+static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
+ .has_prescaler_bypass = true,
+ .has_rdy = true,
+};
+
+static const struct of_device_id sun4i_pwm_dt_ids[] = {
+ {
+ .compatible = "allwinner,sun4i-a10-pwm",
+ .data = &sun4i_pwm_data_a10,
+ }, {
+ .compatible = "allwinner,sun7i-a20-pwm",
+ .data = &sun4i_pwm_data_a20,
+ }, {
+ /* sentinel */
+ },
+};
+MODULE_DEVICE_TABLE(of, sun4i_pwm_dt_ids);
+
+static int sun4i_pwm_probe(struct platform_device *pdev)
+{
+ struct sun4i_pwm_chip *pwm;
+ struct resource *res;
+ u32 val;
+ int i, ret;
+ const struct of_device_id *match;
+
+ match = of_match_device(sun4i_pwm_dt_ids, &pdev->dev);
+
+ pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+ if (!pwm)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pwm->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pwm->base))
+ return PTR_ERR(pwm->base);
+
+ pwm->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(pwm->clk))
+ return PTR_ERR(pwm->clk);
+
+ pwm->chip.dev = &pdev->dev;
+ pwm->chip.ops = &sun4i_pwm_ops;
+ pwm->chip.base = -1;
+ pwm->chip.npwm = 2;
+ pwm->chip.can_sleep = true;
+ pwm->chip.of_xlate = of_pwm_xlate_with_flags;
+ pwm->chip.of_pwm_n_cells = 3;
+ pwm->data = match->data;
+
+ spin_lock_init(&pwm->ctrl_lock);
+
+ ret = pwmchip_add(&pwm->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, pwm);
+
+ ret = clk_prepare_enable(pwm->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable PWM clock\n");
+ goto clk_error;
+ }
+
+ val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
+ for (i = 0; i < pwm->chip.npwm; i++)
+ if (!(val & BIT_CH(PWM_ACT_STATE, i)))
+ pwm->chip.pwms[i].polarity = PWM_POLARITY_INVERSED;
+ clk_disable_unprepare(pwm->clk);
+
+ return 0;
+
+clk_error:
+ pwmchip_remove(&pwm->chip);
+ return ret;
+}
+
+static int sun4i_pwm_remove(struct platform_device *pdev)
+{
+ struct sun4i_pwm_chip *pwm = platform_get_drvdata(pdev);
+
+ return pwmchip_remove(&pwm->chip);
+}
+
+static struct platform_driver sun4i_pwm_driver = {
+ .driver = {
+ .name = "sun4i-pwm",
+ .of_match_table = sun4i_pwm_dt_ids,
+ },
+ .probe = sun4i_pwm_probe,
+ .remove = sun4i_pwm_remove,
+};
+module_platform_driver(sun4i_pwm_driver);
+
+MODULE_ALIAS("platform:sun4i-pwm");
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
+MODULE_DESCRIPTION("Allwinner sun4i PWM driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 5b97cae5423a..cabd7d8e05cc 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -87,7 +87,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* cycles at the PWM clock rate will take period_ns nanoseconds.
*/
rate = clk_get_rate(pc->clk) >> PWM_DUTY_WIDTH;
- hz = 1000000000ul / period_ns;
+ hz = NSEC_PER_SEC / period_ns;
rate = (rate + (hz / 2)) / hz;
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c
index f64c5decb747..47295940a868 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -815,8 +815,7 @@ struct dma_async_tx_descriptor *tsi721_prep_rio_sg(struct dma_chan *dchan,
return txd;
}
-static int tsi721_device_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
- unsigned long arg)
+static int tsi721_terminate_all(struct dma_chan *dchan)
{
struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan);
struct tsi721_tx_desc *desc, *_d;
@@ -825,9 +824,6 @@ static int tsi721_device_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
dev_dbg(dchan->device->dev, "%s: Entry\n", __func__);
- if (cmd != DMA_TERMINATE_ALL)
- return -ENOSYS;
-
spin_lock_bh(&bdma_chan->lock);
bdma_chan->active = false;
@@ -901,7 +897,7 @@ int tsi721_register_dma(struct tsi721_device *priv)
mport->dma.device_tx_status = tsi721_tx_status;
mport->dma.device_issue_pending = tsi721_issue_pending;
mport->dma.device_prep_slave_sg = tsi721_prep_rio_sg;
- mport->dma.device_control = tsi721_device_control;
+ mport->dma.device_terminate_all = tsi721_terminate_all;
err = dma_async_device_register(&mport->dma);
if (err)
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
index e8647f7cf25e..00c5cc3d9546 100644
--- a/drivers/regulator/qcom_rpm-regulator.c
+++ b/drivers/regulator/qcom_rpm-regulator.c
@@ -205,6 +205,7 @@ static int rpm_reg_write(struct qcom_rpm_reg *vreg,
vreg->val[req->word] |= value << req->shift;
return qcom_rpm_write(vreg->rpm,
+ QCOM_RPM_ACTIVE_STATE,
vreg->resource,
vreg->val,
vreg->parts->request_len);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 3bc9ddbe5cf7..cedb41c95dae 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -801,6 +801,96 @@ config RTC_DRV_DS1553
This driver can also be built as a module. If so, the module
will be called rtc-ds1553.
+config RTC_DRV_DS1685_FAMILY
+ tristate "Dallas/Maxim DS1685 Family"
+ help
+ If you say yes here you get support for the Dallas/Maxim DS1685
+ family of real time chips. This family includes the DS1685/DS1687,
+ DS1689/DS1693, DS17285/DS17287, DS17485/DS17487, and
+ DS17885/DS17887 chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds1685.
+
+choice
+ prompt "Subtype"
+ depends on RTC_DRV_DS1685_FAMILY
+ default RTC_DRV_DS1685
+
+config RTC_DRV_DS1685
+ bool "DS1685/DS1687"
+ help
+ This enables support for the Dallas/Maxim DS1685/DS1687 real time
+ clock chip.
+
+ This chip is commonly found in SGI O2 (IP32) and SGI Octane (IP30)
+ systems, as well as EPPC-405-UC modules by electronic system design
+ GmbH.
+
+config RTC_DRV_DS1689
+ bool "DS1689/DS1693"
+ help
+ This enables support for the Dallas/Maxim DS1689/DS1693 real time
+ clock chip.
+
+ This is an older RTC chip, supplanted by the DS1685/DS1687 above,
+ which supports a few minor features such as Vcc, Vbat, and Power
+ Cycle counters, plus a customer-specific, 8-byte ROM/Serial number.
+
+ It also works for the even older DS1688/DS1691 RTC chips, which are
+ virtually the same and carry the same model number. Both chips
+ have 114 bytes of user NVRAM.
+
+config RTC_DRV_DS17285
+ bool "DS17285/DS17287"
+ help
+ This enables support for the Dallas/Maxim DS17285/DS17287 real time
+ clock chip.
+
+ This chip features 2kb of extended NV-SRAM. It may possibly be
+ found in some SGI O2 systems (rare).
+
+config RTC_DRV_DS17485
+ bool "DS17485/DS17487"
+ help
+ This enables support for the Dallas/Maxim DS17485/DS17487 real time
+ clock chip.
+
+ This chip features 4kb of extended NV-SRAM.
+
+config RTC_DRV_DS17885
+ bool "DS17885/DS17887"
+ help
+ This enables support for the Dallas/Maxim DS17885/DS17887 real time
+ clock chip.
+
+ This chip features 8kb of extended NV-SRAM.
+
+endchoice
+
+config RTC_DS1685_PROC_REGS
+ bool "Display register values in /proc"
+ depends on RTC_DRV_DS1685_FAMILY && PROC_FS
+ help
+ Enable this to display a readout of all of the RTC registers in
+ /proc/drivers/rtc. Keep in mind that this can potentially lead
+ to lost interrupts, as reading Control Register C will clear
+ all pending IRQ flags.
+
+ Unless you are debugging this driver, choose N.
+
+config RTC_DS1685_SYSFS_REGS
+ bool "SysFS access to RTC register bits"
+ depends on RTC_DRV_DS1685_FAMILY && SYSFS
+ help
+ Enable this to provide access to the RTC control register bits
+ in /sys. Some of the bits are read-write, others are read-only.
+
+ Keep in mind that reading Control C's bits automatically clears
+ all pending IRQ flags - this can cause lost interrupts.
+
+ If you know that you need access to these bits, choose Y, Else N.
+
config RTC_DRV_DS1742
tristate "Maxim/Dallas DS1742/1743"
depends on HAS_IOMEM
@@ -1152,34 +1242,6 @@ config RTC_DRV_AT91SAM9
probably want to use the real RTC block instead of the "RTT as an
RTC" driver.
-config RTC_DRV_AT91SAM9_RTT
- int
- range 0 1
- default 0
- depends on RTC_DRV_AT91SAM9
- help
- This option is only relevant for legacy board support and
- won't be used when booting a DT board.
-
- More than one RTT module is available. You can choose which
- one will be used as an RTC. The default of zero is normally
- OK to use, though some systems use that for non-RTC purposes.
-
-config RTC_DRV_AT91SAM9_GPBR
- int
- range 0 3
- default 0
- prompt "Backup Register Number"
- depends on RTC_DRV_AT91SAM9
- help
- This option is only relevant for legacy board support and
- won't be used when booting a DT board.
-
- The RTC driver needs to use one of the General Purpose Backup
- Registers (GPBRs) as well as the RTT. You can choose which one
- will be used. The default of zero is normally OK to use, but
- on some systems other software needs to use that register.
-
config RTC_DRV_AU1XXX
tristate "Au1xxx Counter0 RTC support"
depends on MIPS_ALCHEMY
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 99ded8b75e95..69c87062b098 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_RTC_DRV_DS1390) += rtc-ds1390.o
obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
+obj-$(CONFIG_RTC_DRV_DS1685_FAMILY) += rtc-ds1685.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o
obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c
new file mode 100644
index 000000000000..8c3bfcb115b7
--- /dev/null
+++ b/drivers/rtc/rtc-ds1685.c
@@ -0,0 +1,2252 @@
+/*
+ * An rtc driver for the Dallas/Maxim DS1685/DS1687 and related real-time
+ * chips.
+ *
+ * Copyright (C) 2011-2014 Joshua Kinard <kumba@gentoo.org>.
+ * Copyright (C) 2009 Matthias Fuchs <matthias.fuchs@esd-electronics.com>.
+ *
+ * References:
+ * DS1685/DS1687 3V/5V Real-Time Clocks, 19-5215, Rev 4/10.
+ * DS17x85/DS17x87 3V/5V Real-Time Clocks, 19-5222, Rev 4/10.
+ * DS1689/DS1693 3V/5V Serialized Real-Time Clocks, Rev 112105.
+ * Application Note 90, Using the Multiplex Bus RTC Extended Features.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/workqueue.h>
+
+#include <linux/rtc/ds1685.h>
+
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif
+
+#define DRV_VERSION "0.42.0"
+
+
+/* ----------------------------------------------------------------------- */
+/* Standard read/write functions if platform does not provide overrides */
+
+/**
+ * ds1685_read - read a value from an rtc register.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @reg: the register address to read.
+ */
+static u8
+ds1685_read(struct ds1685_priv *rtc, int reg)
+{
+ return readb((u8 __iomem *)rtc->regs +
+ (reg * rtc->regstep));
+}
+
+/**
+ * ds1685_write - write a value to an rtc register.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @reg: the register address to write.
+ * @value: value to write to the register.
+ */
+static void
+ds1685_write(struct ds1685_priv *rtc, int reg, u8 value)
+{
+ writeb(value, ((u8 __iomem *)rtc->regs +
+ (reg * rtc->regstep)));
+}
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* Inlined functions */
+
+/**
+ * ds1685_rtc_bcd2bin - bcd2bin wrapper in case platform doesn't support BCD.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @val: u8 time value to consider converting.
+ * @bcd_mask: u8 mask value if BCD mode is used.
+ * @bin_mask: u8 mask value if BIN mode is used.
+ *
+ * Returns the value, converted to BIN if originally in BCD and bcd_mode TRUE.
+ */
+static inline u8
+ds1685_rtc_bcd2bin(struct ds1685_priv *rtc, u8 val, u8 bcd_mask, u8 bin_mask)
+{
+ if (rtc->bcd_mode)
+ return (bcd2bin(val) & bcd_mask);
+
+ return (val & bin_mask);
+}
+
+/**
+ * ds1685_rtc_bin2bcd - bin2bcd wrapper in case platform doesn't support BCD.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @val: u8 time value to consider converting.
+ * @bin_mask: u8 mask value if BIN mode is used.
+ * @bcd_mask: u8 mask value if BCD mode is used.
+ *
+ * Returns the value, converted to BCD if originally in BIN and bcd_mode TRUE.
+ */
+static inline u8
+ds1685_rtc_bin2bcd(struct ds1685_priv *rtc, u8 val, u8 bin_mask, u8 bcd_mask)
+{
+ if (rtc->bcd_mode)
+ return (bin2bcd(val) & bcd_mask);
+
+ return (val & bin_mask);
+}
+
+/**
+ * ds1685_rtc_switch_to_bank0 - switch the rtc to bank 0.
+ * @rtc: pointer to the ds1685 rtc structure.
+ */
+static inline void
+ds1685_rtc_switch_to_bank0(struct ds1685_priv *rtc)
+{
+ rtc->write(rtc, RTC_CTRL_A,
+ (rtc->read(rtc, RTC_CTRL_A) & ~(RTC_CTRL_A_DV0)));
+}
+
+/**
+ * ds1685_rtc_switch_to_bank1 - switch the rtc to bank 1.
+ * @rtc: pointer to the ds1685 rtc structure.
+ */
+static inline void
+ds1685_rtc_switch_to_bank1(struct ds1685_priv *rtc)
+{
+ rtc->write(rtc, RTC_CTRL_A,
+ (rtc->read(rtc, RTC_CTRL_A) | RTC_CTRL_A_DV0));
+}
+
+/**
+ * ds1685_rtc_begin_data_access - prepare the rtc for data access.
+ * @rtc: pointer to the ds1685 rtc structure.
+ *
+ * This takes several steps to prepare the rtc for access to get/set time
+ * and alarm values from the rtc registers:
+ * - Sets the SET bit in Control Register B.
+ * - Reads Ext Control Register 4A and checks the INCR bit.
+ * - If INCR is active, a short delay is added before Ext Control Register 4A
+ * is read again in a loop until INCR is inactive.
+ * - Switches the rtc to bank 1. This allows access to all relevant
+ * data for normal rtc operation, as bank 0 contains only the nvram.
+ */
+static inline void
+ds1685_rtc_begin_data_access(struct ds1685_priv *rtc)
+{
+ /* Set the SET bit in Ctrl B */
+ rtc->write(rtc, RTC_CTRL_B,
+ (rtc->read(rtc, RTC_CTRL_B) | RTC_CTRL_B_SET));
+
+ /* Read Ext Ctrl 4A and check the INCR bit to avoid a lockout. */
+ while (rtc->read(rtc, RTC_EXT_CTRL_4A) & RTC_CTRL_4A_INCR)
+ cpu_relax();
+
+ /* Switch to Bank 1 */
+ ds1685_rtc_switch_to_bank1(rtc);
+}
+
+/**
+ * ds1685_rtc_end_data_access - end data access on the rtc.
+ * @rtc: pointer to the ds1685 rtc structure.
+ *
+ * This ends what was started by ds1685_rtc_begin_data_access:
+ * - Switches the rtc back to bank 0.
+ * - Clears the SET bit in Control Register B.
+ */
+static inline void
+ds1685_rtc_end_data_access(struct ds1685_priv *rtc)
+{
+ /* Switch back to Bank 0 */
+ ds1685_rtc_switch_to_bank1(rtc);
+
+ /* Clear the SET bit in Ctrl B */
+ rtc->write(rtc, RTC_CTRL_B,
+ (rtc->read(rtc, RTC_CTRL_B) & ~(RTC_CTRL_B_SET)));
+}
+
+/**
+ * ds1685_rtc_begin_ctrl_access - prepare the rtc for ctrl access.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @flags: irq flags variable for spin_lock_irqsave.
+ *
+ * This takes several steps to prepare the rtc for access to read just the
+ * control registers:
+ * - Sets a spinlock on the rtc IRQ.
+ * - Switches the rtc to bank 1. This allows access to the two extended
+ * control registers.
+ *
+ * Only use this where you are certain another lock will not be held.
+ */
+static inline void
+ds1685_rtc_begin_ctrl_access(struct ds1685_priv *rtc, unsigned long flags)
+{
+ spin_lock_irqsave(&rtc->lock, flags);
+ ds1685_rtc_switch_to_bank1(rtc);
+}
+
+/**
+ * ds1685_rtc_end_ctrl_access - end ctrl access on the rtc.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @flags: irq flags variable for spin_unlock_irqrestore.
+ *
+ * This ends what was started by ds1685_rtc_begin_ctrl_access:
+ * - Switches the rtc back to bank 0.
+ * - Unsets the spinlock on the rtc IRQ.
+ */
+static inline void
+ds1685_rtc_end_ctrl_access(struct ds1685_priv *rtc, unsigned long flags)
+{
+ ds1685_rtc_switch_to_bank0(rtc);
+ spin_unlock_irqrestore(&rtc->lock, flags);
+}
+
+/**
+ * ds1685_rtc_get_ssn - retrieve the silicon serial number.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @ssn: u8 array to hold the bits of the silicon serial number.
+ *
+ * This number starts at 0x40, and is 8-bytes long, ending at 0x47. The
+ * first byte is the model number, the next six bytes are the serial number
+ * digits, and the final byte is a CRC check byte. Together, they form the
+ * silicon serial number.
+ *
+ * These values are stored in bank1, so ds1685_rtc_switch_to_bank1 must be
+ * called first before calling this function, else data will be read out of
+ * the bank0 NVRAM. Be sure to call ds1685_rtc_switch_to_bank0 when done.
+ */
+static inline void
+ds1685_rtc_get_ssn(struct ds1685_priv *rtc, u8 *ssn)
+{
+ ssn[0] = rtc->read(rtc, RTC_BANK1_SSN_MODEL);
+ ssn[1] = rtc->read(rtc, RTC_BANK1_SSN_BYTE_1);
+ ssn[2] = rtc->read(rtc, RTC_BANK1_SSN_BYTE_2);
+ ssn[3] = rtc->read(rtc, RTC_BANK1_SSN_BYTE_3);
+ ssn[4] = rtc->read(rtc, RTC_BANK1_SSN_BYTE_4);
+ ssn[5] = rtc->read(rtc, RTC_BANK1_SSN_BYTE_5);
+ ssn[6] = rtc->read(rtc, RTC_BANK1_SSN_BYTE_6);
+ ssn[7] = rtc->read(rtc, RTC_BANK1_SSN_CRC);
+}
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* Read/Set Time & Alarm functions */
+
+/**
+ * ds1685_rtc_read_time - reads the time registers.
+ * @dev: pointer to device structure.
+ * @tm: pointer to rtc_time structure.
+ */
+static int
+ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ctrlb, century;
+ u8 seconds, minutes, hours, wday, mday, month, years;
+
+ /* Fetch the time info from the RTC registers. */
+ ds1685_rtc_begin_data_access(rtc);
+ seconds = rtc->read(rtc, RTC_SECS);
+ minutes = rtc->read(rtc, RTC_MINS);
+ hours = rtc->read(rtc, RTC_HRS);
+ wday = rtc->read(rtc, RTC_WDAY);
+ mday = rtc->read(rtc, RTC_MDAY);
+ month = rtc->read(rtc, RTC_MONTH);
+ years = rtc->read(rtc, RTC_YEAR);
+ century = rtc->read(rtc, RTC_CENTURY);
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ ds1685_rtc_end_data_access(rtc);
+
+ /* bcd2bin if needed, perform fixups, and store to rtc_time. */
+ years = ds1685_rtc_bcd2bin(rtc, years, RTC_YEAR_BCD_MASK,
+ RTC_YEAR_BIN_MASK);
+ century = ds1685_rtc_bcd2bin(rtc, century, RTC_CENTURY_MASK,
+ RTC_CENTURY_MASK);
+ tm->tm_sec = ds1685_rtc_bcd2bin(rtc, seconds, RTC_SECS_BCD_MASK,
+ RTC_SECS_BIN_MASK);
+ tm->tm_min = ds1685_rtc_bcd2bin(rtc, minutes, RTC_MINS_BCD_MASK,
+ RTC_MINS_BIN_MASK);
+ tm->tm_hour = ds1685_rtc_bcd2bin(rtc, hours, RTC_HRS_24_BCD_MASK,
+ RTC_HRS_24_BIN_MASK);
+ tm->tm_wday = (ds1685_rtc_bcd2bin(rtc, wday, RTC_WDAY_MASK,
+ RTC_WDAY_MASK) - 1);
+ tm->tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK,
+ RTC_MDAY_BIN_MASK);
+ tm->tm_mon = (ds1685_rtc_bcd2bin(rtc, month, RTC_MONTH_BCD_MASK,
+ RTC_MONTH_BIN_MASK) - 1);
+ tm->tm_year = ((years + (century * 100)) - 1900);
+ tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+ tm->tm_isdst = 0; /* RTC has hardcoded timezone, so don't use. */
+
+ return rtc_valid_tm(tm);
+}
+
+/**
+ * ds1685_rtc_set_time - sets the time registers.
+ * @dev: pointer to device structure.
+ * @tm: pointer to rtc_time structure.
+ */
+static int
+ds1685_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ctrlb, seconds, minutes, hours, wday, mday, month, years, century;
+
+ /* Fetch the time info from rtc_time. */
+ seconds = ds1685_rtc_bin2bcd(rtc, tm->tm_sec, RTC_SECS_BIN_MASK,
+ RTC_SECS_BCD_MASK);
+ minutes = ds1685_rtc_bin2bcd(rtc, tm->tm_min, RTC_MINS_BIN_MASK,
+ RTC_MINS_BCD_MASK);
+ hours = ds1685_rtc_bin2bcd(rtc, tm->tm_hour, RTC_HRS_24_BIN_MASK,
+ RTC_HRS_24_BCD_MASK);
+ wday = ds1685_rtc_bin2bcd(rtc, (tm->tm_wday + 1), RTC_WDAY_MASK,
+ RTC_WDAY_MASK);
+ mday = ds1685_rtc_bin2bcd(rtc, tm->tm_mday, RTC_MDAY_BIN_MASK,
+ RTC_MDAY_BCD_MASK);
+ month = ds1685_rtc_bin2bcd(rtc, (tm->tm_mon + 1), RTC_MONTH_BIN_MASK,
+ RTC_MONTH_BCD_MASK);
+ years = ds1685_rtc_bin2bcd(rtc, (tm->tm_year % 100),
+ RTC_YEAR_BIN_MASK, RTC_YEAR_BCD_MASK);
+ century = ds1685_rtc_bin2bcd(rtc, ((tm->tm_year + 1900) / 100),
+ RTC_CENTURY_MASK, RTC_CENTURY_MASK);
+
+ /*
+ * Perform Sanity Checks:
+ * - Months: !> 12, Month Day != 0.
+ * - Month Day !> Max days in current month.
+ * - Hours !>= 24, Mins !>= 60, Secs !>= 60, & Weekday !> 7.
+ */
+ if ((tm->tm_mon > 11) || (mday == 0))
+ return -EDOM;
+
+ if (tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year))
+ return -EDOM;
+
+ if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) ||
+ (tm->tm_sec >= 60) || (wday > 7))
+ return -EDOM;
+
+ /*
+ * Set the data mode to use and store the time values in the
+ * RTC registers.
+ */
+ ds1685_rtc_begin_data_access(rtc);
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ if (rtc->bcd_mode)
+ ctrlb &= ~(RTC_CTRL_B_DM);
+ else
+ ctrlb |= RTC_CTRL_B_DM;
+ rtc->write(rtc, RTC_CTRL_B, ctrlb);
+ rtc->write(rtc, RTC_SECS, seconds);
+ rtc->write(rtc, RTC_MINS, minutes);
+ rtc->write(rtc, RTC_HRS, hours);
+ rtc->write(rtc, RTC_WDAY, wday);
+ rtc->write(rtc, RTC_MDAY, mday);
+ rtc->write(rtc, RTC_MONTH, month);
+ rtc->write(rtc, RTC_YEAR, years);
+ rtc->write(rtc, RTC_CENTURY, century);
+ ds1685_rtc_end_data_access(rtc);
+
+ return 0;
+}
+
+/**
+ * ds1685_rtc_read_alarm - reads the alarm registers.
+ * @dev: pointer to device structure.
+ * @alrm: pointer to rtc_wkalrm structure.
+ *
+ * There are three primary alarm registers: seconds, minutes, and hours.
+ * A fourth alarm register for the month date is also available in bank1 for
+ * kickstart/wakeup features. The DS1685/DS1687 manual states that a
+ * "don't care" value ranging from 0xc0 to 0xff may be written into one or
+ * more of the three alarm bytes to act as a wildcard value. The fourth
+ * byte doesn't support a "don't care" value.
+ */
+static int
+ds1685_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 seconds, minutes, hours, mday, ctrlb, ctrlc;
+
+ /* Fetch the alarm info from the RTC alarm registers. */
+ ds1685_rtc_begin_data_access(rtc);
+ seconds = rtc->read(rtc, RTC_SECS_ALARM);
+ minutes = rtc->read(rtc, RTC_MINS_ALARM);
+ hours = rtc->read(rtc, RTC_HRS_ALARM);
+ mday = rtc->read(rtc, RTC_MDAY_ALARM);
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ ctrlc = rtc->read(rtc, RTC_CTRL_C);
+ ds1685_rtc_end_data_access(rtc);
+
+ /* Check month date. */
+ if (!(mday >= 1) && (mday <= 31))
+ return -EDOM;
+
+ /*
+ * Check the three alarm bytes.
+ *
+ * The Linux RTC system doesn't support the "don't care" capability
+ * of this RTC chip. We check for it anyways in case support is
+ * added in the future.
+ */
+ if (unlikely((seconds >= 0xc0) && (seconds <= 0xff)))
+ alrm->time.tm_sec = -1;
+ else
+ alrm->time.tm_sec = ds1685_rtc_bcd2bin(rtc, seconds,
+ RTC_SECS_BCD_MASK,
+ RTC_SECS_BIN_MASK);
+
+ if (unlikely((minutes >= 0xc0) && (minutes <= 0xff)))
+ alrm->time.tm_min = -1;
+ else
+ alrm->time.tm_min = ds1685_rtc_bcd2bin(rtc, minutes,
+ RTC_MINS_BCD_MASK,
+ RTC_MINS_BIN_MASK);
+
+ if (unlikely((hours >= 0xc0) && (hours <= 0xff)))
+ alrm->time.tm_hour = -1;
+ else
+ alrm->time.tm_hour = ds1685_rtc_bcd2bin(rtc, hours,
+ RTC_HRS_24_BCD_MASK,
+ RTC_HRS_24_BIN_MASK);
+
+ /* Write the data to rtc_wkalrm. */
+ alrm->time.tm_mday = ds1685_rtc_bcd2bin(rtc, mday, RTC_MDAY_BCD_MASK,
+ RTC_MDAY_BIN_MASK);
+ alrm->time.tm_mon = -1;
+ alrm->time.tm_year = -1;
+ alrm->time.tm_wday = -1;
+ alrm->time.tm_yday = -1;
+ alrm->time.tm_isdst = -1;
+ alrm->enabled = !!(ctrlb & RTC_CTRL_B_AIE);
+ alrm->pending = !!(ctrlc & RTC_CTRL_C_AF);
+
+ return 0;
+}
+
+/**
+ * ds1685_rtc_set_alarm - sets the alarm in registers.
+ * @dev: pointer to device structure.
+ * @alrm: pointer to rtc_wkalrm structure.
+ */
+static int
+ds1685_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ctrlb, seconds, minutes, hours, mday;
+
+ /* Fetch the alarm info and convert to BCD. */
+ seconds = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_sec,
+ RTC_SECS_BIN_MASK,
+ RTC_SECS_BCD_MASK);
+ minutes = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_min,
+ RTC_MINS_BIN_MASK,
+ RTC_MINS_BCD_MASK);
+ hours = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_hour,
+ RTC_HRS_24_BIN_MASK,
+ RTC_HRS_24_BCD_MASK);
+ mday = ds1685_rtc_bin2bcd(rtc, alrm->time.tm_mday,
+ RTC_MDAY_BIN_MASK,
+ RTC_MDAY_BCD_MASK);
+
+ /* Check the month date for validity. */
+ if (!(mday >= 1) && (mday <= 31))
+ return -EDOM;
+
+ /*
+ * Check the three alarm bytes.
+ *
+ * The Linux RTC system doesn't support the "don't care" capability
+ * of this RTC chip because rtc_valid_tm tries to validate every
+ * field, and we only support four fields. We put the support
+ * here anyways for the future.
+ */
+ if (unlikely((seconds >= 0xc0) && (seconds <= 0xff)))
+ seconds = 0xff;
+
+ if (unlikely((minutes >= 0xc0) && (minutes <= 0xff)))
+ minutes = 0xff;
+
+ if (unlikely((hours >= 0xc0) && (hours <= 0xff)))
+ hours = 0xff;
+
+ alrm->time.tm_mon = -1;
+ alrm->time.tm_year = -1;
+ alrm->time.tm_wday = -1;
+ alrm->time.tm_yday = -1;
+ alrm->time.tm_isdst = -1;
+
+ /* Disable the alarm interrupt first. */
+ ds1685_rtc_begin_data_access(rtc);
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ rtc->write(rtc, RTC_CTRL_B, (ctrlb & ~(RTC_CTRL_B_AIE)));
+
+ /* Read ctrlc to clear RTC_CTRL_C_AF. */
+ rtc->read(rtc, RTC_CTRL_C);
+
+ /*
+ * Set the data mode to use and store the time values in the
+ * RTC registers.
+ */
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ if (rtc->bcd_mode)
+ ctrlb &= ~(RTC_CTRL_B_DM);
+ else
+ ctrlb |= RTC_CTRL_B_DM;
+ rtc->write(rtc, RTC_CTRL_B, ctrlb);
+ rtc->write(rtc, RTC_SECS_ALARM, seconds);
+ rtc->write(rtc, RTC_MINS_ALARM, minutes);
+ rtc->write(rtc, RTC_HRS_ALARM, hours);
+ rtc->write(rtc, RTC_MDAY_ALARM, mday);
+
+ /* Re-enable the alarm if needed. */
+ if (alrm->enabled) {
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ ctrlb |= RTC_CTRL_B_AIE;
+ rtc->write(rtc, RTC_CTRL_B, ctrlb);
+ }
+
+ /* Done! */
+ ds1685_rtc_end_data_access(rtc);
+
+ return 0;
+}
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* /dev/rtcX Interface functions */
+
+#ifdef CONFIG_RTC_INTF_DEV
+/**
+ * ds1685_rtc_alarm_irq_enable - replaces ioctl() RTC_AIE on/off.
+ * @dev: pointer to device structure.
+ * @enabled: flag indicating whether to enable or disable.
+ */
+static int
+ds1685_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct ds1685_priv *rtc = dev_get_drvdata(dev);
+ unsigned long flags = 0;
+
+ /* Enable/disable the Alarm IRQ-Enable flag. */
+ spin_lock_irqsave(&rtc->lock, flags);
+
+ /* Flip the requisite interrupt-enable bit. */
+ if (enabled)
+ rtc->write(rtc, RTC_CTRL_B, (rtc->read(rtc, RTC_CTRL_B) |
+ RTC_CTRL_B_AIE));
+ else
+ rtc->write(rtc, RTC_CTRL_B, (rtc->read(rtc, RTC_CTRL_B) &
+ ~(RTC_CTRL_B_AIE)));
+
+ /* Read Control C to clear all the flag bits. */
+ rtc->read(rtc, RTC_CTRL_C);
+ spin_unlock_irqrestore(&rtc->lock, flags);
+
+ return 0;
+}
+#endif
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* IRQ handler & workqueue. */
+
+/**
+ * ds1685_rtc_irq_handler - IRQ handler.
+ * @irq: IRQ number.
+ * @dev_id: platform device pointer.
+ */
+static irqreturn_t
+ds1685_rtc_irq_handler(int irq, void *dev_id)
+{
+ struct platform_device *pdev = dev_id;
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ctrlb, ctrlc;
+ unsigned long events = 0;
+ u8 num_irqs = 0;
+
+ /* Abort early if the device isn't ready yet (i.e., DEBUG_SHIRQ). */
+ if (unlikely(!rtc))
+ return IRQ_HANDLED;
+
+ /* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */
+ spin_lock(&rtc->lock);
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ ctrlc = rtc->read(rtc, RTC_CTRL_C);
+
+ /* Is the IRQF bit set? */
+ if (likely(ctrlc & RTC_CTRL_C_IRQF)) {
+ /*
+ * We need to determine if it was one of the standard
+ * events: PF, AF, or UF. If so, we handle them and
+ * update the RTC core.
+ */
+ if (likely(ctrlc & RTC_CTRL_B_PAU_MASK)) {
+ events = RTC_IRQF;
+
+ /* Check for a periodic interrupt. */
+ if ((ctrlb & RTC_CTRL_B_PIE) &&
+ (ctrlc & RTC_CTRL_C_PF)) {
+ events |= RTC_PF;
+ num_irqs++;
+ }
+
+ /* Check for an alarm interrupt. */
+ if ((ctrlb & RTC_CTRL_B_AIE) &&
+ (ctrlc & RTC_CTRL_C_AF)) {
+ events |= RTC_AF;
+ num_irqs++;
+ }
+
+ /* Check for an update interrupt. */
+ if ((ctrlb & RTC_CTRL_B_UIE) &&
+ (ctrlc & RTC_CTRL_C_UF)) {
+ events |= RTC_UF;
+ num_irqs++;
+ }
+
+ rtc_update_irq(rtc->dev, num_irqs, events);
+ } else {
+ /*
+ * One of the "extended" interrupts was received that
+ * is not recognized by the RTC core. These need to
+ * be handled in task context as they can call other
+ * functions and the time spent in irq context needs
+ * to be minimized. Schedule them into a workqueue
+ * and inform the RTC core that the IRQs were handled.
+ */
+ spin_unlock(&rtc->lock);
+ schedule_work(&rtc->work);
+ rtc_update_irq(rtc->dev, 0, 0);
+ return IRQ_HANDLED;
+ }
+ }
+ spin_unlock(&rtc->lock);
+
+ return events ? IRQ_HANDLED : IRQ_NONE;
+}
+
+/**
+ * ds1685_rtc_work_queue - work queue handler.
+ * @work: work_struct containing data to work on in task context.
+ */
+static void
+ds1685_rtc_work_queue(struct work_struct *work)
+{
+ struct ds1685_priv *rtc = container_of(work,
+ struct ds1685_priv, work);
+ struct platform_device *pdev = to_platform_device(&rtc->dev->dev);
+ struct mutex *rtc_mutex = &rtc->dev->ops_lock;
+ u8 ctrl4a, ctrl4b;
+
+ mutex_lock(rtc_mutex);
+
+ ds1685_rtc_switch_to_bank1(rtc);
+ ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A);
+ ctrl4b = rtc->read(rtc, RTC_EXT_CTRL_4B);
+
+ /*
+ * Check for a kickstart interrupt. With Vcc applied, this
+ * typically means that the power button was pressed, so we
+ * begin the shutdown sequence.
+ */
+ if ((ctrl4b & RTC_CTRL_4B_KSE) && (ctrl4a & RTC_CTRL_4A_KF)) {
+ /* Briefly disable kickstarts to debounce button presses. */
+ rtc->write(rtc, RTC_EXT_CTRL_4B,
+ (rtc->read(rtc, RTC_EXT_CTRL_4B) &
+ ~(RTC_CTRL_4B_KSE)));
+
+ /* Clear the kickstart flag. */
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (ctrl4a & ~(RTC_CTRL_4A_KF)));
+
+
+ /*
+ * Sleep 500ms before re-enabling kickstarts. This allows
+ * adequate time to avoid reading signal jitter as additional
+ * button presses.
+ */
+ msleep(500);
+ rtc->write(rtc, RTC_EXT_CTRL_4B,
+ (rtc->read(rtc, RTC_EXT_CTRL_4B) |
+ RTC_CTRL_4B_KSE));
+
+ /* Call the platform pre-poweroff function. Else, shutdown. */
+ if (rtc->prepare_poweroff != NULL)
+ rtc->prepare_poweroff();
+ else
+ ds1685_rtc_poweroff(pdev);
+ }
+
+ /*
+ * Check for a wake-up interrupt. With Vcc applied, this is
+ * essentially a second alarm interrupt, except it takes into
+ * account the 'date' register in bank1 in addition to the
+ * standard three alarm registers.
+ */
+ if ((ctrl4b & RTC_CTRL_4B_WIE) && (ctrl4a & RTC_CTRL_4A_WF)) {
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (ctrl4a & ~(RTC_CTRL_4A_WF)));
+
+ /* Call the platform wake_alarm function if defined. */
+ if (rtc->wake_alarm != NULL)
+ rtc->wake_alarm();
+ else
+ dev_warn(&pdev->dev,
+ "Wake Alarm IRQ just occurred!\n");
+ }
+
+ /*
+ * Check for a ram-clear interrupt. This happens if RIE=1 and RF=0
+ * when RCE=1 in 4B. This clears all NVRAM bytes in bank0 by setting
+ * each byte to a logic 1. This has no effect on any extended
+ * NV-SRAM that might be present, nor on the time/calendar/alarm
+ * registers. After a ram-clear is completed, there is a minimum
+ * recovery time of ~150ms in which all reads/writes are locked out.
+ * NOTE: A ram-clear can still occur if RCE=1 and RIE=0. We cannot
+ * catch this scenario.
+ */
+ if ((ctrl4b & RTC_CTRL_4B_RIE) && (ctrl4a & RTC_CTRL_4A_RF)) {
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (ctrl4a & ~(RTC_CTRL_4A_RF)));
+ msleep(150);
+
+ /* Call the platform post_ram_clear function if defined. */
+ if (rtc->post_ram_clear != NULL)
+ rtc->post_ram_clear();
+ else
+ dev_warn(&pdev->dev,
+ "RAM-Clear IRQ just occurred!\n");
+ }
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ mutex_unlock(rtc_mutex);
+}
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* ProcFS interface */
+
+#ifdef CONFIG_PROC_FS
+#define NUM_REGS 6 /* Num of control registers. */
+#define NUM_BITS 8 /* Num bits per register. */
+#define NUM_SPACES 4 /* Num spaces between each bit. */
+
+/*
+ * Periodic Interrupt Rates.
+ */
+static const char *ds1685_rtc_pirq_rate[16] = {
+ "none", "3.90625ms", "7.8125ms", "0.122070ms", "0.244141ms",
+ "0.488281ms", "0.9765625ms", "1.953125ms", "3.90625ms", "7.8125ms",
+ "15.625ms", "31.25ms", "62.5ms", "125ms", "250ms", "500ms"
+};
+
+/*
+ * Square-Wave Output Frequencies.
+ */
+static const char *ds1685_rtc_sqw_freq[16] = {
+ "none", "256Hz", "128Hz", "8192Hz", "4096Hz", "2048Hz", "1024Hz",
+ "512Hz", "256Hz", "128Hz", "64Hz", "32Hz", "16Hz", "8Hz", "4Hz", "2Hz"
+};
+
+#ifdef CONFIG_RTC_DS1685_PROC_REGS
+/**
+ * ds1685_rtc_print_regs - helper function to print register values.
+ * @hex: hex byte to convert into binary bits.
+ * @dest: destination char array.
+ *
+ * This is basically a hex->binary function, just with extra spacing between
+ * the digits. It only works on 1-byte values (8 bits).
+ */
+static char*
+ds1685_rtc_print_regs(u8 hex, char *dest)
+{
+ u32 i, j;
+ char *tmp = dest;
+
+ for (i = 0; i < NUM_BITS; i++) {
+ *tmp++ = ((hex & 0x80) != 0 ? '1' : '0');
+ for (j = 0; j < NUM_SPACES; j++)
+ *tmp++ = ' ';
+ hex <<= 1;
+ }
+ *tmp++ = '\0';
+
+ return dest;
+}
+#endif
+
+/**
+ * ds1685_rtc_proc - procfs access function.
+ * @dev: pointer to device structure.
+ * @seq: pointer to seq_file structure.
+ */
+static int
+ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8];
+ char *model = '\0';
+#ifdef CONFIG_RTC_DS1685_PROC_REGS
+ char bits[NUM_REGS][(NUM_BITS * NUM_SPACES) + NUM_BITS + 1];
+#endif
+
+ /* Read all the relevant data from the control registers. */
+ ds1685_rtc_switch_to_bank1(rtc);
+ ds1685_rtc_get_ssn(rtc, ssn);
+ ctrla = rtc->read(rtc, RTC_CTRL_A);
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ ctrlc = rtc->read(rtc, RTC_CTRL_C);
+ ctrld = rtc->read(rtc, RTC_CTRL_D);
+ ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A);
+ ctrl4b = rtc->read(rtc, RTC_EXT_CTRL_4B);
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ /* Determine the RTC model. */
+ switch (ssn[0]) {
+ case RTC_MODEL_DS1685:
+ model = "DS1685/DS1687\0";
+ break;
+ case RTC_MODEL_DS1689:
+ model = "DS1689/DS1693\0";
+ break;
+ case RTC_MODEL_DS17285:
+ model = "DS17285/DS17287\0";
+ break;
+ case RTC_MODEL_DS17485:
+ model = "DS17485/DS17487\0";
+ break;
+ case RTC_MODEL_DS17885:
+ model = "DS17885/DS17887\0";
+ break;
+ default:
+ model = "Unknown\0";
+ break;
+ }
+
+ /* Print out the information. */
+ seq_printf(seq,
+ "Model\t\t: %s\n"
+ "Oscillator\t: %s\n"
+ "12/24hr\t\t: %s\n"
+ "DST\t\t: %s\n"
+ "Data mode\t: %s\n"
+ "Battery\t\t: %s\n"
+ "Aux batt\t: %s\n"
+ "Update IRQ\t: %s\n"
+ "Periodic IRQ\t: %s\n"
+ "Periodic Rate\t: %s\n"
+ "SQW Freq\t: %s\n"
+#ifdef CONFIG_RTC_DS1685_PROC_REGS
+ "Serial #\t: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"
+ "Register Status\t:\n"
+ " Ctrl A\t: UIP DV2 DV1 DV0 RS3 RS2 RS1 RS0\n"
+ "\t\t: %s\n"
+ " Ctrl B\t: SET PIE AIE UIE SQWE DM 2412 DSE\n"
+ "\t\t: %s\n"
+ " Ctrl C\t: IRQF PF AF UF --- --- --- ---\n"
+ "\t\t: %s\n"
+ " Ctrl D\t: VRT --- --- --- --- --- --- ---\n"
+ "\t\t: %s\n"
+#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
+ " Ctrl 4A\t: VRT2 INCR BME --- PAB RF WF KF\n"
+#else
+ " Ctrl 4A\t: VRT2 INCR --- --- PAB RF WF KF\n"
+#endif
+ "\t\t: %s\n"
+ " Ctrl 4B\t: ABE E32k CS RCE PRS RIE WIE KSE\n"
+ "\t\t: %s\n",
+#else
+ "Serial #\t: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+#endif
+ model,
+ ((ctrla & RTC_CTRL_A_DV1) ? "enabled" : "disabled"),
+ ((ctrlb & RTC_CTRL_B_2412) ? "24-hour" : "12-hour"),
+ ((ctrlb & RTC_CTRL_B_DSE) ? "enabled" : "disabled"),
+ ((ctrlb & RTC_CTRL_B_DM) ? "binary" : "BCD"),
+ ((ctrld & RTC_CTRL_D_VRT) ? "ok" : "exhausted or n/a"),
+ ((ctrl4a & RTC_CTRL_4A_VRT2) ? "ok" : "exhausted or n/a"),
+ ((ctrlb & RTC_CTRL_B_UIE) ? "yes" : "no"),
+ ((ctrlb & RTC_CTRL_B_PIE) ? "yes" : "no"),
+ (!(ctrl4b & RTC_CTRL_4B_E32K) ?
+ ds1685_rtc_pirq_rate[(ctrla & RTC_CTRL_A_RS_MASK)] : "none"),
+ (!((ctrl4b & RTC_CTRL_4B_E32K)) ?
+ ds1685_rtc_sqw_freq[(ctrla & RTC_CTRL_A_RS_MASK)] : "32768Hz"),
+#ifdef CONFIG_RTC_DS1685_PROC_REGS
+ ssn[0], ssn[1], ssn[2], ssn[3], ssn[4], ssn[5], ssn[6], ssn[7],
+ ds1685_rtc_print_regs(ctrla, bits[0]),
+ ds1685_rtc_print_regs(ctrlb, bits[1]),
+ ds1685_rtc_print_regs(ctrlc, bits[2]),
+ ds1685_rtc_print_regs(ctrld, bits[3]),
+ ds1685_rtc_print_regs(ctrl4a, bits[4]),
+ ds1685_rtc_print_regs(ctrl4b, bits[5]));
+#else
+ ssn[0], ssn[1], ssn[2], ssn[3], ssn[4], ssn[5], ssn[6], ssn[7]);
+#endif
+ return 0;
+}
+#else
+#define ds1685_rtc_proc NULL
+#endif /* CONFIG_PROC_FS */
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* RTC Class operations */
+
+static const struct rtc_class_ops
+ds1685_rtc_ops = {
+ .proc = ds1685_rtc_proc,
+ .read_time = ds1685_rtc_read_time,
+ .set_time = ds1685_rtc_set_time,
+ .read_alarm = ds1685_rtc_read_alarm,
+ .set_alarm = ds1685_rtc_set_alarm,
+ .alarm_irq_enable = ds1685_rtc_alarm_irq_enable,
+};
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* SysFS interface */
+
+#ifdef CONFIG_SYSFS
+/**
+ * ds1685_rtc_sysfs_nvram_read - reads rtc nvram via sysfs.
+ * @file: pointer to file structure.
+ * @kobj: pointer to kobject structure.
+ * @bin_attr: pointer to bin_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ * @pos: current file position pointer.
+ * @size: size of the data to read.
+ */
+static ssize_t
+ds1685_rtc_sysfs_nvram_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t pos, size_t size)
+{
+ struct platform_device *pdev =
+ to_platform_device(container_of(kobj, struct device, kobj));
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ ssize_t count;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&rtc->lock, flags);
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ /* Read NVRAM in time and bank0 registers. */
+ for (count = 0; size > 0 && pos < NVRAM_TOTAL_SZ_BANK0;
+ count++, size--) {
+ if (count < NVRAM_SZ_TIME)
+ *buf++ = rtc->read(rtc, (NVRAM_TIME_BASE + pos++));
+ else
+ *buf++ = rtc->read(rtc, (NVRAM_BANK0_BASE + pos++));
+ }
+
+#ifndef CONFIG_RTC_DRV_DS1689
+ if (size > 0) {
+ ds1685_rtc_switch_to_bank1(rtc);
+
+#ifndef CONFIG_RTC_DRV_DS1685
+ /* Enable burst-mode on DS17x85/DS17x87 */
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (rtc->read(rtc, RTC_EXT_CTRL_4A) |
+ RTC_CTRL_4A_BME));
+
+ /* We need one write to RTC_BANK1_RAM_ADDR_LSB to start
+ * reading with burst-mode */
+ rtc->write(rtc, RTC_BANK1_RAM_ADDR_LSB,
+ (pos - NVRAM_TOTAL_SZ_BANK0));
+#endif
+
+ /* Read NVRAM in bank1 registers. */
+ for (count = 0; size > 0 && pos < NVRAM_TOTAL_SZ;
+ count++, size--) {
+#ifdef CONFIG_RTC_DRV_DS1685
+ /* DS1685/DS1687 has to write to RTC_BANK1_RAM_ADDR
+ * before each read. */
+ rtc->write(rtc, RTC_BANK1_RAM_ADDR,
+ (pos - NVRAM_TOTAL_SZ_BANK0));
+#endif
+ *buf++ = rtc->read(rtc, RTC_BANK1_RAM_DATA_PORT);
+ pos++;
+ }
+
+#ifndef CONFIG_RTC_DRV_DS1685
+ /* Disable burst-mode on DS17x85/DS17x87 */
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (rtc->read(rtc, RTC_EXT_CTRL_4A) &
+ ~(RTC_CTRL_4A_BME)));
+#endif
+ ds1685_rtc_switch_to_bank0(rtc);
+ }
+#endif /* !CONFIG_RTC_DRV_DS1689 */
+ spin_unlock_irqrestore(&rtc->lock, flags);
+
+ /*
+ * XXX: Bug? this appears to cause the function to get executed
+ * several times in succession. But it's the only way to actually get
+ * data written out to a file.
+ */
+ return count;
+}
+
+/**
+ * ds1685_rtc_sysfs_nvram_write - writes rtc nvram via sysfs.
+ * @file: pointer to file structure.
+ * @kobj: pointer to kobject structure.
+ * @bin_attr: pointer to bin_attribute structure.
+ * @buf: pointer to char array to hold the input.
+ * @pos: current file position pointer.
+ * @size: size of the data to write.
+ */
+static ssize_t
+ds1685_rtc_sysfs_nvram_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t pos, size_t size)
+{
+ struct platform_device *pdev =
+ to_platform_device(container_of(kobj, struct device, kobj));
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ ssize_t count;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&rtc->lock, flags);
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ /* Write NVRAM in time and bank0 registers. */
+ for (count = 0; size > 0 && pos < NVRAM_TOTAL_SZ_BANK0;
+ count++, size--)
+ if (count < NVRAM_SZ_TIME)
+ rtc->write(rtc, (NVRAM_TIME_BASE + pos++),
+ *buf++);
+ else
+ rtc->write(rtc, (NVRAM_BANK0_BASE), *buf++);
+
+#ifndef CONFIG_RTC_DRV_DS1689
+ if (size > 0) {
+ ds1685_rtc_switch_to_bank1(rtc);
+
+#ifndef CONFIG_RTC_DRV_DS1685
+ /* Enable burst-mode on DS17x85/DS17x87 */
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (rtc->read(rtc, RTC_EXT_CTRL_4A) |
+ RTC_CTRL_4A_BME));
+
+ /* We need one write to RTC_BANK1_RAM_ADDR_LSB to start
+ * writing with burst-mode */
+ rtc->write(rtc, RTC_BANK1_RAM_ADDR_LSB,
+ (pos - NVRAM_TOTAL_SZ_BANK0));
+#endif
+
+ /* Write NVRAM in bank1 registers. */
+ for (count = 0; size > 0 && pos < NVRAM_TOTAL_SZ;
+ count++, size--) {
+#ifdef CONFIG_RTC_DRV_DS1685
+ /* DS1685/DS1687 has to write to RTC_BANK1_RAM_ADDR
+ * before each read. */
+ rtc->write(rtc, RTC_BANK1_RAM_ADDR,
+ (pos - NVRAM_TOTAL_SZ_BANK0));
+#endif
+ rtc->write(rtc, RTC_BANK1_RAM_DATA_PORT, *buf++);
+ pos++;
+ }
+
+#ifndef CONFIG_RTC_DRV_DS1685
+ /* Disable burst-mode on DS17x85/DS17x87 */
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (rtc->read(rtc, RTC_EXT_CTRL_4A) &
+ ~(RTC_CTRL_4A_BME)));
+#endif
+ ds1685_rtc_switch_to_bank0(rtc);
+ }
+#endif /* !CONFIG_RTC_DRV_DS1689 */
+ spin_unlock_irqrestore(&rtc->lock, flags);
+
+ return count;
+}
+
+/**
+ * struct ds1685_rtc_sysfs_nvram_attr - sysfs attributes for rtc nvram.
+ * @attr: nvram attributes.
+ * @read: nvram read function.
+ * @write: nvram write function.
+ * @size: nvram total size (bank0 + extended).
+ */
+static struct bin_attribute
+ds1685_rtc_sysfs_nvram_attr = {
+ .attr = {
+ .name = "nvram",
+ .mode = S_IRUGO | S_IWUSR,
+ },
+ .read = ds1685_rtc_sysfs_nvram_read,
+ .write = ds1685_rtc_sysfs_nvram_write,
+ .size = NVRAM_TOTAL_SZ
+};
+
+/**
+ * ds1685_rtc_sysfs_battery_show - sysfs file for main battery status.
+ * @dev: pointer to device structure.
+ * @attr: pointer to device_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ */
+static ssize_t
+ds1685_rtc_sysfs_battery_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ctrld;
+
+ ctrld = rtc->read(rtc, RTC_CTRL_D);
+
+ return snprintf(buf, 13, "%s\n",
+ (ctrld & RTC_CTRL_D_VRT) ? "ok" : "not ok or N/A");
+}
+static DEVICE_ATTR(battery, S_IRUGO, ds1685_rtc_sysfs_battery_show, NULL);
+
+/**
+ * ds1685_rtc_sysfs_auxbatt_show - sysfs file for aux battery status.
+ * @dev: pointer to device structure.
+ * @attr: pointer to device_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ */
+static ssize_t
+ds1685_rtc_sysfs_auxbatt_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ctrl4a;
+
+ ds1685_rtc_switch_to_bank1(rtc);
+ ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A);
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ return snprintf(buf, 13, "%s\n",
+ (ctrl4a & RTC_CTRL_4A_VRT2) ? "ok" : "not ok or N/A");
+}
+static DEVICE_ATTR(auxbatt, S_IRUGO, ds1685_rtc_sysfs_auxbatt_show, NULL);
+
+/**
+ * ds1685_rtc_sysfs_serial_show - sysfs file for silicon serial number.
+ * @dev: pointer to device structure.
+ * @attr: pointer to device_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ */
+static ssize_t
+ds1685_rtc_sysfs_serial_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+ u8 ssn[8];
+
+ ds1685_rtc_switch_to_bank1(rtc);
+ ds1685_rtc_get_ssn(rtc, ssn);
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ return snprintf(buf, 24, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ ssn[0], ssn[1], ssn[2], ssn[3], ssn[4], ssn[5],
+ ssn[6], ssn[7]);
+
+ return 0;
+}
+static DEVICE_ATTR(serial, S_IRUGO, ds1685_rtc_sysfs_serial_show, NULL);
+
+/**
+ * struct ds1685_rtc_sysfs_misc_attrs - list for misc RTC features.
+ */
+static struct attribute*
+ds1685_rtc_sysfs_misc_attrs[] = {
+ &dev_attr_battery.attr,
+ &dev_attr_auxbatt.attr,
+ &dev_attr_serial.attr,
+ NULL,
+};
+
+/**
+ * struct ds1685_rtc_sysfs_misc_grp - attr group for misc RTC features.
+ */
+static const struct attribute_group
+ds1685_rtc_sysfs_misc_grp = {
+ .name = "misc",
+ .attrs = ds1685_rtc_sysfs_misc_attrs,
+};
+
+#ifdef CONFIG_RTC_DS1685_SYSFS_REGS
+/**
+ * struct ds1685_rtc_ctrl_regs.
+ * @name: char pointer for the bit name.
+ * @reg: control register the bit is in.
+ * @bit: the bit's offset in the register.
+ */
+struct ds1685_rtc_ctrl_regs {
+ const char *name;
+ const u8 reg;
+ const u8 bit;
+};
+
+/*
+ * Ctrl register bit lookup table.
+ */
+static const struct ds1685_rtc_ctrl_regs
+ds1685_ctrl_regs_table[] = {
+ { "uip", RTC_CTRL_A, RTC_CTRL_A_UIP },
+ { "dv2", RTC_CTRL_A, RTC_CTRL_A_DV2 },
+ { "dv1", RTC_CTRL_A, RTC_CTRL_A_DV1 },
+ { "dv0", RTC_CTRL_A, RTC_CTRL_A_DV0 },
+ { "rs3", RTC_CTRL_A, RTC_CTRL_A_RS3 },
+ { "rs2", RTC_CTRL_A, RTC_CTRL_A_RS2 },
+ { "rs1", RTC_CTRL_A, RTC_CTRL_A_RS1 },
+ { "rs0", RTC_CTRL_A, RTC_CTRL_A_RS0 },
+ { "set", RTC_CTRL_B, RTC_CTRL_B_SET },
+ { "pie", RTC_CTRL_B, RTC_CTRL_B_PIE },
+ { "aie", RTC_CTRL_B, RTC_CTRL_B_AIE },
+ { "uie", RTC_CTRL_B, RTC_CTRL_B_UIE },
+ { "sqwe", RTC_CTRL_B, RTC_CTRL_B_SQWE },
+ { "dm", RTC_CTRL_B, RTC_CTRL_B_DM },
+ { "2412", RTC_CTRL_B, RTC_CTRL_B_2412 },
+ { "dse", RTC_CTRL_B, RTC_CTRL_B_DSE },
+ { "irqf", RTC_CTRL_C, RTC_CTRL_C_IRQF },
+ { "pf", RTC_CTRL_C, RTC_CTRL_C_PF },
+ { "af", RTC_CTRL_C, RTC_CTRL_C_AF },
+ { "uf", RTC_CTRL_C, RTC_CTRL_C_UF },
+ { "vrt", RTC_CTRL_D, RTC_CTRL_D_VRT },
+ { "vrt2", RTC_EXT_CTRL_4A, RTC_CTRL_4A_VRT2 },
+ { "incr", RTC_EXT_CTRL_4A, RTC_CTRL_4A_INCR },
+ { "pab", RTC_EXT_CTRL_4A, RTC_CTRL_4A_PAB },
+ { "rf", RTC_EXT_CTRL_4A, RTC_CTRL_4A_RF },
+ { "wf", RTC_EXT_CTRL_4A, RTC_CTRL_4A_WF },
+ { "kf", RTC_EXT_CTRL_4A, RTC_CTRL_4A_KF },
+#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
+ { "bme", RTC_EXT_CTRL_4A, RTC_CTRL_4A_BME },
+#endif
+ { "abe", RTC_EXT_CTRL_4B, RTC_CTRL_4B_ABE },
+ { "e32k", RTC_EXT_CTRL_4B, RTC_CTRL_4B_E32K },
+ { "cs", RTC_EXT_CTRL_4B, RTC_CTRL_4B_CS },
+ { "rce", RTC_EXT_CTRL_4B, RTC_CTRL_4B_RCE },
+ { "prs", RTC_EXT_CTRL_4B, RTC_CTRL_4B_PRS },
+ { "rie", RTC_EXT_CTRL_4B, RTC_CTRL_4B_RIE },
+ { "wie", RTC_EXT_CTRL_4B, RTC_CTRL_4B_WIE },
+ { "kse", RTC_EXT_CTRL_4B, RTC_CTRL_4B_KSE },
+ { NULL, 0, 0 },
+};
+
+/**
+ * ds1685_rtc_sysfs_ctrl_regs_lookup - ctrl register bit lookup function.
+ * @name: ctrl register bit to look up in ds1685_ctrl_regs_table.
+ */
+static const struct ds1685_rtc_ctrl_regs*
+ds1685_rtc_sysfs_ctrl_regs_lookup(const char *name)
+{
+ const struct ds1685_rtc_ctrl_regs *p = ds1685_ctrl_regs_table;
+
+ for (; p->name != NULL; ++p)
+ if (strcmp(p->name, name) == 0)
+ return p;
+
+ return NULL;
+}
+
+/**
+ * ds1685_rtc_sysfs_ctrl_regs_show - reads a ctrl register bit via sysfs.
+ * @dev: pointer to device structure.
+ * @attr: pointer to device_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ */
+static ssize_t
+ds1685_rtc_sysfs_ctrl_regs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 tmp;
+ struct ds1685_priv *rtc = dev_get_drvdata(dev);
+ const struct ds1685_rtc_ctrl_regs *reg_info =
+ ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name);
+
+ /* Make sure we actually matched something. */
+ if (!reg_info)
+ return -EINVAL;
+
+ /* No spinlock during a read -- mutex is already held. */
+ ds1685_rtc_switch_to_bank1(rtc);
+ tmp = rtc->read(rtc, reg_info->reg) & reg_info->bit;
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ return snprintf(buf, 2, "%d\n", (tmp ? 1 : 0));
+}
+
+/**
+ * ds1685_rtc_sysfs_ctrl_regs_store - writes a ctrl register bit via sysfs.
+ * @dev: pointer to device structure.
+ * @attr: pointer to device_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ * @count: number of bytes written.
+ */
+static ssize_t
+ds1685_rtc_sysfs_ctrl_regs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ds1685_priv *rtc = dev_get_drvdata(dev);
+ u8 reg = 0, bit = 0, tmp;
+ unsigned long flags = 0;
+ long int val = 0;
+ const struct ds1685_rtc_ctrl_regs *reg_info =
+ ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name);
+
+ /* We only accept numbers. */
+ if (kstrtol(buf, 10, &val) < 0)
+ return -EINVAL;
+
+ /* bits are binary, 0 or 1 only. */
+ if ((val != 0) && (val != 1))
+ return -ERANGE;
+
+ /* Make sure we actually matched something. */
+ if (!reg_info)
+ return -EINVAL;
+
+ reg = reg_info->reg;
+ bit = reg_info->bit;
+
+ /* Safe to spinlock during a write. */
+ ds1685_rtc_begin_ctrl_access(rtc, flags);
+ tmp = rtc->read(rtc, reg);
+ rtc->write(rtc, reg, (val ? (tmp | bit) : (tmp & ~(bit))));
+ ds1685_rtc_end_ctrl_access(rtc, flags);
+
+ return count;
+}
+
+/**
+ * DS1685_RTC_SYSFS_CTRL_REG_RO - device_attribute for read-only register bit.
+ * @bit: bit to read.
+ */
+#define DS1685_RTC_SYSFS_CTRL_REG_RO(bit) \
+ static DEVICE_ATTR(bit, S_IRUGO, \
+ ds1685_rtc_sysfs_ctrl_regs_show, NULL)
+
+/**
+ * DS1685_RTC_SYSFS_CTRL_REG_RW - device_attribute for read-write register bit.
+ * @bit: bit to read or write.
+ */
+#define DS1685_RTC_SYSFS_CTRL_REG_RW(bit) \
+ static DEVICE_ATTR(bit, S_IRUGO | S_IWUSR, \
+ ds1685_rtc_sysfs_ctrl_regs_show, \
+ ds1685_rtc_sysfs_ctrl_regs_store)
+
+/*
+ * Control Register A bits.
+ */
+DS1685_RTC_SYSFS_CTRL_REG_RO(uip);
+DS1685_RTC_SYSFS_CTRL_REG_RW(dv2);
+DS1685_RTC_SYSFS_CTRL_REG_RW(dv1);
+DS1685_RTC_SYSFS_CTRL_REG_RO(dv0);
+DS1685_RTC_SYSFS_CTRL_REG_RW(rs3);
+DS1685_RTC_SYSFS_CTRL_REG_RW(rs2);
+DS1685_RTC_SYSFS_CTRL_REG_RW(rs1);
+DS1685_RTC_SYSFS_CTRL_REG_RW(rs0);
+
+static struct attribute*
+ds1685_rtc_sysfs_ctrla_attrs[] = {
+ &dev_attr_uip.attr,
+ &dev_attr_dv2.attr,
+ &dev_attr_dv1.attr,
+ &dev_attr_dv0.attr,
+ &dev_attr_rs3.attr,
+ &dev_attr_rs2.attr,
+ &dev_attr_rs1.attr,
+ &dev_attr_rs0.attr,
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_ctrla_grp = {
+ .name = "ctrla",
+ .attrs = ds1685_rtc_sysfs_ctrla_attrs,
+};
+
+
+/*
+ * Control Register B bits.
+ */
+DS1685_RTC_SYSFS_CTRL_REG_RO(set);
+DS1685_RTC_SYSFS_CTRL_REG_RW(pie);
+DS1685_RTC_SYSFS_CTRL_REG_RW(aie);
+DS1685_RTC_SYSFS_CTRL_REG_RW(uie);
+DS1685_RTC_SYSFS_CTRL_REG_RW(sqwe);
+DS1685_RTC_SYSFS_CTRL_REG_RO(dm);
+DS1685_RTC_SYSFS_CTRL_REG_RO(2412);
+DS1685_RTC_SYSFS_CTRL_REG_RO(dse);
+
+static struct attribute*
+ds1685_rtc_sysfs_ctrlb_attrs[] = {
+ &dev_attr_set.attr,
+ &dev_attr_pie.attr,
+ &dev_attr_aie.attr,
+ &dev_attr_uie.attr,
+ &dev_attr_sqwe.attr,
+ &dev_attr_dm.attr,
+ &dev_attr_2412.attr,
+ &dev_attr_dse.attr,
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_ctrlb_grp = {
+ .name = "ctrlb",
+ .attrs = ds1685_rtc_sysfs_ctrlb_attrs,
+};
+
+/*
+ * Control Register C bits.
+ *
+ * Reading Control C clears these bits! Reading them individually can
+ * possibly cause an interrupt to be missed. Use the /proc interface
+ * to see all the bits in this register simultaneously.
+ */
+DS1685_RTC_SYSFS_CTRL_REG_RO(irqf);
+DS1685_RTC_SYSFS_CTRL_REG_RO(pf);
+DS1685_RTC_SYSFS_CTRL_REG_RO(af);
+DS1685_RTC_SYSFS_CTRL_REG_RO(uf);
+
+static struct attribute*
+ds1685_rtc_sysfs_ctrlc_attrs[] = {
+ &dev_attr_irqf.attr,
+ &dev_attr_pf.attr,
+ &dev_attr_af.attr,
+ &dev_attr_uf.attr,
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_ctrlc_grp = {
+ .name = "ctrlc",
+ .attrs = ds1685_rtc_sysfs_ctrlc_attrs,
+};
+
+/*
+ * Control Register D bits.
+ */
+DS1685_RTC_SYSFS_CTRL_REG_RO(vrt);
+
+static struct attribute*
+ds1685_rtc_sysfs_ctrld_attrs[] = {
+ &dev_attr_vrt.attr,
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_ctrld_grp = {
+ .name = "ctrld",
+ .attrs = ds1685_rtc_sysfs_ctrld_attrs,
+};
+
+/*
+ * Control Register 4A bits.
+ */
+DS1685_RTC_SYSFS_CTRL_REG_RO(vrt2);
+DS1685_RTC_SYSFS_CTRL_REG_RO(incr);
+DS1685_RTC_SYSFS_CTRL_REG_RW(pab);
+DS1685_RTC_SYSFS_CTRL_REG_RW(rf);
+DS1685_RTC_SYSFS_CTRL_REG_RW(wf);
+DS1685_RTC_SYSFS_CTRL_REG_RW(kf);
+#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
+DS1685_RTC_SYSFS_CTRL_REG_RO(bme);
+#endif
+
+static struct attribute*
+ds1685_rtc_sysfs_ctrl4a_attrs[] = {
+ &dev_attr_vrt2.attr,
+ &dev_attr_incr.attr,
+ &dev_attr_pab.attr,
+ &dev_attr_rf.attr,
+ &dev_attr_wf.attr,
+ &dev_attr_kf.attr,
+#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
+ &dev_attr_bme.attr,
+#endif
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_ctrl4a_grp = {
+ .name = "ctrl4a",
+ .attrs = ds1685_rtc_sysfs_ctrl4a_attrs,
+};
+
+/*
+ * Control Register 4B bits.
+ */
+DS1685_RTC_SYSFS_CTRL_REG_RW(abe);
+DS1685_RTC_SYSFS_CTRL_REG_RW(e32k);
+DS1685_RTC_SYSFS_CTRL_REG_RO(cs);
+DS1685_RTC_SYSFS_CTRL_REG_RW(rce);
+DS1685_RTC_SYSFS_CTRL_REG_RW(prs);
+DS1685_RTC_SYSFS_CTRL_REG_RW(rie);
+DS1685_RTC_SYSFS_CTRL_REG_RW(wie);
+DS1685_RTC_SYSFS_CTRL_REG_RW(kse);
+
+static struct attribute*
+ds1685_rtc_sysfs_ctrl4b_attrs[] = {
+ &dev_attr_abe.attr,
+ &dev_attr_e32k.attr,
+ &dev_attr_cs.attr,
+ &dev_attr_rce.attr,
+ &dev_attr_prs.attr,
+ &dev_attr_rie.attr,
+ &dev_attr_wie.attr,
+ &dev_attr_kse.attr,
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_ctrl4b_grp = {
+ .name = "ctrl4b",
+ .attrs = ds1685_rtc_sysfs_ctrl4b_attrs,
+};
+
+
+/**
+ * struct ds1685_rtc_ctrl_regs.
+ * @name: char pointer for the bit name.
+ * @reg: control register the bit is in.
+ * @bit: the bit's offset in the register.
+ */
+struct ds1685_rtc_time_regs {
+ const char *name;
+ const u8 reg;
+ const u8 mask;
+ const u8 min;
+ const u8 max;
+};
+
+/*
+ * Time/Date register lookup tables.
+ */
+static const struct ds1685_rtc_time_regs
+ds1685_time_regs_bcd_table[] = {
+ { "seconds", RTC_SECS, RTC_SECS_BCD_MASK, 0, 59 },
+ { "minutes", RTC_MINS, RTC_MINS_BCD_MASK, 0, 59 },
+ { "hours", RTC_HRS, RTC_HRS_24_BCD_MASK, 0, 23 },
+ { "wday", RTC_WDAY, RTC_WDAY_MASK, 1, 7 },
+ { "mday", RTC_MDAY, RTC_MDAY_BCD_MASK, 1, 31 },
+ { "month", RTC_MONTH, RTC_MONTH_BCD_MASK, 1, 12 },
+ { "year", RTC_YEAR, RTC_YEAR_BCD_MASK, 0, 99 },
+ { "century", RTC_CENTURY, RTC_CENTURY_MASK, 0, 99 },
+ { "alarm_seconds", RTC_SECS_ALARM, RTC_SECS_BCD_MASK, 0, 59 },
+ { "alarm_minutes", RTC_MINS_ALARM, RTC_MINS_BCD_MASK, 0, 59 },
+ { "alarm_hours", RTC_HRS_ALARM, RTC_HRS_24_BCD_MASK, 0, 23 },
+ { "alarm_mday", RTC_MDAY_ALARM, RTC_MDAY_ALARM_MASK, 1, 31 },
+ { NULL, 0, 0, 0, 0 },
+};
+
+static const struct ds1685_rtc_time_regs
+ds1685_time_regs_bin_table[] = {
+ { "seconds", RTC_SECS, RTC_SECS_BIN_MASK, 0x00, 0x3b },
+ { "minutes", RTC_MINS, RTC_MINS_BIN_MASK, 0x00, 0x3b },
+ { "hours", RTC_HRS, RTC_HRS_24_BIN_MASK, 0x00, 0x17 },
+ { "wday", RTC_WDAY, RTC_WDAY_MASK, 0x01, 0x07 },
+ { "mday", RTC_MDAY, RTC_MDAY_BIN_MASK, 0x01, 0x1f },
+ { "month", RTC_MONTH, RTC_MONTH_BIN_MASK, 0x01, 0x0c },
+ { "year", RTC_YEAR, RTC_YEAR_BIN_MASK, 0x00, 0x63 },
+ { "century", RTC_CENTURY, RTC_CENTURY_MASK, 0x00, 0x63 },
+ { "alarm_seconds", RTC_SECS_ALARM, RTC_SECS_BIN_MASK, 0x00, 0x3b },
+ { "alarm_minutes", RTC_MINS_ALARM, RTC_MINS_BIN_MASK, 0x00, 0x3b },
+ { "alarm_hours", RTC_HRS_ALARM, RTC_HRS_24_BIN_MASK, 0x00, 0x17 },
+ { "alarm_mday", RTC_MDAY_ALARM, RTC_MDAY_ALARM_MASK, 0x01, 0x1f },
+ { NULL, 0, 0, 0x00, 0x00 },
+};
+
+/**
+ * ds1685_rtc_sysfs_time_regs_bcd_lookup - time/date reg bit lookup function.
+ * @name: register bit to look up in ds1685_time_regs_bcd_table.
+ */
+static const struct ds1685_rtc_time_regs*
+ds1685_rtc_sysfs_time_regs_lookup(const char *name, bool bcd_mode)
+{
+ const struct ds1685_rtc_time_regs *p;
+
+ if (bcd_mode)
+ p = ds1685_time_regs_bcd_table;
+ else
+ p = ds1685_time_regs_bin_table;
+
+ for (; p->name != NULL; ++p)
+ if (strcmp(p->name, name) == 0)
+ return p;
+
+ return NULL;
+}
+
+/**
+ * ds1685_rtc_sysfs_time_regs_show - reads a time/date register via sysfs.
+ * @dev: pointer to device structure.
+ * @attr: pointer to device_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ */
+static ssize_t
+ds1685_rtc_sysfs_time_regs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 tmp;
+ struct ds1685_priv *rtc = dev_get_drvdata(dev);
+ const struct ds1685_rtc_time_regs *bcd_reg_info =
+ ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, true);
+ const struct ds1685_rtc_time_regs *bin_reg_info =
+ ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false);
+
+ /* Make sure we actually matched something. */
+ if (!bcd_reg_info && !bin_reg_info)
+ return -EINVAL;
+
+ /* bcd_reg_info->reg == bin_reg_info->reg. */
+ ds1685_rtc_begin_data_access(rtc);
+ tmp = rtc->read(rtc, bcd_reg_info->reg);
+ ds1685_rtc_end_data_access(rtc);
+
+ tmp = ds1685_rtc_bcd2bin(rtc, tmp, bcd_reg_info->mask,
+ bin_reg_info->mask);
+
+ return snprintf(buf, 4, "%d\n", tmp);
+}
+
+/**
+ * ds1685_rtc_sysfs_time_regs_store - writes a time/date register via sysfs.
+ * @dev: pointer to device structure.
+ * @attr: pointer to device_attribute structure.
+ * @buf: pointer to char array to hold the output.
+ * @count: number of bytes written.
+ */
+static ssize_t
+ds1685_rtc_sysfs_time_regs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ long int val = 0;
+ struct ds1685_priv *rtc = dev_get_drvdata(dev);
+ const struct ds1685_rtc_time_regs *bcd_reg_info =
+ ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, true);
+ const struct ds1685_rtc_time_regs *bin_reg_info =
+ ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false);
+
+ /* We only accept numbers. */
+ if (kstrtol(buf, 10, &val) < 0)
+ return -EINVAL;
+
+ /* Make sure we actually matched something. */
+ if (!bcd_reg_info && !bin_reg_info)
+ return -EINVAL;
+
+ /* Check for a valid range. */
+ if (rtc->bcd_mode) {
+ if ((val < bcd_reg_info->min) || (val > bcd_reg_info->max))
+ return -ERANGE;
+ } else {
+ if ((val < bin_reg_info->min) || (val > bin_reg_info->max))
+ return -ERANGE;
+ }
+
+ val = ds1685_rtc_bin2bcd(rtc, val, bin_reg_info->mask,
+ bcd_reg_info->mask);
+
+ /* bcd_reg_info->reg == bin_reg_info->reg. */
+ ds1685_rtc_begin_data_access(rtc);
+ rtc->write(rtc, bcd_reg_info->reg, val);
+ ds1685_rtc_end_data_access(rtc);
+
+ return count;
+}
+
+/**
+ * DS1685_RTC_SYSFS_REG_RW - device_attribute for a read-write time register.
+ * @reg: time/date register to read or write.
+ */
+#define DS1685_RTC_SYSFS_TIME_REG_RW(reg) \
+ static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, \
+ ds1685_rtc_sysfs_time_regs_show, \
+ ds1685_rtc_sysfs_time_regs_store)
+
+/*
+ * Time/Date Register bits.
+ */
+DS1685_RTC_SYSFS_TIME_REG_RW(seconds);
+DS1685_RTC_SYSFS_TIME_REG_RW(minutes);
+DS1685_RTC_SYSFS_TIME_REG_RW(hours);
+DS1685_RTC_SYSFS_TIME_REG_RW(wday);
+DS1685_RTC_SYSFS_TIME_REG_RW(mday);
+DS1685_RTC_SYSFS_TIME_REG_RW(month);
+DS1685_RTC_SYSFS_TIME_REG_RW(year);
+DS1685_RTC_SYSFS_TIME_REG_RW(century);
+DS1685_RTC_SYSFS_TIME_REG_RW(alarm_seconds);
+DS1685_RTC_SYSFS_TIME_REG_RW(alarm_minutes);
+DS1685_RTC_SYSFS_TIME_REG_RW(alarm_hours);
+DS1685_RTC_SYSFS_TIME_REG_RW(alarm_mday);
+
+static struct attribute*
+ds1685_rtc_sysfs_time_attrs[] = {
+ &dev_attr_seconds.attr,
+ &dev_attr_minutes.attr,
+ &dev_attr_hours.attr,
+ &dev_attr_wday.attr,
+ &dev_attr_mday.attr,
+ &dev_attr_month.attr,
+ &dev_attr_year.attr,
+ &dev_attr_century.attr,
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_time_grp = {
+ .name = "datetime",
+ .attrs = ds1685_rtc_sysfs_time_attrs,
+};
+
+static struct attribute*
+ds1685_rtc_sysfs_alarm_attrs[] = {
+ &dev_attr_alarm_seconds.attr,
+ &dev_attr_alarm_minutes.attr,
+ &dev_attr_alarm_hours.attr,
+ &dev_attr_alarm_mday.attr,
+ NULL,
+};
+
+static const struct attribute_group
+ds1685_rtc_sysfs_alarm_grp = {
+ .name = "alarm",
+ .attrs = ds1685_rtc_sysfs_alarm_attrs,
+};
+#endif /* CONFIG_RTC_DS1685_SYSFS_REGS */
+
+
+/**
+ * ds1685_rtc_sysfs_register - register sysfs files.
+ * @dev: pointer to device structure.
+ */
+static int
+ds1685_rtc_sysfs_register(struct device *dev)
+{
+ int ret = 0;
+
+ sysfs_bin_attr_init(&ds1685_rtc_sysfs_nvram_attr);
+ ret = sysfs_create_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_RTC_DS1685_SYSFS_REGS
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrla_grp);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlb_grp);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlc_grp);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrld_grp);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4a_grp);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4b_grp);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_time_grp);
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_alarm_grp);
+ if (ret)
+ return ret;
+#endif
+ return 0;
+}
+
+/**
+ * ds1685_rtc_sysfs_unregister - unregister sysfs files.
+ * @dev: pointer to device structure.
+ */
+static int
+ds1685_rtc_sysfs_unregister(struct device *dev)
+{
+ sysfs_remove_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp);
+
+#ifdef CONFIG_RTC_DS1685_SYSFS_REGS
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrla_grp);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlb_grp);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlc_grp);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrld_grp);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4a_grp);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4b_grp);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_time_grp);
+ sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_alarm_grp);
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_SYSFS */
+
+
+
+/* ----------------------------------------------------------------------- */
+/* Driver Probe/Removal */
+
+/**
+ * ds1685_rtc_probe - initializes rtc driver.
+ * @pdev: pointer to platform_device structure.
+ */
+static int
+ds1685_rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc_dev;
+ struct resource *res;
+ struct ds1685_priv *rtc;
+ struct ds1685_rtc_platform_data *pdata;
+ u8 ctrla, ctrlb, hours;
+ unsigned char am_pm;
+ int ret = 0;
+
+ /* Get the platform data. */
+ pdata = (struct ds1685_rtc_platform_data *) pdev->dev.platform_data;
+ if (!pdata)
+ return -ENODEV;
+
+ /* Allocate memory for the rtc device. */
+ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ if (!rtc)
+ return -ENOMEM;
+
+ /*
+ * Allocate/setup any IORESOURCE_MEM resources, if required. Not all
+ * platforms put the RTC in an easy-access place. Like the SGI Octane,
+ * which attaches the RTC to a "ByteBus", hooked to a SuperIO chip
+ * that sits behind the IOC3 PCI metadevice.
+ */
+ if (pdata->alloc_io_resources) {
+ /* Get the platform resources. */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+ rtc->size = resource_size(res);
+
+ /* Request a memory region. */
+ /* XXX: mmio-only for now. */
+ if (!devm_request_mem_region(&pdev->dev, res->start, rtc->size,
+ pdev->name))
+ return -EBUSY;
+
+ /*
+ * Set the base address for the rtc, and ioremap its
+ * registers.
+ */
+ rtc->baseaddr = res->start;
+ rtc->regs = devm_ioremap(&pdev->dev, res->start, rtc->size);
+ if (!rtc->regs)
+ return -ENOMEM;
+ }
+ rtc->alloc_io_resources = pdata->alloc_io_resources;
+
+ /* Get the register step size. */
+ if (pdata->regstep > 0)
+ rtc->regstep = pdata->regstep;
+ else
+ rtc->regstep = 1;
+
+ /* Platform read function, else default if mmio setup */
+ if (pdata->plat_read)
+ rtc->read = pdata->plat_read;
+ else
+ if (pdata->alloc_io_resources)
+ rtc->read = ds1685_read;
+ else
+ return -ENXIO;
+
+ /* Platform write function, else default if mmio setup */
+ if (pdata->plat_write)
+ rtc->write = pdata->plat_write;
+ else
+ if (pdata->alloc_io_resources)
+ rtc->write = ds1685_write;
+ else
+ return -ENXIO;
+
+ /* Platform pre-shutdown function, if defined. */
+ if (pdata->plat_prepare_poweroff)
+ rtc->prepare_poweroff = pdata->plat_prepare_poweroff;
+
+ /* Platform wake_alarm function, if defined. */
+ if (pdata->plat_wake_alarm)
+ rtc->wake_alarm = pdata->plat_wake_alarm;
+
+ /* Platform post_ram_clear function, if defined. */
+ if (pdata->plat_post_ram_clear)
+ rtc->post_ram_clear = pdata->plat_post_ram_clear;
+
+ /* Init the spinlock, workqueue, & set the driver data. */
+ spin_lock_init(&rtc->lock);
+ INIT_WORK(&rtc->work, ds1685_rtc_work_queue);
+ platform_set_drvdata(pdev, rtc);
+
+ /* Turn the oscillator on if is not already on (DV1 = 1). */
+ ctrla = rtc->read(rtc, RTC_CTRL_A);
+ if (!(ctrla & RTC_CTRL_A_DV1))
+ ctrla |= RTC_CTRL_A_DV1;
+
+ /* Enable the countdown chain (DV2 = 0) */
+ ctrla &= ~(RTC_CTRL_A_DV2);
+
+ /* Clear RS3-RS0 in Control A. */
+ ctrla &= ~(RTC_CTRL_A_RS_MASK);
+
+ /*
+ * All done with Control A. Switch to Bank 1 for the remainder of
+ * the RTC setup so we have access to the extended functions.
+ */
+ ctrla |= RTC_CTRL_A_DV0;
+ rtc->write(rtc, RTC_CTRL_A, ctrla);
+
+ /* Default to 32768kHz output. */
+ rtc->write(rtc, RTC_EXT_CTRL_4B,
+ (rtc->read(rtc, RTC_EXT_CTRL_4B) | RTC_CTRL_4B_E32K));
+
+ /* Set the SET bit in Control B so we can do some housekeeping. */
+ rtc->write(rtc, RTC_CTRL_B,
+ (rtc->read(rtc, RTC_CTRL_B) | RTC_CTRL_B_SET));
+
+ /* Read Ext Ctrl 4A and check the INCR bit to avoid a lockout. */
+ while (rtc->read(rtc, RTC_EXT_CTRL_4A) & RTC_CTRL_4A_INCR)
+ cpu_relax();
+
+ /*
+ * If the platform supports BCD mode, then set DM=0 in Control B.
+ * Otherwise, set DM=1 for BIN mode.
+ */
+ ctrlb = rtc->read(rtc, RTC_CTRL_B);
+ if (pdata->bcd_mode)
+ ctrlb &= ~(RTC_CTRL_B_DM);
+ else
+ ctrlb |= RTC_CTRL_B_DM;
+ rtc->bcd_mode = pdata->bcd_mode;
+
+ /*
+ * Disable Daylight Savings Time (DSE = 0).
+ * The RTC has hardcoded timezone information that is rendered
+ * obselete. We'll let the OS deal with DST settings instead.
+ */
+ if (ctrlb & RTC_CTRL_B_DSE)
+ ctrlb &= ~(RTC_CTRL_B_DSE);
+
+ /* Force 24-hour mode (2412 = 1). */
+ if (!(ctrlb & RTC_CTRL_B_2412)) {
+ /* Reinitialize the time hours. */
+ hours = rtc->read(rtc, RTC_HRS);
+ am_pm = hours & RTC_HRS_AMPM_MASK;
+ hours = ds1685_rtc_bcd2bin(rtc, hours, RTC_HRS_12_BCD_MASK,
+ RTC_HRS_12_BIN_MASK);
+ hours = ((hours == 12) ? 0 : ((am_pm) ? hours + 12 : hours));
+
+ /* Enable 24-hour mode. */
+ ctrlb |= RTC_CTRL_B_2412;
+
+ /* Write back to Control B, including DM & DSE bits. */
+ rtc->write(rtc, RTC_CTRL_B, ctrlb);
+
+ /* Write the time hours back. */
+ rtc->write(rtc, RTC_HRS,
+ ds1685_rtc_bin2bcd(rtc, hours,
+ RTC_HRS_24_BIN_MASK,
+ RTC_HRS_24_BCD_MASK));
+
+ /* Reinitialize the alarm hours. */
+ hours = rtc->read(rtc, RTC_HRS_ALARM);
+ am_pm = hours & RTC_HRS_AMPM_MASK;
+ hours = ds1685_rtc_bcd2bin(rtc, hours, RTC_HRS_12_BCD_MASK,
+ RTC_HRS_12_BIN_MASK);
+ hours = ((hours == 12) ? 0 : ((am_pm) ? hours + 12 : hours));
+
+ /* Write the alarm hours back. */
+ rtc->write(rtc, RTC_HRS_ALARM,
+ ds1685_rtc_bin2bcd(rtc, hours,
+ RTC_HRS_24_BIN_MASK,
+ RTC_HRS_24_BCD_MASK));
+ } else {
+ /* 24-hour mode is already set, so write Control B back. */
+ rtc->write(rtc, RTC_CTRL_B, ctrlb);
+ }
+
+ /* Unset the SET bit in Control B so the RTC can update. */
+ rtc->write(rtc, RTC_CTRL_B,
+ (rtc->read(rtc, RTC_CTRL_B) & ~(RTC_CTRL_B_SET)));
+
+ /* Check the main battery. */
+ if (!(rtc->read(rtc, RTC_CTRL_D) & RTC_CTRL_D_VRT))
+ dev_warn(&pdev->dev,
+ "Main battery is exhausted! RTC may be invalid!\n");
+
+ /* Check the auxillary battery. It is optional. */
+ if (!(rtc->read(rtc, RTC_EXT_CTRL_4A) & RTC_CTRL_4A_VRT2))
+ dev_warn(&pdev->dev,
+ "Aux battery is exhausted or not available.\n");
+
+ /* Read Ctrl B and clear PIE/AIE/UIE. */
+ rtc->write(rtc, RTC_CTRL_B,
+ (rtc->read(rtc, RTC_CTRL_B) & ~(RTC_CTRL_B_PAU_MASK)));
+
+ /* Reading Ctrl C auto-clears PF/AF/UF. */
+ rtc->read(rtc, RTC_CTRL_C);
+
+ /* Read Ctrl 4B and clear RIE/WIE/KSE. */
+ rtc->write(rtc, RTC_EXT_CTRL_4B,
+ (rtc->read(rtc, RTC_EXT_CTRL_4B) & ~(RTC_CTRL_4B_RWK_MASK)));
+
+ /* Clear RF/WF/KF in Ctrl 4A. */
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (rtc->read(rtc, RTC_EXT_CTRL_4A) & ~(RTC_CTRL_4A_RWK_MASK)));
+
+ /*
+ * Re-enable KSE to handle power button events. We do not enable
+ * WIE or RIE by default.
+ */
+ rtc->write(rtc, RTC_EXT_CTRL_4B,
+ (rtc->read(rtc, RTC_EXT_CTRL_4B) | RTC_CTRL_4B_KSE));
+
+ /*
+ * Fetch the IRQ and setup the interrupt handler.
+ *
+ * Not all platforms have the IRQF pin tied to something. If not, the
+ * RTC will still set the *IE / *F flags and raise IRQF in ctrlc, but
+ * there won't be an automatic way of notifying the kernel about it,
+ * unless ctrlc is explicitly polled.
+ */
+ if (!pdata->no_irq) {
+ ret = platform_get_irq(pdev, 0);
+ if (ret > 0) {
+ rtc->irq_num = ret;
+
+ /* Request an IRQ. */
+ ret = devm_request_irq(&pdev->dev, rtc->irq_num,
+ ds1685_rtc_irq_handler,
+ IRQF_SHARED, pdev->name, pdev);
+
+ /* Check to see if something came back. */
+ if (unlikely(ret)) {
+ dev_warn(&pdev->dev,
+ "RTC interrupt not available\n");
+ rtc->irq_num = 0;
+ }
+ } else
+ return ret;
+ }
+ rtc->no_irq = pdata->no_irq;
+
+ /* Setup complete. */
+ ds1685_rtc_switch_to_bank0(rtc);
+
+ /* Register the device as an RTC. */
+ rtc_dev = rtc_device_register(pdev->name, &pdev->dev,
+ &ds1685_rtc_ops, THIS_MODULE);
+
+ /* Success? */
+ if (IS_ERR(rtc_dev))
+ return PTR_ERR(rtc_dev);
+
+ /* Maximum periodic rate is 8192Hz (0.122070ms). */
+ rtc_dev->max_user_freq = RTC_MAX_USER_FREQ;
+
+ /* See if the platform doesn't support UIE. */
+ if (pdata->uie_unsupported)
+ rtc_dev->uie_unsupported = 1;
+ rtc->uie_unsupported = pdata->uie_unsupported;
+
+ rtc->dev = rtc_dev;
+
+#ifdef CONFIG_SYSFS
+ ret = ds1685_rtc_sysfs_register(&pdev->dev);
+ if (ret)
+ rtc_device_unregister(rtc->dev);
+#endif
+
+ /* Done! */
+ return ret;
+}
+
+/**
+ * ds1685_rtc_remove - removes rtc driver.
+ * @pdev: pointer to platform_device structure.
+ */
+static int
+ds1685_rtc_remove(struct platform_device *pdev)
+{
+ struct ds1685_priv *rtc = platform_get_drvdata(pdev);
+
+#ifdef CONFIG_SYSFS
+ ds1685_rtc_sysfs_unregister(&pdev->dev);
+#endif
+
+ rtc_device_unregister(rtc->dev);
+
+ /* Read Ctrl B and clear PIE/AIE/UIE. */
+ rtc->write(rtc, RTC_CTRL_B,
+ (rtc->read(rtc, RTC_CTRL_B) &
+ ~(RTC_CTRL_B_PAU_MASK)));
+
+ /* Reading Ctrl C auto-clears PF/AF/UF. */
+ rtc->read(rtc, RTC_CTRL_C);
+
+ /* Read Ctrl 4B and clear RIE/WIE/KSE. */
+ rtc->write(rtc, RTC_EXT_CTRL_4B,
+ (rtc->read(rtc, RTC_EXT_CTRL_4B) &
+ ~(RTC_CTRL_4B_RWK_MASK)));
+
+ /* Manually clear RF/WF/KF in Ctrl 4A. */
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (rtc->read(rtc, RTC_EXT_CTRL_4A) &
+ ~(RTC_CTRL_4A_RWK_MASK)));
+
+ cancel_work_sync(&rtc->work);
+
+ return 0;
+}
+
+/**
+ * ds1685_rtc_driver - rtc driver properties.
+ */
+static struct platform_driver ds1685_rtc_driver = {
+ .driver = {
+ .name = "rtc-ds1685",
+ .owner = THIS_MODULE,
+ },
+ .probe = ds1685_rtc_probe,
+ .remove = ds1685_rtc_remove,
+};
+
+/**
+ * ds1685_rtc_init - rtc module init.
+ */
+static int __init
+ds1685_rtc_init(void)
+{
+ return platform_driver_register(&ds1685_rtc_driver);
+}
+
+/**
+ * ds1685_rtc_exit - rtc module exit.
+ */
+static void __exit
+ds1685_rtc_exit(void)
+{
+ platform_driver_unregister(&ds1685_rtc_driver);
+}
+
+module_init(ds1685_rtc_init);
+module_exit(ds1685_rtc_exit);
+/* ----------------------------------------------------------------------- */
+
+
+/* ----------------------------------------------------------------------- */
+/* Poweroff function */
+
+/**
+ * ds1685_rtc_poweroff - uses the RTC chip to power the system off.
+ * @pdev: pointer to platform_device structure.
+ */
+extern void __noreturn
+ds1685_rtc_poweroff(struct platform_device *pdev)
+{
+ u8 ctrla, ctrl4a, ctrl4b;
+ struct ds1685_priv *rtc;
+
+ /* Check for valid RTC data, else, spin forever. */
+ if (unlikely(!pdev)) {
+ pr_emerg("rtc-ds1685: platform device data not available, spinning forever ...\n");
+ unreachable();
+ } else {
+ /* Get the rtc data. */
+ rtc = platform_get_drvdata(pdev);
+
+ /*
+ * Disable our IRQ. We're powering down, so we're not
+ * going to worry about cleaning up. Most of that should
+ * have been taken care of by the shutdown scripts and this
+ * is the final function call.
+ */
+ if (!rtc->no_irq)
+ disable_irq_nosync(rtc->irq_num);
+
+ /* Oscillator must be on and the countdown chain enabled. */
+ ctrla = rtc->read(rtc, RTC_CTRL_A);
+ ctrla |= RTC_CTRL_A_DV1;
+ ctrla &= ~(RTC_CTRL_A_DV2);
+ rtc->write(rtc, RTC_CTRL_A, ctrla);
+
+ /*
+ * Read Control 4A and check the status of the auxillary
+ * battery. This must be present and working (VRT2 = 1)
+ * for wakeup and kickstart functionality to be useful.
+ */
+ ds1685_rtc_switch_to_bank1(rtc);
+ ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A);
+ if (ctrl4a & RTC_CTRL_4A_VRT2) {
+ /* Clear all of the interrupt flags on Control 4A. */
+ ctrl4a &= ~(RTC_CTRL_4A_RWK_MASK);
+ rtc->write(rtc, RTC_EXT_CTRL_4A, ctrl4a);
+
+ /*
+ * The auxillary battery is present and working.
+ * Enable extended functions (ABE=1), enable
+ * wake-up (WIE=1), and enable kickstart (KSE=1)
+ * in Control 4B.
+ */
+ ctrl4b = rtc->read(rtc, RTC_EXT_CTRL_4B);
+ ctrl4b |= (RTC_CTRL_4B_ABE | RTC_CTRL_4B_WIE |
+ RTC_CTRL_4B_KSE);
+ rtc->write(rtc, RTC_EXT_CTRL_4B, ctrl4b);
+ }
+
+ /* Set PAB to 1 in Control 4A to power the system down. */
+ dev_warn(&pdev->dev, "Powerdown.\n");
+ msleep(20);
+ rtc->write(rtc, RTC_EXT_CTRL_4A,
+ (ctrl4a | RTC_CTRL_4A_PAB));
+
+ /* Spin ... we do not switch back to bank0. */
+ unreachable();
+ }
+}
+EXPORT_SYMBOL(ds1685_rtc_poweroff);
+/* ----------------------------------------------------------------------- */
+
+
+MODULE_AUTHOR("Joshua Kinard <kumba@gentoo.org>");
+MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd-electronics.com>");
+MODULE_DESCRIPTION("Dallas/Maxim DS1685/DS1687-series RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:rtc-ds1685");
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index ee3ba7e6b45e..f9b082784b90 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -275,7 +275,8 @@ static int isl12022_probe(struct i2c_client *client,
#ifdef CONFIG_OF
static const struct of_device_id isl12022_dt_match[] = {
- { .compatible = "isl,isl12022" },
+ { .compatible = "isl,isl12022" }, /* for backward compat., don't use */
+ { .compatible = "isil,isl12022" },
{ },
};
#endif
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c
index b8f862953f7f..da818d3337ce 100644
--- a/drivers/rtc/rtc-isl12057.c
+++ b/drivers/rtc/rtc-isl12057.c
@@ -644,7 +644,8 @@ static SIMPLE_DEV_PM_OPS(isl12057_rtc_pm_ops, isl12057_rtc_suspend,
#ifdef CONFIG_OF
static const struct of_device_id isl12057_dt_match[] = {
- { .compatible = "isl,isl12057" },
+ { .compatible = "isl,isl12057" }, /* for backward compat., don't use */
+ { .compatible = "isil,isl12057" },
{ },
};
#endif
diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c
index 9b9794d42ffe..d9631e15f7b5 100644
--- a/drivers/scsi/csiostor/csio_init.c
+++ b/drivers/scsi/csiostor/csio_init.c
@@ -113,12 +113,9 @@ static const struct file_operations csio_mem_debugfs_fops = {
void csio_add_debugfs_mem(struct csio_hw *hw, const char *name,
unsigned int idx, unsigned int size_mb)
{
- struct dentry *de;
-
- de = debugfs_create_file(name, S_IRUSR, hw->debugfs_root,
- (void *)hw + idx, &csio_mem_debugfs_fops);
- if (de && de->d_inode)
- de->d_inode->i_size = size_mb << 20;
+ debugfs_create_file_size(name, S_IRUSR, hw->debugfs_root,
+ (void *)hw + idx, &csio_mem_debugfs_fops,
+ size_mb << 20);
}
static int csio_setup_debugfs(struct csio_hw *hw)
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index c52bb5dfaedb..f164f24a4a55 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -950,6 +950,12 @@ static int virtscsi_probe(struct virtio_device *vdev)
u32 num_queues;
struct scsi_host_template *hostt;
+ if (!vdev->config->get) {
+ dev_err(&vdev->dev, "%s failure: config access disabled\n",
+ __func__);
+ return -EINVAL;
+ }
+
/* We need to know how many queues before we allocate. */
num_queues = virtscsi_config_get(vdev, num_queues) ? : 1;
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 011a3363c265..c0d660f1aaac 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -81,6 +81,7 @@ static const struct of_device_id car_match[] __initconst = {
{ .compatible = "nvidia,tegra30-car", },
{ .compatible = "nvidia,tegra114-car", },
{ .compatible = "nvidia,tegra124-car", },
+ { .compatible = "nvidia,tegra132-car", },
{},
};
diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c
index 8646fa920d8d..4d2f71bf65c5 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra30.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra30.c
@@ -56,7 +56,7 @@ struct tegra_fuse_info {
static void __iomem *fuse_base;
static struct clk *fuse_clk;
-static struct tegra_fuse_info *fuse_info;
+static const struct tegra_fuse_info *fuse_info;
u32 tegra30_fuse_readl(const unsigned int offset)
{
@@ -78,18 +78,18 @@ u32 tegra30_fuse_readl(const unsigned int offset)
return val;
}
-static struct tegra_fuse_info tegra30_info = {
+static const struct tegra_fuse_info tegra30_info = {
.size = 0x2a4,
.spare_bit = 0x144,
.speedo_idx = SPEEDO_TEGRA30,
};
-static struct tegra_fuse_info tegra114_info = {
+static const struct tegra_fuse_info tegra114_info = {
.size = 0x2a0,
.speedo_idx = SPEEDO_TEGRA114,
};
-static struct tegra_fuse_info tegra124_info = {
+static const struct tegra_fuse_info tegra124_info = {
.size = 0x300,
.speedo_idx = SPEEDO_TEGRA124,
};
@@ -182,6 +182,7 @@ static void __init legacy_fuse_init(void)
fuse_info = &tegra114_info;
break;
case TEGRA124:
+ case TEGRA132:
fuse_info = &tegra124_info;
break;
default:
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index a2c0ceb95f8f..c956395cf46f 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -70,6 +70,10 @@
#define PMC_SCRATCH41 0x140
+#define PMC_SENSOR_CTRL 0x1b0
+#define PMC_SENSOR_CTRL_SCRATCH_WRITE (1 << 2)
+#define PMC_SENSOR_CTRL_ENABLE_RST (1 << 1)
+
#define IO_DPD_REQ 0x1b8
#define IO_DPD_REQ_CODE_IDLE (0 << 30)
#define IO_DPD_REQ_CODE_OFF (1 << 30)
@@ -81,6 +85,18 @@
#define IO_DPD2_STATUS 0x1c4
#define SEL_DPD_TIM 0x1c8
+#define PMC_SCRATCH54 0x258
+#define PMC_SCRATCH54_DATA_SHIFT 8
+#define PMC_SCRATCH54_ADDR_SHIFT 0
+
+#define PMC_SCRATCH55 0x25c
+#define PMC_SCRATCH55_RESET_TEGRA (1 << 31)
+#define PMC_SCRATCH55_CNTRL_ID_SHIFT 27
+#define PMC_SCRATCH55_PINMUX_SHIFT 24
+#define PMC_SCRATCH55_16BITOP (1 << 15)
+#define PMC_SCRATCH55_CHECKSUM_SHIFT 16
+#define PMC_SCRATCH55_I2CSLV1_SHIFT 0
+
#define GPU_RG_CNTRL 0x2d4
struct tegra_pmc_soc {
@@ -88,6 +104,9 @@ struct tegra_pmc_soc {
const char *const *powergates;
unsigned int num_cpu_powergates;
const u8 *cpu_powergates;
+
+ bool has_tsense_reset;
+ bool has_gpu_clamps;
};
/**
@@ -110,6 +129,7 @@ struct tegra_pmc_soc {
* @powergates_lock: mutex for power gate register access
*/
struct tegra_pmc {
+ struct device *dev;
void __iomem *base;
struct clk *clk;
@@ -225,11 +245,11 @@ int tegra_powergate_remove_clamping(int id)
return -EINVAL;
/*
- * The Tegra124 GPU has a separate register (with different semantics)
- * to remove clamps.
+ * On Tegra124 and later, the clamps for the GPU are controlled by a
+ * separate register (with different semantics).
*/
- if (tegra_get_chip_id() == TEGRA124) {
- if (id == TEGRA_POWERGATE_3D) {
+ if (id == TEGRA_POWERGATE_3D) {
+ if (pmc->soc->has_gpu_clamps) {
tegra_pmc_writel(0, GPU_RG_CNTRL);
return 0;
}
@@ -703,6 +723,83 @@ static void tegra_pmc_init(struct tegra_pmc *pmc)
tegra_pmc_writel(value, PMC_CNTRL);
}
+void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc)
+{
+ static const char disabled[] = "emergency thermal reset disabled";
+ u32 pmu_addr, ctrl_id, reg_addr, reg_data, pinmux;
+ struct device *dev = pmc->dev;
+ struct device_node *np;
+ u32 value, checksum;
+
+ if (!pmc->soc->has_tsense_reset)
+ goto out;
+
+ np = of_find_node_by_name(pmc->dev->of_node, "i2c-thermtrip");
+ if (!np) {
+ dev_warn(dev, "i2c-thermtrip node not found, %s.\n", disabled);
+ goto out;
+ }
+
+ if (of_property_read_u32(np, "nvidia,i2c-controller-id", &ctrl_id)) {
+ dev_err(dev, "I2C controller ID missing, %s.\n", disabled);
+ goto out;
+ }
+
+ if (of_property_read_u32(np, "nvidia,bus-addr", &pmu_addr)) {
+ dev_err(dev, "nvidia,bus-addr missing, %s.\n", disabled);
+ goto out;
+ }
+
+ if (of_property_read_u32(np, "nvidia,reg-addr", &reg_addr)) {
+ dev_err(dev, "nvidia,reg-addr missing, %s.\n", disabled);
+ goto out;
+ }
+
+ if (of_property_read_u32(np, "nvidia,reg-data", &reg_data)) {
+ dev_err(dev, "nvidia,reg-data missing, %s.\n", disabled);
+ goto out;
+ }
+
+ if (of_property_read_u32(np, "nvidia,pinmux-id", &pinmux))
+ pinmux = 0;
+
+ value = tegra_pmc_readl(PMC_SENSOR_CTRL);
+ value |= PMC_SENSOR_CTRL_SCRATCH_WRITE;
+ tegra_pmc_writel(value, PMC_SENSOR_CTRL);
+
+ value = (reg_data << PMC_SCRATCH54_DATA_SHIFT) |
+ (reg_addr << PMC_SCRATCH54_ADDR_SHIFT);
+ tegra_pmc_writel(value, PMC_SCRATCH54);
+
+ value = PMC_SCRATCH55_RESET_TEGRA;
+ value |= ctrl_id << PMC_SCRATCH55_CNTRL_ID_SHIFT;
+ value |= pinmux << PMC_SCRATCH55_PINMUX_SHIFT;
+ value |= pmu_addr << PMC_SCRATCH55_I2CSLV1_SHIFT;
+
+ /*
+ * Calculate checksum of SCRATCH54, SCRATCH55 fields. Bits 23:16 will
+ * contain the checksum and are currently zero, so they are not added.
+ */
+ checksum = reg_addr + reg_data + (value & 0xff) + ((value >> 8) & 0xff)
+ + ((value >> 24) & 0xff);
+ checksum &= 0xff;
+ checksum = 0x100 - checksum;
+
+ value |= checksum << PMC_SCRATCH55_CHECKSUM_SHIFT;
+
+ tegra_pmc_writel(value, PMC_SCRATCH55);
+
+ value = tegra_pmc_readl(PMC_SENSOR_CTRL);
+ value |= PMC_SENSOR_CTRL_ENABLE_RST;
+ tegra_pmc_writel(value, PMC_SENSOR_CTRL);
+
+ dev_info(pmc->dev, "emergency thermal reset enabled\n");
+
+out:
+ of_node_put(np);
+ return;
+}
+
static int tegra_pmc_probe(struct platform_device *pdev)
{
void __iomem *base = pmc->base;
@@ -728,8 +825,12 @@ static int tegra_pmc_probe(struct platform_device *pdev)
return err;
}
+ pmc->dev = &pdev->dev;
+
tegra_pmc_init(pmc);
+ tegra_pmc_init_tsense_reset(pmc);
+
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
err = tegra_powergate_debugfs_init();
if (err < 0)
@@ -739,7 +840,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
static int tegra_pmc_suspend(struct device *dev)
{
tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41);
@@ -753,10 +854,11 @@ static int tegra_pmc_resume(struct device *dev)
return 0;
}
-#endif
static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume);
+#endif
+
static const char * const tegra20_powergates[] = {
[TEGRA_POWERGATE_CPU] = "cpu",
[TEGRA_POWERGATE_3D] = "3d",
@@ -772,6 +874,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.powergates = tegra20_powergates,
.num_cpu_powergates = 0,
.cpu_powergates = NULL,
+ .has_tsense_reset = false,
+ .has_gpu_clamps = false,
};
static const char * const tegra30_powergates[] = {
@@ -803,6 +907,8 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.powergates = tegra30_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
.cpu_powergates = tegra30_cpu_powergates,
+ .has_tsense_reset = true,
+ .has_gpu_clamps = false,
};
static const char * const tegra114_powergates[] = {
@@ -838,6 +944,8 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.powergates = tegra114_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
.cpu_powergates = tegra114_cpu_powergates,
+ .has_tsense_reset = true,
+ .has_gpu_clamps = false,
};
static const char * const tegra124_powergates[] = {
@@ -879,6 +987,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.powergates = tegra124_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates),
.cpu_powergates = tegra124_cpu_powergates,
+ .has_tsense_reset = true,
+ .has_gpu_clamps = true,
};
static const struct of_device_id tegra_pmc_match[] = {
@@ -894,7 +1004,9 @@ static struct platform_driver tegra_pmc_driver = {
.name = "tegra-pmc",
.suppress_bind_attrs = true,
.of_match_table = tegra_pmc_match,
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
.pm = &tegra_pmc_pm_ops,
+#endif
},
.probe = tegra_pmc_probe,
};
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index 6bed611e1934..135bdad7a6de 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -1,5 +1,6 @@
#
# TI Keystone SOC drivers
#
-obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS) += knav_qmss_queue.o knav_qmss_acc.o
+obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS) += knav_qmss.o
+knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o
obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o
diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
index 6fbfde6e748f..ef6f69db0bd0 100644
--- a/drivers/soc/ti/knav_qmss_acc.c
+++ b/drivers/soc/ti/knav_qmss_acc.c
@@ -209,7 +209,7 @@ static irqreturn_t knav_acc_int_handler(int irq, void *_instdata)
return IRQ_HANDLED;
}
-int knav_range_setup_acc_irq(struct knav_range_info *range,
+static int knav_range_setup_acc_irq(struct knav_range_info *range,
int queue, bool enabled)
{
struct knav_device *kdev = range->kdev;
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 8e6a95d91d33..6d8646db52cc 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -626,6 +626,7 @@ int knav_queue_push(void *qhandle, dma_addr_t dma,
atomic_inc(&qh->stats.pushes);
return 0;
}
+EXPORT_SYMBOL_GPL(knav_queue_push);
/**
* knav_queue_pop() - pop data (or descriptor) from the head of a queue
@@ -663,6 +664,7 @@ dma_addr_t knav_queue_pop(void *qhandle, unsigned *size)
atomic_inc(&qh->stats.pops);
return dma;
}
+EXPORT_SYMBOL_GPL(knav_queue_pop);
/* carve out descriptors and push into queue */
static void kdesc_fill_pool(struct knav_pool *pool)
@@ -717,12 +719,14 @@ dma_addr_t knav_pool_desc_virt_to_dma(void *ph, void *virt)
struct knav_pool *pool = ph;
return pool->region->dma_start + (virt - pool->region->virt_start);
}
+EXPORT_SYMBOL_GPL(knav_pool_desc_virt_to_dma);
void *knav_pool_desc_dma_to_virt(void *ph, dma_addr_t dma)
{
struct knav_pool *pool = ph;
return pool->region->virt_start + (dma - pool->region->dma_start);
}
+EXPORT_SYMBOL_GPL(knav_pool_desc_dma_to_virt);
/**
* knav_pool_create() - Create a pool of descriptors
@@ -878,6 +882,7 @@ void *knav_pool_desc_get(void *ph)
data = knav_pool_desc_dma_to_virt(pool, dma);
return data;
}
+EXPORT_SYMBOL_GPL(knav_pool_desc_get);
/**
* knav_pool_desc_put() - return a descriptor to the pool
@@ -890,6 +895,7 @@ void knav_pool_desc_put(void *ph, void *desc)
dma = knav_pool_desc_virt_to_dma(pool, desc);
knav_queue_push(pool->queue, dma, pool->region->desc_size, 0);
}
+EXPORT_SYMBOL_GPL(knav_pool_desc_put);
/**
* knav_pool_desc_map() - Map descriptor for DMA transfer
@@ -916,6 +922,7 @@ int knav_pool_desc_map(void *ph, void *desc, unsigned size,
return 0;
}
+EXPORT_SYMBOL_GPL(knav_pool_desc_map);
/**
* knav_pool_desc_unmap() - Unmap descriptor after DMA transfer
@@ -938,6 +945,7 @@ void *knav_pool_desc_unmap(void *ph, dma_addr_t dma, unsigned dma_sz)
prefetch(desc);
return desc;
}
+EXPORT_SYMBOL_GPL(knav_pool_desc_unmap);
/**
* knav_pool_count() - Get the number of descriptors in pool.
@@ -949,6 +957,7 @@ int knav_pool_count(void *ph)
struct knav_pool *pool = ph;
return knav_queue_get_count(pool->queue);
}
+EXPORT_SYMBOL_GPL(knav_pool_count);
static void knav_queue_setup_region(struct knav_device *kdev,
struct knav_region *region)
diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c
index 17b34cbadc03..3fb91c81015a 100644
--- a/drivers/spi/spi-bcm53xx.c
+++ b/drivers/spi/spi-bcm53xx.c
@@ -216,7 +216,7 @@ static struct spi_board_info bcm53xx_info = {
static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS),
- BCMA_CORETABLE_END
+ {},
};
MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl);
diff --git a/drivers/ssb/driver_gige.c b/drivers/ssb/driver_gige.c
index 21f71a1581fa..e9734051e3c4 100644
--- a/drivers/ssb/driver_gige.c
+++ b/drivers/ssb/driver_gige.c
@@ -24,7 +24,7 @@ MODULE_LICENSE("GPL");
static const struct ssb_device_id ssb_gige_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_ETHERNET_GBIT, SSB_ANY_REV),
- SSB_DEVTABLE_END
+ {},
};
/* MODULE_DEVICE_TABLE(ssb, ssb_gige_tbl); */
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c
index e969107ddb47..6440e3b293ca 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/staging/iio/light/isl29028.c
@@ -537,8 +537,8 @@ static const struct i2c_device_id isl29028_id[] = {
MODULE_DEVICE_TABLE(i2c, isl29028_id);
static const struct of_device_id isl29028_of_match[] = {
- { .compatible = "isl,isl29028", },
- { .compatible = "isil,isl29028", },/* deprecated, don't use */
+ { .compatible = "isl,isl29028", }, /* for backward compat., don't use */
+ { .compatible = "isil,isl29028", },
{ },
};
MODULE_DEVICE_TABLE(of, isl29028_of_match);
diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c
index 5bb9c85cec81..88614b71cf6d 100644
--- a/drivers/staging/lustre/lustre/llite/dcache.c
+++ b/drivers/staging/lustre/lustre/llite/dcache.c
@@ -263,14 +263,6 @@ void ll_invalidate_aliases(struct inode *inode)
dentry, dentry, dentry->d_parent,
dentry->d_inode, dentry->d_flags);
- if (unlikely(dentry == dentry->d_sb->s_root)) {
- CERROR("%s: called on root dentry=%p, fid="DFID"\n",
- ll_get_fsname(dentry->d_sb, NULL, 0),
- dentry, PFID(ll_inode2fid(inode)));
- lustre_dump_dentry(dentry, 1);
- dump_stack();
- }
-
d_lustre_invalidate(dentry, 0);
}
ll_unlock_dcache(inode);
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 37306e0c7aad..d032c2b086cc 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -816,7 +816,6 @@ int ll_show_options(struct seq_file *seq, struct dentry *dentry);
void ll_dirty_page_discard_warn(struct page *page, int ioret);
int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
struct super_block *, struct lookup_intent *);
-void lustre_dump_dentry(struct dentry *, int recur);
int ll_obd_statfs(struct inode *inode, void *arg);
int ll_get_max_mdsize(struct ll_sb_info *sbi, int *max_mdsize);
int ll_get_default_mdsize(struct ll_sb_info *sbi, int *default_mdsize);
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 45aaa1cc56bc..0c1b583a4ea1 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -665,48 +665,6 @@ int ll_get_default_cookiesize(struct ll_sb_info *sbi, int *lmmsize)
return rc;
}
-static void ll_dump_inode(struct inode *inode)
-{
- struct ll_d_hlist_node *tmp;
- int dentry_count = 0;
-
- LASSERT(inode != NULL);
-
- ll_d_hlist_for_each(tmp, &inode->i_dentry)
- dentry_count++;
-
- CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n",
- inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino,
- inode->i_mode, atomic_read(&inode->i_count), dentry_count);
-}
-
-void lustre_dump_dentry(struct dentry *dentry, int recur)
-{
- struct list_head *tmp;
- int subdirs = 0;
-
- LASSERT(dentry != NULL);
-
- list_for_each(tmp, &dentry->d_subdirs)
- subdirs++;
-
- CERROR("dentry %p dump: name=%pd parent=%pd (%p), inode=%p, count=%u, flags=0x%x, fsdata=%p, %d subdirs\n",
- dentry, dentry, dentry->d_parent, dentry->d_parent,
- dentry->d_inode, d_count(dentry),
- dentry->d_flags, dentry->d_fsdata, subdirs);
- if (dentry->d_inode != NULL)
- ll_dump_inode(dentry->d_inode);
-
- if (recur == 0)
- return;
-
- list_for_each(tmp, &dentry->d_subdirs) {
- struct dentry *d = list_entry(tmp, struct dentry, d_child);
-
- lustre_dump_dentry(d, recur - 1);
- }
-}
-
static void client_common_put_super(struct super_block *sb)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index b8e213eb36cc..366e551aeff0 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -32,6 +32,7 @@ menu "USB Peripheral Controller"
config USB_AT91
tristate "Atmel AT91 USB Device Port"
depends on ARCH_AT91
+ depends on OF || COMPILE_TEST
help
Many Atmel AT91 processors (such as the AT91RM2000) have a
full speed USB Device Port with support for five configurable
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c
index c0ec5f71f16f..2fbedca3c2b4 100644
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -31,16 +31,9 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_data/atmel.h>
-
-#include <asm/byteorder.h>
-#include <mach/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/gpio.h>
-
-#include <mach/cpu.h>
-#include <mach/at91sam9261_matrix.h>
-#include <mach/at91_matrix.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/atmel-matrix.h>
#include "at91_udc.h"
@@ -66,7 +59,15 @@
#define DRIVER_VERSION "3 May 2006"
static const char driver_name [] = "at91_udc";
-static const char ep0name[] = "ep0";
+static const char * const ep_names[] = {
+ "ep0",
+ "ep1",
+ "ep2",
+ "ep3-int",
+ "ep4",
+ "ep5",
+};
+#define ep0name ep_names[0]
#define VBUS_POLL_TIMEOUT msecs_to_jiffies(1000)
@@ -895,8 +896,6 @@ static void clk_on(struct at91_udc *udc)
return;
udc->clocked = 1;
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_enable(udc->uclk);
clk_enable(udc->iclk);
clk_enable(udc->fclk);
}
@@ -909,8 +908,6 @@ static void clk_off(struct at91_udc *udc)
udc->gadget.speed = USB_SPEED_UNKNOWN;
clk_disable(udc->fclk);
clk_disable(udc->iclk);
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_disable(udc->uclk);
}
/*
@@ -919,8 +916,6 @@ static void clk_off(struct at91_udc *udc)
*/
static void pullup(struct at91_udc *udc, int is_on)
{
- int active = !udc->board.pullup_active_low;
-
if (!udc->enabled || !udc->vbus)
is_on = 0;
DBG("%sactive\n", is_on ? "" : "in");
@@ -929,40 +924,15 @@ static void pullup(struct at91_udc *udc, int is_on)
clk_on(udc);
at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM);
at91_udp_write(udc, AT91_UDP_TXVC, 0);
- if (cpu_is_at91rm9200())
- gpio_set_value(udc->board.pullup_pin, active);
- else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
- u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
-
- txvc |= AT91_UDP_TXVC_PUON;
- at91_udp_write(udc, AT91_UDP_TXVC, txvc);
- } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
- u32 usbpucr;
-
- usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
- usbpucr |= AT91_MATRIX_USBPUCR_PUON;
- at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
- }
} else {
stop_activity(udc);
at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM);
at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
- if (cpu_is_at91rm9200())
- gpio_set_value(udc->board.pullup_pin, !active);
- else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
- u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
-
- txvc &= ~AT91_UDP_TXVC_PUON;
- at91_udp_write(udc, AT91_UDP_TXVC, txvc);
- } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
- u32 usbpucr;
-
- usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
- usbpucr &= ~AT91_MATRIX_USBPUCR_PUON;
- at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
- }
clk_off(udc);
}
+
+ if (udc->caps && udc->caps->pullup)
+ udc->caps->pullup(udc, is_on);
}
/* vbus is here! turn everything on that's ready */
@@ -1535,74 +1505,6 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
/*-------------------------------------------------------------------------*/
-static struct at91_udc controller = {
- .gadget = {
- .ops = &at91_udc_ops,
- .ep0 = &controller.ep[0].ep,
- .name = driver_name,
- },
- .ep[0] = {
- .ep = {
- .name = ep0name,
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .maxpacket = 8,
- .int_mask = 1 << 0,
- },
- .ep[1] = {
- .ep = {
- .name = "ep1",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 64,
- .int_mask = 1 << 1,
- },
- .ep[2] = {
- .ep = {
- .name = "ep2",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 64,
- .int_mask = 1 << 2,
- },
- .ep[3] = {
- .ep = {
- /* could actually do bulk too */
- .name = "ep3-int",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .maxpacket = 8,
- .int_mask = 1 << 3,
- },
- .ep[4] = {
- .ep = {
- .name = "ep4",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 256,
- .int_mask = 1 << 4,
- },
- .ep[5] = {
- .ep = {
- .name = "ep5",
- .ops = &at91_ep_ops,
- },
- .udc = &controller,
- .is_pingpong = 1,
- .maxpacket = 256,
- .int_mask = 1 << 5,
- },
- /* ep6 and ep7 are also reserved (custom silicon might use them) */
-};
-
static void at91_vbus_update(struct at91_udc *udc, unsigned value)
{
value ^= udc->board.vbus_active_low;
@@ -1687,12 +1589,202 @@ static void at91udc_shutdown(struct platform_device *dev)
spin_unlock_irqrestore(&udc->lock, flags);
}
-static void at91udc_of_init(struct at91_udc *udc,
- struct device_node *np)
+static int at91rm9200_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int ret;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0:
+ case 3:
+ ep->maxpacket = 8;
+ break;
+ case 1 ... 2:
+ ep->maxpacket = 64;
+ break;
+ case 4 ... 5:
+ ep->maxpacket = 256;
+ break;
+ }
+ }
+
+ if (!gpio_is_valid(udc->board.pullup_pin)) {
+ DBG("no D+ pullup?\n");
+ return -ENODEV;
+ }
+
+ ret = devm_gpio_request(&udc->pdev->dev, udc->board.pullup_pin,
+ "udc_pullup");
+ if (ret) {
+ DBG("D+ pullup is busy\n");
+ return ret;
+ }
+
+ gpio_direction_output(udc->board.pullup_pin,
+ udc->board.pullup_active_low);
+
+ return 0;
+}
+
+static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on)
+{
+ int active = !udc->board.pullup_active_low;
+
+ if (is_on)
+ gpio_set_value(udc->board.pullup_pin, active);
+ else
+ gpio_set_value(udc->board.pullup_pin, !active);
+}
+
+static const struct at91_udc_caps at91rm9200_udc_caps = {
+ .init = at91rm9200_udc_init,
+ .pullup = at91rm9200_udc_pullup,
+};
+
+static int at91sam9260_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0 ... 3:
+ ep->maxpacket = 64;
+ break;
+ case 4 ... 5:
+ ep->maxpacket = 512;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void at91sam9260_udc_pullup(struct at91_udc *udc, int is_on)
+{
+ u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
+
+ if (is_on)
+ txvc |= AT91_UDP_TXVC_PUON;
+ else
+ txvc &= ~AT91_UDP_TXVC_PUON;
+
+ at91_udp_write(udc, AT91_UDP_TXVC, txvc);
+}
+
+static const struct at91_udc_caps at91sam9260_udc_caps = {
+ .init = at91sam9260_udc_init,
+ .pullup = at91sam9260_udc_pullup,
+};
+
+static int at91sam9261_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0:
+ ep->maxpacket = 8;
+ break;
+ case 1 ... 3:
+ ep->maxpacket = 64;
+ break;
+ case 4 ... 5:
+ ep->maxpacket = 256;
+ break;
+ }
+ }
+
+ udc->matrix = syscon_regmap_lookup_by_phandle(udc->pdev->dev.of_node,
+ "atmel,matrix");
+ if (IS_ERR(udc->matrix))
+ return PTR_ERR(udc->matrix);
+
+ return 0;
+}
+
+static void at91sam9261_udc_pullup(struct at91_udc *udc, int is_on)
+{
+ u32 usbpucr = 0;
+
+ if (is_on)
+ usbpucr = AT91_MATRIX_USBPUCR_PUON;
+
+ regmap_update_bits(udc->matrix, AT91SAM9261_MATRIX_USBPUCR,
+ AT91_MATRIX_USBPUCR_PUON, usbpucr);
+}
+
+static const struct at91_udc_caps at91sam9261_udc_caps = {
+ .init = at91sam9261_udc_init,
+ .pullup = at91sam9261_udc_pullup,
+};
+
+static int at91sam9263_udc_init(struct at91_udc *udc)
+{
+ struct at91_ep *ep;
+ int i;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+
+ switch (i) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ ep->maxpacket = 64;
+ break;
+ case 4:
+ case 5:
+ ep->maxpacket = 256;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static const struct at91_udc_caps at91sam9263_udc_caps = {
+ .init = at91sam9263_udc_init,
+ .pullup = at91sam9260_udc_pullup,
+};
+
+static const struct of_device_id at91_udc_dt_ids[] = {
+ {
+ .compatible = "atmel,at91rm9200-udc",
+ .data = &at91rm9200_udc_caps,
+ },
+ {
+ .compatible = "atmel,at91sam9260-udc",
+ .data = &at91sam9260_udc_caps,
+ },
+ {
+ .compatible = "atmel,at91sam9261-udc",
+ .data = &at91sam9261_udc_caps,
+ },
+ {
+ .compatible = "atmel,at91sam9263-udc",
+ .data = &at91sam9263_udc_caps,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
+
+static void at91udc_of_init(struct at91_udc *udc, struct device_node *np)
{
struct at91_udc_data *board = &udc->board;
- u32 val;
+ const struct of_device_id *match;
enum of_gpio_flags flags;
+ u32 val;
if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0)
board->vbus_polled = 1;
@@ -1705,6 +1797,10 @@ static void at91udc_of_init(struct at91_udc *udc,
&flags);
board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+
+ match = of_match_node(at91_udc_dt_ids, np);
+ if (match)
+ udc->caps = match->data;
}
static int at91udc_probe(struct platform_device *pdev)
@@ -1713,97 +1809,67 @@ static int at91udc_probe(struct platform_device *pdev)
struct at91_udc *udc;
int retval;
struct resource *res;
+ struct at91_ep *ep;
+ int i;
- if (!dev_get_platdata(dev) && !pdev->dev.of_node) {
- /* small (so we copy it) but critical! */
- DBG("missing platform_data\n");
- return -ENODEV;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
-
- if (!request_mem_region(res->start, resource_size(res), driver_name)) {
- DBG("someone's using UDC memory\n");
- return -EBUSY;
- }
+ udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL);
+ if (!udc)
+ return -ENOMEM;
/* init software state */
- udc = &controller;
udc->gadget.dev.parent = dev;
- if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
- at91udc_of_init(udc, pdev->dev.of_node);
- else
- memcpy(&udc->board, dev_get_platdata(dev),
- sizeof(struct at91_udc_data));
+ at91udc_of_init(udc, pdev->dev.of_node);
udc->pdev = pdev;
udc->enabled = 0;
spin_lock_init(&udc->lock);
- /* rm9200 needs manual D+ pullup; off by default */
- if (cpu_is_at91rm9200()) {
- if (!gpio_is_valid(udc->board.pullup_pin)) {
- DBG("no D+ pullup?\n");
- retval = -ENODEV;
- goto fail0;
- }
- retval = gpio_request(udc->board.pullup_pin, "udc_pullup");
- if (retval) {
- DBG("D+ pullup is busy\n");
- goto fail0;
- }
- gpio_direction_output(udc->board.pullup_pin,
- udc->board.pullup_active_low);
- }
+ udc->gadget.ops = &at91_udc_ops;
+ udc->gadget.ep0 = &udc->ep[0].ep;
+ udc->gadget.name = driver_name;
+ udc->gadget.dev.init_name = "gadget";
- /* newer chips have more FIFO memory than rm9200 */
- if (cpu_is_at91sam9260() || cpu_is_at91sam9g20()) {
- udc->ep[0].maxpacket = 64;
- udc->ep[3].maxpacket = 64;
- udc->ep[4].maxpacket = 512;
- udc->ep[5].maxpacket = 512;
- } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
- udc->ep[3].maxpacket = 64;
- } else if (cpu_is_at91sam9263()) {
- udc->ep[0].maxpacket = 64;
- udc->ep[3].maxpacket = 64;
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+ ep->ep.name = ep_names[i];
+ ep->ep.ops = &at91_ep_ops;
+ ep->udc = udc;
+ ep->int_mask = BIT(i);
+ if (i != 0 && i != 3)
+ ep->is_pingpong = 1;
}
- udc->udp_baseaddr = ioremap(res->start, resource_size(res));
- if (!udc->udp_baseaddr) {
- retval = -ENOMEM;
- goto fail0a;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ udc->udp_baseaddr = devm_ioremap_resource(dev, res);
+ if (IS_ERR(udc->udp_baseaddr))
+ return PTR_ERR(udc->udp_baseaddr);
+
+ if (udc->caps && udc->caps->init) {
+ retval = udc->caps->init(udc);
+ if (retval)
+ return retval;
}
udc_reinit(udc);
/* get interface and function clocks */
- udc->iclk = clk_get(dev, "udc_clk");
- udc->fclk = clk_get(dev, "udpck");
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- udc->uclk = clk_get(dev, "usb_clk");
- if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk) ||
- (IS_ENABLED(CONFIG_COMMON_CLK) && IS_ERR(udc->uclk))) {
- DBG("clocks missing\n");
- retval = -ENODEV;
- goto fail1;
- }
+ udc->iclk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(udc->iclk))
+ return PTR_ERR(udc->iclk);
+
+ udc->fclk = devm_clk_get(dev, "hclk");
+ if (IS_ERR(udc->fclk))
+ return PTR_ERR(udc->fclk);
/* don't do anything until we have both gadget driver and VBUS */
- if (IS_ENABLED(CONFIG_COMMON_CLK)) {
- clk_set_rate(udc->uclk, 48000000);
- retval = clk_prepare(udc->uclk);
- if (retval)
- goto fail1;
- }
+ clk_set_rate(udc->fclk, 48000000);
retval = clk_prepare(udc->fclk);
if (retval)
- goto fail1a;
+ return retval;
retval = clk_prepare_enable(udc->iclk);
if (retval)
- goto fail1b;
+ goto err_unprepare_fclk;
+
at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff);
/* Clear all pending interrupts - UDP may be used by bootloader. */
@@ -1812,18 +1878,21 @@ static int at91udc_probe(struct platform_device *pdev)
/* request UDC and maybe VBUS irqs */
udc->udp_irq = platform_get_irq(pdev, 0);
- retval = request_irq(udc->udp_irq, at91_udc_irq,
- 0, driver_name, udc);
- if (retval < 0) {
+ retval = devm_request_irq(dev, udc->udp_irq, at91_udc_irq, 0,
+ driver_name, udc);
+ if (retval) {
DBG("request irq %d failed\n", udc->udp_irq);
- goto fail1c;
+ goto err_unprepare_iclk;
}
+
if (gpio_is_valid(udc->board.vbus_pin)) {
- retval = gpio_request(udc->board.vbus_pin, "udc_vbus");
- if (retval < 0) {
+ retval = devm_gpio_request(dev, udc->board.vbus_pin,
+ "udc_vbus");
+ if (retval) {
DBG("request vbus pin failed\n");
- goto fail2;
+ goto err_unprepare_iclk;
}
+
gpio_direction_input(udc->board.vbus_pin);
/*
@@ -1840,12 +1909,13 @@ static int at91udc_probe(struct platform_device *pdev)
mod_timer(&udc->vbus_timer,
jiffies + VBUS_POLL_TIMEOUT);
} else {
- if (request_irq(gpio_to_irq(udc->board.vbus_pin),
- at91_vbus_irq, 0, driver_name, udc)) {
+ retval = devm_request_irq(dev,
+ gpio_to_irq(udc->board.vbus_pin),
+ at91_vbus_irq, 0, driver_name, udc);
+ if (retval) {
DBG("request vbus irq %d failed\n",
udc->board.vbus_pin);
- retval = -EBUSY;
- goto fail3;
+ goto err_unprepare_iclk;
}
}
} else {
@@ -1854,49 +1924,27 @@ static int at91udc_probe(struct platform_device *pdev)
}
retval = usb_add_gadget_udc(dev, &udc->gadget);
if (retval)
- goto fail4;
+ goto err_unprepare_iclk;
dev_set_drvdata(dev, udc);
device_init_wakeup(dev, 1);
create_debug_file(udc);
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
return 0;
-fail4:
- if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
- free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
-fail3:
- if (gpio_is_valid(udc->board.vbus_pin))
- gpio_free(udc->board.vbus_pin);
-fail2:
- free_irq(udc->udp_irq, udc);
-fail1c:
+
+err_unprepare_iclk:
clk_unprepare(udc->iclk);
-fail1b:
+err_unprepare_fclk:
clk_unprepare(udc->fclk);
-fail1a:
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_unprepare(udc->uclk);
-fail1:
- if (IS_ENABLED(CONFIG_COMMON_CLK) && !IS_ERR(udc->uclk))
- clk_put(udc->uclk);
- if (!IS_ERR(udc->fclk))
- clk_put(udc->fclk);
- if (!IS_ERR(udc->iclk))
- clk_put(udc->iclk);
- iounmap(udc->udp_baseaddr);
-fail0a:
- if (cpu_is_at91rm9200())
- gpio_free(udc->board.pullup_pin);
-fail0:
- release_mem_region(res->start, resource_size(res));
+
DBG("%s probe failed, %d\n", driver_name, retval);
+
return retval;
}
static int __exit at91udc_remove(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(pdev);
- struct resource *res;
unsigned long flags;
DBG("remove\n");
@@ -1911,29 +1959,9 @@ static int __exit at91udc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
- if (gpio_is_valid(udc->board.vbus_pin)) {
- free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
- gpio_free(udc->board.vbus_pin);
- }
- free_irq(udc->udp_irq, udc);
- iounmap(udc->udp_baseaddr);
-
- if (cpu_is_at91rm9200())
- gpio_free(udc->board.pullup_pin);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_unprepare(udc->uclk);
clk_unprepare(udc->fclk);
clk_unprepare(udc->iclk);
- clk_put(udc->iclk);
- clk_put(udc->fclk);
- if (IS_ENABLED(CONFIG_COMMON_CLK))
- clk_put(udc->uclk);
-
return 0;
}
@@ -1989,15 +2017,6 @@ static int at91udc_resume(struct platform_device *pdev)
#define at91udc_resume NULL
#endif
-#if defined(CONFIG_OF)
-static const struct of_device_id at91_udc_dt_ids[] = {
- { .compatible = "atmel,at91rm9200-udc" },
- { /* sentinel */ }
-};
-
-MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
-#endif
-
static struct platform_driver at91_udc_driver = {
.remove = __exit_p(at91udc_remove),
.shutdown = at91udc_shutdown,
@@ -2005,7 +2024,7 @@ static struct platform_driver at91_udc_driver = {
.resume = at91udc_resume,
.driver = {
.name = (char *) driver_name,
- .of_match_table = of_match_ptr(at91_udc_dt_ids),
+ .of_match_table = at91_udc_dt_ids,
},
};
diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h
index 467dcfb74a51..2679c8b217cc 100644
--- a/drivers/usb/gadget/udc/at91_udc.h
+++ b/drivers/usb/gadget/udc/at91_udc.h
@@ -107,6 +107,11 @@ struct at91_ep {
unsigned fifo_bank:1;
};
+struct at91_udc_caps {
+ int (*init)(struct at91_udc *udc);
+ void (*pullup)(struct at91_udc *udc, int is_on);
+};
+
/*
* driver is non-SMP, and just blocks IRQs whenever it needs
* access protection for chip registers or driver state
@@ -115,6 +120,7 @@ struct at91_udc {
struct usb_gadget gadget;
struct at91_ep ep[NUM_ENDPOINTS];
struct usb_gadget_driver *driver;
+ const struct at91_udc_caps *caps;
unsigned vbus:1;
unsigned enabled:1;
unsigned clocked:1;
@@ -125,7 +131,7 @@ struct at91_udc {
unsigned active_suspend:1;
u8 addr;
struct at91_udc_data board;
- struct clk *iclk, *fclk, *uclk;
+ struct clk *iclk, *fclk;
struct platform_device *pdev;
struct proc_dir_entry *pde;
void __iomem *udp_baseaddr;
@@ -133,6 +139,7 @@ struct at91_udc {
spinlock_t lock;
struct timer_list vbus_timer;
struct work_struct vbus_timer_work;
+ struct regmap *matrix;
};
static inline struct at91_udc *to_udc(struct usb_gadget *g)
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
index c0410862c2a1..d79cb35dbf8a 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
@@ -265,14 +265,17 @@ static void usba_init_debugfs(struct usba_udc *udc)
goto err_root;
udc->debugfs_root = root;
- regs = debugfs_create_file("regs", 0400, root, udc, &regs_dbg_fops);
- if (!regs)
- goto err_regs;
-
regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM,
CTRL_IOMEM_ID);
- regs->d_inode->i_size = resource_size(regs_resource);
- udc->debugfs_regs = regs;
+
+ if (regs_resource) {
+ regs = debugfs_create_file_size("regs", 0400, root, udc,
+ &regs_dbg_fops,
+ resource_size(regs_resource));
+ if (!regs)
+ goto err_regs;
+ udc->debugfs_regs = regs;
+ }
usba_ep_init_debugfs(udc, to_usba_ep(udc->gadget.ep0));
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
index cd6d0afb6b8f..526cfab41d5f 100644
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -306,7 +306,7 @@ static int bcma_hcd_resume(struct bcma_device *dev)
static const struct bcma_device_id bcma_hcd_table[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
- BCMA_CORETABLE_END
+ {},
};
MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c
index 0196f766df73..ffc32f4b1b1b 100644
--- a/drivers/usb/host/ssb-hcd.c
+++ b/drivers/usb/host/ssb-hcd.c
@@ -251,7 +251,7 @@ static const struct ssb_device_id ssb_hcd_table[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
- SSB_DEVTABLE_END
+ {},
};
MODULE_DEVICE_TABLE(ssb, ssb_hcd_table);
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 8dccca9013ed..afa06d28725d 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -528,9 +528,9 @@ static void handle_rx(struct vhost_net *net)
.msg_controllen = 0,
.msg_flags = MSG_DONTWAIT,
};
- struct virtio_net_hdr_mrg_rxbuf hdr = {
- .hdr.flags = 0,
- .hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE
+ struct virtio_net_hdr hdr = {
+ .flags = 0,
+ .gso_type = VIRTIO_NET_HDR_GSO_NONE
};
size_t total_len = 0;
int err, mergeable;
@@ -539,6 +539,7 @@ static void handle_rx(struct vhost_net *net)
size_t vhost_len, sock_len;
struct socket *sock;
struct iov_iter fixup;
+ __virtio16 num_buffers;
mutex_lock(&vq->mutex);
sock = vq->private_data;
@@ -616,9 +617,9 @@ static void handle_rx(struct vhost_net *net)
}
/* TODO: Should check and handle checksum. */
- hdr.num_buffers = cpu_to_vhost16(vq, headcount);
+ num_buffers = cpu_to_vhost16(vq, headcount);
if (likely(mergeable) &&
- copy_to_iter(&hdr.num_buffers, 2, &fixup) != 2) {
+ copy_to_iter(&num_buffers, 2, &fixup) != 2) {
vq_err(vq, "Failed num_buffers write");
vhost_discard_vq_desc(vq, headcount);
break;
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 00b228638274..b546da5d8ea3 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -12,16 +12,32 @@ config VIRTIO_PCI
depends on PCI
select VIRTIO
---help---
- This drivers provides support for virtio based paravirtual device
+ This driver provides support for virtio based paravirtual device
drivers over PCI. This requires that your VMM has appropriate PCI
virtio backends. Most QEMU based VMMs should support these devices
(like KVM or Xen).
- Currently, the ABI is not considered stable so there is no guarantee
- that this version of the driver will work with your VMM.
-
If unsure, say M.
+config VIRTIO_PCI_LEGACY
+ bool "Support for legacy virtio draft 0.9.X and older devices"
+ default y
+ depends on VIRTIO_PCI
+ ---help---
+ Virtio PCI Card 0.9.X Draft (circa 2014) and older device support.
+
+ This option enables building a transitional driver, supporting
+ both devices conforming to Virtio 1 specification, and legacy devices.
+ If disabled, you get a slightly smaller, non-transitional driver,
+ with no legacy compatibility.
+
+ So look out into your driveway. Do you have a flying car? If
+ so, you can happily disable this option and virtio will not
+ break. Otherwise, leave it set. Unless you're testing what
+ life will be like in The Future.
+
+ If unsure, say Y.
+
config VIRTIO_BALLOON
tristate "Virtio balloon driver"
depends on VIRTIO
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index bf5104b56894..d85565b8ea46 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o
obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
-virtio_pci-y := virtio_pci_legacy.o virtio_pci_common.o
+virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
+virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index b9f70dfc4751..5ce2aa48fc6e 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -236,7 +236,10 @@ static int virtio_dev_probe(struct device *_d)
if (err)
goto err;
- add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+ /* If probe didn't do it, mark device DRIVER_OK ourselves. */
+ if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
+ virtio_device_ready(dev);
+
if (drv->scan)
drv->scan(dev);
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 50c5f42d7a9f..0413157f3b49 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -44,8 +44,7 @@ static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES;
module_param(oom_pages, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(oom_pages, "pages to free on OOM");
-struct virtio_balloon
-{
+struct virtio_balloon {
struct virtio_device *vdev;
struct virtqueue *inflate_vq, *deflate_vq, *stats_vq;
@@ -466,6 +465,12 @@ static int virtballoon_probe(struct virtio_device *vdev)
struct virtio_balloon *vb;
int err;
+ if (!vdev->config->get) {
+ dev_err(&vdev->dev, "%s failure: config access disabled\n",
+ __func__);
+ return -EINVAL;
+ }
+
vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL);
if (!vb) {
err = -ENOMEM;
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 00d115b22bd8..cad569890908 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -1,7 +1,7 @@
/*
* Virtio memory mapped device driver
*
- * Copyright 2011, ARM Ltd.
+ * Copyright 2011-2014, ARM Ltd.
*
* This module allows virtio devices to be used over a virtual, memory mapped
* platform device.
@@ -50,36 +50,6 @@
*
*
*
- * Registers layout (all 32-bit wide):
- *
- * offset d. name description
- * ------ -- ---------------- -----------------
- *
- * 0x000 R MagicValue Magic value "virt"
- * 0x004 R Version Device version (current max. 1)
- * 0x008 R DeviceID Virtio device ID
- * 0x00c R VendorID Virtio vendor ID
- *
- * 0x010 R HostFeatures Features supported by the host
- * 0x014 W HostFeaturesSel Set of host features to access via HostFeatures
- *
- * 0x020 W GuestFeatures Features activated by the guest
- * 0x024 W GuestFeaturesSel Set of activated features to set via GuestFeatures
- * 0x028 W GuestPageSize Size of guest's memory page in bytes
- *
- * 0x030 W QueueSel Queue selector
- * 0x034 R QueueNumMax Maximum size of the currently selected queue
- * 0x038 W QueueNum Queue size for the currently selected queue
- * 0x03c W QueueAlign Used Ring alignment for the current queue
- * 0x040 RW QueuePFN PFN for the currently selected queue
- *
- * 0x050 W QueueNotify Queue notifier
- * 0x060 R InterruptStatus Interrupt status register
- * 0x064 W InterruptACK Interrupt acknowledge register
- * 0x070 RW Status Device status register
- *
- * 0x100+ RW Device-specific configuration space
- *
* Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
@@ -145,11 +115,16 @@ struct virtio_mmio_vq_info {
static u64 vm_get_features(struct virtio_device *vdev)
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+ u64 features;
+
+ writel(1, vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES_SEL);
+ features = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES);
+ features <<= 32;
- /* TODO: Features > 32 bits */
- writel(0, vm_dev->base + VIRTIO_MMIO_HOST_FEATURES_SEL);
+ writel(0, vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES_SEL);
+ features |= readl(vm_dev->base + VIRTIO_MMIO_DEVICE_FEATURES);
- return readl(vm_dev->base + VIRTIO_MMIO_HOST_FEATURES);
+ return features;
}
static int vm_finalize_features(struct virtio_device *vdev)
@@ -159,11 +134,20 @@ static int vm_finalize_features(struct virtio_device *vdev)
/* Give virtio_ring a chance to accept features. */
vring_transport_features(vdev);
- /* Make sure we don't have any features > 32 bits! */
- BUG_ON((u32)vdev->features != vdev->features);
+ /* Make sure there is are no mixed devices */
+ if (vm_dev->version == 2 &&
+ !__virtio_test_bit(vdev, VIRTIO_F_VERSION_1)) {
+ dev_err(&vdev->dev, "New virtio-mmio devices (version 2) must provide VIRTIO_F_VERSION_1 feature!\n");
+ return -EINVAL;
+ }
+
+ writel(1, vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES_SEL);
+ writel((u32)(vdev->features >> 32),
+ vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES);
- writel(0, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SEL);
- writel(vdev->features, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES);
+ writel(0, vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES_SEL);
+ writel((u32)vdev->features,
+ vm_dev->base + VIRTIO_MMIO_DRIVER_FEATURES);
return 0;
}
@@ -275,7 +259,12 @@ static void vm_del_vq(struct virtqueue *vq)
/* Select and deactivate the queue */
writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
- writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+ if (vm_dev->version == 1) {
+ writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+ } else {
+ writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
+ WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
+ }
size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN));
free_pages_exact(info->queue, size);
@@ -312,7 +301,8 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
/* Queue shouldn't already be set up. */
- if (readl(vm_dev->base + VIRTIO_MMIO_QUEUE_PFN)) {
+ if (readl(vm_dev->base + (vm_dev->version == 1 ?
+ VIRTIO_MMIO_QUEUE_PFN : VIRTIO_MMIO_QUEUE_READY))) {
err = -ENOENT;
goto error_available;
}
@@ -356,13 +346,6 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
info->num /= 2;
}
- /* Activate the queue */
- writel(info->num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
- writel(VIRTIO_MMIO_VRING_ALIGN,
- vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
- writel(virt_to_phys(info->queue) >> PAGE_SHIFT,
- vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
-
/* Create the vring */
vq = vring_new_virtqueue(index, info->num, VIRTIO_MMIO_VRING_ALIGN, vdev,
true, info->queue, vm_notify, callback, name);
@@ -371,6 +354,33 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
goto error_new_virtqueue;
}
+ /* Activate the queue */
+ writel(info->num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
+ if (vm_dev->version == 1) {
+ writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
+ writel(virt_to_phys(info->queue) >> PAGE_SHIFT,
+ vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+ } else {
+ u64 addr;
+
+ addr = virt_to_phys(info->queue);
+ writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_LOW);
+ writel((u32)(addr >> 32),
+ vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_HIGH);
+
+ addr = virt_to_phys(virtqueue_get_avail(vq));
+ writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_LOW);
+ writel((u32)(addr >> 32),
+ vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);
+
+ addr = virt_to_phys(virtqueue_get_used(vq));
+ writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_USED_LOW);
+ writel((u32)(addr >> 32),
+ vm_dev->base + VIRTIO_MMIO_QUEUE_USED_HIGH);
+
+ writel(1, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
+ }
+
vq->priv = info;
info->vq = vq;
@@ -381,7 +391,12 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
return vq;
error_new_virtqueue:
- writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+ if (vm_dev->version == 1) {
+ writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+ } else {
+ writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
+ WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
+ }
free_pages_exact(info->queue, size);
error_alloc_pages:
kfree(info);
@@ -476,16 +491,32 @@ static int virtio_mmio_probe(struct platform_device *pdev)
/* Check device version */
vm_dev->version = readl(vm_dev->base + VIRTIO_MMIO_VERSION);
- if (vm_dev->version != 1) {
+ if (vm_dev->version < 1 || vm_dev->version > 2) {
dev_err(&pdev->dev, "Version %ld not supported!\n",
vm_dev->version);
return -ENXIO;
}
vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
+ if (vm_dev->vdev.id.device == 0) {
+ /*
+ * virtio-mmio device with an ID 0 is a (dummy) placeholder
+ * with no function. End probing now with no error reported.
+ */
+ return -ENODEV;
+ }
vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
- writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
+ /* Reject legacy-only IDs for version 2 devices */
+ if (vm_dev->version == 2 &&
+ virtio_device_is_legacy_only(vm_dev->vdev.id)) {
+ dev_err(&pdev->dev, "Version 2 not supported for devices %u!\n",
+ vm_dev->vdev.id.device);
+ return -ENODEV;
+ }
+
+ if (vm_dev->version == 1)
+ writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
platform_set_drvdata(pdev, vm_dev);
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 9756f21b809e..e894eb278d83 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -19,6 +19,14 @@
#include "virtio_pci_common.h"
+static bool force_legacy = false;
+
+#if IS_ENABLED(CONFIG_VIRTIO_PCI_LEGACY)
+module_param(force_legacy, bool, 0444);
+MODULE_PARM_DESC(force_legacy,
+ "Force legacy mode for transitional virtio 1 devices");
+#endif
+
/* wait for pending irq handlers */
void vp_synchronize_vectors(struct virtio_device *vdev)
{
@@ -464,15 +472,97 @@ static const struct pci_device_id virtio_pci_id_table[] = {
MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);
+static void virtio_pci_release_dev(struct device *_d)
+{
+ struct virtio_device *vdev = dev_to_virtio(_d);
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+
+ /* As struct device is a kobject, it's not safe to
+ * free the memory (including the reference counter itself)
+ * until it's release callback. */
+ kfree(vp_dev);
+}
+
static int virtio_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
- return virtio_pci_legacy_probe(pci_dev, id);
+ struct virtio_pci_device *vp_dev;
+ int rc;
+
+ /* allocate our structure and fill it out */
+ vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL);
+ if (!vp_dev)
+ return -ENOMEM;
+
+ pci_set_drvdata(pci_dev, vp_dev);
+ vp_dev->vdev.dev.parent = &pci_dev->dev;
+ vp_dev->vdev.dev.release = virtio_pci_release_dev;
+ vp_dev->pci_dev = pci_dev;
+ INIT_LIST_HEAD(&vp_dev->virtqueues);
+ spin_lock_init(&vp_dev->lock);
+
+ /* Disable MSI/MSIX to bring device to a known good state. */
+ pci_msi_off(pci_dev);
+
+ /* enable the device */
+ rc = pci_enable_device(pci_dev);
+ if (rc)
+ goto err_enable_device;
+
+ rc = pci_request_regions(pci_dev, "virtio-pci");
+ if (rc)
+ goto err_request_regions;
+
+ if (force_legacy) {
+ rc = virtio_pci_legacy_probe(vp_dev);
+ /* Also try modern mode if we can't map BAR0 (no IO space). */
+ if (rc == -ENODEV || rc == -ENOMEM)
+ rc = virtio_pci_modern_probe(vp_dev);
+ if (rc)
+ goto err_probe;
+ } else {
+ rc = virtio_pci_modern_probe(vp_dev);
+ if (rc == -ENODEV)
+ rc = virtio_pci_legacy_probe(vp_dev);
+ if (rc)
+ goto err_probe;
+ }
+
+ pci_set_master(pci_dev);
+
+ rc = register_virtio_device(&vp_dev->vdev);
+ if (rc)
+ goto err_register;
+
+ return 0;
+
+err_register:
+ if (vp_dev->ioaddr)
+ virtio_pci_legacy_remove(vp_dev);
+ else
+ virtio_pci_modern_remove(vp_dev);
+err_probe:
+ pci_release_regions(pci_dev);
+err_request_regions:
+ pci_disable_device(pci_dev);
+err_enable_device:
+ kfree(vp_dev);
+ return rc;
}
static void virtio_pci_remove(struct pci_dev *pci_dev)
{
- virtio_pci_legacy_remove(pci_dev);
+ struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
+
+ unregister_virtio_device(&vp_dev->vdev);
+
+ if (vp_dev->ioaddr)
+ virtio_pci_legacy_remove(vp_dev);
+ else
+ virtio_pci_modern_remove(vp_dev);
+
+ pci_release_regions(pci_dev);
+ pci_disable_device(pci_dev);
}
static struct pci_driver virtio_pci_driver = {
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h
index 5a497289b7e9..28ee4e56badf 100644
--- a/drivers/virtio/virtio_pci_common.h
+++ b/drivers/virtio/virtio_pci_common.h
@@ -53,12 +53,32 @@ struct virtio_pci_device {
struct virtio_device vdev;
struct pci_dev *pci_dev;
+ /* In legacy mode, these two point to within ->legacy. */
+ /* Where to read and clear interrupt */
+ u8 __iomem *isr;
+
+ /* Modern only fields */
+ /* The IO mapping for the PCI config space (non-legacy mode) */
+ struct virtio_pci_common_cfg __iomem *common;
+ /* Device-specific data (non-legacy mode) */
+ void __iomem *device;
+ /* Base of vq notifications (non-legacy mode). */
+ void __iomem *notify_base;
+
+ /* So we can sanity-check accesses. */
+ size_t notify_len;
+ size_t device_len;
+
+ /* Capability for when we need to map notifications per-vq. */
+ int notify_map_cap;
+
+ /* Multiply queue_notify_off by this value. (non-legacy mode). */
+ u32 notify_offset_multiplier;
+
+ /* Legacy only field */
/* the IO mapping for the PCI config space */
void __iomem *ioaddr;
- /* the IO mapping for ISR operation */
- void __iomem *isr;
-
/* a list of queues so we can dispatch IRQs */
spinlock_t lock;
struct list_head virtqueues;
@@ -127,8 +147,19 @@ const char *vp_bus_name(struct virtio_device *vdev);
*/
int vp_set_vq_affinity(struct virtqueue *vq, int cpu);
-int virtio_pci_legacy_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *id);
-void virtio_pci_legacy_remove(struct pci_dev *pci_dev);
+#if IS_ENABLED(CONFIG_VIRTIO_PCI_LEGACY)
+int virtio_pci_legacy_probe(struct virtio_pci_device *);
+void virtio_pci_legacy_remove(struct virtio_pci_device *);
+#else
+static inline int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
+{
+ return -ENODEV;
+}
+static inline void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev)
+{
+}
+#endif
+int virtio_pci_modern_probe(struct virtio_pci_device *);
+void virtio_pci_modern_remove(struct virtio_pci_device *);
#endif
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
index a5486e65e04b..256a5278a515 100644
--- a/drivers/virtio/virtio_pci_legacy.c
+++ b/drivers/virtio/virtio_pci_legacy.c
@@ -211,23 +211,10 @@ static const struct virtio_config_ops virtio_pci_config_ops = {
.set_vq_affinity = vp_set_vq_affinity,
};
-static void virtio_pci_release_dev(struct device *_d)
-{
- struct virtio_device *vdev = dev_to_virtio(_d);
- struct virtio_pci_device *vp_dev = to_vp_device(vdev);
-
- /* As struct device is a kobject, it's not safe to
- * free the memory (including the reference counter itself)
- * until it's release callback. */
- kfree(vp_dev);
-}
-
/* the PCI probing function */
-int virtio_pci_legacy_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *id)
+int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
{
- struct virtio_pci_device *vp_dev;
- int err;
+ struct pci_dev *pci_dev = vp_dev->pci_dev;
/* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */
if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f)
@@ -239,41 +226,12 @@ int virtio_pci_legacy_probe(struct pci_dev *pci_dev,
return -ENODEV;
}
- /* allocate our structure and fill it out */
- vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL);
- if (vp_dev == NULL)
- return -ENOMEM;
-
- vp_dev->vdev.dev.parent = &pci_dev->dev;
- vp_dev->vdev.dev.release = virtio_pci_release_dev;
- vp_dev->vdev.config = &virtio_pci_config_ops;
- vp_dev->pci_dev = pci_dev;
- INIT_LIST_HEAD(&vp_dev->virtqueues);
- spin_lock_init(&vp_dev->lock);
-
- /* Disable MSI/MSIX to bring device to a known good state. */
- pci_msi_off(pci_dev);
-
- /* enable the device */
- err = pci_enable_device(pci_dev);
- if (err)
- goto out;
-
- err = pci_request_regions(pci_dev, "virtio-pci");
- if (err)
- goto out_enable_device;
-
vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0);
- if (vp_dev->ioaddr == NULL) {
- err = -ENOMEM;
- goto out_req_regions;
- }
+ if (!vp_dev->ioaddr)
+ return -ENOMEM;
vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR;
- pci_set_drvdata(pci_dev, vp_dev);
- pci_set_master(pci_dev);
-
/* we use the subsystem vendor/device id as the virtio vendor/device
* id. this allows us to use the same PCI vendor/device id for all
* virtio devices and to identify the particular virtio driver by
@@ -281,36 +239,18 @@ int virtio_pci_legacy_probe(struct pci_dev *pci_dev,
vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor;
vp_dev->vdev.id.device = pci_dev->subsystem_device;
+ vp_dev->vdev.config = &virtio_pci_config_ops;
+
vp_dev->config_vector = vp_config_vector;
vp_dev->setup_vq = setup_vq;
vp_dev->del_vq = del_vq;
- /* finally register the virtio device */
- err = register_virtio_device(&vp_dev->vdev);
- if (err)
- goto out_set_drvdata;
-
return 0;
-
-out_set_drvdata:
- pci_iounmap(pci_dev, vp_dev->ioaddr);
-out_req_regions:
- pci_release_regions(pci_dev);
-out_enable_device:
- pci_disable_device(pci_dev);
-out:
- kfree(vp_dev);
- return err;
}
-void virtio_pci_legacy_remove(struct pci_dev *pci_dev)
+void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev)
{
- struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
-
- unregister_virtio_device(&vp_dev->vdev);
+ struct pci_dev *pci_dev = vp_dev->pci_dev;
- vp_del_vqs(&vp_dev->vdev);
pci_iounmap(pci_dev, vp_dev->ioaddr);
- pci_release_regions(pci_dev);
- pci_disable_device(pci_dev);
}
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
new file mode 100644
index 000000000000..2aa38e59db2e
--- /dev/null
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -0,0 +1,695 @@
+/*
+ * Virtio PCI driver - modern (virtio 1.0) device support
+ *
+ * This module allows virtio devices to be used over a virtual PCI device.
+ * This can be used with QEMU based VMMs like KVM or Xen.
+ *
+ * Copyright IBM Corp. 2007
+ * Copyright Red Hat, Inc. 2014
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Rusty Russell <rusty@rustcorp.com.au>
+ * Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#define VIRTIO_PCI_NO_LEGACY
+#include "virtio_pci_common.h"
+
+static void __iomem *map_capability(struct pci_dev *dev, int off,
+ size_t minlen,
+ u32 align,
+ u32 start, u32 size,
+ size_t *len)
+{
+ u8 bar;
+ u32 offset, length;
+ void __iomem *p;
+
+ pci_read_config_byte(dev, off + offsetof(struct virtio_pci_cap,
+ bar),
+ &bar);
+ pci_read_config_dword(dev, off + offsetof(struct virtio_pci_cap, offset),
+ &offset);
+ pci_read_config_dword(dev, off + offsetof(struct virtio_pci_cap, length),
+ &length);
+
+ if (length <= start) {
+ dev_err(&dev->dev,
+ "virtio_pci: bad capability len %u (>%u expected)\n",
+ length, start);
+ return NULL;
+ }
+
+ if (length - start < minlen) {
+ dev_err(&dev->dev,
+ "virtio_pci: bad capability len %u (>=%zu expected)\n",
+ length, minlen);
+ return NULL;
+ }
+
+ length -= start;
+
+ if (start + offset < offset) {
+ dev_err(&dev->dev,
+ "virtio_pci: map wrap-around %u+%u\n",
+ start, offset);
+ return NULL;
+ }
+
+ offset += start;
+
+ if (offset & (align - 1)) {
+ dev_err(&dev->dev,
+ "virtio_pci: offset %u not aligned to %u\n",
+ offset, align);
+ return NULL;
+ }
+
+ if (length > size)
+ length = size;
+
+ if (len)
+ *len = length;
+
+ if (minlen + offset < minlen ||
+ minlen + offset > pci_resource_len(dev, bar)) {
+ dev_err(&dev->dev,
+ "virtio_pci: map virtio %zu@%u "
+ "out of range on bar %i length %lu\n",
+ minlen, offset,
+ bar, (unsigned long)pci_resource_len(dev, bar));
+ return NULL;
+ }
+
+ p = pci_iomap_range(dev, bar, offset, length);
+ if (!p)
+ dev_err(&dev->dev,
+ "virtio_pci: unable to map virtio %u@%u on bar %i\n",
+ length, offset, bar);
+ return p;
+}
+
+static void iowrite64_twopart(u64 val, __le32 __iomem *lo, __le32 __iomem *hi)
+{
+ iowrite32((u32)val, lo);
+ iowrite32(val >> 32, hi);
+}
+
+/* virtio config->get_features() implementation */
+static u64 vp_get_features(struct virtio_device *vdev)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ u64 features;
+
+ iowrite32(0, &vp_dev->common->device_feature_select);
+ features = ioread32(&vp_dev->common->device_feature);
+ iowrite32(1, &vp_dev->common->device_feature_select);
+ features |= ((u64)ioread32(&vp_dev->common->device_feature) << 32);
+
+ return features;
+}
+
+/* virtio config->finalize_features() implementation */
+static int vp_finalize_features(struct virtio_device *vdev)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+
+ /* Give virtio_ring a chance to accept features. */
+ vring_transport_features(vdev);
+
+ if (!__virtio_test_bit(vdev, VIRTIO_F_VERSION_1)) {
+ dev_err(&vdev->dev, "virtio: device uses modern interface "
+ "but does not have VIRTIO_F_VERSION_1\n");
+ return -EINVAL;
+ }
+
+ iowrite32(0, &vp_dev->common->guest_feature_select);
+ iowrite32((u32)vdev->features, &vp_dev->common->guest_feature);
+ iowrite32(1, &vp_dev->common->guest_feature_select);
+ iowrite32(vdev->features >> 32, &vp_dev->common->guest_feature);
+
+ return 0;
+}
+
+/* virtio config->get() implementation */
+static void vp_get(struct virtio_device *vdev, unsigned offset,
+ void *buf, unsigned len)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ u8 b;
+ __le16 w;
+ __le32 l;
+
+ BUG_ON(offset + len > vp_dev->device_len);
+
+ switch (len) {
+ case 1:
+ b = ioread8(vp_dev->device + offset);
+ memcpy(buf, &b, sizeof b);
+ break;
+ case 2:
+ w = cpu_to_le16(ioread16(vp_dev->device + offset));
+ memcpy(buf, &w, sizeof w);
+ break;
+ case 4:
+ l = cpu_to_le32(ioread32(vp_dev->device + offset));
+ memcpy(buf, &l, sizeof l);
+ break;
+ case 8:
+ l = cpu_to_le32(ioread32(vp_dev->device + offset));
+ memcpy(buf, &l, sizeof l);
+ l = cpu_to_le32(ioread32(vp_dev->device + offset + sizeof l));
+ memcpy(buf + sizeof l, &l, sizeof l);
+ break;
+ default:
+ BUG();
+ }
+}
+
+/* the config->set() implementation. it's symmetric to the config->get()
+ * implementation */
+static void vp_set(struct virtio_device *vdev, unsigned offset,
+ const void *buf, unsigned len)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ u8 b;
+ __le16 w;
+ __le32 l;
+
+ BUG_ON(offset + len > vp_dev->device_len);
+
+ switch (len) {
+ case 1:
+ memcpy(&b, buf, sizeof b);
+ iowrite8(b, vp_dev->device + offset);
+ break;
+ case 2:
+ memcpy(&w, buf, sizeof w);
+ iowrite16(le16_to_cpu(w), vp_dev->device + offset);
+ break;
+ case 4:
+ memcpy(&l, buf, sizeof l);
+ iowrite32(le32_to_cpu(l), vp_dev->device + offset);
+ break;
+ case 8:
+ memcpy(&l, buf, sizeof l);
+ iowrite32(le32_to_cpu(l), vp_dev->device + offset);
+ memcpy(&l, buf + sizeof l, sizeof l);
+ iowrite32(le32_to_cpu(l), vp_dev->device + offset + sizeof l);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static u32 vp_generation(struct virtio_device *vdev)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ return ioread8(&vp_dev->common->config_generation);
+}
+
+/* config->{get,set}_status() implementations */
+static u8 vp_get_status(struct virtio_device *vdev)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ return ioread8(&vp_dev->common->device_status);
+}
+
+static void vp_set_status(struct virtio_device *vdev, u8 status)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ /* We should never be setting status to 0. */
+ BUG_ON(status == 0);
+ iowrite8(status, &vp_dev->common->device_status);
+}
+
+static void vp_reset(struct virtio_device *vdev)
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ /* 0 status means a reset. */
+ iowrite8(0, &vp_dev->common->device_status);
+ /* Flush out the status write, and flush in device writes,
+ * including MSI-X interrupts, if any. */
+ ioread8(&vp_dev->common->device_status);
+ /* Flush pending VQ/configuration callbacks. */
+ vp_synchronize_vectors(vdev);
+}
+
+static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector)
+{
+ /* Setup the vector used for configuration events */
+ iowrite16(vector, &vp_dev->common->msix_config);
+ /* Verify we had enough resources to assign the vector */
+ /* Will also flush the write out to device */
+ return ioread16(&vp_dev->common->msix_config);
+}
+
+static size_t vring_pci_size(u16 num)
+{
+ /* We only need a cacheline separation. */
+ return PAGE_ALIGN(vring_size(num, SMP_CACHE_BYTES));
+}
+
+static void *alloc_virtqueue_pages(int *num)
+{
+ void *pages;
+
+ /* TODO: allocate each queue chunk individually */
+ for (; *num && vring_pci_size(*num) > PAGE_SIZE; *num /= 2) {
+ pages = alloc_pages_exact(vring_pci_size(*num),
+ GFP_KERNEL|__GFP_ZERO|__GFP_NOWARN);
+ if (pages)
+ return pages;
+ }
+
+ if (!*num)
+ return NULL;
+
+ /* Try to get a single page. You are my only hope! */
+ return alloc_pages_exact(vring_pci_size(*num), GFP_KERNEL|__GFP_ZERO);
+}
+
+static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
+ struct virtio_pci_vq_info *info,
+ unsigned index,
+ void (*callback)(struct virtqueue *vq),
+ const char *name,
+ u16 msix_vec)
+{
+ struct virtio_pci_common_cfg __iomem *cfg = vp_dev->common;
+ struct virtqueue *vq;
+ u16 num, off;
+ int err;
+
+ if (index >= ioread16(&cfg->num_queues))
+ return ERR_PTR(-ENOENT);
+
+ /* Select the queue we're interested in */
+ iowrite16(index, &cfg->queue_select);
+
+ /* Check if queue is either not available or already active. */
+ num = ioread16(&cfg->queue_size);
+ if (!num || ioread16(&cfg->queue_enable))
+ return ERR_PTR(-ENOENT);
+
+ if (num & (num - 1)) {
+ dev_warn(&vp_dev->pci_dev->dev, "bad queue size %u", num);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* get offset of notification word for this vq */
+ off = ioread16(&cfg->queue_notify_off);
+
+ info->num = num;
+ info->msix_vector = msix_vec;
+
+ info->queue = alloc_virtqueue_pages(&info->num);
+ if (info->queue == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* create the vring */
+ vq = vring_new_virtqueue(index, info->num,
+ SMP_CACHE_BYTES, &vp_dev->vdev,
+ true, info->queue, vp_notify, callback, name);
+ if (!vq) {
+ err = -ENOMEM;
+ goto err_new_queue;
+ }
+
+ /* activate the queue */
+ iowrite16(num, &cfg->queue_size);
+ iowrite64_twopart(virt_to_phys(info->queue),
+ &cfg->queue_desc_lo, &cfg->queue_desc_hi);
+ iowrite64_twopart(virt_to_phys(virtqueue_get_avail(vq)),
+ &cfg->queue_avail_lo, &cfg->queue_avail_hi);
+ iowrite64_twopart(virt_to_phys(virtqueue_get_used(vq)),
+ &cfg->queue_used_lo, &cfg->queue_used_hi);
+
+ if (vp_dev->notify_base) {
+ /* offset should not wrap */
+ if ((u64)off * vp_dev->notify_offset_multiplier + 2
+ > vp_dev->notify_len) {
+ dev_warn(&vp_dev->pci_dev->dev,
+ "bad notification offset %u (x %u) "
+ "for queue %u > %zd",
+ off, vp_dev->notify_offset_multiplier,
+ index, vp_dev->notify_len);
+ err = -EINVAL;
+ goto err_map_notify;
+ }
+ vq->priv = (void __force *)vp_dev->notify_base +
+ off * vp_dev->notify_offset_multiplier;
+ } else {
+ vq->priv = (void __force *)map_capability(vp_dev->pci_dev,
+ vp_dev->notify_map_cap, 2, 2,
+ off * vp_dev->notify_offset_multiplier, 2,
+ NULL);
+ }
+
+ if (!vq->priv) {
+ err = -ENOMEM;
+ goto err_map_notify;
+ }
+
+ if (msix_vec != VIRTIO_MSI_NO_VECTOR) {
+ iowrite16(msix_vec, &cfg->queue_msix_vector);
+ msix_vec = ioread16(&cfg->queue_msix_vector);
+ if (msix_vec == VIRTIO_MSI_NO_VECTOR) {
+ err = -EBUSY;
+ goto err_assign_vector;
+ }
+ }
+
+ return vq;
+
+err_assign_vector:
+ if (!vp_dev->notify_base)
+ pci_iounmap(vp_dev->pci_dev, (void __iomem __force *)vq->priv);
+err_map_notify:
+ vring_del_virtqueue(vq);
+err_new_queue:
+ free_pages_exact(info->queue, vring_pci_size(info->num));
+ return ERR_PTR(err);
+}
+
+static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+ struct virtqueue *vqs[],
+ vq_callback_t *callbacks[],
+ const char *names[])
+{
+ struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+ struct virtqueue *vq;
+ int rc = vp_find_vqs(vdev, nvqs, vqs, callbacks, names);
+
+ if (rc)
+ return rc;
+
+ /* Select and activate all queues. Has to be done last: once we do
+ * this, there's no way to go back except reset.
+ */
+ list_for_each_entry(vq, &vdev->vqs, list) {
+ iowrite16(vq->index, &vp_dev->common->queue_select);
+ iowrite16(1, &vp_dev->common->queue_enable);
+ }
+
+ return 0;
+}
+
+static void del_vq(struct virtio_pci_vq_info *info)
+{
+ struct virtqueue *vq = info->vq;
+ struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
+
+ iowrite16(vq->index, &vp_dev->common->queue_select);
+
+ if (vp_dev->msix_enabled) {
+ iowrite16(VIRTIO_MSI_NO_VECTOR,
+ &vp_dev->common->queue_msix_vector);
+ /* Flush the write out to device */
+ ioread16(&vp_dev->common->queue_msix_vector);
+ }
+
+ if (!vp_dev->notify_base)
+ pci_iounmap(vp_dev->pci_dev, (void __force __iomem *)vq->priv);
+
+ vring_del_virtqueue(vq);
+
+ free_pages_exact(info->queue, vring_pci_size(info->num));
+}
+
+static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
+ .get = NULL,
+ .set = NULL,
+ .generation = vp_generation,
+ .get_status = vp_get_status,
+ .set_status = vp_set_status,
+ .reset = vp_reset,
+ .find_vqs = vp_modern_find_vqs,
+ .del_vqs = vp_del_vqs,
+ .get_features = vp_get_features,
+ .finalize_features = vp_finalize_features,
+ .bus_name = vp_bus_name,
+ .set_vq_affinity = vp_set_vq_affinity,
+};
+
+static const struct virtio_config_ops virtio_pci_config_ops = {
+ .get = vp_get,
+ .set = vp_set,
+ .generation = vp_generation,
+ .get_status = vp_get_status,
+ .set_status = vp_set_status,
+ .reset = vp_reset,
+ .find_vqs = vp_modern_find_vqs,
+ .del_vqs = vp_del_vqs,
+ .get_features = vp_get_features,
+ .finalize_features = vp_finalize_features,
+ .bus_name = vp_bus_name,
+ .set_vq_affinity = vp_set_vq_affinity,
+};
+
+/**
+ * virtio_pci_find_capability - walk capabilities to find device info.
+ * @dev: the pci device
+ * @cfg_type: the VIRTIO_PCI_CAP_* value we seek
+ * @ioresource_types: IORESOURCE_MEM and/or IORESOURCE_IO.
+ *
+ * Returns offset of the capability, or 0.
+ */
+static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 cfg_type,
+ u32 ioresource_types)
+{
+ int pos;
+
+ for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR);
+ pos > 0;
+ pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) {
+ u8 type, bar;
+ pci_read_config_byte(dev, pos + offsetof(struct virtio_pci_cap,
+ cfg_type),
+ &type);
+ pci_read_config_byte(dev, pos + offsetof(struct virtio_pci_cap,
+ bar),
+ &bar);
+
+ /* Ignore structures with reserved BAR values */
+ if (bar > 0x5)
+ continue;
+
+ if (type == cfg_type) {
+ if (pci_resource_len(dev, bar) &&
+ pci_resource_flags(dev, bar) & ioresource_types)
+ return pos;
+ }
+ }
+ return 0;
+}
+
+/* This is part of the ABI. Don't screw with it. */
+static inline void check_offsets(void)
+{
+ /* Note: disk space was harmed in compilation of this function. */
+ BUILD_BUG_ON(VIRTIO_PCI_CAP_VNDR !=
+ offsetof(struct virtio_pci_cap, cap_vndr));
+ BUILD_BUG_ON(VIRTIO_PCI_CAP_NEXT !=
+ offsetof(struct virtio_pci_cap, cap_next));
+ BUILD_BUG_ON(VIRTIO_PCI_CAP_LEN !=
+ offsetof(struct virtio_pci_cap, cap_len));
+ BUILD_BUG_ON(VIRTIO_PCI_CAP_CFG_TYPE !=
+ offsetof(struct virtio_pci_cap, cfg_type));
+ BUILD_BUG_ON(VIRTIO_PCI_CAP_BAR !=
+ offsetof(struct virtio_pci_cap, bar));
+ BUILD_BUG_ON(VIRTIO_PCI_CAP_OFFSET !=
+ offsetof(struct virtio_pci_cap, offset));
+ BUILD_BUG_ON(VIRTIO_PCI_CAP_LENGTH !=
+ offsetof(struct virtio_pci_cap, length));
+ BUILD_BUG_ON(VIRTIO_PCI_NOTIFY_CAP_MULT !=
+ offsetof(struct virtio_pci_notify_cap,
+ notify_off_multiplier));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_DFSELECT !=
+ offsetof(struct virtio_pci_common_cfg,
+ device_feature_select));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_DF !=
+ offsetof(struct virtio_pci_common_cfg, device_feature));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_GFSELECT !=
+ offsetof(struct virtio_pci_common_cfg,
+ guest_feature_select));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_GF !=
+ offsetof(struct virtio_pci_common_cfg, guest_feature));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_MSIX !=
+ offsetof(struct virtio_pci_common_cfg, msix_config));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_NUMQ !=
+ offsetof(struct virtio_pci_common_cfg, num_queues));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_STATUS !=
+ offsetof(struct virtio_pci_common_cfg, device_status));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_CFGGENERATION !=
+ offsetof(struct virtio_pci_common_cfg, config_generation));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_SELECT !=
+ offsetof(struct virtio_pci_common_cfg, queue_select));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_SIZE !=
+ offsetof(struct virtio_pci_common_cfg, queue_size));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_MSIX !=
+ offsetof(struct virtio_pci_common_cfg, queue_msix_vector));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_ENABLE !=
+ offsetof(struct virtio_pci_common_cfg, queue_enable));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_NOFF !=
+ offsetof(struct virtio_pci_common_cfg, queue_notify_off));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_DESCLO !=
+ offsetof(struct virtio_pci_common_cfg, queue_desc_lo));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_DESCHI !=
+ offsetof(struct virtio_pci_common_cfg, queue_desc_hi));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_AVAILLO !=
+ offsetof(struct virtio_pci_common_cfg, queue_avail_lo));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_AVAILHI !=
+ offsetof(struct virtio_pci_common_cfg, queue_avail_hi));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDLO !=
+ offsetof(struct virtio_pci_common_cfg, queue_used_lo));
+ BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDHI !=
+ offsetof(struct virtio_pci_common_cfg, queue_used_hi));
+}
+
+/* the PCI probing function */
+int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
+{
+ struct pci_dev *pci_dev = vp_dev->pci_dev;
+ int err, common, isr, notify, device;
+ u32 notify_length;
+ u32 notify_offset;
+
+ check_offsets();
+
+ /* We only own devices >= 0x1000 and <= 0x107f: leave the rest. */
+ if (pci_dev->device < 0x1000 || pci_dev->device > 0x107f)
+ return -ENODEV;
+
+ if (pci_dev->device < 0x1040) {
+ /* Transitional devices: use the PCI subsystem device id as
+ * virtio device id, same as legacy driver always did.
+ */
+ vp_dev->vdev.id.device = pci_dev->subsystem_device;
+ } else {
+ /* Modern devices: simply use PCI device id, but start from 0x1040. */
+ vp_dev->vdev.id.device = pci_dev->device - 0x1040;
+ }
+ vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor;
+
+ if (virtio_device_is_legacy_only(vp_dev->vdev.id))
+ return -ENODEV;
+
+ /* check for a common config: if not, use legacy mode (bar 0). */
+ common = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_COMMON_CFG,
+ IORESOURCE_IO | IORESOURCE_MEM);
+ if (!common) {
+ dev_info(&pci_dev->dev,
+ "virtio_pci: leaving for legacy driver\n");
+ return -ENODEV;
+ }
+
+ /* If common is there, these should be too... */
+ isr = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_ISR_CFG,
+ IORESOURCE_IO | IORESOURCE_MEM);
+ notify = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_NOTIFY_CFG,
+ IORESOURCE_IO | IORESOURCE_MEM);
+ if (!isr || !notify) {
+ dev_err(&pci_dev->dev,
+ "virtio_pci: missing capabilities %i/%i/%i\n",
+ common, isr, notify);
+ return -EINVAL;
+ }
+
+ /* Device capability is only mandatory for devices that have
+ * device-specific configuration.
+ */
+ device = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_DEVICE_CFG,
+ IORESOURCE_IO | IORESOURCE_MEM);
+
+ err = -EINVAL;
+ vp_dev->common = map_capability(pci_dev, common,
+ sizeof(struct virtio_pci_common_cfg), 4,
+ 0, sizeof(struct virtio_pci_common_cfg),
+ NULL);
+ if (!vp_dev->common)
+ goto err_map_common;
+ vp_dev->isr = map_capability(pci_dev, isr, sizeof(u8), 1,
+ 0, 1,
+ NULL);
+ if (!vp_dev->isr)
+ goto err_map_isr;
+
+ /* Read notify_off_multiplier from config space. */
+ pci_read_config_dword(pci_dev,
+ notify + offsetof(struct virtio_pci_notify_cap,
+ notify_off_multiplier),
+ &vp_dev->notify_offset_multiplier);
+ /* Read notify length and offset from config space. */
+ pci_read_config_dword(pci_dev,
+ notify + offsetof(struct virtio_pci_notify_cap,
+ cap.length),
+ &notify_length);
+
+ pci_read_config_dword(pci_dev,
+ notify + offsetof(struct virtio_pci_notify_cap,
+ cap.length),
+ &notify_offset);
+
+ /* We don't know how many VQs we'll map, ahead of the time.
+ * If notify length is small, map it all now.
+ * Otherwise, map each VQ individually later.
+ */
+ if ((u64)notify_length + (notify_offset % PAGE_SIZE) <= PAGE_SIZE) {
+ vp_dev->notify_base = map_capability(pci_dev, notify, 2, 2,
+ 0, notify_length,
+ &vp_dev->notify_len);
+ if (!vp_dev->notify_base)
+ goto err_map_notify;
+ } else {
+ vp_dev->notify_map_cap = notify;
+ }
+
+ /* Again, we don't know how much we should map, but PAGE_SIZE
+ * is more than enough for all existing devices.
+ */
+ if (device) {
+ vp_dev->device = map_capability(pci_dev, device, 0, 4,
+ 0, PAGE_SIZE,
+ &vp_dev->device_len);
+ if (!vp_dev->device)
+ goto err_map_device;
+
+ vp_dev->vdev.config = &virtio_pci_config_ops;
+ } else {
+ vp_dev->vdev.config = &virtio_pci_config_nodev_ops;
+ }
+
+ vp_dev->config_vector = vp_config_vector;
+ vp_dev->setup_vq = setup_vq;
+ vp_dev->del_vq = del_vq;
+
+ return 0;
+
+err_map_device:
+ if (vp_dev->notify_base)
+ pci_iounmap(pci_dev, vp_dev->notify_base);
+err_map_notify:
+ pci_iounmap(pci_dev, vp_dev->isr);
+err_map_isr:
+ pci_iounmap(pci_dev, vp_dev->common);
+err_map_common:
+ return err;
+}
+
+void virtio_pci_modern_remove(struct virtio_pci_device *vp_dev)
+{
+ struct pci_dev *pci_dev = vp_dev->pci_dev;
+
+ if (vp_dev->device)
+ pci_iounmap(pci_dev, vp_dev->device);
+ if (vp_dev->notify_base)
+ pci_iounmap(pci_dev, vp_dev->notify_base);
+ pci_iounmap(pci_dev, vp_dev->isr);
+ pci_iounmap(pci_dev, vp_dev->common);
+}
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 00ec6b3f96b2..096b857e7b75 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -54,8 +54,7 @@
#define END_USE(vq)
#endif
-struct vring_virtqueue
-{
+struct vring_virtqueue {
struct virtqueue vq;
/* Actual memory layout for this queue */
@@ -245,14 +244,14 @@ static inline int virtqueue_add(struct virtqueue *_vq,
vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) + 1);
vq->num_added++;
+ pr_debug("Added buffer head %i to %p\n", head, vq);
+ END_USE(vq);
+
/* This is very unlikely, but theoretically possible. Kick
* just in case. */
if (unlikely(vq->num_added == (1 << 16) - 1))
virtqueue_kick(_vq);
- pr_debug("Added buffer head %i to %p\n", head, vq);
- END_USE(vq);
-
return 0;
}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 08f41add1461..16f202350997 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -505,6 +505,16 @@ config MESON_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called meson_wdt.
+config MEDIATEK_WATCHDOG
+ tristate "Mediatek SoCs watchdog support"
+ depends on ARCH_MEDIATEK
+ select WATCHDOG_CORE
+ help
+ Say Y here to include support for the watchdog timer
+ in Mediatek SoCs.
+ To compile this driver as a module, choose M here: the
+ module will be called mtk_wdt.
+
# AVR32 Architecture
config AT32AP700X_WDT
@@ -1005,6 +1015,8 @@ config W83627HF_WDT
NCT6775
NCT6776
NCT6779
+ NCT6791
+ NCT6792
This watchdog simply watches your kernel to make sure it doesn't
freeze, and if it does, it reboots your computer after a certain
@@ -1101,7 +1113,7 @@ config ATH79_WDT
config BCM47XX_WDT
tristate "Broadcom BCM47xx Watchdog Timer"
- depends on BCM47XX
+ depends on BCM47XX || ARCH_BCM_5301X
select WATCHDOG_CORE
help
Hardware driver for the Broadcom BCM47xx Watchdog Timer.
@@ -1235,6 +1247,17 @@ config BCM_KONA_WDT_DEBUG
If in doubt, say 'N'.
+config IMGPDC_WDT
+ tristate "Imagination Technologies PDC Watchdog Timer"
+ depends on HAS_IOMEM
+ depends on METAG || MIPS || COMPILE_TEST
+ help
+ Driver for Imagination Technologies PowerDown Controller
+ Watchdog Timer.
+
+ To compile this driver as a loadable module, choose M here.
+ The module will be called imgpdc_wdt.
+
config LANTIQ_WDT
tristate "Lantiq SoC watchdog"
depends on LANTIQ
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index c569ec8f8a76..5c19294d1c30 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_QCOM_WDT) += qcom-wdt.o
obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o
obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o
+obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -142,6 +143,7 @@ obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o
+obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o
# PARISC Architecture
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 9816485f6825..b28a072abf78 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -169,6 +169,17 @@ static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
return NOTIFY_DONE;
}
+static int bcm47xx_wdt_restart(struct notifier_block *this, unsigned long mode,
+ void *cmd)
+{
+ struct bcm47xx_wdt *wdt;
+
+ wdt = container_of(this, struct bcm47xx_wdt, restart_handler);
+ wdt->timer_set(wdt, 1);
+
+ return NOTIFY_DONE;
+}
+
static struct watchdog_ops bcm47xx_wdt_soft_ops = {
.owner = THIS_MODULE,
.start = bcm47xx_wdt_soft_start,
@@ -209,15 +220,23 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
if (ret)
goto err_timer;
- ret = watchdog_register_device(&wdt->wdd);
+ wdt->restart_handler.notifier_call = &bcm47xx_wdt_restart;
+ wdt->restart_handler.priority = 64;
+ ret = register_restart_handler(&wdt->restart_handler);
if (ret)
goto err_notifier;
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret)
+ goto err_handler;
+
dev_info(&pdev->dev, "BCM47xx Watchdog Timer enabled (%d seconds%s%s)\n",
timeout, nowayout ? ", nowayout" : "",
soft ? ", Software Timer" : "");
return 0;
+err_handler:
+ unregister_restart_handler(&wdt->restart_handler);
err_notifier:
unregister_reboot_notifier(&wdt->notifier);
err_timer:
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index 2cd6b2c2dd2a..e2fe2ebdebd4 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/mfd/da9063/registers.h>
#include <linux/mfd/da9063/core.h>
+#include <linux/reboot.h>
#include <linux/regmap.h>
/*
@@ -38,6 +39,7 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
struct da9063_watchdog {
struct da9063 *da9063;
struct watchdog_device wdtdev;
+ struct notifier_block restart_handler;
};
static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs)
@@ -119,6 +121,23 @@ static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
return ret;
}
+static int da9063_wdt_restart_handler(struct notifier_block *this,
+ unsigned long mode, void *cmd)
+{
+ struct da9063_watchdog *wdt = container_of(this,
+ struct da9063_watchdog,
+ restart_handler);
+ int ret;
+
+ ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F,
+ DA9063_SHUTDOWN);
+ if (ret)
+ dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n",
+ ret);
+
+ return NOTIFY_DONE;
+}
+
static const struct watchdog_info da9063_watchdog_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
.identity = "DA9063 Watchdog",
@@ -163,14 +182,25 @@ static int da9063_wdt_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, wdt);
ret = watchdog_register_device(&wdt->wdtdev);
+ if (ret)
+ return ret;
- return ret;
+ wdt->restart_handler.notifier_call = da9063_wdt_restart_handler;
+ wdt->restart_handler.priority = 128;
+ ret = register_restart_handler(&wdt->restart_handler);
+ if (ret)
+ dev_err(wdt->da9063->dev,
+ "Failed to register restart handler (err = %d)\n", ret);
+
+ return 0;
}
static int da9063_wdt_remove(struct platform_device *pdev)
{
struct da9063_watchdog *wdt = dev_get_drvdata(&pdev->dev);
+ unregister_restart_handler(&wdt->restart_handler);
+
watchdog_unregister_device(&wdt->wdtdev);
return 0;
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index b34a2e4e4e43..d0bb9499d12c 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -51,6 +51,8 @@
/* The maximum TOP (timeout period) value that can be set in the watchdog. */
#define DW_WDT_MAX_TOP 15
+#define DW_WDT_DEFAULT_SECONDS 30
+
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
@@ -96,6 +98,12 @@ static inline void dw_wdt_set_next_heartbeat(void)
dw_wdt.next_heartbeat = jiffies + dw_wdt_get_top() * HZ;
}
+static void dw_wdt_keepalive(void)
+{
+ writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs +
+ WDOG_COUNTER_RESTART_REG_OFFSET);
+}
+
static int dw_wdt_set_top(unsigned top_s)
{
int i, top_val = DW_WDT_MAX_TOP;
@@ -110,21 +118,27 @@ static int dw_wdt_set_top(unsigned top_s)
break;
}
- /* Set the new value in the watchdog. */
+ /*
+ * Set the new value in the watchdog. Some versions of dw_wdt
+ * have have TOPINIT in the TIMEOUT_RANGE register (as per
+ * CP_WDT_DUAL_TOP in WDT_COMP_PARAMS_1). On those we
+ * effectively get a pat of the watchdog right here.
+ */
writel(top_val | top_val << WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT,
dw_wdt.regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
+ /*
+ * Add an explicit pat to handle versions of the watchdog that
+ * don't have TOPINIT. This won't hurt on versions that have
+ * it.
+ */
+ dw_wdt_keepalive();
+
dw_wdt_set_next_heartbeat();
return dw_wdt_top_in_seconds(top_val);
}
-static void dw_wdt_keepalive(void)
-{
- writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt.regs +
- WDOG_COUNTER_RESTART_REG_OFFSET);
-}
-
static int dw_wdt_restart_handle(struct notifier_block *this,
unsigned long mode, void *cmd)
{
@@ -167,9 +181,9 @@ static int dw_wdt_open(struct inode *inode, struct file *filp)
if (!dw_wdt_is_enabled()) {
/*
* The watchdog is not currently enabled. Set the timeout to
- * the maximum and then start it.
+ * something reasonable and then start it.
*/
- dw_wdt_set_top(DW_WDT_MAX_TOP);
+ dw_wdt_set_top(DW_WDT_DEFAULT_SECONDS);
writel(WDOG_CONTROL_REG_WDT_EN_MASK,
dw_wdt.regs + WDOG_CONTROL_REG_OFFSET);
}
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index bbdb19b45332..cbc313d37c59 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -31,6 +31,8 @@ struct gpio_wdt_priv {
int gpio;
bool active_low;
bool state;
+ bool always_running;
+ bool armed;
unsigned int hw_algo;
unsigned int hw_margin;
unsigned long last_jiffies;
@@ -48,14 +50,20 @@ static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
gpio_direction_input(priv->gpio);
}
-static int gpio_wdt_start(struct watchdog_device *wdd)
+static void gpio_wdt_start_impl(struct gpio_wdt_priv *priv)
{
- struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
-
priv->state = priv->active_low;
gpio_direction_output(priv->gpio, priv->state);
priv->last_jiffies = jiffies;
mod_timer(&priv->timer, priv->last_jiffies + priv->hw_margin);
+}
+
+static int gpio_wdt_start(struct watchdog_device *wdd)
+{
+ struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
+
+ gpio_wdt_start_impl(priv);
+ priv->armed = true;
return 0;
}
@@ -64,8 +72,11 @@ static int gpio_wdt_stop(struct watchdog_device *wdd)
{
struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
- mod_timer(&priv->timer, 0);
- gpio_wdt_disable(priv);
+ priv->armed = false;
+ if (!priv->always_running) {
+ mod_timer(&priv->timer, 0);
+ gpio_wdt_disable(priv);
+ }
return 0;
}
@@ -91,8 +102,8 @@ static void gpio_wdt_hwping(unsigned long data)
struct watchdog_device *wdd = (struct watchdog_device *)data;
struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
- if (time_after(jiffies, priv->last_jiffies +
- msecs_to_jiffies(wdd->timeout * 1000))) {
+ if (priv->armed && time_after(jiffies, priv->last_jiffies +
+ msecs_to_jiffies(wdd->timeout * 1000))) {
dev_crit(wdd->dev, "Timer expired. System will reboot soon!\n");
return;
}
@@ -197,6 +208,9 @@ static int gpio_wdt_probe(struct platform_device *pdev)
/* Use safe value (1/2 of real timeout) */
priv->hw_margin = msecs_to_jiffies(hw_margin / 2);
+ priv->always_running = of_property_read_bool(pdev->dev.of_node,
+ "always-running");
+
watchdog_set_drvdata(&priv->wdd, priv);
priv->wdd.info = &gpio_wdt_ident;
@@ -216,8 +230,15 @@ static int gpio_wdt_probe(struct platform_device *pdev)
priv->notifier.notifier_call = gpio_wdt_notify_sys;
ret = register_reboot_notifier(&priv->notifier);
if (ret)
- watchdog_unregister_device(&priv->wdd);
+ goto error_unregister;
+ if (priv->always_running)
+ gpio_wdt_start_impl(priv);
+
+ return 0;
+
+error_unregister:
+ watchdog_unregister_device(&priv->wdd);
return ret;
}
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 75d2243b94f5..ada3e44f9932 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -745,7 +745,7 @@ static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
dev_info(&dev->dev,
"HP Watchdog Timer Driver: NMI decoding initialized"
- ", allow kernel dump: %s (default = 0/OFF)\n",
+ ", allow kernel dump: %s (default = 1/ON)\n",
(allow_kdump == 0) ? "OFF" : "ON");
return 0;
diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c
new file mode 100644
index 000000000000..c8def68d9e4c
--- /dev/null
+++ b/drivers/watchdog/imgpdc_wdt.c
@@ -0,0 +1,289 @@
+/*
+ * Imagination Technologies PowerDown Controller Watchdog Timer.
+ *
+ * Copyright (c) 2014 Imagination Technologies Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * Based on drivers/watchdog/sunxi_wdt.c Copyright (c) 2013 Carlo Caione
+ * 2012 Henrik Nordstrom
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/watchdog.h>
+
+/* registers */
+#define PDC_WDT_SOFT_RESET 0x00
+#define PDC_WDT_CONFIG 0x04
+ #define PDC_WDT_CONFIG_ENABLE BIT(31)
+ #define PDC_WDT_CONFIG_DELAY_MASK 0x1f
+
+#define PDC_WDT_TICKLE1 0x08
+#define PDC_WDT_TICKLE1_MAGIC 0xabcd1234
+#define PDC_WDT_TICKLE2 0x0c
+#define PDC_WDT_TICKLE2_MAGIC 0x4321dcba
+
+#define PDC_WDT_TICKLE_STATUS_MASK 0x7
+#define PDC_WDT_TICKLE_STATUS_SHIFT 0
+#define PDC_WDT_TICKLE_STATUS_HRESET 0x0 /* Hard reset */
+#define PDC_WDT_TICKLE_STATUS_TIMEOUT 0x1 /* Timeout */
+#define PDC_WDT_TICKLE_STATUS_TICKLE 0x2 /* Tickled incorrectly */
+#define PDC_WDT_TICKLE_STATUS_SRESET 0x3 /* Soft reset */
+#define PDC_WDT_TICKLE_STATUS_USER 0x4 /* User reset */
+
+/* Timeout values are in seconds */
+#define PDC_WDT_MIN_TIMEOUT 1
+#define PDC_WDT_DEF_TIMEOUT 64
+
+static int heartbeat;
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. "
+ "(default = " __MODULE_STRING(PDC_WDT_DEF_TIMEOUT) ")");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+struct pdc_wdt_dev {
+ struct watchdog_device wdt_dev;
+ struct clk *wdt_clk;
+ struct clk *sys_clk;
+ void __iomem *base;
+};
+
+static int pdc_wdt_keepalive(struct watchdog_device *wdt_dev)
+{
+ struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev);
+
+ writel(PDC_WDT_TICKLE1_MAGIC, wdt->base + PDC_WDT_TICKLE1);
+ writel(PDC_WDT_TICKLE2_MAGIC, wdt->base + PDC_WDT_TICKLE2);
+
+ return 0;
+}
+
+static int pdc_wdt_stop(struct watchdog_device *wdt_dev)
+{
+ unsigned int val;
+ struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev);
+
+ val = readl(wdt->base + PDC_WDT_CONFIG);
+ val &= ~PDC_WDT_CONFIG_ENABLE;
+ writel(val, wdt->base + PDC_WDT_CONFIG);
+
+ /* Must tickle to finish the stop */
+ pdc_wdt_keepalive(wdt_dev);
+
+ return 0;
+}
+
+static int pdc_wdt_set_timeout(struct watchdog_device *wdt_dev,
+ unsigned int new_timeout)
+{
+ unsigned int val;
+ struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev);
+ unsigned long clk_rate = clk_get_rate(wdt->wdt_clk);
+
+ wdt->wdt_dev.timeout = new_timeout;
+
+ val = readl(wdt->base + PDC_WDT_CONFIG) & ~PDC_WDT_CONFIG_DELAY_MASK;
+ val |= order_base_2(new_timeout * clk_rate) - 1;
+ writel(val, wdt->base + PDC_WDT_CONFIG);
+
+ return 0;
+}
+
+/* Start the watchdog timer (delay should already be set) */
+static int pdc_wdt_start(struct watchdog_device *wdt_dev)
+{
+ unsigned int val;
+ struct pdc_wdt_dev *wdt = watchdog_get_drvdata(wdt_dev);
+
+ val = readl(wdt->base + PDC_WDT_CONFIG);
+ val |= PDC_WDT_CONFIG_ENABLE;
+ writel(val, wdt->base + PDC_WDT_CONFIG);
+
+ return 0;
+}
+
+static struct watchdog_info pdc_wdt_info = {
+ .identity = "IMG PDC Watchdog",
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+};
+
+static const struct watchdog_ops pdc_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = pdc_wdt_start,
+ .stop = pdc_wdt_stop,
+ .ping = pdc_wdt_keepalive,
+ .set_timeout = pdc_wdt_set_timeout,
+};
+
+static int pdc_wdt_probe(struct platform_device *pdev)
+{
+ int ret, val;
+ unsigned long clk_rate;
+ struct resource *res;
+ struct pdc_wdt_dev *pdc_wdt;
+
+ pdc_wdt = devm_kzalloc(&pdev->dev, sizeof(*pdc_wdt), GFP_KERNEL);
+ if (!pdc_wdt)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pdc_wdt->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pdc_wdt->base))
+ return PTR_ERR(pdc_wdt->base);
+
+ pdc_wdt->sys_clk = devm_clk_get(&pdev->dev, "sys");
+ if (IS_ERR(pdc_wdt->sys_clk)) {
+ dev_err(&pdev->dev, "failed to get the sys clock\n");
+ return PTR_ERR(pdc_wdt->sys_clk);
+ }
+
+ pdc_wdt->wdt_clk = devm_clk_get(&pdev->dev, "wdt");
+ if (IS_ERR(pdc_wdt->wdt_clk)) {
+ dev_err(&pdev->dev, "failed to get the wdt clock\n");
+ return PTR_ERR(pdc_wdt->wdt_clk);
+ }
+
+ ret = clk_prepare_enable(pdc_wdt->sys_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "could not prepare or enable sys clock\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(pdc_wdt->wdt_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "could not prepare or enable wdt clock\n");
+ goto disable_sys_clk;
+ }
+
+ /* We use the clock rate to calculate the max timeout */
+ clk_rate = clk_get_rate(pdc_wdt->wdt_clk);
+ if (clk_rate == 0) {
+ dev_err(&pdev->dev, "failed to get clock rate\n");
+ ret = -EINVAL;
+ goto disable_wdt_clk;
+ }
+
+ if (order_base_2(clk_rate) > PDC_WDT_CONFIG_DELAY_MASK + 1) {
+ dev_err(&pdev->dev, "invalid clock rate\n");
+ ret = -EINVAL;
+ goto disable_wdt_clk;
+ }
+
+ if (order_base_2(clk_rate) == 0)
+ pdc_wdt->wdt_dev.min_timeout = PDC_WDT_MIN_TIMEOUT + 1;
+ else
+ pdc_wdt->wdt_dev.min_timeout = PDC_WDT_MIN_TIMEOUT;
+
+ pdc_wdt->wdt_dev.info = &pdc_wdt_info;
+ pdc_wdt->wdt_dev.ops = &pdc_wdt_ops;
+ pdc_wdt->wdt_dev.max_timeout = 1 << PDC_WDT_CONFIG_DELAY_MASK;
+ pdc_wdt->wdt_dev.parent = &pdev->dev;
+
+ ret = watchdog_init_timeout(&pdc_wdt->wdt_dev, heartbeat, &pdev->dev);
+ if (ret < 0) {
+ pdc_wdt->wdt_dev.timeout = pdc_wdt->wdt_dev.max_timeout;
+ dev_warn(&pdev->dev,
+ "Initial timeout out of range! setting max timeout\n");
+ }
+
+ pdc_wdt_stop(&pdc_wdt->wdt_dev);
+
+ /* Find what caused the last reset */
+ val = readl(pdc_wdt->base + PDC_WDT_TICKLE1);
+ val = (val & PDC_WDT_TICKLE_STATUS_MASK) >> PDC_WDT_TICKLE_STATUS_SHIFT;
+ switch (val) {
+ case PDC_WDT_TICKLE_STATUS_TICKLE:
+ case PDC_WDT_TICKLE_STATUS_TIMEOUT:
+ pdc_wdt->wdt_dev.bootstatus |= WDIOF_CARDRESET;
+ dev_info(&pdev->dev,
+ "watchdog module last reset due to timeout\n");
+ break;
+ case PDC_WDT_TICKLE_STATUS_HRESET:
+ dev_info(&pdev->dev,
+ "watchdog module last reset due to hard reset\n");
+ break;
+ case PDC_WDT_TICKLE_STATUS_SRESET:
+ dev_info(&pdev->dev,
+ "watchdog module last reset due to soft reset\n");
+ break;
+ case PDC_WDT_TICKLE_STATUS_USER:
+ dev_info(&pdev->dev,
+ "watchdog module last reset due to user reset\n");
+ break;
+ default:
+ dev_info(&pdev->dev,
+ "contains an illegal status code (%08x)\n", val);
+ break;
+ }
+
+ watchdog_set_nowayout(&pdc_wdt->wdt_dev, nowayout);
+
+ platform_set_drvdata(pdev, pdc_wdt);
+ watchdog_set_drvdata(&pdc_wdt->wdt_dev, pdc_wdt);
+
+ ret = watchdog_register_device(&pdc_wdt->wdt_dev);
+ if (ret)
+ goto disable_wdt_clk;
+
+ return 0;
+
+disable_wdt_clk:
+ clk_disable_unprepare(pdc_wdt->wdt_clk);
+disable_sys_clk:
+ clk_disable_unprepare(pdc_wdt->sys_clk);
+ return ret;
+}
+
+static void pdc_wdt_shutdown(struct platform_device *pdev)
+{
+ struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
+
+ pdc_wdt_stop(&pdc_wdt->wdt_dev);
+}
+
+static int pdc_wdt_remove(struct platform_device *pdev)
+{
+ struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev);
+
+ pdc_wdt_stop(&pdc_wdt->wdt_dev);
+ watchdog_unregister_device(&pdc_wdt->wdt_dev);
+ clk_disable_unprepare(pdc_wdt->wdt_clk);
+ clk_disable_unprepare(pdc_wdt->sys_clk);
+
+ return 0;
+}
+
+static const struct of_device_id pdc_wdt_match[] = {
+ { .compatible = "img,pdc-wdt" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, pdc_wdt_match);
+
+static struct platform_driver pdc_wdt_driver = {
+ .driver = {
+ .name = "imgpdc-wdt",
+ .of_match_table = pdc_wdt_match,
+ },
+ .probe = pdc_wdt_probe,
+ .remove = pdc_wdt_remove,
+ .shutdown = pdc_wdt_shutdown,
+};
+module_platform_driver(pdc_wdt_driver);
+
+MODULE_AUTHOR("Jude Abraham <Jude.Abraham@imgtec.com>");
+MODULE_AUTHOR("Naidu Tellapati <Naidu.Tellapati@imgtec.com>");
+MODULE_DESCRIPTION("Imagination Technologies PDC Watchdog Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 5142bbabe027..5e6d808d358a 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -205,7 +205,7 @@ static inline void imx2_wdt_ping_if_active(struct watchdog_device *wdog)
}
}
-static struct watchdog_ops imx2_wdt_ops = {
+static const struct watchdog_ops imx2_wdt_ops = {
.owner = THIS_MODULE,
.start = imx2_wdt_start,
.stop = imx2_wdt_stop,
@@ -213,7 +213,7 @@ static struct watchdog_ops imx2_wdt_ops = {
.set_timeout = imx2_wdt_set_timeout,
};
-static struct regmap_config imx2_wdt_regmap_config = {
+static const struct regmap_config imx2_wdt_regmap_config = {
.reg_bits = 16,
.reg_stride = 2,
.val_bits = 16,
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index 0b93739c0106..e54839b12650 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -12,8 +12,8 @@
* http://www.ite.com.tw/
*
* Support of the watchdog timers, which are available on
- * IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726
- * and IT8728.
+ * IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726,
+ * IT8728 and IT8783.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -87,6 +87,7 @@
#define IT8721_ID 0x8721
#define IT8726_ID 0x8726 /* the data sheet suggest wrongly 0x8716 */
#define IT8728_ID 0x8728
+#define IT8783_ID 0x8783
/* GPIO Configuration Registers LDN=0x07 */
#define WDTCTRL 0x71
@@ -633,6 +634,7 @@ static int __init it87_wdt_init(void)
case IT8720_ID:
case IT8721_ID:
case IT8728_ID:
+ case IT8783_ID:
max_units = 65535;
try_gameport = 0;
break;
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 18e41afa4da3..4c2cc09c0c57 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -24,6 +24,7 @@
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/err.h>
+#include <linux/of.h>
#include <asm/mach-jz4740/timer.h>
@@ -142,6 +143,14 @@ static const struct watchdog_ops jz4740_wdt_ops = {
.set_timeout = jz4740_wdt_set_timeout,
};
+#ifdef CONFIG_OF
+static const struct of_device_id jz4740_wdt_of_matches[] = {
+ { .compatible = "ingenic,jz4740-watchdog", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches)
+#endif
+
static int jz4740_wdt_probe(struct platform_device *pdev)
{
struct jz4740_wdt_drvdata *drvdata;
@@ -211,6 +220,7 @@ static struct platform_driver jz4740_wdt_driver = {
.remove = jz4740_wdt_remove,
.driver = {
.name = "jz4740-wdt",
+ .of_match_table = of_match_ptr(jz4740_wdt_of_matches),
},
};
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
new file mode 100644
index 000000000000..a87f6df6e85f
--- /dev/null
+++ b/drivers/watchdog/mtk_wdt.c
@@ -0,0 +1,251 @@
+/*
+ * Mediatek Watchdog Driver
+ *
+ * Copyright (C) 2014 Matthias Brugger
+ *
+ * Matthias Brugger <matthias.bgg@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Based on sunxi_wdt.c
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+
+#define WDT_MAX_TIMEOUT 31
+#define WDT_MIN_TIMEOUT 1
+#define WDT_LENGTH_TIMEOUT(n) ((n) << 5)
+
+#define WDT_LENGTH 0x04
+#define WDT_LENGTH_KEY 0x8
+
+#define WDT_RST 0x08
+#define WDT_RST_RELOAD 0x1971
+
+#define WDT_MODE 0x00
+#define WDT_MODE_EN (1 << 0)
+#define WDT_MODE_EXT_POL_LOW (0 << 1)
+#define WDT_MODE_EXT_POL_HIGH (1 << 1)
+#define WDT_MODE_EXRST_EN (1 << 2)
+#define WDT_MODE_IRQ_EN (1 << 3)
+#define WDT_MODE_AUTO_START (1 << 4)
+#define WDT_MODE_DUAL_EN (1 << 6)
+#define WDT_MODE_KEY 0x22000000
+
+#define WDT_SWRST 0x14
+#define WDT_SWRST_KEY 0x1209
+
+#define DRV_NAME "mtk-wdt"
+#define DRV_VERSION "1.0"
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+static unsigned int timeout = WDT_MAX_TIMEOUT;
+
+struct mtk_wdt_dev {
+ struct watchdog_device wdt_dev;
+ void __iomem *wdt_base;
+ struct notifier_block restart_handler;
+};
+
+static int mtk_reset_handler(struct notifier_block *this, unsigned long mode,
+ void *cmd)
+{
+ struct mtk_wdt_dev *mtk_wdt;
+ void __iomem *wdt_base;
+
+ mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler);
+ wdt_base = mtk_wdt->wdt_base;
+
+ while (1) {
+ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
+ mdelay(5);
+ }
+
+ return NOTIFY_DONE;
+}
+
+static int mtk_wdt_ping(struct watchdog_device *wdt_dev)
+{
+ struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+ void __iomem *wdt_base = mtk_wdt->wdt_base;
+
+ iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST);
+
+ return 0;
+}
+
+static int mtk_wdt_set_timeout(struct watchdog_device *wdt_dev,
+ unsigned int timeout)
+{
+ struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+ void __iomem *wdt_base = mtk_wdt->wdt_base;
+ u32 reg;
+
+ wdt_dev->timeout = timeout;
+
+ /*
+ * One bit is the value of 512 ticks
+ * The clock has 32 KHz
+ */
+ reg = WDT_LENGTH_TIMEOUT(timeout << 6) | WDT_LENGTH_KEY;
+ iowrite32(reg, wdt_base + WDT_LENGTH);
+
+ mtk_wdt_ping(wdt_dev);
+
+ return 0;
+}
+
+static int mtk_wdt_stop(struct watchdog_device *wdt_dev)
+{
+ struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+ void __iomem *wdt_base = mtk_wdt->wdt_base;
+ u32 reg;
+
+ reg = readl(wdt_base + WDT_MODE);
+ reg &= ~WDT_MODE_EN;
+ iowrite32(reg, wdt_base + WDT_MODE);
+
+ return 0;
+}
+
+static int mtk_wdt_start(struct watchdog_device *wdt_dev)
+{
+ u32 reg;
+ struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+ void __iomem *wdt_base = mtk_wdt->wdt_base;
+ u32 ret;
+
+ ret = mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
+ if (ret < 0)
+ return ret;
+
+ reg = ioread32(wdt_base + WDT_MODE);
+ reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
+ reg |= (WDT_MODE_EN | WDT_MODE_KEY);
+ iowrite32(reg, wdt_base + WDT_MODE);
+
+ return 0;
+}
+
+static const struct watchdog_info mtk_wdt_info = {
+ .identity = DRV_NAME,
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+};
+
+static const struct watchdog_ops mtk_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = mtk_wdt_start,
+ .stop = mtk_wdt_stop,
+ .ping = mtk_wdt_ping,
+ .set_timeout = mtk_wdt_set_timeout,
+};
+
+static int mtk_wdt_probe(struct platform_device *pdev)
+{
+ struct mtk_wdt_dev *mtk_wdt;
+ struct resource *res;
+ int err;
+
+ mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL);
+ if (!mtk_wdt)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, mtk_wdt);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mtk_wdt->wdt_base))
+ return PTR_ERR(mtk_wdt->wdt_base);
+
+ mtk_wdt->wdt_dev.info = &mtk_wdt_info;
+ mtk_wdt->wdt_dev.ops = &mtk_wdt_ops;
+ mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT;
+ mtk_wdt->wdt_dev.max_timeout = WDT_MAX_TIMEOUT;
+ mtk_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT;
+ mtk_wdt->wdt_dev.parent = &pdev->dev;
+
+ watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev);
+ watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout);
+
+ watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
+
+ mtk_wdt_stop(&mtk_wdt->wdt_dev);
+
+ err = watchdog_register_device(&mtk_wdt->wdt_dev);
+ if (unlikely(err))
+ return err;
+
+ mtk_wdt->restart_handler.notifier_call = mtk_reset_handler;
+ mtk_wdt->restart_handler.priority = 128;
+ err = register_restart_handler(&mtk_wdt->restart_handler);
+ if (err)
+ dev_warn(&pdev->dev,
+ "cannot register restart handler (err=%d)\n", err);
+
+ dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
+ mtk_wdt->wdt_dev.timeout, nowayout);
+
+ return 0;
+}
+
+static int mtk_wdt_remove(struct platform_device *pdev)
+{
+ struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
+
+ unregister_restart_handler(&mtk_wdt->restart_handler);
+
+ watchdog_unregister_device(&mtk_wdt->wdt_dev);
+
+ return 0;
+}
+
+static const struct of_device_id mtk_wdt_dt_ids[] = {
+ { .compatible = "mediatek,mt6589-wdt" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
+
+static struct platform_driver mtk_wdt_driver = {
+ .probe = mtk_wdt_probe,
+ .remove = mtk_wdt_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .of_match_table = mtk_wdt_dt_ids,
+ },
+};
+
+module_platform_driver(mtk_wdt_driver);
+
+module_param(timeout, uint, 0);
+MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds");
+
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Matthias Brugger <matthias.bgg@gmail.com>");
+MODULE_DESCRIPTION("Mediatek WatchDog Timer Driver");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 9f2709db61ca..1e6be9e40577 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -189,7 +189,7 @@ static int omap_wdt_set_timeout(struct watchdog_device *wdog,
}
static const struct watchdog_info omap_wdt_info = {
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.identity = "OMAP Watchdog",
};
diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c
index a7a0695971e4..b7c68e275aeb 100644
--- a/drivers/watchdog/retu_wdt.c
+++ b/drivers/watchdog/retu_wdt.c
@@ -94,7 +94,7 @@ static int retu_wdt_set_timeout(struct watchdog_device *wdog,
}
static const struct watchdog_info retu_wdt_info = {
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.identity = "Retu watchdog",
};
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index 11aad5b7aafe..a6f7e2e29beb 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -45,6 +45,7 @@
static struct clk *rt288x_wdt_clk;
static unsigned long rt288x_wdt_freq;
static void __iomem *rt288x_wdt_base;
+static struct reset_control *rt288x_wdt_reset;
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
@@ -151,16 +152,18 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
if (IS_ERR(rt288x_wdt_clk))
return PTR_ERR(rt288x_wdt_clk);
- device_reset(&pdev->dev);
+ rt288x_wdt_reset = devm_reset_control_get(&pdev->dev, NULL);
+ if (!IS_ERR(rt288x_wdt_reset))
+ reset_control_deassert(rt288x_wdt_reset);
rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE;
rt288x_wdt_dev.dev = &pdev->dev;
rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
-
rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
- rt288x_wdt_dev.timeout = rt288x_wdt_dev.max_timeout;
+ watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
+ &pdev->dev);
watchdog_set_nowayout(&rt288x_wdt_dev, nowayout);
ret = watchdog_register_device(&rt288x_wdt_dev);
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 12c15903d098..2c1db6fa9a27 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -57,7 +57,7 @@ static int twl4030_wdt_set_timeout(struct watchdog_device *wdt,
}
static const struct watchdog_info twl4030_wdt_info = {
- .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.identity = "TWL4030 Watchdog",
};
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 7165704a3e33..5824e25eebbb 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -50,7 +50,7 @@ static int cr_wdt_control; /* WDT control register */
enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf,
w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, w83627dhg_p,
- w83667hg_b, nct6775, nct6776, nct6779 };
+ w83667hg_b, nct6775, nct6776, nct6779, nct6791, nct6792 };
static int timeout; /* in seconds */
module_param(timeout, int, 0);
@@ -95,6 +95,8 @@ MODULE_PARM_DESC(early_disable, "Disable watchdog at boot time (default=0)");
#define NCT6775_ID 0xb4
#define NCT6776_ID 0xc3
#define NCT6779_ID 0xc5
+#define NCT6791_ID 0xc8
+#define NCT6792_ID 0xc9
#define W83627HF_WDT_TIMEOUT 0xf6
#define W83697HF_WDT_TIMEOUT 0xf4
@@ -195,6 +197,8 @@ static int w83627hf_init(struct watchdog_device *wdog, enum chips chip)
case nct6775:
case nct6776:
case nct6779:
+ case nct6791:
+ case nct6792:
/*
* These chips have a fixed WDTO# output pin (W83627UHG),
* or support more than one WDTO# output pin.
@@ -395,6 +399,12 @@ static int wdt_find(int addr)
case NCT6779_ID:
ret = nct6779;
break;
+ case NCT6791_ID:
+ ret = nct6791;
+ break;
+ case NCT6792_ID:
+ ret = nct6792;
+ break;
case 0xff:
ret = -ENODEV;
break;
@@ -428,6 +438,8 @@ static int __init wdt_init(void)
"NCT6775",
"NCT6776",
"NCT6779",
+ "NCT6791",
+ "NCT6792",
};
wdt_io = 0x2e;
diff --git a/fs/Kconfig b/fs/Kconfig
index a6bb530b1ec5..ec35851e5b71 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -13,13 +13,6 @@ if BLOCK
source "fs/ext2/Kconfig"
source "fs/ext3/Kconfig"
source "fs/ext4/Kconfig"
-
-config FS_XIP
-# execute in place
- bool
- depends on EXT2_FS_XIP
- default y
-
source "fs/jbd/Kconfig"
source "fs/jbd2/Kconfig"
@@ -40,6 +33,21 @@ source "fs/ocfs2/Kconfig"
source "fs/btrfs/Kconfig"
source "fs/nilfs2/Kconfig"
+config FS_DAX
+ bool "Direct Access (DAX) support"
+ depends on MMU
+ depends on !(ARM || MIPS || SPARC)
+ help
+ Direct Access (DAX) can be used on memory-backed block devices.
+ If the block device supports DAX and the filesystem supports DAX,
+ then you can avoid using the pagecache to buffer I/Os. Turning
+ on this option will compile in support for DAX; you will need to
+ mount the filesystem using the -o dax option.
+
+ If you do not have a block device that is capable of using this,
+ or if unsure, say N. Saying Y will increase the size of the kernel
+ by about 5kB.
+
endif # BLOCK
# Posix ACL utility routines
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index c055d56ec63d..270c48148f79 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -149,13 +149,6 @@ config BINFMT_EM86
later load the module when you want to use a Linux/Intel binary. The
module will be called binfmt_em86. If unsure, say Y.
-config BINFMT_SOM
- tristate "Kernel support for SOM binaries"
- depends on PARISC && HPUX
- help
- SOM is a binary executable format inherited from HP/UX. Say
- Y here to be able to load and execute SOM binaries directly.
-
config BINFMT_MISC
tristate "Kernel support for MISC binaries"
---help---
diff --git a/fs/Makefile b/fs/Makefile
index bedff48e8fdc..a88ac4838c9e 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SIGNALFD) += signalfd.o
obj-$(CONFIG_TIMERFD) += timerfd.o
obj-$(CONFIG_EVENTFD) += eventfd.o
obj-$(CONFIG_AIO) += aio.o
+obj-$(CONFIG_FS_DAX) += dax.o
obj-$(CONFIG_FILE_LOCKING) += locks.o
obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o
@@ -37,7 +38,6 @@ obj-$(CONFIG_BINFMT_SCRIPT) += binfmt_script.o
obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
-obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
obj-$(CONFIG_FS_MBCACHE) += mbcache.o
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index ff44ff3ff015..c8764bd7497d 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -30,6 +30,8 @@
#define AFFS_AC_SIZE (AFFS_CACHE_SIZE/sizeof(struct affs_ext_key)/2)
#define AFFS_AC_MASK (AFFS_AC_SIZE-1)
+#define AFFSNAMEMAX 30U
+
struct affs_ext_key {
u32 ext; /* idx of the extended block */
u32 key; /* block number */
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index c852f2fa1710..388da1ea815d 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -30,7 +30,7 @@ affs_insert_hash(struct inode *dir, struct buffer_head *bh)
ino = bh->b_blocknr;
offset = affs_hash_name(sb, AFFS_TAIL(sb, bh)->name + 1, AFFS_TAIL(sb, bh)->name[0]);
- pr_debug("%s(dir=%u, ino=%d)\n", __func__, (u32)dir->i_ino, ino);
+ pr_debug("%s(dir=%lu, ino=%d)\n", __func__, dir->i_ino, ino);
dir_bh = affs_bread(sb, dir->i_ino);
if (!dir_bh)
@@ -80,8 +80,8 @@ affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh)
sb = dir->i_sb;
rem_ino = rem_bh->b_blocknr;
offset = affs_hash_name(sb, AFFS_TAIL(sb, rem_bh)->name+1, AFFS_TAIL(sb, rem_bh)->name[0]);
- pr_debug("%s(dir=%d, ino=%d, hashval=%d)\n",
- __func__, (u32)dir->i_ino, rem_ino, offset);
+ pr_debug("%s(dir=%lu, ino=%d, hashval=%d)\n", __func__, dir->i_ino,
+ rem_ino, offset);
bh = affs_bread(sb, dir->i_ino);
if (!bh)
@@ -483,11 +483,10 @@ affs_check_name(const unsigned char *name, int len, bool notruncate)
{
int i;
- if (len > 30) {
+ if (len > AFFSNAMEMAX) {
if (notruncate)
return -ENAMETOOLONG;
- else
- len = 30;
+ len = AFFSNAMEMAX;
}
for (i = 0; i < len; i++) {
if (name[i] < ' ' || name[i] == ':'
@@ -508,7 +507,7 @@ affs_check_name(const unsigned char *name, int len, bool notruncate)
int
affs_copy_name(unsigned char *bstr, struct dentry *dentry)
{
- int len = min(dentry->d_name.len, 30u);
+ u32 len = min(dentry->d_name.len, AFFSNAMEMAX);
*bstr++ = len;
memcpy(bstr, dentry->d_name.name, len);
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c
index c8de51185c23..675148950fed 100644
--- a/fs/affs/bitmap.c
+++ b/fs/affs/bitmap.c
@@ -99,7 +99,6 @@ err_bh_read:
err_range:
affs_error(sb, "affs_free_block","Block %u outside partition", block);
- return;
}
/*
diff --git a/fs/affs/dir.c b/fs/affs/dir.c
index 59f07bec92a6..ac4f318aafba 100644
--- a/fs/affs/dir.c
+++ b/fs/affs/dir.c
@@ -54,8 +54,7 @@ affs_readdir(struct file *file, struct dir_context *ctx)
u32 ino;
int error = 0;
- pr_debug("%s(ino=%lu,f_pos=%lx)\n",
- __func__, inode->i_ino, (unsigned long)ctx->pos);
+ pr_debug("%s(ino=%lu,f_pos=%llx)\n", __func__, inode->i_ino, ctx->pos);
if (ctx->pos < 2) {
file->private_data = (void *)0;
@@ -115,11 +114,11 @@ inside:
break;
}
- namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30);
+ namelen = min(AFFS_TAIL(sb, fh_bh)->name[0],
+ (u8)AFFSNAMEMAX);
name = AFFS_TAIL(sb, fh_bh)->name + 1;
- pr_debug("readdir(): dir_emit(\"%.*s\", "
- "ino=%u), hash=%d, f_pos=%x\n",
- namelen, name, ino, hash_pos, (u32)ctx->pos);
+ pr_debug("readdir(): dir_emit(\"%.*s\", ino=%u), hash=%d, f_pos=%llx\n",
+ namelen, name, ino, hash_pos, ctx->pos);
if (!dir_emit(ctx, name, namelen, ino, DT_UNKNOWN))
goto done;
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 8faa6593ca6d..d2468bf95669 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -180,8 +180,7 @@ affs_get_extblock_slow(struct inode *inode, u32 ext)
ext_key = be32_to_cpu(AFFS_TAIL(sb, bh)->extension);
if (ext < AFFS_I(inode)->i_extcnt)
goto read_ext;
- if (ext > AFFS_I(inode)->i_extcnt)
- BUG();
+ BUG_ON(ext > AFFS_I(inode)->i_extcnt);
bh = affs_alloc_extblock(inode, bh, ext);
if (IS_ERR(bh))
return bh;
@@ -198,8 +197,7 @@ affs_get_extblock_slow(struct inode *inode, u32 ext)
struct buffer_head *prev_bh;
/* allocate a new extended block */
- if (ext > AFFS_I(inode)->i_extcnt)
- BUG();
+ BUG_ON(ext > AFFS_I(inode)->i_extcnt);
/* get previous extended block */
prev_bh = affs_get_extblock(inode, ext - 1);
@@ -299,8 +297,8 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
struct buffer_head *ext_bh;
u32 ext;
- pr_debug("%s(%u, %lu)\n",
- __func__, (u32)inode->i_ino, (unsigned long)block);
+ pr_debug("%s(%lu, %llu)\n", __func__, inode->i_ino,
+ (unsigned long long)block);
BUG_ON(block > (sector_t)0x7fffffffUL);
@@ -330,8 +328,9 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
/* store new block */
if (bh_result->b_blocknr)
- affs_warning(sb, "get_block", "block already set (%lx)",
- (unsigned long)bh_result->b_blocknr);
+ affs_warning(sb, "get_block",
+ "block already set (%llx)",
+ (unsigned long long)bh_result->b_blocknr);
AFFS_BLOCK(sb, ext_bh, block) = cpu_to_be32(blocknr);
AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(block + 1);
affs_adjust_checksum(ext_bh, blocknr - bh_result->b_blocknr + 1);
@@ -353,8 +352,8 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
return 0;
err_big:
- affs_error(inode->i_sb, "get_block", "strange block request %d",
- (int)block);
+ affs_error(inode->i_sb, "get_block", "strange block request %llu",
+ (unsigned long long)block);
return -EIO;
err_ext:
// unlock cache
@@ -399,6 +398,13 @@ affs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
size_t count = iov_iter_count(iter);
ssize_t ret;
+ if (rw == WRITE) {
+ loff_t size = offset + count;
+
+ if (AFFS_I(inode)->mmu_private < size)
+ return 0;
+ }
+
ret = blockdev_direct_IO(rw, iocb, inode, iter, offset, affs_get_block);
if (ret < 0 && (rw & WRITE))
affs_write_failed(mapping, offset + count);
@@ -503,7 +509,7 @@ affs_do_readpage_ofs(struct page *page, unsigned to)
u32 bidx, boff, bsize;
u32 tmp;
- pr_debug("%s(%u, %ld, 0, %d)\n", __func__, (u32)inode->i_ino,
+ pr_debug("%s(%lu, %ld, 0, %d)\n", __func__, inode->i_ino,
page->index, to);
BUG_ON(to > PAGE_CACHE_SIZE);
kmap(page);
@@ -539,7 +545,7 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize)
u32 size, bsize;
u32 tmp;
- pr_debug("%s(%u, %d)\n", __func__, (u32)inode->i_ino, newsize);
+ pr_debug("%s(%lu, %d)\n", __func__, inode->i_ino, newsize);
bsize = AFFS_SB(sb)->s_data_blksize;
bh = NULL;
size = AFFS_I(inode)->mmu_private;
@@ -608,7 +614,7 @@ affs_readpage_ofs(struct file *file, struct page *page)
u32 to;
int err;
- pr_debug("%s(%u, %ld)\n", __func__, (u32)inode->i_ino, page->index);
+ pr_debug("%s(%lu, %ld)\n", __func__, inode->i_ino, page->index);
to = PAGE_CACHE_SIZE;
if (((page->index + 1) << PAGE_CACHE_SHIFT) > inode->i_size) {
to = inode->i_size & ~PAGE_CACHE_MASK;
@@ -631,8 +637,8 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
pgoff_t index;
int err = 0;
- pr_debug("%s(%u, %llu, %llu)\n", __func__, (u32)inode->i_ino,
- (unsigned long long)pos, (unsigned long long)pos + len);
+ pr_debug("%s(%lu, %llu, %llu)\n", __func__, inode->i_ino, pos,
+ pos + len);
if (pos > AFFS_I(inode)->mmu_private) {
/* XXX: this probably leaves a too-big i_size in case of
* failure. Should really be updating i_size at write_end time
@@ -681,9 +687,8 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
* due to write_begin.
*/
- pr_debug("%s(%u, %llu, %llu)\n",
- __func__, (u32)inode->i_ino, (unsigned long long)pos,
- (unsigned long long)pos + len);
+ pr_debug("%s(%lu, %llu, %llu)\n", __func__, inode->i_ino, pos,
+ pos + len);
bsize = AFFS_SB(sb)->s_data_blksize;
data = page_address(page);
@@ -831,8 +836,8 @@ affs_truncate(struct inode *inode)
struct buffer_head *ext_bh;
int i;
- pr_debug("truncate(inode=%d, oldsize=%u, newsize=%u)\n",
- (u32)inode->i_ino, (u32)AFFS_I(inode)->mmu_private, (u32)inode->i_size);
+ pr_debug("truncate(inode=%lu, oldsize=%llu, newsize=%llu)\n",
+ inode->i_ino, AFFS_I(inode)->mmu_private, inode->i_size);
last_blk = 0;
ext = 0;
@@ -863,7 +868,7 @@ affs_truncate(struct inode *inode)
if (IS_ERR(ext_bh)) {
affs_warning(sb, "truncate",
"unexpected read error for ext block %u (%ld)",
- (unsigned int)ext, PTR_ERR(ext_bh));
+ ext, PTR_ERR(ext_bh));
return;
}
if (AFFS_I(inode)->i_lc) {
@@ -911,7 +916,7 @@ affs_truncate(struct inode *inode)
if (IS_ERR(bh)) {
affs_warning(sb, "truncate",
"unexpected read error for last block %u (%ld)",
- (unsigned int)ext, PTR_ERR(bh));
+ ext, PTR_ERR(bh));
return;
}
tmp = be32_to_cpu(AFFS_DATA_HEAD(bh)->next);
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index d0609a282e1d..6f34510449e8 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -13,8 +13,6 @@
#include <linux/gfp.h>
#include "affs.h"
-extern const struct inode_operations affs_symlink_inode_operations;
-
struct inode *affs_iget(struct super_block *sb, unsigned long ino)
{
struct affs_sb_info *sbi = AFFS_SB(sb);
@@ -348,9 +346,8 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
u32 block = 0;
int retval;
- pr_debug("%s(dir=%u, inode=%u, \"%pd\", type=%d)\n",
- __func__, (u32)dir->i_ino,
- (u32)inode->i_ino, dentry, type);
+ pr_debug("%s(dir=%lu, inode=%lu, \"%pd\", type=%d)\n", __func__,
+ dir->i_ino, inode->i_ino, dentry, type);
retval = -EIO;
bh = affs_bread(sb, inode->i_ino);
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index bbc38530e924..ffb7bd82c2a5 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -64,15 +64,16 @@ __affs_hash_dentry(struct qstr *qstr, toupper_t toupper, bool notruncate)
{
const u8 *name = qstr->name;
unsigned long hash;
- int i;
+ int retval;
+ u32 len;
- i = affs_check_name(qstr->name, qstr->len, notruncate);
- if (i)
- return i;
+ retval = affs_check_name(qstr->name, qstr->len, notruncate);
+ if (retval)
+ return retval;
hash = init_name_hash();
- i = min(qstr->len, 30u);
- for (; i > 0; name++, i--)
+ len = min(qstr->len, AFFSNAMEMAX);
+ for (; len > 0; name++, len--)
hash = partial_name_hash(toupper(*name), hash);
qstr->hash = end_name_hash(hash);
@@ -114,10 +115,10 @@ static inline int __affs_compare_dentry(unsigned int len,
* If the names are longer than the allowed 30 chars,
* the excess is ignored, so their length may differ.
*/
- if (len >= 30) {
- if (name->len < 30)
+ if (len >= AFFSNAMEMAX) {
+ if (name->len < AFFSNAMEMAX)
return 1;
- len = 30;
+ len = AFFSNAMEMAX;
} else if (len != name->len)
return 1;
@@ -156,10 +157,10 @@ affs_match(struct dentry *dentry, const u8 *name2, toupper_t toupper)
const u8 *name = dentry->d_name.name;
int len = dentry->d_name.len;
- if (len >= 30) {
- if (*name2 < 30)
+ if (len >= AFFSNAMEMAX) {
+ if (*name2 < AFFSNAMEMAX)
return 0;
- len = 30;
+ len = AFFSNAMEMAX;
} else if (len != *name2)
return 0;
@@ -173,9 +174,9 @@ int
affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len)
{
toupper_t toupper = affs_get_toupper(sb);
- int hash;
+ u32 hash;
- hash = len = min(len, 30u);
+ hash = len = min(len, AFFSNAMEMAX);
for (; len > 0; len--)
hash = (hash * 13 + toupper(*name++)) & 0x7ff;
@@ -248,9 +249,8 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
int
affs_unlink(struct inode *dir, struct dentry *dentry)
{
- pr_debug("%s(dir=%d, %lu \"%pd\")\n",
- __func__, (u32)dir->i_ino, dentry->d_inode->i_ino,
- dentry);
+ pr_debug("%s(dir=%lu, %lu \"%pd\")\n", __func__, dir->i_ino,
+ dentry->d_inode->i_ino, dentry);
return affs_remove_header(dentry);
}
@@ -317,9 +317,8 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
int
affs_rmdir(struct inode *dir, struct dentry *dentry)
{
- pr_debug("%s(dir=%u, %lu \"%pd\")\n",
- __func__, (u32)dir->i_ino, dentry->d_inode->i_ino,
- dentry);
+ pr_debug("%s(dir=%lu, %lu \"%pd\")\n", __func__, dir->i_ino,
+ dentry->d_inode->i_ino, dentry);
return affs_remove_header(dentry);
}
@@ -404,8 +403,7 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
struct inode *inode = old_dentry->d_inode;
- pr_debug("%s(%u, %u, \"%pd\")\n",
- __func__, (u32)inode->i_ino, (u32)dir->i_ino,
+ pr_debug("%s(%lu, %lu, \"%pd\")\n", __func__, inode->i_ino, dir->i_ino,
dentry);
return affs_add_entry(dir, inode, dentry, ST_LINKFILE);
@@ -419,9 +417,8 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct buffer_head *bh = NULL;
int retval;
- pr_debug("%s(old=%u,\"%pd\" to new=%u,\"%pd\")\n",
- __func__, (u32)old_dir->i_ino, old_dentry,
- (u32)new_dir->i_ino, new_dentry);
+ pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
+ old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);
retval = affs_check_name(new_dentry->d_name.name,
new_dentry->d_name.len,
diff --git a/fs/affs/super.c b/fs/affs/super.c
index f754ab68a840..4cf0e9113fb6 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -432,39 +432,39 @@ got_root:
sb->s_flags |= MS_RDONLY;
}
switch (chksum) {
- case MUFS_FS:
- case MUFS_INTLFFS:
- case MUFS_DCFFS:
- sbi->s_flags |= SF_MUFS;
- /* fall thru */
- case FS_INTLFFS:
- case FS_DCFFS:
- sbi->s_flags |= SF_INTL;
- break;
- case MUFS_FFS:
- sbi->s_flags |= SF_MUFS;
- break;
- case FS_FFS:
- break;
- case MUFS_OFS:
- sbi->s_flags |= SF_MUFS;
- /* fall thru */
- case FS_OFS:
- sbi->s_flags |= SF_OFS;
- sb->s_flags |= MS_NOEXEC;
- break;
- case MUFS_DCOFS:
- case MUFS_INTLOFS:
- sbi->s_flags |= SF_MUFS;
- case FS_DCOFS:
- case FS_INTLOFS:
- sbi->s_flags |= SF_INTL | SF_OFS;
- sb->s_flags |= MS_NOEXEC;
- break;
- default:
- pr_err("Unknown filesystem on device %s: %08X\n",
- sb->s_id, chksum);
- return -EINVAL;
+ case MUFS_FS:
+ case MUFS_INTLFFS:
+ case MUFS_DCFFS:
+ sbi->s_flags |= SF_MUFS;
+ /* fall thru */
+ case FS_INTLFFS:
+ case FS_DCFFS:
+ sbi->s_flags |= SF_INTL;
+ break;
+ case MUFS_FFS:
+ sbi->s_flags |= SF_MUFS;
+ break;
+ case FS_FFS:
+ break;
+ case MUFS_OFS:
+ sbi->s_flags |= SF_MUFS;
+ /* fall thru */
+ case FS_OFS:
+ sbi->s_flags |= SF_OFS;
+ sb->s_flags |= MS_NOEXEC;
+ break;
+ case MUFS_DCOFS:
+ case MUFS_INTLOFS:
+ sbi->s_flags |= SF_MUFS;
+ case FS_DCOFS:
+ case FS_INTLOFS:
+ sbi->s_flags |= SF_INTL | SF_OFS;
+ sb->s_flags |= MS_NOEXEC;
+ break;
+ default:
+ pr_err("Unknown filesystem on device %s: %08X\n",
+ sb->s_id, chksum);
+ return -EINVAL;
}
if (mount_flags & SF_VERBOSE) {
@@ -584,7 +584,7 @@ affs_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_bavail = free;
buf->f_fsid.val[0] = (u32)id;
buf->f_fsid.val[1] = (u32)(id >> 32);
- buf->f_namelen = 30;
+ buf->f_namelen = AFFSNAMEMAX;
return 0;
}
@@ -602,6 +602,7 @@ static void affs_kill_sb(struct super_block *sb)
affs_free_bitmap(sb);
affs_brelse(sbi->s_root_bh);
kfree(sbi->s_prefix);
+ mutex_destroy(&sbi->s_bmlock);
kfree(sbi);
}
}
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index edf47774b03d..e089f1985fca 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -274,9 +274,9 @@ more:
static struct inode *
befs_alloc_inode(struct super_block *sb)
{
- struct befs_inode_info *bi;
- bi = (struct befs_inode_info *)kmem_cache_alloc(befs_inode_cachep,
- GFP_KERNEL);
+ struct befs_inode_info *bi;
+
+ bi = kmem_cache_alloc(befs_inode_cachep, GFP_KERNEL);
if (!bi)
return NULL;
return &bi->vfs_inode;
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
deleted file mode 100644
index 4e00ed68d4a6..000000000000
--- a/fs/binfmt_som.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * linux/fs/binfmt_som.c
- *
- * These are the functions used to load SOM format executables as used
- * by HP-UX.
- *
- * Copyright 1999 Matthew Wilcox <willy@bofh.ai>
- * based on binfmt_elf which is
- * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
- */
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/binfmts.h>
-#include <linux/som.h>
-#include <linux/string.h>
-#include <linux/file.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/shm.h>
-#include <linux/personality.h>
-#include <linux/init.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-
-
-#include <linux/elf.h>
-
-static int load_som_binary(struct linux_binprm * bprm);
-static int load_som_library(struct file *);
-
-/*
- * If we don't support core dumping, then supply a NULL so we
- * don't even try.
- */
-#if 0
-static int som_core_dump(struct coredump_params *cprm);
-#else
-#define som_core_dump NULL
-#endif
-
-#define SOM_PAGESTART(_v) ((_v) & ~(unsigned long)(SOM_PAGESIZE-1))
-#define SOM_PAGEOFFSET(_v) ((_v) & (SOM_PAGESIZE-1))
-#define SOM_PAGEALIGN(_v) (((_v) + SOM_PAGESIZE - 1) & ~(SOM_PAGESIZE - 1))
-
-static struct linux_binfmt som_format = {
- .module = THIS_MODULE,
- .load_binary = load_som_binary,
- .load_shlib = load_som_library,
- .core_dump = som_core_dump,
- .min_coredump = SOM_PAGESIZE
-};
-
-/*
- * create_som_tables() parses the env- and arg-strings in new user
- * memory and creates the pointer tables from them, and puts their
- * addresses on the "stack", returning the new stack pointer value.
- */
-static void create_som_tables(struct linux_binprm *bprm)
-{
- char **argv, **envp;
- int argc = bprm->argc;
- int envc = bprm->envc;
- unsigned long p;
- unsigned long *sp;
-
- /* Word-align the stack pointer */
- sp = (unsigned long *)((bprm->p + 3) & ~3);
-
- envp = (char **) sp;
- sp += envc + 1;
- argv = (char **) sp;
- sp += argc + 1;
-
- __put_user((unsigned long) envp,++sp);
- __put_user((unsigned long) argv,++sp);
-
- __put_user(argc, ++sp);
-
- bprm->p = (unsigned long) sp;
-
- p = current->mm->arg_start;
- while (argc-- > 0) {
- __put_user((char *)p,argv++);
- p += strlen_user((char *)p);
- }
- __put_user(NULL, argv);
- current->mm->arg_end = current->mm->env_start = p;
- while (envc-- > 0) {
- __put_user((char *)p,envp++);
- p += strlen_user((char *)p);
- }
- __put_user(NULL, envp);
- current->mm->env_end = p;
-}
-
-static int check_som_header(struct som_hdr *som_ex)
-{
- int *buf = (int *)som_ex;
- int i, ck;
-
- if (som_ex->system_id != SOM_SID_PARISC_1_0 &&
- som_ex->system_id != SOM_SID_PARISC_1_1 &&
- som_ex->system_id != SOM_SID_PARISC_2_0)
- return -ENOEXEC;
-
- if (som_ex->a_magic != SOM_EXEC_NONSHARE &&
- som_ex->a_magic != SOM_EXEC_SHARE &&
- som_ex->a_magic != SOM_EXEC_DEMAND)
- return -ENOEXEC;
-
- if (som_ex->version_id != SOM_ID_OLD &&
- som_ex->version_id != SOM_ID_NEW)
- return -ENOEXEC;
-
- ck = 0;
- for (i=0; i<32; i++)
- ck ^= buf[i];
- if (ck != 0)
- return -ENOEXEC;
-
- return 0;
-}
-
-static int map_som_binary(struct file *file,
- const struct som_exec_auxhdr *hpuxhdr)
-{
- unsigned long code_start, code_size, data_start, data_size;
- unsigned long bss_start, som_brk;
- int retval;
- int prot = PROT_READ | PROT_EXEC;
- int flags = MAP_FIXED|MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
-
- mm_segment_t old_fs = get_fs();
- set_fs(get_ds());
-
- code_start = SOM_PAGESTART(hpuxhdr->exec_tmem);
- code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize);
- current->mm->start_code = code_start;
- current->mm->end_code = code_start + code_size;
- retval = vm_mmap(file, code_start, code_size, prot,
- flags, SOM_PAGESTART(hpuxhdr->exec_tfile));
- if (retval < 0 && retval > -1024)
- goto out;
-
- data_start = SOM_PAGESTART(hpuxhdr->exec_dmem);
- data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize);
- current->mm->start_data = data_start;
- current->mm->end_data = bss_start = data_start + data_size;
- retval = vm_mmap(file, data_start, data_size,
- prot | PROT_WRITE, flags,
- SOM_PAGESTART(hpuxhdr->exec_dfile));
- if (retval < 0 && retval > -1024)
- goto out;
-
- som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize);
- current->mm->start_brk = current->mm->brk = som_brk;
- retval = vm_mmap(NULL, bss_start, som_brk - bss_start,
- prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0);
- if (retval > 0 || retval < -1024)
- retval = 0;
-out:
- set_fs(old_fs);
- return retval;
-}
-
-
-/*
- * These are the functions used to load SOM executables and shared
- * libraries. There is no binary dependent code anywhere else.
- */
-
-static int
-load_som_binary(struct linux_binprm * bprm)
-{
- int retval;
- unsigned int size;
- unsigned long som_entry;
- struct som_hdr *som_ex;
- struct som_exec_auxhdr *hpuxhdr;
- struct pt_regs *regs = current_pt_regs();
-
- /* Get the exec-header */
- som_ex = (struct som_hdr *) bprm->buf;
-
- retval = check_som_header(som_ex);
- if (retval != 0)
- goto out;
-
- /* Now read in the auxiliary header information */
-
- retval = -ENOMEM;
- size = som_ex->aux_header_size;
- if (size > SOM_PAGESIZE)
- goto out;
- hpuxhdr = kmalloc(size, GFP_KERNEL);
- if (!hpuxhdr)
- goto out;
-
- retval = kernel_read(bprm->file, som_ex->aux_header_location,
- (char *) hpuxhdr, size);
- if (retval != size) {
- if (retval >= 0)
- retval = -EIO;
- goto out_free;
- }
-
- /* Flush all traces of the currently running executable */
- retval = flush_old_exec(bprm);
- if (retval)
- goto out_free;
-
- /* OK, This is the point of no return */
- current->personality = PER_HPUX;
- setup_new_exec(bprm);
-
- /* Set the task size for HP-UX processes such that
- * the gateway page is outside the address space.
- * This can be fixed later, but for now, this is much
- * easier.
- */
-
- current->thread.task_size = 0xc0000000;
-
- /* Set map base to allow enough room for hp-ux heap growth */
-
- current->thread.map_base = 0x80000000;
-
- retval = map_som_binary(bprm->file, hpuxhdr);
- if (retval < 0)
- goto out_free;
-
- som_entry = hpuxhdr->exec_entry;
- kfree(hpuxhdr);
-
- set_binfmt(&som_format);
- install_exec_creds(bprm);
- setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
-
- create_som_tables(bprm);
-
- current->mm->start_stack = bprm->p;
-
-#if 0
- printk("(start_brk) %08lx\n" , (unsigned long) current->mm->start_brk);
- printk("(end_code) %08lx\n" , (unsigned long) current->mm->end_code);
- printk("(start_code) %08lx\n" , (unsigned long) current->mm->start_code);
- printk("(end_data) %08lx\n" , (unsigned long) current->mm->end_data);
- printk("(start_stack) %08lx\n" , (unsigned long) current->mm->start_stack);
- printk("(brk) %08lx\n" , (unsigned long) current->mm->brk);
-#endif
-
- map_hpux_gateway_page(current,current->mm);
-
- start_thread_som(regs, som_entry, bprm->p);
- return 0;
-
- /* error cleanup */
-out_free:
- kfree(hpuxhdr);
-out:
- return retval;
-}
-
-static int load_som_library(struct file *f)
-{
-/* No lib support in SOM yet. gizza chance.. */
- return -ENOEXEC;
-}
- /* Install the SOM loader.
- * N.B. We *rely* on the table being the right size with the
- * right number of free slots...
- */
-
-static int __init init_som_binfmt(void)
-{
- register_binfmt(&som_format);
- return 0;
-}
-
-static void __exit exit_som_binfmt(void)
-{
- /* Remove the SOM loader. */
- unregister_binfmt(&som_format);
-}
-
-core_initcall(init_som_binfmt);
-module_exit(exit_som_binfmt);
-
-MODULE_LICENSE("GPL");
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 86c893884eb9..281ee011bb6a 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -28,29 +28,6 @@
#include "coda_int.h"
-/* dir inode-ops */
-static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, bool excl);
-static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, unsigned int flags);
-static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
- struct dentry *entry);
-static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
-static int coda_symlink(struct inode *dir_inode, struct dentry *entry,
- const char *symname);
-static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, umode_t mode);
-static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
-static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
- struct inode *new_inode, struct dentry *new_dentry);
-
-/* dir file-ops */
-static int coda_readdir(struct file *file, struct dir_context *ctx);
-
-/* dentry ops */
-static int coda_dentry_revalidate(struct dentry *de, unsigned int flags);
-static int coda_dentry_delete(const struct dentry *);
-
-/* support routines */
-static int coda_venus_readdir(struct file *, struct dir_context *);
-
/* same as fs/bad_inode.c */
static int coda_return_EIO(void)
{
@@ -58,38 +35,6 @@ static int coda_return_EIO(void)
}
#define CODA_EIO_ERROR ((void *) (coda_return_EIO))
-const struct dentry_operations coda_dentry_operations =
-{
- .d_revalidate = coda_dentry_revalidate,
- .d_delete = coda_dentry_delete,
-};
-
-const struct inode_operations coda_dir_inode_operations =
-{
- .create = coda_create,
- .lookup = coda_lookup,
- .link = coda_link,
- .unlink = coda_unlink,
- .symlink = coda_symlink,
- .mkdir = coda_mkdir,
- .rmdir = coda_rmdir,
- .mknod = CODA_EIO_ERROR,
- .rename = coda_rename,
- .permission = coda_permission,
- .getattr = coda_getattr,
- .setattr = coda_setattr,
-};
-
-const struct file_operations coda_dir_operations = {
- .llseek = generic_file_llseek,
- .read = generic_read_dir,
- .iterate = coda_readdir,
- .open = coda_open,
- .release = coda_release,
- .fsync = coda_fsync,
-};
-
-
/* inode operations for directories */
/* access routines: lookup, readlink, permission */
static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags)
@@ -374,33 +319,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
return error;
}
-
-/* file operations for directories */
-static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
-{
- struct coda_file_info *cfi;
- struct file *host_file;
- int ret;
-
- cfi = CODA_FTOC(coda_file);
- BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
- host_file = cfi->cfi_container;
-
- if (host_file->f_op->iterate) {
- struct inode *host_inode = file_inode(host_file);
- mutex_lock(&host_inode->i_mutex);
- ret = -ENOENT;
- if (!IS_DEADDIR(host_inode)) {
- ret = host_file->f_op->iterate(host_file, ctx);
- file_accessed(host_file);
- }
- mutex_unlock(&host_inode->i_mutex);
- return ret;
- }
- /* Venus: we must read Venus dirents from a file */
- return coda_venus_readdir(coda_file, ctx);
-}
-
static inline unsigned int CDT2DT(unsigned char cdt)
{
unsigned int dt;
@@ -495,6 +413,33 @@ out:
return 0;
}
+/* file operations for directories */
+static int coda_readdir(struct file *coda_file, struct dir_context *ctx)
+{
+ struct coda_file_info *cfi;
+ struct file *host_file;
+ int ret;
+
+ cfi = CODA_FTOC(coda_file);
+ BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
+ host_file = cfi->cfi_container;
+
+ if (host_file->f_op->iterate) {
+ struct inode *host_inode = file_inode(host_file);
+
+ mutex_lock(&host_inode->i_mutex);
+ ret = -ENOENT;
+ if (!IS_DEADDIR(host_inode)) {
+ ret = host_file->f_op->iterate(host_file, ctx);
+ file_accessed(host_file);
+ }
+ mutex_unlock(&host_inode->i_mutex);
+ return ret;
+ }
+ /* Venus: we must read Venus dirents from a file */
+ return coda_venus_readdir(coda_file, ctx);
+}
+
/* called when a cache lookup succeeds */
static int coda_dentry_revalidate(struct dentry *de, unsigned int flags)
{
@@ -603,3 +548,32 @@ int coda_revalidate_inode(struct inode *inode)
}
return 0;
}
+
+const struct dentry_operations coda_dentry_operations = {
+ .d_revalidate = coda_dentry_revalidate,
+ .d_delete = coda_dentry_delete,
+};
+
+const struct inode_operations coda_dir_inode_operations = {
+ .create = coda_create,
+ .lookup = coda_lookup,
+ .link = coda_link,
+ .unlink = coda_unlink,
+ .symlink = coda_symlink,
+ .mkdir = coda_mkdir,
+ .rmdir = coda_rmdir,
+ .mknod = CODA_EIO_ERROR,
+ .rename = coda_rename,
+ .permission = coda_permission,
+ .getattr = coda_getattr,
+ .setattr = coda_setattr,
+};
+
+const struct file_operations coda_dir_operations = {
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+ .iterate = coda_readdir,
+ .open = coda_open,
+ .release = coda_release,
+ .fsync = coda_fsync,
+};
diff --git a/fs/dax.c b/fs/dax.c
new file mode 100644
index 000000000000..ed1619ec6537
--- /dev/null
+++ b/fs/dax.c
@@ -0,0 +1,534 @@
+/*
+ * fs/dax.c - Direct Access filesystem code
+ * Copyright (c) 2013-2014 Intel Corporation
+ * Author: Matthew Wilcox <matthew.r.wilcox@intel.com>
+ * Author: Ross Zwisler <ross.zwisler@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/atomic.h>
+#include <linux/blkdev.h>
+#include <linux/buffer_head.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/highmem.h>
+#include <linux/memcontrol.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/uio.h>
+#include <linux/vmstat.h>
+
+int dax_clear_blocks(struct inode *inode, sector_t block, long size)
+{
+ struct block_device *bdev = inode->i_sb->s_bdev;
+ sector_t sector = block << (inode->i_blkbits - 9);
+
+ might_sleep();
+ do {
+ void *addr;
+ unsigned long pfn;
+ long count;
+
+ count = bdev_direct_access(bdev, sector, &addr, &pfn, size);
+ if (count < 0)
+ return count;
+ BUG_ON(size < count);
+ while (count > 0) {
+ unsigned pgsz = PAGE_SIZE - offset_in_page(addr);
+ if (pgsz > count)
+ pgsz = count;
+ if (pgsz < PAGE_SIZE)
+ memset(addr, 0, pgsz);
+ else
+ clear_page(addr);
+ addr += pgsz;
+ size -= pgsz;
+ count -= pgsz;
+ BUG_ON(pgsz & 511);
+ sector += pgsz / 512;
+ cond_resched();
+ }
+ } while (size);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dax_clear_blocks);
+
+static long dax_get_addr(struct buffer_head *bh, void **addr, unsigned blkbits)
+{
+ unsigned long pfn;
+ sector_t sector = bh->b_blocknr << (blkbits - 9);
+ return bdev_direct_access(bh->b_bdev, sector, addr, &pfn, bh->b_size);
+}
+
+static void dax_new_buf(void *addr, unsigned size, unsigned first, loff_t pos,
+ loff_t end)
+{
+ loff_t final = end - pos + first; /* The final byte of the buffer */
+
+ if (first > 0)
+ memset(addr, 0, first);
+ if (final < size)
+ memset(addr + final, 0, size - final);
+}
+
+static bool buffer_written(struct buffer_head *bh)
+{
+ return buffer_mapped(bh) && !buffer_unwritten(bh);
+}
+
+/*
+ * When ext4 encounters a hole, it returns without modifying the buffer_head
+ * which means that we can't trust b_size. To cope with this, we set b_state
+ * to 0 before calling get_block and, if any bit is set, we know we can trust
+ * b_size. Unfortunate, really, since ext4 knows precisely how long a hole is
+ * and would save us time calling get_block repeatedly.
+ */
+static bool buffer_size_valid(struct buffer_head *bh)
+{
+ return bh->b_state != 0;
+}
+
+static ssize_t dax_io(int rw, struct inode *inode, struct iov_iter *iter,
+ loff_t start, loff_t end, get_block_t get_block,
+ struct buffer_head *bh)
+{
+ ssize_t retval = 0;
+ loff_t pos = start;
+ loff_t max = start;
+ loff_t bh_max = start;
+ void *addr;
+ bool hole = false;
+
+ if (rw != WRITE)
+ end = min(end, i_size_read(inode));
+
+ while (pos < end) {
+ unsigned len;
+ if (pos == max) {
+ unsigned blkbits = inode->i_blkbits;
+ sector_t block = pos >> blkbits;
+ unsigned first = pos - (block << blkbits);
+ long size;
+
+ if (pos == bh_max) {
+ bh->b_size = PAGE_ALIGN(end - pos);
+ bh->b_state = 0;
+ retval = get_block(inode, block, bh,
+ rw == WRITE);
+ if (retval)
+ break;
+ if (!buffer_size_valid(bh))
+ bh->b_size = 1 << blkbits;
+ bh_max = pos - first + bh->b_size;
+ } else {
+ unsigned done = bh->b_size -
+ (bh_max - (pos - first));
+ bh->b_blocknr += done >> blkbits;
+ bh->b_size -= done;
+ }
+
+ hole = (rw != WRITE) && !buffer_written(bh);
+ if (hole) {
+ addr = NULL;
+ size = bh->b_size - first;
+ } else {
+ retval = dax_get_addr(bh, &addr, blkbits);
+ if (retval < 0)
+ break;
+ if (buffer_unwritten(bh) || buffer_new(bh))
+ dax_new_buf(addr, retval, first, pos,
+ end);
+ addr += first;
+ size = retval - first;
+ }
+ max = min(pos + size, end);
+ }
+
+ if (rw == WRITE)
+ len = copy_from_iter(addr, max - pos, iter);
+ else if (!hole)
+ len = copy_to_iter(addr, max - pos, iter);
+ else
+ len = iov_iter_zero(max - pos, iter);
+
+ if (!len)
+ break;
+
+ pos += len;
+ addr += len;
+ }
+
+ return (pos == start) ? retval : pos - start;
+}
+
+/**
+ * dax_do_io - Perform I/O to a DAX file
+ * @rw: READ to read or WRITE to write
+ * @iocb: The control block for this I/O
+ * @inode: The file which the I/O is directed at
+ * @iter: The addresses to do I/O from or to
+ * @pos: The file offset where the I/O starts
+ * @get_block: The filesystem method used to translate file offsets to blocks
+ * @end_io: A filesystem callback for I/O completion
+ * @flags: See below
+ *
+ * This function uses the same locking scheme as do_blockdev_direct_IO:
+ * If @flags has DIO_LOCKING set, we assume that the i_mutex is held by the
+ * caller for writes. For reads, we take and release the i_mutex ourselves.
+ * If DIO_LOCKING is not set, the filesystem takes care of its own locking.
+ * As with do_blockdev_direct_IO(), we increment i_dio_count while the I/O
+ * is in progress.
+ */
+ssize_t dax_do_io(int rw, struct kiocb *iocb, struct inode *inode,
+ struct iov_iter *iter, loff_t pos,
+ get_block_t get_block, dio_iodone_t end_io, int flags)
+{
+ struct buffer_head bh;
+ ssize_t retval = -EINVAL;
+ loff_t end = pos + iov_iter_count(iter);
+
+ memset(&bh, 0, sizeof(bh));
+
+ if ((flags & DIO_LOCKING) && (rw == READ)) {
+ struct address_space *mapping = inode->i_mapping;
+ mutex_lock(&inode->i_mutex);
+ retval = filemap_write_and_wait_range(mapping, pos, end - 1);
+ if (retval) {
+ mutex_unlock(&inode->i_mutex);
+ goto out;
+ }
+ }
+
+ /* Protects against truncate */
+ atomic_inc(&inode->i_dio_count);
+
+ retval = dax_io(rw, inode, iter, pos, end, get_block, &bh);
+
+ if ((flags & DIO_LOCKING) && (rw == READ))
+ mutex_unlock(&inode->i_mutex);
+
+ if ((retval > 0) && end_io)
+ end_io(iocb, pos, retval, bh.b_private);
+
+ inode_dio_done(inode);
+ out:
+ return retval;
+}
+EXPORT_SYMBOL_GPL(dax_do_io);
+
+/*
+ * The user has performed a load from a hole in the file. Allocating
+ * a new page in the file would cause excessive storage usage for
+ * workloads with sparse files. We allocate a page cache page instead.
+ * We'll kick it out of the page cache if it's ever written to,
+ * otherwise it will simply fall out of the page cache under memory
+ * pressure without ever having been dirtied.
+ */
+static int dax_load_hole(struct address_space *mapping, struct page *page,
+ struct vm_fault *vmf)
+{
+ unsigned long size;
+ struct inode *inode = mapping->host;
+ if (!page)
+ page = find_or_create_page(mapping, vmf->pgoff,
+ GFP_KERNEL | __GFP_ZERO);
+ if (!page)
+ return VM_FAULT_OOM;
+ /* Recheck i_size under page lock to avoid truncate race */
+ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (vmf->pgoff >= size) {
+ unlock_page(page);
+ page_cache_release(page);
+ return VM_FAULT_SIGBUS;
+ }
+
+ vmf->page = page;
+ return VM_FAULT_LOCKED;
+}
+
+static int copy_user_bh(struct page *to, struct buffer_head *bh,
+ unsigned blkbits, unsigned long vaddr)
+{
+ void *vfrom, *vto;
+ if (dax_get_addr(bh, &vfrom, blkbits) < 0)
+ return -EIO;
+ vto = kmap_atomic(to);
+ copy_user_page(vto, vfrom, vaddr, to);
+ kunmap_atomic(vto);
+ return 0;
+}
+
+static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
+ struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct address_space *mapping = inode->i_mapping;
+ sector_t sector = bh->b_blocknr << (inode->i_blkbits - 9);
+ unsigned long vaddr = (unsigned long)vmf->virtual_address;
+ void *addr;
+ unsigned long pfn;
+ pgoff_t size;
+ int error;
+
+ i_mmap_lock_read(mapping);
+
+ /*
+ * Check truncate didn't happen while we were allocating a block.
+ * If it did, this block may or may not be still allocated to the
+ * file. We can't tell the filesystem to free it because we can't
+ * take i_mutex here. In the worst case, the file still has blocks
+ * allocated past the end of the file.
+ */
+ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (unlikely(vmf->pgoff >= size)) {
+ error = -EIO;
+ goto out;
+ }
+
+ error = bdev_direct_access(bh->b_bdev, sector, &addr, &pfn, bh->b_size);
+ if (error < 0)
+ goto out;
+ if (error < PAGE_SIZE) {
+ error = -EIO;
+ goto out;
+ }
+
+ if (buffer_unwritten(bh) || buffer_new(bh))
+ clear_page(addr);
+
+ error = vm_insert_mixed(vma, vaddr, pfn);
+
+ out:
+ i_mmap_unlock_read(mapping);
+
+ if (bh->b_end_io)
+ bh->b_end_io(bh, 1);
+
+ return error;
+}
+
+static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
+ get_block_t get_block)
+{
+ struct file *file = vma->vm_file;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ struct page *page;
+ struct buffer_head bh;
+ unsigned long vaddr = (unsigned long)vmf->virtual_address;
+ unsigned blkbits = inode->i_blkbits;
+ sector_t block;
+ pgoff_t size;
+ int error;
+ int major = 0;
+
+ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (vmf->pgoff >= size)
+ return VM_FAULT_SIGBUS;
+
+ memset(&bh, 0, sizeof(bh));
+ block = (sector_t)vmf->pgoff << (PAGE_SHIFT - blkbits);
+ bh.b_size = PAGE_SIZE;
+
+ repeat:
+ page = find_get_page(mapping, vmf->pgoff);
+ if (page) {
+ if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) {
+ page_cache_release(page);
+ return VM_FAULT_RETRY;
+ }
+ if (unlikely(page->mapping != mapping)) {
+ unlock_page(page);
+ page_cache_release(page);
+ goto repeat;
+ }
+ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (unlikely(vmf->pgoff >= size)) {
+ /*
+ * We have a struct page covering a hole in the file
+ * from a read fault and we've raced with a truncate
+ */
+ error = -EIO;
+ goto unlock_page;
+ }
+ }
+
+ error = get_block(inode, block, &bh, 0);
+ if (!error && (bh.b_size < PAGE_SIZE))
+ error = -EIO; /* fs corruption? */
+ if (error)
+ goto unlock_page;
+
+ if (!buffer_mapped(&bh) && !buffer_unwritten(&bh) && !vmf->cow_page) {
+ if (vmf->flags & FAULT_FLAG_WRITE) {
+ error = get_block(inode, block, &bh, 1);
+ count_vm_event(PGMAJFAULT);
+ mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
+ major = VM_FAULT_MAJOR;
+ if (!error && (bh.b_size < PAGE_SIZE))
+ error = -EIO;
+ if (error)
+ goto unlock_page;
+ } else {
+ return dax_load_hole(mapping, page, vmf);
+ }
+ }
+
+ if (vmf->cow_page) {
+ struct page *new_page = vmf->cow_page;
+ if (buffer_written(&bh))
+ error = copy_user_bh(new_page, &bh, blkbits, vaddr);
+ else
+ clear_user_highpage(new_page, vaddr);
+ if (error)
+ goto unlock_page;
+ vmf->page = page;
+ if (!page) {
+ i_mmap_lock_read(mapping);
+ /* Check we didn't race with truncate */
+ size = (i_size_read(inode) + PAGE_SIZE - 1) >>
+ PAGE_SHIFT;
+ if (vmf->pgoff >= size) {
+ i_mmap_unlock_read(mapping);
+ error = -EIO;
+ goto out;
+ }
+ }
+ return VM_FAULT_LOCKED;
+ }
+
+ /* Check we didn't race with a read fault installing a new page */
+ if (!page && major)
+ page = find_lock_page(mapping, vmf->pgoff);
+
+ if (page) {
+ unmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT,
+ PAGE_CACHE_SIZE, 0);
+ delete_from_page_cache(page);
+ unlock_page(page);
+ page_cache_release(page);
+ }
+
+ error = dax_insert_mapping(inode, &bh, vma, vmf);
+
+ out:
+ if (error == -ENOMEM)
+ return VM_FAULT_OOM | major;
+ /* -EBUSY is fine, somebody else faulted on the same PTE */
+ if ((error < 0) && (error != -EBUSY))
+ return VM_FAULT_SIGBUS | major;
+ return VM_FAULT_NOPAGE | major;
+
+ unlock_page:
+ if (page) {
+ unlock_page(page);
+ page_cache_release(page);
+ }
+ goto out;
+}
+
+/**
+ * dax_fault - handle a page fault on a DAX file
+ * @vma: The virtual memory area where the fault occurred
+ * @vmf: The description of the fault
+ * @get_block: The filesystem method used to translate file offsets to blocks
+ *
+ * When a page fault occurs, filesystems may call this helper in their
+ * fault handler for DAX files.
+ */
+int dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
+ get_block_t get_block)
+{
+ int result;
+ struct super_block *sb = file_inode(vma->vm_file)->i_sb;
+
+ if (vmf->flags & FAULT_FLAG_WRITE) {
+ sb_start_pagefault(sb);
+ file_update_time(vma->vm_file);
+ }
+ result = do_dax_fault(vma, vmf, get_block);
+ if (vmf->flags & FAULT_FLAG_WRITE)
+ sb_end_pagefault(sb);
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(dax_fault);
+
+/**
+ * dax_zero_page_range - zero a range within a page of a DAX file
+ * @inode: The file being truncated
+ * @from: The file offset that is being truncated to
+ * @length: The number of bytes to zero
+ * @get_block: The filesystem method used to translate file offsets to blocks
+ *
+ * This function can be called by a filesystem when it is zeroing part of a
+ * page in a DAX file. This is intended for hole-punch operations. If
+ * you are truncating a file, the helper function dax_truncate_page() may be
+ * more convenient.
+ *
+ * We work in terms of PAGE_CACHE_SIZE here for commonality with
+ * block_truncate_page(), but we could go down to PAGE_SIZE if the filesystem
+ * took care of disposing of the unnecessary blocks. Even if the filesystem
+ * block size is smaller than PAGE_SIZE, we have to zero the rest of the page
+ * since the file might be mmapped.
+ */
+int dax_zero_page_range(struct inode *inode, loff_t from, unsigned length,
+ get_block_t get_block)
+{
+ struct buffer_head bh;
+ pgoff_t index = from >> PAGE_CACHE_SHIFT;
+ unsigned offset = from & (PAGE_CACHE_SIZE-1);
+ int err;
+
+ /* Block boundary? Nothing to do */
+ if (!length)
+ return 0;
+ BUG_ON((offset + length) > PAGE_CACHE_SIZE);
+
+ memset(&bh, 0, sizeof(bh));
+ bh.b_size = PAGE_CACHE_SIZE;
+ err = get_block(inode, index, &bh, 0);
+ if (err < 0)
+ return err;
+ if (buffer_written(&bh)) {
+ void *addr;
+ err = dax_get_addr(&bh, &addr, inode->i_blkbits);
+ if (err < 0)
+ return err;
+ memset(addr + offset, 0, length);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dax_zero_page_range);
+
+/**
+ * dax_truncate_page - handle a partial page being truncated in a DAX file
+ * @inode: The file being truncated
+ * @from: The file offset that is being truncated to
+ * @get_block: The filesystem method used to translate file offsets to blocks
+ *
+ * Similar to block_truncate_page(), this function can be called by a
+ * filesystem when it is truncating a DAX file to handle the partial page.
+ *
+ * We work in terms of PAGE_CACHE_SIZE here for commonality with
+ * block_truncate_page(), but we could go down to PAGE_SIZE if the filesystem
+ * took care of disposing of the unnecessary blocks. Even if the filesystem
+ * block size is smaller than PAGE_SIZE, we have to zero the rest of the page
+ * since the file might be mmapped.
+ */
+int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block)
+{
+ unsigned length = PAGE_CACHE_ALIGN(from) - from;
+ return dax_zero_page_range(inode, from, length, get_block);
+}
+EXPORT_SYMBOL_GPL(dax_truncate_page);
diff --git a/fs/dcache.c b/fs/dcache.c
index 7d34f04ec7aa..dc400fd29f4d 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -511,7 +511,7 @@ static void __dentry_kill(struct dentry *dentry)
* dentry_iput drops the locks, at which point nobody (except
* transient RCU lookups) can reach this dentry.
*/
- BUG_ON((int)dentry->d_lockref.count > 0);
+ BUG_ON(dentry->d_lockref.count > 0);
this_cpu_dec(nr_dentry);
if (dentry->d_op && dentry->d_op->d_release)
dentry->d_op->d_release(dentry);
@@ -564,7 +564,7 @@ static inline struct dentry *lock_parent(struct dentry *dentry)
struct dentry *parent = dentry->d_parent;
if (IS_ROOT(dentry))
return NULL;
- if (unlikely((int)dentry->d_lockref.count < 0))
+ if (unlikely(dentry->d_lockref.count < 0))
return NULL;
if (likely(spin_trylock(&parent->d_lock)))
return parent;
@@ -593,6 +593,110 @@ again:
return parent;
}
+/*
+ * Try to do a lockless dput(), and return whether that was successful.
+ *
+ * If unsuccessful, we return false, having already taken the dentry lock.
+ *
+ * The caller needs to hold the RCU read lock, so that the dentry is
+ * guaranteed to stay around even if the refcount goes down to zero!
+ */
+static inline bool fast_dput(struct dentry *dentry)
+{
+ int ret;
+ unsigned int d_flags;
+
+ /*
+ * If we have a d_op->d_delete() operation, we sould not
+ * let the dentry count go to zero, so use "put__or_lock".
+ */
+ if (unlikely(dentry->d_flags & DCACHE_OP_DELETE))
+ return lockref_put_or_lock(&dentry->d_lockref);
+
+ /*
+ * .. otherwise, we can try to just decrement the
+ * lockref optimistically.
+ */
+ ret = lockref_put_return(&dentry->d_lockref);
+
+ /*
+ * If the lockref_put_return() failed due to the lock being held
+ * by somebody else, the fast path has failed. We will need to
+ * get the lock, and then check the count again.
+ */
+ if (unlikely(ret < 0)) {
+ spin_lock(&dentry->d_lock);
+ if (dentry->d_lockref.count > 1) {
+ dentry->d_lockref.count--;
+ spin_unlock(&dentry->d_lock);
+ return 1;
+ }
+ return 0;
+ }
+
+ /*
+ * If we weren't the last ref, we're done.
+ */
+ if (ret)
+ return 1;
+
+ /*
+ * Careful, careful. The reference count went down
+ * to zero, but we don't hold the dentry lock, so
+ * somebody else could get it again, and do another
+ * dput(), and we need to not race with that.
+ *
+ * However, there is a very special and common case
+ * where we don't care, because there is nothing to
+ * do: the dentry is still hashed, it does not have
+ * a 'delete' op, and it's referenced and already on
+ * the LRU list.
+ *
+ * NOTE! Since we aren't locked, these values are
+ * not "stable". However, it is sufficient that at
+ * some point after we dropped the reference the
+ * dentry was hashed and the flags had the proper
+ * value. Other dentry users may have re-gotten
+ * a reference to the dentry and change that, but
+ * our work is done - we can leave the dentry
+ * around with a zero refcount.
+ */
+ smp_rmb();
+ d_flags = ACCESS_ONCE(dentry->d_flags);
+ d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST;
+
+ /* Nothing to do? Dropping the reference was all we needed? */
+ if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
+ return 1;
+
+ /*
+ * Not the fast normal case? Get the lock. We've already decremented
+ * the refcount, but we'll need to re-check the situation after
+ * getting the lock.
+ */
+ spin_lock(&dentry->d_lock);
+
+ /*
+ * Did somebody else grab a reference to it in the meantime, and
+ * we're no longer the last user after all? Alternatively, somebody
+ * else could have killed it and marked it dead. Either way, we
+ * don't need to do anything else.
+ */
+ if (dentry->d_lockref.count) {
+ spin_unlock(&dentry->d_lock);
+ return 1;
+ }
+
+ /*
+ * Re-get the reference we optimistically dropped. We hold the
+ * lock, and we just tested that it was zero, so we can just
+ * set it to 1.
+ */
+ dentry->d_lockref.count = 1;
+ return 0;
+}
+
+
/*
* This is dput
*
@@ -625,8 +729,14 @@ void dput(struct dentry *dentry)
return;
repeat:
- if (lockref_put_or_lock(&dentry->d_lockref))
+ rcu_read_lock();
+ if (likely(fast_dput(dentry))) {
+ rcu_read_unlock();
return;
+ }
+
+ /* Slow case: now with the dentry lock held */
+ rcu_read_unlock();
/* Unreachable? Get rid of it */
if (unlikely(d_unhashed(dentry)))
@@ -813,7 +923,7 @@ static void shrink_dentry_list(struct list_head *list)
* We found an inuse dentry which was not removed from
* the LRU because of laziness during lookup. Do not free it.
*/
- if ((int)dentry->d_lockref.count > 0) {
+ if (dentry->d_lockref.count > 0) {
spin_unlock(&dentry->d_lock);
if (parent)
spin_unlock(&parent->d_lock);
@@ -2191,37 +2301,6 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
}
EXPORT_SYMBOL(d_hash_and_lookup);
-/**
- * d_validate - verify dentry provided from insecure source (deprecated)
- * @dentry: The dentry alleged to be valid child of @dparent
- * @dparent: The parent dentry (known to be valid)
- *
- * An insecure source has sent us a dentry, here we verify it and dget() it.
- * This is used by ncpfs in its readdir implementation.
- * Zero is returned in the dentry is invalid.
- *
- * This function is slow for big directories, and deprecated, do not use it.
- */
-int d_validate(struct dentry *dentry, struct dentry *dparent)
-{
- struct dentry *child;
-
- spin_lock(&dparent->d_lock);
- list_for_each_entry(child, &dparent->d_subdirs, d_child) {
- if (dentry == child) {
- spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
- __dget_dlock(dentry);
- spin_unlock(&dentry->d_lock);
- spin_unlock(&dparent->d_lock);
- return 1;
- }
- }
- spin_unlock(&dparent->d_lock);
-
- return 0;
-}
-EXPORT_SYMBOL(d_validate);
-
/*
* When a file is deleted, we have two options:
* - turn this dentry into a negative dentry
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 05f2960ed7c3..45b18a5e225c 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -34,93 +34,16 @@ static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;
static bool debugfs_registered;
-static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev_t dev,
- void *data, const struct file_operations *fops)
-
+static struct inode *debugfs_get_inode(struct super_block *sb)
{
struct inode *inode = new_inode(sb);
-
if (inode) {
inode->i_ino = get_next_ino();
- inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- switch (mode & S_IFMT) {
- default:
- init_special_inode(inode, mode, dev);
- break;
- case S_IFREG:
- inode->i_fop = fops ? fops : &debugfs_file_operations;
- inode->i_private = data;
- break;
- case S_IFLNK:
- inode->i_op = &debugfs_link_operations;
- inode->i_private = data;
- break;
- case S_IFDIR:
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
-
- /* directory inodes start off with i_nlink == 2
- * (for "." entry) */
- inc_nlink(inode);
- break;
- }
}
return inode;
}
-/* SMP-safe */
-static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
- umode_t mode, dev_t dev, void *data,
- const struct file_operations *fops)
-{
- struct inode *inode;
- int error = -EPERM;
-
- if (dentry->d_inode)
- return -EEXIST;
-
- inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
- if (inode) {
- d_instantiate(dentry, inode);
- dget(dentry);
- error = 0;
- }
- return error;
-}
-
-static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
-{
- int res;
-
- mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
- res = debugfs_mknod(dir, dentry, mode, 0, NULL, NULL);
- if (!res) {
- inc_nlink(dir);
- fsnotify_mkdir(dir, dentry);
- }
- return res;
-}
-
-static int debugfs_link(struct inode *dir, struct dentry *dentry, umode_t mode,
- void *data)
-{
- mode = (mode & S_IALLUGO) | S_IFLNK;
- return debugfs_mknod(dir, dentry, mode, 0, data, NULL);
-}
-
-static int debugfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
- void *data, const struct file_operations *fops)
-{
- int res;
-
- mode = (mode & S_IALLUGO) | S_IFREG;
- res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
- if (!res)
- fsnotify_create(dir, dentry);
- return res;
-}
-
static inline int debugfs_positive(struct dentry *dentry)
{
return dentry->d_inode && !d_unhashed(dentry);
@@ -252,6 +175,18 @@ static const struct super_operations debugfs_super_operations = {
.show_options = debugfs_show_options,
};
+static struct vfsmount *debugfs_automount(struct path *path)
+{
+ struct vfsmount *(*f)(void *);
+ f = (struct vfsmount *(*)(void *))path->dentry->d_fsdata;
+ return f(path->dentry->d_inode->i_private);
+}
+
+static const struct dentry_operations debugfs_dops = {
+ .d_delete = always_delete_dentry,
+ .d_automount = debugfs_automount,
+};
+
static int debug_fill_super(struct super_block *sb, void *data, int silent)
{
static struct tree_descr debug_files[] = {{""}};
@@ -276,6 +211,7 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
goto fail;
sb->s_op = &debugfs_super_operations;
+ sb->s_d_op = &debugfs_dops;
debugfs_apply_options(sb);
@@ -302,11 +238,9 @@ static struct file_system_type debug_fs_type = {
};
MODULE_ALIAS_FS("debugfs");
-static struct dentry *__create_file(const char *name, umode_t mode,
- struct dentry *parent, void *data,
- const struct file_operations *fops)
+static struct dentry *start_creating(const char *name, struct dentry *parent)
{
- struct dentry *dentry = NULL;
+ struct dentry *dentry;
int error;
pr_debug("debugfs: creating file '%s'\n",name);
@@ -314,7 +248,7 @@ static struct dentry *__create_file(const char *name, umode_t mode,
error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
&debugfs_mount_count);
if (error)
- goto exit;
+ return ERR_PTR(error);
/* If the parent is not specified, we create it in the root.
* We need the root dentry to do this, which is in the super
@@ -326,31 +260,26 @@ static struct dentry *__create_file(const char *name, umode_t mode,
mutex_lock(&parent->d_inode->i_mutex);
dentry = lookup_one_len(name, parent, strlen(name));
- if (!IS_ERR(dentry)) {
- switch (mode & S_IFMT) {
- case S_IFDIR:
- error = debugfs_mkdir(parent->d_inode, dentry, mode);
-
- break;
- case S_IFLNK:
- error = debugfs_link(parent->d_inode, dentry, mode,
- data);
- break;
- default:
- error = debugfs_create(parent->d_inode, dentry, mode,
- data, fops);
- break;
- }
+ if (!IS_ERR(dentry) && dentry->d_inode) {
dput(dentry);
- } else
- error = PTR_ERR(dentry);
- mutex_unlock(&parent->d_inode->i_mutex);
-
- if (error) {
- dentry = NULL;
- simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ dentry = ERR_PTR(-EEXIST);
}
-exit:
+ if (IS_ERR(dentry))
+ mutex_unlock(&parent->d_inode->i_mutex);
+ return dentry;
+}
+
+static struct dentry *failed_creating(struct dentry *dentry)
+{
+ mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
+ dput(dentry);
+ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+ return NULL;
+}
+
+static struct dentry *end_creating(struct dentry *dentry)
+{
+ mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
return dentry;
}
@@ -384,19 +313,71 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops)
{
- switch (mode & S_IFMT) {
- case S_IFREG:
- case 0:
- break;
- default:
- BUG();
- }
+ struct dentry *dentry;
+ struct inode *inode;
+
+ if (!(mode & S_IFMT))
+ mode |= S_IFREG;
+ BUG_ON(!S_ISREG(mode));
+ dentry = start_creating(name, parent);
+
+ if (IS_ERR(dentry))
+ return NULL;
- return __create_file(name, mode, parent, data, fops);
+ inode = debugfs_get_inode(dentry->d_sb);
+ if (unlikely(!inode))
+ return failed_creating(dentry);
+
+ inode->i_mode = mode;
+ inode->i_fop = fops ? fops : &debugfs_file_operations;
+ inode->i_private = data;
+ d_instantiate(dentry, inode);
+ fsnotify_create(dentry->d_parent->d_inode, dentry);
+ return end_creating(dentry);
}
EXPORT_SYMBOL_GPL(debugfs_create_file);
/**
+ * debugfs_create_file_size - create a file in the debugfs filesystem
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ * on. The inode.i_private pointer will point to this value on
+ * the open() call.
+ * @fops: a pointer to a struct file_operations that should be used for
+ * this file.
+ * @file_size: initial file size
+ *
+ * This is the basic "create a file" function for debugfs. It allows for a
+ * wide range of flexibility in creating a file, or a directory (if you want
+ * to create a directory, the debugfs_create_dir() function is
+ * recommended to be used instead.)
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, %NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *debugfs_create_file_size(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops,
+ loff_t file_size)
+{
+ struct dentry *de = debugfs_create_file(name, mode, parent, data, fops);
+
+ if (de)
+ de->d_inode->i_size = file_size;
+ return de;
+}
+EXPORT_SYMBOL_GPL(debugfs_create_file_size);
+
+/**
* debugfs_create_dir - create a directory in the debugfs filesystem
* @name: a pointer to a string containing the name of the directory to
* create.
@@ -416,12 +397,65 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
*/
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
{
- return __create_file(name, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
- parent, NULL, NULL);
+ struct dentry *dentry = start_creating(name, parent);
+ struct inode *inode;
+
+ if (IS_ERR(dentry))
+ return NULL;
+
+ inode = debugfs_get_inode(dentry->d_sb);
+ if (unlikely(!inode))
+ return failed_creating(dentry);
+
+ inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+ inode->i_op = &simple_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+
+ /* directory inodes start off with i_nlink == 2 (for "." entry) */
+ inc_nlink(inode);
+ d_instantiate(dentry, inode);
+ inc_nlink(dentry->d_parent->d_inode);
+ fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
+ return end_creating(dentry);
}
EXPORT_SYMBOL_GPL(debugfs_create_dir);
/**
+ * debugfs_create_automount - create automount point in the debugfs filesystem
+ * @name: a pointer to a string containing the name of the file to create.
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @f: function to be called when pathname resolution steps on that one.
+ * @data: opaque argument to pass to f().
+ *
+ * @f should return what ->d_automount() would.
+ */
+struct dentry *debugfs_create_automount(const char *name,
+ struct dentry *parent,
+ struct vfsmount *(*f)(void *),
+ void *data)
+{
+ struct dentry *dentry = start_creating(name, parent);
+ struct inode *inode;
+
+ if (IS_ERR(dentry))
+ return NULL;
+
+ inode = debugfs_get_inode(dentry->d_sb);
+ if (unlikely(!inode))
+ return failed_creating(dentry);
+
+ inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+ inode->i_flags |= S_AUTOMOUNT;
+ inode->i_private = data;
+ dentry->d_fsdata = (void *)f;
+ d_instantiate(dentry, inode);
+ return end_creating(dentry);
+}
+EXPORT_SYMBOL(debugfs_create_automount);
+
+/**
* debugfs_create_symlink- create a symbolic link in the debugfs filesystem
* @name: a pointer to a string containing the name of the symbolic link to
* create.
@@ -447,17 +481,28 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
const char *target)
{
- struct dentry *result;
- char *link;
-
- link = kstrdup(target, GFP_KERNEL);
+ struct dentry *dentry;
+ struct inode *inode;
+ char *link = kstrdup(target, GFP_KERNEL);
if (!link)
return NULL;
- result = __create_file(name, S_IFLNK | S_IRWXUGO, parent, link, NULL);
- if (!result)
+ dentry = start_creating(name, parent);
+ if (IS_ERR(dentry)) {
kfree(link);
- return result;
+ return NULL;
+ }
+
+ inode = debugfs_get_inode(dentry->d_sb);
+ if (unlikely(!inode)) {
+ kfree(link);
+ return failed_creating(dentry);
+ }
+ inode->i_mode = S_IFLNK | S_IRWXUGO;
+ inode->i_op = &debugfs_link_operations;
+ inode->i_private = link;
+ d_instantiate(dentry, inode);
+ return end_creating(dentry);
}
EXPORT_SYMBOL_GPL(debugfs_create_symlink);
diff --git a/fs/eventfd.c b/fs/eventfd.c
index 4b0a226024fa..8d0c0df01854 100644
--- a/fs/eventfd.c
+++ b/fs/eventfd.c
@@ -118,18 +118,18 @@ static unsigned int eventfd_poll(struct file *file, poll_table *wait)
{
struct eventfd_ctx *ctx = file->private_data;
unsigned int events = 0;
- unsigned long flags;
+ u64 count;
poll_wait(file, &ctx->wqh, wait);
+ smp_rmb();
+ count = ctx->count;
- spin_lock_irqsave(&ctx->wqh.lock, flags);
- if (ctx->count > 0)
+ if (count > 0)
events |= POLLIN;
- if (ctx->count == ULLONG_MAX)
+ if (count == ULLONG_MAX)
events |= POLLERR;
- if (ULLONG_MAX - 1 > ctx->count)
+ if (ULLONG_MAX - 1 > count)
events |= POLLOUT;
- spin_unlock_irqrestore(&ctx->wqh.lock, flags);
return events;
}
diff --git a/fs/exec.c b/fs/exec.c
index ad8798e26be9..c7f9b733406d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -794,8 +794,14 @@ exit:
struct file *open_exec(const char *name)
{
- struct filename tmp = { .name = name };
- return do_open_execat(AT_FDCWD, &tmp, 0);
+ struct filename *filename = getname_kernel(name);
+ struct file *f = ERR_CAST(filename);
+
+ if (!IS_ERR(filename)) {
+ f = do_open_execat(AT_FDCWD, filename, 0);
+ putname(filename);
+ }
+ return f;
}
EXPORT_SYMBOL(open_exec);
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index 6fc91df99ff8..a198e94813fe 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -985,7 +985,6 @@ const struct address_space_operations exofs_aops = {
.direct_IO = exofs_direct_IO,
/* With these NULL has special meaning or default is not exported */
- .get_xip_mem = NULL,
.migratepage = NULL,
.launder_page = NULL,
.is_partially_uptodate = NULL,
diff --git a/fs/ext2/Kconfig b/fs/ext2/Kconfig
index 14a6780fd034..c634874e12d9 100644
--- a/fs/ext2/Kconfig
+++ b/fs/ext2/Kconfig
@@ -42,14 +42,3 @@ config EXT2_FS_SECURITY
If you are not using a security module that requires using
extended attributes for file security labels, say N.
-
-config EXT2_FS_XIP
- bool "Ext2 execute in place support"
- depends on EXT2_FS && MMU
- help
- Execute in place can be used on memory-backed block devices. If you
- enable this option, you can select to mount block devices which are
- capable of this feature without using the page cache.
-
- If you do not use a block device that is capable of using this,
- or if unsure, say N.
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile
index f42af45cfd88..445b0e996a12 100644
--- a/fs/ext2/Makefile
+++ b/fs/ext2/Makefile
@@ -10,4 +10,3 @@ ext2-y := balloc.o dir.o file.o ialloc.o inode.o \
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
ext2-$(CONFIG_EXT2_FS_SECURITY) += xattr_security.o
-ext2-$(CONFIG_EXT2_FS_XIP) += xip.o
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index e4279ead4a05..678f9ab08c48 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -380,10 +380,15 @@ struct ext2_inode {
#define EXT2_MOUNT_NO_UID32 0x000200 /* Disable 32-bit UIDs */
#define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */
#define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */
-#define EXT2_MOUNT_XIP 0x010000 /* Execute in place */
+#define EXT2_MOUNT_XIP 0x010000 /* Obsolete, use DAX */
#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
#define EXT2_MOUNT_RESERVATION 0x080000 /* Preallocation */
+#ifdef CONFIG_FS_DAX
+#define EXT2_MOUNT_DAX 0x100000 /* Direct Access */
+#else
+#define EXT2_MOUNT_DAX 0
+#endif
#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
@@ -788,11 +793,10 @@ extern int ext2_fsync(struct file *file, loff_t start, loff_t end,
int datasync);
extern const struct inode_operations ext2_file_inode_operations;
extern const struct file_operations ext2_file_operations;
-extern const struct file_operations ext2_xip_file_operations;
+extern const struct file_operations ext2_dax_file_operations;
/* inode.c */
extern const struct address_space_operations ext2_aops;
-extern const struct address_space_operations ext2_aops_xip;
extern const struct address_space_operations ext2_nobh_aops;
/* namei.c */
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 7c87b22a7228..e31701713516 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -25,6 +25,36 @@
#include "xattr.h"
#include "acl.h"
+#ifdef CONFIG_FS_DAX
+static int ext2_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return dax_fault(vma, vmf, ext2_get_block);
+}
+
+static int ext2_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return dax_mkwrite(vma, vmf, ext2_get_block);
+}
+
+static const struct vm_operations_struct ext2_dax_vm_ops = {
+ .fault = ext2_dax_fault,
+ .page_mkwrite = ext2_dax_mkwrite,
+};
+
+static int ext2_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ if (!IS_DAX(file_inode(file)))
+ return generic_file_mmap(file, vma);
+
+ file_accessed(file);
+ vma->vm_ops = &ext2_dax_vm_ops;
+ vma->vm_flags |= VM_MIXEDMAP;
+ return 0;
+}
+#else
+#define ext2_file_mmap generic_file_mmap
+#endif
+
/*
* Called when filp is released. This happens when all file descriptors
* for a single struct file are closed. Note that different open() calls
@@ -70,7 +100,7 @@ const struct file_operations ext2_file_operations = {
#ifdef CONFIG_COMPAT
.compat_ioctl = ext2_compat_ioctl,
#endif
- .mmap = generic_file_mmap,
+ .mmap = ext2_file_mmap,
.open = dquot_file_open,
.release = ext2_release_file,
.fsync = ext2_fsync,
@@ -78,16 +108,18 @@ const struct file_operations ext2_file_operations = {
.splice_write = iter_file_splice_write,
};
-#ifdef CONFIG_EXT2_FS_XIP
-const struct file_operations ext2_xip_file_operations = {
+#ifdef CONFIG_FS_DAX
+const struct file_operations ext2_dax_file_operations = {
.llseek = generic_file_llseek,
- .read = xip_file_read,
- .write = xip_file_write,
+ .read = new_sync_read,
+ .write = new_sync_write,
+ .read_iter = generic_file_read_iter,
+ .write_iter = generic_file_write_iter,
.unlocked_ioctl = ext2_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ext2_compat_ioctl,
#endif
- .mmap = xip_file_mmap,
+ .mmap = ext2_file_mmap,
.open = dquot_file_open,
.release = ext2_release_file,
.fsync = ext2_fsync,
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 36d35c36311d..6434bc000125 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -34,7 +34,6 @@
#include <linux/aio.h>
#include "ext2.h"
#include "acl.h"
-#include "xip.h"
#include "xattr.h"
static int __ext2_write_inode(struct inode *inode, int do_sync);
@@ -731,12 +730,14 @@ static int ext2_get_blocks(struct inode *inode,
goto cleanup;
}
- if (ext2_use_xip(inode->i_sb)) {
+ if (IS_DAX(inode)) {
/*
- * we need to clear the block
+ * block must be initialised before we put it in the tree
+ * so that it's not found by another thread before it's
+ * initialised
*/
- err = ext2_clear_xip_target (inode,
- le32_to_cpu(chain[depth-1].key));
+ err = dax_clear_blocks(inode, le32_to_cpu(chain[depth-1].key),
+ 1 << inode->i_blkbits);
if (err) {
mutex_unlock(&ei->truncate_mutex);
goto cleanup;
@@ -859,7 +860,12 @@ ext2_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
size_t count = iov_iter_count(iter);
ssize_t ret;
- ret = blockdev_direct_IO(rw, iocb, inode, iter, offset, ext2_get_block);
+ if (IS_DAX(inode))
+ ret = dax_do_io(rw, iocb, inode, iter, offset, ext2_get_block,
+ NULL, DIO_LOCKING);
+ else
+ ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
+ ext2_get_block);
if (ret < 0 && (rw & WRITE))
ext2_write_failed(mapping, offset + count);
return ret;
@@ -885,11 +891,6 @@ const struct address_space_operations ext2_aops = {
.error_remove_page = generic_error_remove_page,
};
-const struct address_space_operations ext2_aops_xip = {
- .bmap = ext2_bmap,
- .get_xip_mem = ext2_get_xip_mem,
-};
-
const struct address_space_operations ext2_nobh_aops = {
.readpage = ext2_readpage,
.readpages = ext2_readpages,
@@ -1201,8 +1202,8 @@ static int ext2_setsize(struct inode *inode, loff_t newsize)
inode_dio_wait(inode);
- if (mapping_is_xip(inode->i_mapping))
- error = xip_truncate_page(inode->i_mapping, newsize);
+ if (IS_DAX(inode))
+ error = dax_truncate_page(inode, newsize, ext2_get_block);
else if (test_opt(inode->i_sb, NOBH))
error = nobh_truncate_page(inode->i_mapping,
newsize, ext2_get_block);
@@ -1273,7 +1274,8 @@ void ext2_set_inode_flags(struct inode *inode)
{
unsigned int flags = EXT2_I(inode)->i_flags;
- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
+ inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
+ S_DIRSYNC | S_DAX);
if (flags & EXT2_SYNC_FL)
inode->i_flags |= S_SYNC;
if (flags & EXT2_APPEND_FL)
@@ -1284,6 +1286,8 @@ void ext2_set_inode_flags(struct inode *inode)
inode->i_flags |= S_NOATIME;
if (flags & EXT2_DIRSYNC_FL)
inode->i_flags |= S_DIRSYNC;
+ if (test_opt(inode->i_sb, DAX))
+ inode->i_flags |= S_DAX;
}
/* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
@@ -1384,9 +1388,9 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
if (S_ISREG(inode->i_mode)) {
inode->i_op = &ext2_file_inode_operations;
- if (ext2_use_xip(inode->i_sb)) {
- inode->i_mapping->a_ops = &ext2_aops_xip;
- inode->i_fop = &ext2_xip_file_operations;
+ if (test_opt(inode->i_sb, DAX)) {
+ inode->i_mapping->a_ops = &ext2_aops;
+ inode->i_fop = &ext2_dax_file_operations;
} else if (test_opt(inode->i_sb, NOBH)) {
inode->i_mapping->a_ops = &ext2_nobh_aops;
inode->i_fop = &ext2_file_operations;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index c268d0af1db9..148f6e3789ea 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -35,7 +35,6 @@
#include "ext2.h"
#include "xattr.h"
#include "acl.h"
-#include "xip.h"
static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
{
@@ -105,9 +104,9 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode
return PTR_ERR(inode);
inode->i_op = &ext2_file_inode_operations;
- if (ext2_use_xip(inode->i_sb)) {
- inode->i_mapping->a_ops = &ext2_aops_xip;
- inode->i_fop = &ext2_xip_file_operations;
+ if (test_opt(inode->i_sb, DAX)) {
+ inode->i_mapping->a_ops = &ext2_aops;
+ inode->i_fop = &ext2_dax_file_operations;
} else if (test_opt(inode->i_sb, NOBH)) {
inode->i_mapping->a_ops = &ext2_nobh_aops;
inode->i_fop = &ext2_file_operations;
@@ -126,9 +125,9 @@ static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
return PTR_ERR(inode);
inode->i_op = &ext2_file_inode_operations;
- if (ext2_use_xip(inode->i_sb)) {
- inode->i_mapping->a_ops = &ext2_aops_xip;
- inode->i_fop = &ext2_xip_file_operations;
+ if (test_opt(inode->i_sb, DAX)) {
+ inode->i_mapping->a_ops = &ext2_aops;
+ inode->i_fop = &ext2_dax_file_operations;
} else if (test_opt(inode->i_sb, NOBH)) {
inode->i_mapping->a_ops = &ext2_nobh_aops;
inode->i_fop = &ext2_file_operations;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index ae55fddc26a9..d0e746e96511 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -35,7 +35,6 @@
#include "ext2.h"
#include "xattr.h"
#include "acl.h"
-#include "xip.h"
static void ext2_sync_super(struct super_block *sb,
struct ext2_super_block *es, int wait);
@@ -292,9 +291,11 @@ static int ext2_show_options(struct seq_file *seq, struct dentry *root)
seq_puts(seq, ",grpquota");
#endif
-#if defined(CONFIG_EXT2_FS_XIP)
+#ifdef CONFIG_FS_DAX
if (sbi->s_mount_opt & EXT2_MOUNT_XIP)
seq_puts(seq, ",xip");
+ if (sbi->s_mount_opt & EXT2_MOUNT_DAX)
+ seq_puts(seq, ",dax");
#endif
if (!test_opt(sb, RESERVATION))
@@ -403,7 +404,7 @@ enum {
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic,
Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
- Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
+ Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
};
@@ -432,6 +433,7 @@ static const match_table_t tokens = {
{Opt_acl, "acl"},
{Opt_noacl, "noacl"},
{Opt_xip, "xip"},
+ {Opt_dax, "dax"},
{Opt_grpquota, "grpquota"},
{Opt_ignore, "noquota"},
{Opt_quota, "quota"},
@@ -559,10 +561,14 @@ static int parse_options(char *options, struct super_block *sb)
break;
#endif
case Opt_xip:
-#ifdef CONFIG_EXT2_FS_XIP
- set_opt (sbi->s_mount_opt, XIP);
+ ext2_msg(sb, KERN_INFO, "use dax instead of xip");
+ set_opt(sbi->s_mount_opt, XIP);
+ /* Fall through */
+ case Opt_dax:
+#ifdef CONFIG_FS_DAX
+ set_opt(sbi->s_mount_opt, DAX);
#else
- ext2_msg(sb, KERN_INFO, "xip option not supported");
+ ext2_msg(sb, KERN_INFO, "dax option not supported");
#endif
break;
@@ -877,9 +883,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
MS_POSIXACL : 0);
- ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset
- EXT2_MOUNT_XIP if not */
-
if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
(EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -909,11 +912,17 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
- if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) {
- if (!silent)
+ if (sbi->s_mount_opt & EXT2_MOUNT_DAX) {
+ if (blocksize != PAGE_SIZE) {
ext2_msg(sb, KERN_ERR,
- "error: unsupported blocksize for xip");
- goto failed_mount;
+ "error: unsupported blocksize for dax");
+ goto failed_mount;
+ }
+ if (!sb->s_bdev->bd_disk->fops->direct_access) {
+ ext2_msg(sb, KERN_ERR,
+ "error: device does not support dax");
+ goto failed_mount;
+ }
}
/* If the blocksize doesn't match, re-read the thing.. */
@@ -1259,7 +1268,6 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
{
struct ext2_sb_info * sbi = EXT2_SB(sb);
struct ext2_super_block * es;
- unsigned long old_mount_opt = sbi->s_mount_opt;
struct ext2_mount_options old_opts;
unsigned long old_sb_flags;
int err;
@@ -1284,22 +1292,11 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
- ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset
- EXT2_MOUNT_XIP if not */
-
- if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) {
- ext2_msg(sb, KERN_WARNING,
- "warning: unsupported blocksize for xip");
- err = -EINVAL;
- goto restore_opts;
- }
-
es = sbi->s_es;
- if ((sbi->s_mount_opt ^ old_mount_opt) & EXT2_MOUNT_XIP) {
+ if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT2_MOUNT_DAX) {
ext2_msg(sb, KERN_WARNING, "warning: refusing change of "
- "xip flag with busy inodes while remounting");
- sbi->s_mount_opt &= ~EXT2_MOUNT_XIP;
- sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP;
+ "dax flag with busy inodes while remounting");
+ sbi->s_mount_opt ^= EXT2_MOUNT_DAX;
}
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
spin_unlock(&sbi->s_lock);
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
deleted file mode 100644
index bbc5fec6ff7f..000000000000
--- a/fs/ext2/xip.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * linux/fs/ext2/xip.c
- *
- * Copyright (C) 2005 IBM Corporation
- * Author: Carsten Otte (cotte@de.ibm.com)
- */
-
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/buffer_head.h>
-#include <linux/blkdev.h>
-#include "ext2.h"
-#include "xip.h"
-
-static inline long __inode_direct_access(struct inode *inode, sector_t block,
- void **kaddr, unsigned long *pfn, long size)
-{
- struct block_device *bdev = inode->i_sb->s_bdev;
- sector_t sector = block * (PAGE_SIZE / 512);
- return bdev_direct_access(bdev, sector, kaddr, pfn, size);
-}
-
-static inline int
-__ext2_get_block(struct inode *inode, pgoff_t pgoff, int create,
- sector_t *result)
-{
- struct buffer_head tmp;
- int rc;
-
- memset(&tmp, 0, sizeof(struct buffer_head));
- tmp.b_size = 1 << inode->i_blkbits;
- rc = ext2_get_block(inode, pgoff, &tmp, create);
- *result = tmp.b_blocknr;
-
- /* did we get a sparse block (hole in the file)? */
- if (!tmp.b_blocknr && !rc) {
- BUG_ON(create);
- rc = -ENODATA;
- }
-
- return rc;
-}
-
-int
-ext2_clear_xip_target(struct inode *inode, sector_t block)
-{
- void *kaddr;
- unsigned long pfn;
- long size;
-
- size = __inode_direct_access(inode, block, &kaddr, &pfn, PAGE_SIZE);
- if (size < 0)
- return size;
- clear_page(kaddr);
- return 0;
-}
-
-void ext2_xip_verify_sb(struct super_block *sb)
-{
- struct ext2_sb_info *sbi = EXT2_SB(sb);
-
- if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
- !sb->s_bdev->bd_disk->fops->direct_access) {
- sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
- ext2_msg(sb, KERN_WARNING,
- "warning: ignoring xip option - "
- "not supported by bdev");
- }
-}
-
-int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create,
- void **kmem, unsigned long *pfn)
-{
- long rc;
- sector_t block;
-
- /* first, retrieve the sector number */
- rc = __ext2_get_block(mapping->host, pgoff, create, &block);
- if (rc)
- return rc;
-
- /* retrieve address of the target data */
- rc = __inode_direct_access(mapping->host, block, kmem, pfn, PAGE_SIZE);
- return (rc < 0) ? rc : 0;
-}
diff --git a/fs/ext2/xip.h b/fs/ext2/xip.h
deleted file mode 100644
index 18b34d2f31b3..000000000000
--- a/fs/ext2/xip.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/fs/ext2/xip.h
- *
- * Copyright (C) 2005 IBM Corporation
- * Author: Carsten Otte (cotte@de.ibm.com)
- */
-
-#ifdef CONFIG_EXT2_FS_XIP
-extern void ext2_xip_verify_sb (struct super_block *);
-extern int ext2_clear_xip_target (struct inode *, sector_t);
-
-static inline int ext2_use_xip (struct super_block *sb)
-{
- struct ext2_sb_info *sbi = EXT2_SB(sb);
- return (sbi->s_mount_opt & EXT2_MOUNT_XIP);
-}
-int ext2_get_xip_mem(struct address_space *, pgoff_t, int,
- void **, unsigned long *);
-#define mapping_is_xip(map) unlikely(map->a_ops->get_xip_mem)
-#else
-#define mapping_is_xip(map) 0
-#define ext2_xip_verify_sb(sb) do { } while (0)
-#define ext2_use_xip(sb) 0
-#define ext2_clear_xip_target(inode, chain) 0
-#define ext2_get_xip_mem NULL
-#endif
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index a75fba67bb1f..982d934fd9ac 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -965,6 +965,11 @@ struct ext4_inode_info {
#define EXT4_MOUNT_ERRORS_MASK 0x00070
#define EXT4_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */
#define EXT4_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/
+#ifdef CONFIG_FS_DAX
+#define EXT4_MOUNT_DAX 0x00200 /* Direct Access */
+#else
+#define EXT4_MOUNT_DAX 0
+#endif
#define EXT4_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */
#define EXT4_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */
#define EXT4_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */
@@ -2578,6 +2583,7 @@ extern const struct file_operations ext4_dir_operations;
/* file.c */
extern const struct inode_operations ext4_file_inode_operations;
extern const struct file_operations ext4_file_operations;
+extern const struct file_operations ext4_dax_file_operations;
extern loff_t ext4_llseek(struct file *file, loff_t offset, int origin);
/* inline.c */
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 7cb592386121..33a09da16c9c 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -95,7 +95,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
struct inode *inode = file_inode(iocb->ki_filp);
struct mutex *aio_mutex = NULL;
struct blk_plug plug;
- int o_direct = file->f_flags & O_DIRECT;
+ int o_direct = io_is_direct(file);
int overwrite = 0;
size_t length = iov_iter_count(from);
ssize_t ret;
@@ -191,6 +191,26 @@ errout:
return ret;
}
+#ifdef CONFIG_FS_DAX
+static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return dax_fault(vma, vmf, ext4_get_block);
+ /* Is this the right get_block? */
+}
+
+static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return dax_mkwrite(vma, vmf, ext4_get_block);
+}
+
+static const struct vm_operations_struct ext4_dax_vm_ops = {
+ .fault = ext4_dax_fault,
+ .page_mkwrite = ext4_dax_mkwrite,
+};
+#else
+#define ext4_dax_vm_ops ext4_file_vm_ops
+#endif
+
static const struct vm_operations_struct ext4_file_vm_ops = {
.fault = filemap_fault,
.map_pages = filemap_map_pages,
@@ -200,7 +220,12 @@ static const struct vm_operations_struct ext4_file_vm_ops = {
static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
{
file_accessed(file);
- vma->vm_ops = &ext4_file_vm_ops;
+ if (IS_DAX(file_inode(file))) {
+ vma->vm_ops = &ext4_dax_vm_ops;
+ vma->vm_flags |= VM_MIXEDMAP;
+ } else {
+ vma->vm_ops = &ext4_file_vm_ops;
+ }
return 0;
}
@@ -599,6 +624,26 @@ const struct file_operations ext4_file_operations = {
.fallocate = ext4_fallocate,
};
+#ifdef CONFIG_FS_DAX
+const struct file_operations ext4_dax_file_operations = {
+ .llseek = ext4_llseek,
+ .read = new_sync_read,
+ .write = new_sync_write,
+ .read_iter = generic_file_read_iter,
+ .write_iter = ext4_file_write_iter,
+ .unlocked_ioctl = ext4_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ext4_compat_ioctl,
+#endif
+ .mmap = ext4_file_mmap,
+ .open = ext4_file_open,
+ .release = ext4_release_file,
+ .fsync = ext4_sync_file,
+ /* Splice not yet supported with DAX */
+ .fallocate = ext4_fallocate,
+};
+#endif
+
const struct inode_operations ext4_file_inode_operations = {
.setattr = ext4_setattr,
.getattr = ext4_getattr,
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 36b369697a13..6b9878a24182 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -689,14 +689,22 @@ retry:
inode_dio_done(inode);
goto locked;
}
- ret = __blockdev_direct_IO(rw, iocb, inode,
- inode->i_sb->s_bdev, iter, offset,
- ext4_get_block, NULL, NULL, 0);
+ if (IS_DAX(inode))
+ ret = dax_do_io(rw, iocb, inode, iter, offset,
+ ext4_get_block, NULL, 0);
+ else
+ ret = __blockdev_direct_IO(rw, iocb, inode,
+ inode->i_sb->s_bdev, iter, offset,
+ ext4_get_block, NULL, NULL, 0);
inode_dio_done(inode);
} else {
locked:
- ret = blockdev_direct_IO(rw, iocb, inode, iter,
- offset, ext4_get_block);
+ if (IS_DAX(inode))
+ ret = dax_do_io(rw, iocb, inode, iter, offset,
+ ext4_get_block, NULL, DIO_LOCKING);
+ else
+ ret = blockdev_direct_IO(rw, iocb, inode, iter,
+ offset, ext4_get_block);
if (unlikely((rw & WRITE) && ret < 0)) {
loff_t isize = i_size_read(inode);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5653fa42930b..85404f15e53a 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -657,6 +657,18 @@ has_zeroout:
return retval;
}
+static void ext4_end_io_unwritten(struct buffer_head *bh, int uptodate)
+{
+ struct inode *inode = bh->b_assoc_map->host;
+ /* XXX: breaks on 32-bit > 16GB. Is that even supported? */
+ loff_t offset = (loff_t)(uintptr_t)bh->b_private << inode->i_blkbits;
+ int err;
+ if (!uptodate)
+ return;
+ WARN_ON(!buffer_unwritten(bh));
+ err = ext4_convert_unwritten_extents(NULL, inode, offset, bh->b_size);
+}
+
/* Maximum number of blocks we map for direct IO at once. */
#define DIO_MAX_BLOCKS 4096
@@ -694,6 +706,11 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,
map_bh(bh, inode->i_sb, map.m_pblk);
bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
+ if (IS_DAX(inode) && buffer_unwritten(bh) && !io_end) {
+ bh->b_assoc_map = inode->i_mapping;
+ bh->b_private = (void *)(unsigned long)iblock;
+ bh->b_end_io = ext4_end_io_unwritten;
+ }
if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
set_buffer_defer_completion(bh);
bh->b_size = inode->i_sb->s_blocksize * map.m_len;
@@ -3010,13 +3027,14 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
get_block_func = ext4_get_block_write;
dio_flags = DIO_LOCKING;
}
- ret = __blockdev_direct_IO(rw, iocb, inode,
- inode->i_sb->s_bdev, iter,
- offset,
- get_block_func,
- ext4_end_io_dio,
- NULL,
- dio_flags);
+ if (IS_DAX(inode))
+ ret = dax_do_io(rw, iocb, inode, iter, offset, get_block_func,
+ ext4_end_io_dio, dio_flags);
+ else
+ ret = __blockdev_direct_IO(rw, iocb, inode,
+ inode->i_sb->s_bdev, iter, offset,
+ get_block_func,
+ ext4_end_io_dio, NULL, dio_flags);
/*
* Put our reference to io_end. This can free the io_end structure e.g.
@@ -3180,19 +3198,12 @@ void ext4_set_aops(struct inode *inode)
inode->i_mapping->a_ops = &ext4_aops;
}
-/*
- * ext4_block_zero_page_range() zeros out a mapping of length 'length'
- * starting from file offset 'from'. The range to be zero'd must
- * be contained with in one block. If the specified range exceeds
- * the end of the block it will be shortened to end of the block
- * that cooresponds to 'from'
- */
-static int ext4_block_zero_page_range(handle_t *handle,
+static int __ext4_block_zero_page_range(handle_t *handle,
struct address_space *mapping, loff_t from, loff_t length)
{
ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
unsigned offset = from & (PAGE_CACHE_SIZE-1);
- unsigned blocksize, max, pos;
+ unsigned blocksize, pos;
ext4_lblk_t iblock;
struct inode *inode = mapping->host;
struct buffer_head *bh;
@@ -3205,14 +3216,6 @@ static int ext4_block_zero_page_range(handle_t *handle,
return -ENOMEM;
blocksize = inode->i_sb->s_blocksize;
- max = blocksize - (offset & (blocksize - 1));
-
- /*
- * correct length if it does not fall between
- * 'from' and the end of the block
- */
- if (length > max || length < 0)
- length = max;
iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
@@ -3278,6 +3281,33 @@ unlock:
}
/*
+ * ext4_block_zero_page_range() zeros out a mapping of length 'length'
+ * starting from file offset 'from'. The range to be zero'd must
+ * be contained with in one block. If the specified range exceeds
+ * the end of the block it will be shortened to end of the block
+ * that cooresponds to 'from'
+ */
+static int ext4_block_zero_page_range(handle_t *handle,
+ struct address_space *mapping, loff_t from, loff_t length)
+{
+ struct inode *inode = mapping->host;
+ unsigned offset = from & (PAGE_CACHE_SIZE-1);
+ unsigned blocksize = inode->i_sb->s_blocksize;
+ unsigned max = blocksize - (offset & (blocksize - 1));
+
+ /*
+ * correct length if it does not fall between
+ * 'from' and the end of the block
+ */
+ if (length > max || length < 0)
+ length = max;
+
+ if (IS_DAX(inode))
+ return dax_zero_page_range(inode, from, length, ext4_get_block);
+ return __ext4_block_zero_page_range(handle, mapping, from, length);
+}
+
+/*
* ext4_block_truncate_page() zeroes out a mapping from file offset `from'
* up to the end of the block which corresponds to `from'.
* This required during truncate. We need to physically zero the tail end
@@ -3798,8 +3828,10 @@ void ext4_set_inode_flags(struct inode *inode)
new_fl |= S_NOATIME;
if (flags & EXT4_DIRSYNC_FL)
new_fl |= S_DIRSYNC;
+ if (test_opt(inode->i_sb, DAX))
+ new_fl |= S_DAX;
inode_set_flags(inode, new_fl,
- S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
+ S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
}
/* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
@@ -4052,7 +4084,10 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
if (S_ISREG(inode->i_mode)) {
inode->i_op = &ext4_file_inode_operations;
- inode->i_fop = &ext4_file_operations;
+ if (test_opt(inode->i_sb, DAX))
+ inode->i_fop = &ext4_dax_file_operations;
+ else
+ inode->i_fop = &ext4_file_operations;
ext4_set_aops(inode);
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &ext4_dir_inode_operations;
@@ -4139,6 +4174,65 @@ static int ext4_inode_blocks_set(handle_t *handle,
return 0;
}
+struct other_inode {
+ unsigned long orig_ino;
+ struct ext4_inode *raw_inode;
+};
+
+static int other_inode_match(struct inode * inode, unsigned long ino,
+ void *data)
+{
+ struct other_inode *oi = (struct other_inode *) data;
+
+ if ((inode->i_ino != ino) ||
+ (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
+ I_DIRTY_SYNC | I_DIRTY_DATASYNC)) ||
+ ((inode->i_state & I_DIRTY_TIME) == 0))
+ return 0;
+ spin_lock(&inode->i_lock);
+ if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
+ I_DIRTY_SYNC | I_DIRTY_DATASYNC)) == 0) &&
+ (inode->i_state & I_DIRTY_TIME)) {
+ struct ext4_inode_info *ei = EXT4_I(inode);
+
+ inode->i_state &= ~(I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED);
+ spin_unlock(&inode->i_lock);
+
+ spin_lock(&ei->i_raw_lock);
+ EXT4_INODE_SET_XTIME(i_ctime, inode, oi->raw_inode);
+ EXT4_INODE_SET_XTIME(i_mtime, inode, oi->raw_inode);
+ EXT4_INODE_SET_XTIME(i_atime, inode, oi->raw_inode);
+ ext4_inode_csum_set(inode, oi->raw_inode, ei);
+ spin_unlock(&ei->i_raw_lock);
+ trace_ext4_other_inode_update_time(inode, oi->orig_ino);
+ return -1;
+ }
+ spin_unlock(&inode->i_lock);
+ return -1;
+}
+
+/*
+ * Opportunistically update the other time fields for other inodes in
+ * the same inode table block.
+ */
+static void ext4_update_other_inodes_time(struct super_block *sb,
+ unsigned long orig_ino, char *buf)
+{
+ struct other_inode oi;
+ unsigned long ino;
+ int i, inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
+ int inode_size = EXT4_INODE_SIZE(sb);
+
+ oi.orig_ino = orig_ino;
+ ino = orig_ino & ~(inodes_per_block - 1);
+ for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) {
+ if (ino == orig_ino)
+ continue;
+ oi.raw_inode = (struct ext4_inode *) buf;
+ (void) find_inode_nowait(sb, ino, other_inode_match, &oi);
+ }
+}
+
/*
* Post the struct inode info into an on-disk inode location in the
* buffer-cache. This gobbles the caller's reference to the
@@ -4248,10 +4342,11 @@ static int ext4_do_update_inode(handle_t *handle,
cpu_to_le16(ei->i_extra_isize);
}
}
-
ext4_inode_csum_set(inode, raw_inode, ei);
-
spin_unlock(&ei->i_raw_lock);
+ if (inode->i_sb->s_flags & MS_LAZYTIME)
+ ext4_update_other_inodes_time(inode->i_sb, inode->i_ino,
+ bh->b_data);
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
rc = ext4_handle_dirty_metadata(handle, NULL, bh);
@@ -4534,7 +4629,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
* Truncate pagecache after we've waited for commit
* in data=journal mode to make pages freeable.
*/
- truncate_pagecache(inode, inode->i_size);
+ truncate_pagecache(inode, inode->i_size);
}
/*
* We want to call ext4_truncate() even if attr->ia_size ==
@@ -4840,11 +4935,17 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
* If the inode is marked synchronous, we don't honour that here - doing
* so would cause a commit on atime updates, which we don't bother doing.
* We handle synchronous inodes at the highest possible level.
+ *
+ * If only the I_DIRTY_TIME flag is set, we can skip everything. If
+ * I_DIRTY_TIME and I_DIRTY_SYNC is set, the only inode fields we need
+ * to copy into the on-disk inode structure are the timestamp files.
*/
void ext4_dirty_inode(struct inode *inode, int flags)
{
handle_t *handle;
+ if (flags == I_DIRTY_TIME)
+ return;
handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
if (IS_ERR(handle))
goto out;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 2291923dae4e..28fe71a2904c 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2235,7 +2235,10 @@ retry:
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
inode->i_op = &ext4_file_inode_operations;
- inode->i_fop = &ext4_file_operations;
+ if (test_opt(inode->i_sb, DAX))
+ inode->i_fop = &ext4_dax_file_operations;
+ else
+ inode->i_fop = &ext4_file_operations;
ext4_set_aops(inode);
err = ext4_add_nondir(handle, dentry, inode);
if (!err && IS_DIRSYNC(dir))
@@ -2299,7 +2302,10 @@ retry:
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
inode->i_op = &ext4_file_inode_operations;
- inode->i_fop = &ext4_file_operations;
+ if (test_opt(inode->i_sb, DAX))
+ inode->i_fop = &ext4_dax_file_operations;
+ else
+ inode->i_fop = &ext4_file_operations;
ext4_set_aops(inode);
d_tmpfile(dentry, inode);
err = ext4_orphan_add(handle, inode);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 64c39c7c594f..1adac6868e6f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1124,8 +1124,9 @@ enum {
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
- Opt_usrquota, Opt_grpquota, Opt_i_version,
+ Opt_usrquota, Opt_grpquota, Opt_i_version, Opt_dax,
Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
+ Opt_lazytime, Opt_nolazytime,
Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
Opt_inode_readahead_blks, Opt_journal_ioprio,
Opt_dioread_nolock, Opt_dioread_lock,
@@ -1187,8 +1188,11 @@ static const match_table_t tokens = {
{Opt_barrier, "barrier"},
{Opt_nobarrier, "nobarrier"},
{Opt_i_version, "i_version"},
+ {Opt_dax, "dax"},
{Opt_stripe, "stripe=%u"},
{Opt_delalloc, "delalloc"},
+ {Opt_lazytime, "lazytime"},
+ {Opt_nolazytime, "nolazytime"},
{Opt_nodelalloc, "nodelalloc"},
{Opt_removed, "mblk_io_submit"},
{Opt_removed, "nomblk_io_submit"},
@@ -1371,6 +1375,7 @@ static const struct mount_opts {
{Opt_min_batch_time, 0, MOPT_GTE0},
{Opt_inode_readahead_blks, 0, MOPT_GTE0},
{Opt_init_itable, 0, MOPT_GTE0},
+ {Opt_dax, EXT4_MOUNT_DAX, MOPT_SET},
{Opt_stripe, 0, MOPT_GTE0},
{Opt_resuid, 0, MOPT_GTE0},
{Opt_resgid, 0, MOPT_GTE0},
@@ -1446,6 +1451,12 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
case Opt_i_version:
sb->s_flags |= MS_I_VERSION;
return 1;
+ case Opt_lazytime:
+ sb->s_flags |= MS_LAZYTIME;
+ return 1;
+ case Opt_nolazytime:
+ sb->s_flags &= ~MS_LAZYTIME;
+ return 1;
}
for (m = ext4_mount_opts; m->token != Opt_err; m++)
@@ -1607,6 +1618,11 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
}
sbi->s_jquota_fmt = m->mount_opt;
#endif
+#ifndef CONFIG_FS_DAX
+ } else if (token == Opt_dax) {
+ ext4_msg(sb, KERN_INFO, "dax option not supported");
+ return -1;
+#endif
} else {
if (!args->from)
arg = 1;
@@ -3589,6 +3605,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
"both data=journal and dioread_nolock");
goto failed_mount;
}
+ if (test_opt(sb, DAX)) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "both data=journal and dax");
+ goto failed_mount;
+ }
if (test_opt(sb, DELALLOC))
clear_opt(sb, DELALLOC);
}
@@ -3652,6 +3673,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount;
}
+ if (sbi->s_mount_opt & EXT4_MOUNT_DAX) {
+ if (blocksize != PAGE_SIZE) {
+ ext4_msg(sb, KERN_ERR,
+ "error: unsupported blocksize for dax");
+ goto failed_mount;
+ }
+ if (!sb->s_bdev->bd_disk->fops->direct_access) {
+ ext4_msg(sb, KERN_ERR,
+ "error: device does not support dax");
+ goto failed_mount;
+ }
+ }
+
if (sb->s_blocksize != blocksize) {
/* Validate the filesystem blocksize */
if (!sb_set_blocksize(sb, blocksize)) {
@@ -4869,6 +4903,18 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
err = -EINVAL;
goto restore_opts;
}
+ if (test_opt(sb, DAX)) {
+ ext4_msg(sb, KERN_ERR, "can't mount with "
+ "both data=journal and dax");
+ err = -EINVAL;
+ goto restore_opts;
+ }
+ }
+
+ if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_DAX) {
+ ext4_msg(sb, KERN_WARNING, "warning: refusing change of "
+ "dax flag with busy inodes while remounting");
+ sbi->s_mount_opt ^= EXT4_MOUNT_DAX;
}
if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
@@ -5007,6 +5053,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
}
#endif
+ *flags = (*flags & ~MS_LAZYTIME) | (sb->s_flags & MS_LAZYTIME);
ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
kfree(orig_data);
return 0;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 7b41a2dcdd76..497c7c5263c7 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -580,7 +580,7 @@ static void fat_set_state(struct super_block *sb,
{
struct buffer_head *bh;
struct fat_boot_sector *b;
- struct msdos_sb_info *sbi = sb->s_fs_info;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
/* do not change any thing if mounted read only */
if ((sb->s_flags & MS_RDONLY) && !force)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index c399152de397..073657f755d4 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -253,14 +253,19 @@ static bool inode_dirtied_after(struct inode *inode, unsigned long t)
return ret;
}
+#define EXPIRE_DIRTY_ATIME 0x0001
+
/*
* Move expired (dirtied before work->older_than_this) dirty inodes from
* @delaying_queue to @dispatch_queue.
*/
static int move_expired_inodes(struct list_head *delaying_queue,
struct list_head *dispatch_queue,
+ int flags,
struct wb_writeback_work *work)
{
+ unsigned long *older_than_this = NULL;
+ unsigned long expire_time;
LIST_HEAD(tmp);
struct list_head *pos, *node;
struct super_block *sb = NULL;
@@ -268,13 +273,21 @@ static int move_expired_inodes(struct list_head *delaying_queue,
int do_sb_sort = 0;
int moved = 0;
+ if ((flags & EXPIRE_DIRTY_ATIME) == 0)
+ older_than_this = work->older_than_this;
+ else if ((work->reason == WB_REASON_SYNC) == 0) {
+ expire_time = jiffies - (HZ * 86400);
+ older_than_this = &expire_time;
+ }
while (!list_empty(delaying_queue)) {
inode = wb_inode(delaying_queue->prev);
- if (work->older_than_this &&
- inode_dirtied_after(inode, *work->older_than_this))
+ if (older_than_this &&
+ inode_dirtied_after(inode, *older_than_this))
break;
list_move(&inode->i_wb_list, &tmp);
moved++;
+ if (flags & EXPIRE_DIRTY_ATIME)
+ set_bit(__I_DIRTY_TIME_EXPIRED, &inode->i_state);
if (sb_is_blkdev_sb(inode->i_sb))
continue;
if (sb && sb != inode->i_sb)
@@ -315,9 +328,12 @@ out:
static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work)
{
int moved;
+
assert_spin_locked(&wb->list_lock);
list_splice_init(&wb->b_more_io, &wb->b_io);
- moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, work);
+ moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, 0, work);
+ moved += move_expired_inodes(&wb->b_dirty_time, &wb->b_io,
+ EXPIRE_DIRTY_ATIME, work);
trace_writeback_queue_io(wb, work, moved);
}
@@ -441,6 +457,8 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
* updates after data IO completion.
*/
redirty_tail(inode, wb);
+ } else if (inode->i_state & I_DIRTY_TIME) {
+ list_move(&inode->i_wb_list, &wb->b_dirty_time);
} else {
/* The inode is clean. Remove from writeback lists. */
list_del_init(&inode->i_wb_list);
@@ -487,7 +505,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
spin_lock(&inode->i_lock);
dirty = inode->i_state & I_DIRTY;
- inode->i_state &= ~I_DIRTY;
+ if (((dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) &&
+ (inode->i_state & I_DIRTY_TIME)) ||
+ (inode->i_state & I_DIRTY_TIME_EXPIRED)) {
+ dirty |= I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED;
+ trace_writeback_lazytime(inode);
+ }
+ inode->i_state &= ~dirty;
/*
* Paired with smp_mb() in __mark_inode_dirty(). This allows
@@ -507,8 +531,10 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
spin_unlock(&inode->i_lock);
+ if (dirty & I_DIRTY_TIME)
+ mark_inode_dirty_sync(inode);
/* Don't write the inode if only I_DIRTY_PAGES was set */
- if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
+ if (dirty & ~I_DIRTY_PAGES) {
int err = write_inode(inode, wbc);
if (ret == 0)
ret = err;
@@ -556,7 +582,7 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
* make sure inode is on some writeback list and leave it there unless
* we have completely cleaned the inode.
*/
- if (!(inode->i_state & I_DIRTY) &&
+ if (!(inode->i_state & I_DIRTY_ALL) &&
(wbc->sync_mode != WB_SYNC_ALL ||
!mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK)))
goto out;
@@ -571,7 +597,7 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
* If inode is clean, remove it from writeback lists. Otherwise don't
* touch it. See comment above for explanation.
*/
- if (!(inode->i_state & I_DIRTY))
+ if (!(inode->i_state & I_DIRTY_ALL))
list_del_init(&inode->i_wb_list);
spin_unlock(&wb->list_lock);
inode_sync_complete(inode);
@@ -713,7 +739,7 @@ static long writeback_sb_inodes(struct super_block *sb,
wrote += write_chunk - wbc.nr_to_write;
spin_lock(&wb->list_lock);
spin_lock(&inode->i_lock);
- if (!(inode->i_state & I_DIRTY))
+ if (!(inode->i_state & I_DIRTY_ALL))
wrote++;
requeue_inode(inode, wb, &wbc);
inode_sync_complete(inode);
@@ -1151,16 +1177,20 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
* page->mapping->host, so the page-dirtying time is recorded in the internal
* blockdev inode.
*/
+#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
void __mark_inode_dirty(struct inode *inode, int flags)
{
struct super_block *sb = inode->i_sb;
struct backing_dev_info *bdi = NULL;
+ int dirtytime;
+
+ trace_writeback_mark_inode_dirty(inode, flags);
/*
* Don't do this for I_DIRTY_PAGES - that doesn't actually
* dirty the inode itself
*/
- if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
+ if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_TIME)) {
trace_writeback_dirty_inode_start(inode, flags);
if (sb->s_op->dirty_inode)
@@ -1168,6 +1198,9 @@ void __mark_inode_dirty(struct inode *inode, int flags)
trace_writeback_dirty_inode(inode, flags);
}
+ if (flags & I_DIRTY_INODE)
+ flags &= ~I_DIRTY_TIME;
+ dirtytime = flags & I_DIRTY_TIME;
/*
* Paired with smp_mb() in __writeback_single_inode() for the
@@ -1175,16 +1208,21 @@ void __mark_inode_dirty(struct inode *inode, int flags)
*/
smp_mb();
- if ((inode->i_state & flags) == flags)
+ if (((inode->i_state & flags) == flags) ||
+ (dirtytime && (inode->i_state & I_DIRTY_INODE)))
return;
if (unlikely(block_dump))
block_dump___mark_inode_dirty(inode);
spin_lock(&inode->i_lock);
+ if (dirtytime && (inode->i_state & I_DIRTY_INODE))
+ goto out_unlock_inode;
if ((inode->i_state & flags) != flags) {
const int was_dirty = inode->i_state & I_DIRTY;
+ if (flags & I_DIRTY_INODE)
+ inode->i_state &= ~I_DIRTY_TIME;
inode->i_state |= flags;
/*
@@ -1231,8 +1269,10 @@ void __mark_inode_dirty(struct inode *inode, int flags)
}
inode->dirtied_when = jiffies;
- list_move(&inode->i_wb_list, &bdi->wb.b_dirty);
+ list_move(&inode->i_wb_list, dirtytime ?
+ &bdi->wb.b_dirty_time : &bdi->wb.b_dirty);
spin_unlock(&bdi->wb.list_lock);
+ trace_writeback_dirty_inode_enqueue(inode);
if (wakeup_bdi)
bdi_wakeup_thread_delayed(bdi);
diff --git a/fs/fs_pin.c b/fs/fs_pin.c
index 9368236ca100..b06c98796afb 100644
--- a/fs/fs_pin.c
+++ b/fs/fs_pin.c
@@ -1,78 +1,102 @@
#include <linux/fs.h>
+#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/fs_pin.h>
#include "internal.h"
#include "mount.h"
-static void pin_free_rcu(struct rcu_head *head)
-{
- kfree(container_of(head, struct fs_pin, rcu));
-}
-
static DEFINE_SPINLOCK(pin_lock);
-void pin_put(struct fs_pin *p)
-{
- if (atomic_long_dec_and_test(&p->count))
- call_rcu(&p->rcu, pin_free_rcu);
-}
-
void pin_remove(struct fs_pin *pin)
{
spin_lock(&pin_lock);
hlist_del(&pin->m_list);
hlist_del(&pin->s_list);
spin_unlock(&pin_lock);
+ spin_lock_irq(&pin->wait.lock);
+ pin->done = 1;
+ wake_up_locked(&pin->wait);
+ spin_unlock_irq(&pin->wait.lock);
}
-void pin_insert(struct fs_pin *pin, struct vfsmount *m)
+void pin_insert_group(struct fs_pin *pin, struct vfsmount *m, struct hlist_head *p)
{
spin_lock(&pin_lock);
- hlist_add_head(&pin->s_list, &m->mnt_sb->s_pins);
+ if (p)
+ hlist_add_head(&pin->s_list, p);
hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins);
spin_unlock(&pin_lock);
}
+void pin_insert(struct fs_pin *pin, struct vfsmount *m)
+{
+ pin_insert_group(pin, m, &m->mnt_sb->s_pins);
+}
+
+void pin_kill(struct fs_pin *p)
+{
+ wait_queue_t wait;
+
+ if (!p) {
+ rcu_read_unlock();
+ return;
+ }
+ init_wait(&wait);
+ spin_lock_irq(&p->wait.lock);
+ if (likely(!p->done)) {
+ p->done = -1;
+ spin_unlock_irq(&p->wait.lock);
+ rcu_read_unlock();
+ p->kill(p);
+ return;
+ }
+ if (p->done > 0) {
+ spin_unlock_irq(&p->wait.lock);
+ rcu_read_unlock();
+ return;
+ }
+ __add_wait_queue(&p->wait, &wait);
+ while (1) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ spin_unlock_irq(&p->wait.lock);
+ rcu_read_unlock();
+ schedule();
+ rcu_read_lock();
+ if (likely(list_empty(&wait.task_list)))
+ break;
+ /* OK, we know p couldn't have been freed yet */
+ spin_lock_irq(&p->wait.lock);
+ if (p->done > 0) {
+ spin_unlock_irq(&p->wait.lock);
+ break;
+ }
+ }
+ rcu_read_unlock();
+}
+
void mnt_pin_kill(struct mount *m)
{
while (1) {
struct hlist_node *p;
- struct fs_pin *pin;
rcu_read_lock();
p = ACCESS_ONCE(m->mnt_pins.first);
if (!p) {
rcu_read_unlock();
break;
}
- pin = hlist_entry(p, struct fs_pin, m_list);
- if (!atomic_long_inc_not_zero(&pin->count)) {
- rcu_read_unlock();
- cpu_relax();
- continue;
- }
- rcu_read_unlock();
- pin->kill(pin);
+ pin_kill(hlist_entry(p, struct fs_pin, m_list));
}
}
-void sb_pin_kill(struct super_block *sb)
+void group_pin_kill(struct hlist_head *p)
{
while (1) {
- struct hlist_node *p;
- struct fs_pin *pin;
+ struct hlist_node *q;
rcu_read_lock();
- p = ACCESS_ONCE(sb->s_pins.first);
- if (!p) {
+ q = ACCESS_ONCE(p->first);
+ if (!q) {
rcu_read_unlock();
break;
}
- pin = hlist_entry(p, struct fs_pin, s_list);
- if (!atomic_long_inc_not_zero(&pin->count)) {
- rcu_read_unlock();
- cpu_relax();
- continue;
- }
- rcu_read_unlock();
- pin->kill(pin);
+ pin_kill(hlist_entry(q, struct fs_pin, s_list));
}
}
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index ec9c2d33477a..3e32bb8e2d7e 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -654,7 +654,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
{
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
- int sync_state = inode->i_state & I_DIRTY;
+ int sync_state = inode->i_state & I_DIRTY_ALL;
struct gfs2_inode *ip = GFS2_I(inode);
int ret = 0, ret1 = 0;
@@ -667,7 +667,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
if (!gfs2_is_jdata(ip))
sync_state &= ~I_DIRTY_PAGES;
if (datasync)
- sync_state &= ~I_DIRTY_SYNC;
+ sync_state &= ~(I_DIRTY_SYNC | I_DIRTY_TIME);
if (sync_state) {
ret = sync_inode_metadata(inode, 1);
diff --git a/fs/inode.c b/fs/inode.c
index 86bfaca724db..f00b16f45507 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -18,6 +18,7 @@
#include <linux/buffer_head.h> /* for inode_has_buffers */
#include <linux/ratelimit.h>
#include <linux/list_lru.h>
+#include <trace/events/writeback.h>
#include "internal.h"
/*
@@ -30,7 +31,7 @@
* inode_sb_list_lock protects:
* sb->s_inodes, inode->i_sb_list
* bdi->wb.list_lock protects:
- * bdi->wb.b_{dirty,io,more_io}, inode->i_wb_list
+ * bdi->wb.b_{dirty,io,more_io,dirty_time}, inode->i_wb_list
* inode_hash_lock protects:
* inode_hashtable, inode->i_hash
*
@@ -403,7 +404,8 @@ static void inode_lru_list_add(struct inode *inode)
*/
void inode_add_lru(struct inode *inode)
{
- if (!(inode->i_state & (I_DIRTY | I_SYNC | I_FREEING | I_WILL_FREE)) &&
+ if (!(inode->i_state & (I_DIRTY_ALL | I_SYNC |
+ I_FREEING | I_WILL_FREE)) &&
!atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE)
inode_lru_list_add(inode);
}
@@ -634,7 +636,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
spin_unlock(&inode->i_lock);
continue;
}
- if (inode->i_state & I_DIRTY && !kill_dirty) {
+ if (inode->i_state & I_DIRTY_ALL && !kill_dirty) {
spin_unlock(&inode->i_lock);
busy = 1;
continue;
@@ -1268,6 +1270,56 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
}
EXPORT_SYMBOL(ilookup);
+/**
+ * find_inode_nowait - find an inode in the inode cache
+ * @sb: super block of file system to search
+ * @hashval: hash value (usually inode number) to search for
+ * @match: callback used for comparisons between inodes
+ * @data: opaque data pointer to pass to @match
+ *
+ * Search for the inode specified by @hashval and @data in the inode
+ * cache, where the helper function @match will return 0 if the inode
+ * does not match, 1 if the inode does match, and -1 if the search
+ * should be stopped. The @match function must be responsible for
+ * taking the i_lock spin_lock and checking i_state for an inode being
+ * freed or being initialized, and incrementing the reference count
+ * before returning 1. It also must not sleep, since it is called with
+ * the inode_hash_lock spinlock held.
+ *
+ * This is a even more generalized version of ilookup5() when the
+ * function must never block --- find_inode() can block in
+ * __wait_on_freeing_inode() --- or when the caller can not increment
+ * the reference count because the resulting iput() might cause an
+ * inode eviction. The tradeoff is that the @match funtion must be
+ * very carefully implemented.
+ */
+struct inode *find_inode_nowait(struct super_block *sb,
+ unsigned long hashval,
+ int (*match)(struct inode *, unsigned long,
+ void *),
+ void *data)
+{
+ struct hlist_head *head = inode_hashtable + hash(sb, hashval);
+ struct inode *inode, *ret_inode = NULL;
+ int mval;
+
+ spin_lock(&inode_hash_lock);
+ hlist_for_each_entry(inode, head, i_hash) {
+ if (inode->i_sb != sb)
+ continue;
+ mval = match(inode, hashval, data);
+ if (mval == 0)
+ continue;
+ if (mval == 1)
+ ret_inode = inode;
+ goto out;
+ }
+out:
+ spin_unlock(&inode_hash_lock);
+ return ret_inode;
+}
+EXPORT_SYMBOL(find_inode_nowait);
+
int insert_inode_locked(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
@@ -1418,11 +1470,20 @@ static void iput_final(struct inode *inode)
*/
void iput(struct inode *inode)
{
- if (inode) {
- BUG_ON(inode->i_state & I_CLEAR);
-
- if (atomic_dec_and_lock(&inode->i_count, &inode->i_lock))
- iput_final(inode);
+ if (!inode)
+ return;
+ BUG_ON(inode->i_state & I_CLEAR);
+retry:
+ if (atomic_dec_and_lock(&inode->i_count, &inode->i_lock)) {
+ if (inode->i_nlink && (inode->i_state & I_DIRTY_TIME)) {
+ atomic_inc(&inode->i_count);
+ inode->i_state &= ~I_DIRTY_TIME;
+ spin_unlock(&inode->i_lock);
+ trace_writeback_lazytime_iput(inode);
+ mark_inode_dirty_sync(inode);
+ goto retry;
+ }
+ iput_final(inode);
}
}
EXPORT_SYMBOL(iput);
@@ -1481,14 +1542,9 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
return 0;
}
-/*
- * This does the actual work of updating an inodes time or version. Must have
- * had called mnt_want_write() before calling this.
- */
-static int update_time(struct inode *inode, struct timespec *time, int flags)
+int generic_update_time(struct inode *inode, struct timespec *time, int flags)
{
- if (inode->i_op->update_time)
- return inode->i_op->update_time(inode, time, flags);
+ int iflags = I_DIRTY_TIME;
if (flags & S_ATIME)
inode->i_atime = *time;
@@ -1498,9 +1554,27 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
inode->i_ctime = *time;
if (flags & S_MTIME)
inode->i_mtime = *time;
- mark_inode_dirty_sync(inode);
+
+ if (!(inode->i_sb->s_flags & MS_LAZYTIME) || (flags & S_VERSION))
+ iflags |= I_DIRTY_SYNC;
+ __mark_inode_dirty(inode, iflags);
return 0;
}
+EXPORT_SYMBOL(generic_update_time);
+
+/*
+ * This does the actual work of updating an inodes time or version. Must have
+ * had called mnt_want_write() before calling this.
+ */
+static int update_time(struct inode *inode, struct timespec *time, int flags)
+{
+ int (*update_time)(struct inode *, struct timespec *, int);
+
+ update_time = inode->i_op->update_time ? inode->i_op->update_time :
+ generic_update_time;
+
+ return update_time(inode, time, flags);
+}
/**
* touch_atime - update the access time
diff --git a/fs/internal.h b/fs/internal.h
index d92c346a793d..30459dab409d 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -144,7 +144,7 @@ extern const struct file_operations pipefifo_fops;
/*
* fs_pin.c
*/
-extern void sb_pin_kill(struct super_block *sb);
+extern void group_pin_kill(struct hlist_head *p);
extern void mnt_pin_kill(struct mount *m);
/*
diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c
index 92e0644bf867..556de100ebd5 100644
--- a/fs/jffs2/compr_rubin.c
+++ b/fs/jffs2/compr_rubin.c
@@ -84,11 +84,6 @@ static inline int pullbit(struct pushpull *pp)
return bit;
}
-static inline int pulledbits(struct pushpull *pp)
-{
- return pp->ofs;
-}
-
static void init_rubin(struct rubin_state *rs, int div, int *bits)
{
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 7654e87b0428..9ad5ba4b299b 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -510,6 +510,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
sumlen = c->sector_size - je32_to_cpu(sm->offset);
sumptr = buf + buf_size - sumlen;
+ /* sm->offset maybe wrong but MAGIC maybe right */
+ if (sumlen > c->sector_size)
+ goto full_scan;
+
/* Now, make sure the summary itself is available */
if (sumlen > buf_size) {
/* Need to kmalloc for this. */
@@ -544,6 +548,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
}
}
+full_scan:
buf_ofs = jeb->offset;
if (!buf_size) {
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 33aa0cc1f8b8..10815f8dfd8b 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -39,7 +39,7 @@ int jfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
return rc;
mutex_lock(&inode->i_mutex);
- if (!(inode->i_state & I_DIRTY) ||
+ if (!(inode->i_state & I_DIRTY_ALL) ||
(datasync && !(inode->i_state & I_DIRTY_DATASYNC))) {
/* Make sure committed changes hit the disk */
jfs_flush_journal(JFS_SBI(inode->i_sb)->log, 1);
diff --git a/fs/libfs.c b/fs/libfs.c
index 005843ce5dbd..b2ffdb045be4 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -948,7 +948,7 @@ int __generic_file_fsync(struct file *file, loff_t start, loff_t end,
mutex_lock(&inode->i_mutex);
ret = sync_mapping_buffers(inode->i_mapping);
- if (!(inode->i_state & I_DIRTY))
+ if (!(inode->i_state & I_DIRTY_ALL))
goto out;
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
goto out;
diff --git a/fs/mount.h b/fs/mount.h
index 0ad6f760ce52..6a61c2b3e385 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -2,6 +2,7 @@
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/ns_common.h>
+#include <linux/fs_pin.h>
struct mnt_namespace {
atomic_t count;
@@ -62,7 +63,8 @@ struct mount {
int mnt_group_id; /* peer group identifier */
int mnt_expiry_mark; /* true if marked for expiry */
struct hlist_head mnt_pins;
- struct path mnt_ex_mountpoint;
+ struct fs_pin mnt_umount;
+ struct dentry *mnt_ex_mountpoint;
};
#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
diff --git a/fs/namei.c b/fs/namei.c
index bc35b02883bb..96ca11dea4a2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -118,15 +118,6 @@
* POSIX.1 2.4: an empty pathname is invalid (ENOENT).
* PATH_MAX includes the nul terminator --RR.
*/
-void final_putname(struct filename *name)
-{
- if (name->separate) {
- __putname(name->name);
- kfree(name);
- } else {
- __putname(name);
- }
-}
#define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(struct filename))
@@ -145,6 +136,7 @@ getname_flags(const char __user *filename, int flags, int *empty)
result = __getname();
if (unlikely(!result))
return ERR_PTR(-ENOMEM);
+ result->refcnt = 1;
/*
* First, try to embed the struct filename inside the names_cache
@@ -179,6 +171,7 @@ recopy:
}
result->name = kname;
result->separate = true;
+ result->refcnt = 1;
max = PATH_MAX;
goto recopy;
}
@@ -202,7 +195,7 @@ recopy:
return result;
error:
- final_putname(result);
+ putname(result);
return err;
}
@@ -212,43 +205,56 @@ getname(const char __user * filename)
return getname_flags(filename, 0, NULL);
}
-/*
- * The "getname_kernel()" interface doesn't do pathnames longer
- * than EMBEDDED_NAME_MAX. Deal with it - you're a kernel user.
- */
struct filename *
getname_kernel(const char * filename)
{
struct filename *result;
- char *kname;
- int len;
-
- len = strlen(filename);
- if (len >= EMBEDDED_NAME_MAX)
- return ERR_PTR(-ENAMETOOLONG);
+ int len = strlen(filename) + 1;
result = __getname();
if (unlikely(!result))
return ERR_PTR(-ENOMEM);
- kname = (char *)result + sizeof(*result);
- result->name = kname;
+ if (len <= EMBEDDED_NAME_MAX) {
+ result->name = (char *)(result) + sizeof(*result);
+ result->separate = false;
+ } else if (len <= PATH_MAX) {
+ struct filename *tmp;
+
+ tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+ if (unlikely(!tmp)) {
+ __putname(result);
+ return ERR_PTR(-ENOMEM);
+ }
+ tmp->name = (char *)result;
+ tmp->separate = true;
+ result = tmp;
+ } else {
+ __putname(result);
+ return ERR_PTR(-ENAMETOOLONG);
+ }
+ memcpy((char *)result->name, filename, len);
result->uptr = NULL;
result->aname = NULL;
- result->separate = false;
+ result->refcnt = 1;
+ audit_getname(result);
- strlcpy(kname, filename, EMBEDDED_NAME_MAX);
return result;
}
-#ifdef CONFIG_AUDITSYSCALL
void putname(struct filename *name)
{
- if (unlikely(!audit_dummy_context()))
- return audit_putname(name);
- final_putname(name);
+ BUG_ON(name->refcnt <= 0);
+
+ if (--name->refcnt > 0)
+ return;
+
+ if (name->separate) {
+ __putname(name->name);
+ kfree(name);
+ } else
+ __putname(name);
}
-#endif
static int check_acl(struct inode *inode, int mask)
{
@@ -2036,31 +2042,47 @@ static int filename_lookup(int dfd, struct filename *name,
static int do_path_lookup(int dfd, const char *name,
unsigned int flags, struct nameidata *nd)
{
- struct filename filename = { .name = name };
+ struct filename *filename = getname_kernel(name);
+ int retval = PTR_ERR(filename);
- return filename_lookup(dfd, &filename, flags, nd);
+ if (!IS_ERR(filename)) {
+ retval = filename_lookup(dfd, filename, flags, nd);
+ putname(filename);
+ }
+ return retval;
}
/* does lookup, returns the object with parent locked */
struct dentry *kern_path_locked(const char *name, struct path *path)
{
+ struct filename *filename = getname_kernel(name);
struct nameidata nd;
struct dentry *d;
- int err = do_path_lookup(AT_FDCWD, name, LOOKUP_PARENT, &nd);
- if (err)
- return ERR_PTR(err);
+ int err;
+
+ if (IS_ERR(filename))
+ return ERR_CAST(filename);
+
+ err = filename_lookup(AT_FDCWD, filename, LOOKUP_PARENT, &nd);
+ if (err) {
+ d = ERR_PTR(err);
+ goto out;
+ }
if (nd.last_type != LAST_NORM) {
path_put(&nd.path);
- return ERR_PTR(-EINVAL);
+ d = ERR_PTR(-EINVAL);
+ goto out;
}
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
d = __lookup_hash(&nd.last, nd.path.dentry, 0);
if (IS_ERR(d)) {
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
path_put(&nd.path);
- return d;
+ goto out;
}
*path = nd.path;
+out:
+ putname(filename);
return d;
}
@@ -2351,13 +2373,17 @@ static int
filename_mountpoint(int dfd, struct filename *s, struct path *path,
unsigned int flags)
{
- int error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_RCU);
+ int error;
+ if (IS_ERR(s))
+ return PTR_ERR(s);
+ error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_RCU);
if (unlikely(error == -ECHILD))
error = path_mountpoint(dfd, s->name, path, flags);
if (unlikely(error == -ESTALE))
error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_REVAL);
if (likely(!error))
audit_inode(s, path->dentry, 0);
+ putname(s);
return error;
}
@@ -2379,21 +2405,14 @@ int
user_path_mountpoint_at(int dfd, const char __user *name, unsigned int flags,
struct path *path)
{
- struct filename *s = getname(name);
- int error;
- if (IS_ERR(s))
- return PTR_ERR(s);
- error = filename_mountpoint(dfd, s, path, flags);
- putname(s);
- return error;
+ return filename_mountpoint(dfd, getname(name), path, flags);
}
int
kern_path_mountpoint(int dfd, const char *name, struct path *path,
unsigned int flags)
{
- struct filename s = {.name = name};
- return filename_mountpoint(dfd, &s, path, flags);
+ return filename_mountpoint(dfd, getname_kernel(name), path, flags);
}
EXPORT_SYMBOL(kern_path_mountpoint);
@@ -3273,7 +3292,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
{
struct nameidata nd;
struct file *file;
- struct filename filename = { .name = name };
+ struct filename *filename;
int flags = op->lookup_flags | LOOKUP_ROOT;
nd.root.mnt = mnt;
@@ -3282,15 +3301,20 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
if (d_is_symlink(dentry) && op->intent & LOOKUP_OPEN)
return ERR_PTR(-ELOOP);
- file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU);
+ filename = getname_kernel(name);
+ if (unlikely(IS_ERR(filename)))
+ return ERR_CAST(filename);
+
+ file = path_openat(-1, filename, &nd, op, flags | LOOKUP_RCU);
if (unlikely(file == ERR_PTR(-ECHILD)))
- file = path_openat(-1, &filename, &nd, op, flags);
+ file = path_openat(-1, filename, &nd, op, flags);
if (unlikely(file == ERR_PTR(-ESTALE)))
- file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_REVAL);
+ file = path_openat(-1, filename, &nd, op, flags | LOOKUP_REVAL);
+ putname(filename);
return file;
}
-struct dentry *kern_path_create(int dfd, const char *pathname,
+static struct dentry *filename_create(int dfd, struct filename *name,
struct path *path, unsigned int lookup_flags)
{
struct dentry *dentry = ERR_PTR(-EEXIST);
@@ -3305,7 +3329,7 @@ struct dentry *kern_path_create(int dfd, const char *pathname,
*/
lookup_flags &= LOOKUP_REVAL;
- error = do_path_lookup(dfd, pathname, LOOKUP_PARENT|lookup_flags, &nd);
+ error = filename_lookup(dfd, name, LOOKUP_PARENT|lookup_flags, &nd);
if (error)
return ERR_PTR(error);
@@ -3359,6 +3383,19 @@ out:
path_put(&nd.path);
return dentry;
}
+
+struct dentry *kern_path_create(int dfd, const char *pathname,
+ struct path *path, unsigned int lookup_flags)
+{
+ struct filename *filename = getname_kernel(pathname);
+ struct dentry *res;
+
+ if (IS_ERR(filename))
+ return ERR_CAST(filename);
+ res = filename_create(dfd, filename, path, lookup_flags);
+ putname(filename);
+ return res;
+}
EXPORT_SYMBOL(kern_path_create);
void done_path_create(struct path *path, struct dentry *dentry)
@@ -3377,7 +3414,7 @@ struct dentry *user_path_create(int dfd, const char __user *pathname,
struct dentry *res;
if (IS_ERR(tmp))
return ERR_CAST(tmp);
- res = kern_path_create(dfd, tmp->name, path, lookup_flags);
+ res = filename_create(dfd, tmp, path, lookup_flags);
putname(tmp);
return res;
}
diff --git a/fs/namespace.c b/fs/namespace.c
index 6dae553dd69c..72a286e0d33e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -190,6 +190,14 @@ unsigned int mnt_get_count(struct mount *mnt)
#endif
}
+static void drop_mountpoint(struct fs_pin *p)
+{
+ struct mount *m = container_of(p, struct mount, mnt_umount);
+ dput(m->mnt_ex_mountpoint);
+ pin_remove(p);
+ mntput(&m->mnt);
+}
+
static struct mount *alloc_vfsmnt(const char *name)
{
struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
@@ -229,6 +237,7 @@ static struct mount *alloc_vfsmnt(const char *name)
#ifdef CONFIG_FSNOTIFY
INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks);
#endif
+ init_fs_pin(&mnt->mnt_umount, drop_mountpoint);
}
return mnt;
@@ -1289,7 +1298,6 @@ static HLIST_HEAD(unmounted); /* protected by namespace_sem */
static void namespace_unlock(void)
{
- struct mount *mnt;
struct hlist_head head = unmounted;
if (likely(hlist_empty(&head))) {
@@ -1299,23 +1307,11 @@ static void namespace_unlock(void)
head.first->pprev = &head.first;
INIT_HLIST_HEAD(&unmounted);
-
- /* undo decrements we'd done in umount_tree() */
- hlist_for_each_entry(mnt, &head, mnt_hash)
- if (mnt->mnt_ex_mountpoint.mnt)
- mntget(mnt->mnt_ex_mountpoint.mnt);
-
up_write(&namespace_sem);
synchronize_rcu();
- while (!hlist_empty(&head)) {
- mnt = hlist_entry(head.first, struct mount, mnt_hash);
- hlist_del_init(&mnt->mnt_hash);
- if (mnt->mnt_ex_mountpoint.mnt)
- path_put(&mnt->mnt_ex_mountpoint);
- mntput(&mnt->mnt);
- }
+ group_pin_kill(&head);
}
static inline void namespace_lock(void)
@@ -1334,7 +1330,6 @@ void umount_tree(struct mount *mnt, int how)
{
HLIST_HEAD(tmp_list);
struct mount *p;
- struct mount *last = NULL;
for (p = mnt; p; p = next_mnt(p, mnt)) {
hlist_del_init_rcu(&p->mnt_hash);
@@ -1347,33 +1342,28 @@ void umount_tree(struct mount *mnt, int how)
if (how)
propagate_umount(&tmp_list);
- hlist_for_each_entry(p, &tmp_list, mnt_hash) {
+ while (!hlist_empty(&tmp_list)) {
+ p = hlist_entry(tmp_list.first, struct mount, mnt_hash);
+ hlist_del_init_rcu(&p->mnt_hash);
list_del_init(&p->mnt_expire);
list_del_init(&p->mnt_list);
__touch_mnt_namespace(p->mnt_ns);
p->mnt_ns = NULL;
if (how < 2)
p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
+
+ pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, &unmounted);
if (mnt_has_parent(p)) {
hlist_del_init(&p->mnt_mp_list);
put_mountpoint(p->mnt_mp);
mnt_add_count(p->mnt_parent, -1);
- /* move the reference to mountpoint into ->mnt_ex_mountpoint */
- p->mnt_ex_mountpoint.dentry = p->mnt_mountpoint;
- p->mnt_ex_mountpoint.mnt = &p->mnt_parent->mnt;
+ /* old mountpoint will be dropped when we can do that */
+ p->mnt_ex_mountpoint = p->mnt_mountpoint;
p->mnt_mountpoint = p->mnt.mnt_root;
p->mnt_parent = p;
p->mnt_mp = NULL;
}
change_mnt_propagation(p, MS_PRIVATE);
- last = p;
- }
- if (last) {
- last->mnt_hash.next = unmounted.first;
- if (unmounted.first)
- unmounted.first->pprev = &last->mnt_hash.next;
- unmounted.first = tmp_list.first;
- unmounted.first->pprev = &unmounted.first;
}
}
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 008960101520..e7ca827d7694 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -77,6 +77,7 @@ static int ncp_hash_dentry(const struct dentry *, struct qstr *);
static int ncp_compare_dentry(const struct dentry *, const struct dentry *,
unsigned int, const char *, const struct qstr *);
static int ncp_delete_dentry(const struct dentry *);
+static void ncp_d_prune(struct dentry *dentry);
const struct dentry_operations ncp_dentry_operations =
{
@@ -84,6 +85,7 @@ const struct dentry_operations ncp_dentry_operations =
.d_hash = ncp_hash_dentry,
.d_compare = ncp_compare_dentry,
.d_delete = ncp_delete_dentry,
+ .d_prune = ncp_d_prune,
};
#define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
@@ -384,42 +386,6 @@ finished:
return val;
}
-static struct dentry *
-ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
-{
- struct dentry *dent = dentry;
-
- if (d_validate(dent, parent)) {
- if (dent->d_name.len <= NCP_MAXPATHLEN &&
- (unsigned long)dent->d_fsdata == fpos) {
- if (!dent->d_inode) {
- dput(dent);
- dent = NULL;
- }
- return dent;
- }
- dput(dent);
- }
-
- /* If a pointer is invalid, we search the dentry. */
- spin_lock(&parent->d_lock);
- list_for_each_entry(dent, &parent->d_subdirs, d_child) {
- if ((unsigned long)dent->d_fsdata == fpos) {
- if (dent->d_inode)
- dget(dent);
- else
- dent = NULL;
- spin_unlock(&parent->d_lock);
- goto out;
- }
- }
- spin_unlock(&parent->d_lock);
- return NULL;
-
-out:
- return dent;
-}
-
static time_t ncp_obtain_mtime(struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
@@ -435,6 +401,20 @@ static time_t ncp_obtain_mtime(struct dentry *dentry)
return ncp_date_dos2unix(i.modifyTime, i.modifyDate);
}
+static inline void
+ncp_invalidate_dircache_entries(struct dentry *parent)
+{
+ struct ncp_server *server = NCP_SERVER(parent->d_inode);
+ struct dentry *dentry;
+
+ spin_lock(&parent->d_lock);
+ list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
+ dentry->d_fsdata = NULL;
+ ncp_age_dentry(server, dentry);
+ }
+ spin_unlock(&parent->d_lock);
+}
+
static int ncp_readdir(struct file *file, struct dir_context *ctx)
{
struct dentry *dentry = file->f_path.dentry;
@@ -500,10 +480,21 @@ static int ncp_readdir(struct file *file, struct dir_context *ctx)
struct dentry *dent;
bool over;
- dent = ncp_dget_fpos(ctl.cache->dentry[ctl.idx],
- dentry, ctx->pos);
- if (!dent)
+ spin_lock(&dentry->d_lock);
+ if (!(NCP_FINFO(inode)->flags & NCPI_DIR_CACHE)) {
+ spin_unlock(&dentry->d_lock);
+ goto invalid_cache;
+ }
+ dent = ctl.cache->dentry[ctl.idx];
+ if (unlikely(!lockref_get_not_dead(&dent->d_lockref))) {
+ spin_unlock(&dentry->d_lock);
+ goto invalid_cache;
+ }
+ spin_unlock(&dentry->d_lock);
+ if (!dent->d_inode) {
+ dput(dent);
goto invalid_cache;
+ }
over = !dir_emit(ctx, dent->d_name.name,
dent->d_name.len,
dent->d_inode->i_ino, DT_UNKNOWN);
@@ -548,6 +539,9 @@ init_cache:
ctl.filled = 0;
ctl.valid = 1;
read_really:
+ spin_lock(&dentry->d_lock);
+ NCP_FINFO(inode)->flags |= NCPI_DIR_CACHE;
+ spin_unlock(&dentry->d_lock);
if (ncp_is_server_root(inode)) {
ncp_read_volume_list(file, ctx, &ctl);
} else {
@@ -573,6 +567,13 @@ out:
return result;
}
+static void ncp_d_prune(struct dentry *dentry)
+{
+ if (!dentry->d_fsdata) /* not referenced from page cache */
+ return;
+ NCP_FINFO(dentry->d_parent->d_inode)->flags &= ~NCPI_DIR_CACHE;
+}
+
static int
ncp_fill_cache(struct file *file, struct dir_context *ctx,
struct ncp_cache_control *ctrl, struct ncp_entry_info *entry,
@@ -630,6 +631,10 @@ ncp_fill_cache(struct file *file, struct dir_context *ctx,
d_instantiate(newdent, inode);
if (!hashed)
d_rehash(newdent);
+ } else {
+ spin_lock(&dentry->d_lock);
+ NCP_FINFO(inode)->flags &= ~NCPI_DIR_CACHE;
+ spin_unlock(&dentry->d_lock);
}
} else {
struct inode *inode = newdent->d_inode;
@@ -639,12 +644,6 @@ ncp_fill_cache(struct file *file, struct dir_context *ctx,
mutex_unlock(&inode->i_mutex);
}
- if (newdent->d_inode) {
- ino = newdent->d_inode->i_ino;
- newdent->d_fsdata = (void *) ctl.fpos;
- ncp_new_dentry(newdent);
- }
-
if (ctl.idx >= NCP_DIRCACHE_SIZE) {
if (ctl.page) {
kunmap(ctl.page);
@@ -660,8 +659,13 @@ ncp_fill_cache(struct file *file, struct dir_context *ctx,
ctl.cache = kmap(ctl.page);
}
if (ctl.cache) {
- ctl.cache->dentry[ctl.idx] = newdent;
- valid = 1;
+ if (newdent->d_inode) {
+ newdent->d_fsdata = newdent;
+ ctl.cache->dentry[ctl.idx] = newdent;
+ ino = newdent->d_inode->i_ino;
+ ncp_new_dentry(newdent);
+ }
+ valid = 1;
}
dput(newdent);
end_advance:
diff --git a/fs/ncpfs/ncp_fs_i.h b/fs/ncpfs/ncp_fs_i.h
index 4b0bec477846..c4794504f843 100644
--- a/fs/ncpfs/ncp_fs_i.h
+++ b/fs/ncpfs/ncp_fs_i.h
@@ -22,6 +22,7 @@ struct ncp_inode_info {
int access;
int flags;
#define NCPI_KLUDGE_SYMLINK 0x0001
+#define NCPI_DIR_CACHE 0x0002
__u8 file_handle[6];
struct inode vfs_inode;
};
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index b785f74bfe3c..250e443a07f3 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -184,36 +184,6 @@ ncp_new_dentry(struct dentry* dentry)
dentry->d_time = jiffies;
}
-static inline void
-ncp_renew_dentries(struct dentry *parent)
-{
- struct ncp_server *server = NCP_SERVER(parent->d_inode);
- struct dentry *dentry;
-
- spin_lock(&parent->d_lock);
- list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
- if (dentry->d_fsdata == NULL)
- ncp_age_dentry(server, dentry);
- else
- ncp_new_dentry(dentry);
- }
- spin_unlock(&parent->d_lock);
-}
-
-static inline void
-ncp_invalidate_dircache_entries(struct dentry *parent)
-{
- struct ncp_server *server = NCP_SERVER(parent->d_inode);
- struct dentry *dentry;
-
- spin_lock(&parent->d_lock);
- list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
- dentry->d_fsdata = NULL;
- ncp_age_dentry(server, dentry);
- }
- spin_unlock(&parent->d_lock);
-}
-
struct ncp_cache_head {
time_t mtime;
unsigned long time; /* cache age */
diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h
index 84cae2079d21..f22920442172 100644
--- a/fs/nfsd/nfsfh.h
+++ b/fs/nfsd/nfsfh.h
@@ -200,7 +200,7 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2)
{
if (fh1->fh_fsid_type != fh2->fh_fsid_type)
return false;
- if (memcmp(fh1->fh_fsid, fh2->fh_fsid, key_len(fh1->fh_fsid_type) != 0))
+ if (memcmp(fh1->fh_fsid, fh2->fh_fsid, key_len(fh1->fh_fsid_type)) != 0)
return false;
return true;
}
diff --git a/fs/nfsd/pnfs.h b/fs/nfsd/pnfs.h
index fedb4d620a81..d4c4453674c6 100644
--- a/fs/nfsd/pnfs.h
+++ b/fs/nfsd/pnfs.h
@@ -1,6 +1,7 @@
#ifndef _FS_NFSD_PNFS_H
#define _FS_NFSD_PNFS_H 1
+#ifdef CONFIG_NFSD_V4
#include <linux/exportfs.h>
#include <linux/nfsd/export.h>
@@ -50,6 +51,7 @@ __be32 nfsd4_return_client_layouts(struct svc_rqst *rqstp,
int nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
u32 device_generation);
struct nfsd4_deviceid_map *nfsd4_find_devid_map(int idx);
+#endif /* CONFIG_NFSD_V4 */
#ifdef CONFIG_NFSD_PNFS
void nfsd4_setup_layout_type(struct svc_export *exp);
@@ -59,6 +61,9 @@ void nfsd4_return_all_file_layouts(struct nfs4_client *clp,
int nfsd4_init_pnfs(void);
void nfsd4_exit_pnfs(void);
#else
+struct nfs4_client;
+struct nfs4_file;
+
static inline void nfsd4_setup_layout_type(struct svc_export *exp)
{
}
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 46d93e941f3d..44db1808cdb5 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -28,6 +28,7 @@
#include <linux/pipe_fs_i.h>
#include <linux/mpage.h>
#include <linux/quotaops.h>
+#include <linux/blkdev.h>
#include <cluster/masklog.h>
@@ -47,6 +48,9 @@
#include "ocfs2_trace.h"
#include "buffer_head_io.h"
+#include "dir.h"
+#include "namei.h"
+#include "sysfile.h"
static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
@@ -506,18 +510,21 @@ bail:
*
* called like this: dio->get_blocks(dio->inode, fs_startblk,
* fs_count, map_bh, dio->rw == WRITE);
- *
- * Note that we never bother to allocate blocks here, and thus ignore the
- * create argument.
*/
static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
int ret;
+ u32 cpos = 0;
+ int alloc_locked = 0;
u64 p_blkno, inode_blocks, contig_blocks;
unsigned int ext_flags;
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
+ unsigned long len = bh_result->b_size;
+ unsigned int clusters_to_alloc = 0;
+
+ cpos = ocfs2_blocks_to_clusters(inode->i_sb, iblock);
/* This function won't even be called if the request isn't all
* nicely aligned and of the right size, so there's no need
@@ -539,6 +546,40 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
/* We should already CoW the refcounted extent in case of create. */
BUG_ON(create && (ext_flags & OCFS2_EXT_REFCOUNTED));
+ /* allocate blocks if no p_blkno is found, and create == 1 */
+ if (!p_blkno && create) {
+ ret = ocfs2_inode_lock(inode, NULL, 1);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto bail;
+ }
+
+ alloc_locked = 1;
+
+ /* fill hole, allocate blocks can't be larger than the size
+ * of the hole */
+ clusters_to_alloc = ocfs2_clusters_for_bytes(inode->i_sb, len);
+ if (clusters_to_alloc > contig_blocks)
+ clusters_to_alloc = contig_blocks;
+
+ /* allocate extent and insert them into the extent tree */
+ ret = ocfs2_extend_allocation(inode, cpos,
+ clusters_to_alloc, 0);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto bail;
+ }
+
+ ret = ocfs2_extent_map_get_blocks(inode, iblock, &p_blkno,
+ &contig_blocks, &ext_flags);
+ if (ret < 0) {
+ mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n",
+ (unsigned long long)iblock);
+ ret = -EIO;
+ goto bail;
+ }
+ }
+
/*
* get_more_blocks() expects us to describe a hole by clearing
* the mapped bit on bh_result().
@@ -556,6 +597,8 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
contig_blocks = max_blocks;
bh_result->b_size = contig_blocks << blocksize_bits;
bail:
+ if (alloc_locked)
+ ocfs2_inode_unlock(inode, 1);
return ret;
}
@@ -597,6 +640,184 @@ static int ocfs2_releasepage(struct page *page, gfp_t wait)
return try_to_free_buffers(page);
}
+static int ocfs2_is_overwrite(struct ocfs2_super *osb,
+ struct inode *inode, loff_t offset)
+{
+ int ret = 0;
+ u32 v_cpos = 0;
+ u32 p_cpos = 0;
+ unsigned int num_clusters = 0;
+ unsigned int ext_flags = 0;
+
+ v_cpos = ocfs2_bytes_to_clusters(osb->sb, offset);
+ ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos,
+ &num_clusters, &ext_flags);
+ if (ret < 0) {
+ mlog_errno(ret);
+ return ret;
+ }
+
+ if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN))
+ return 1;
+
+ return 0;
+}
+
+static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
+ struct iov_iter *iter,
+ loff_t offset)
+{
+ ssize_t ret = 0;
+ ssize_t written = 0;
+ bool orphaned = false;
+ int is_overwrite = 0;
+ struct file *file = iocb->ki_filp;
+ struct inode *inode = file_inode(file)->i_mapping->host;
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ struct buffer_head *di_bh = NULL;
+ size_t count = iter->count;
+ journal_t *journal = osb->journal->j_journal;
+ u32 zero_len;
+ int cluster_align;
+ loff_t final_size = offset + count;
+ int append_write = offset >= i_size_read(inode) ? 1 : 0;
+ unsigned int num_clusters = 0;
+ unsigned int ext_flags = 0;
+
+ {
+ u64 o = offset;
+
+ zero_len = do_div(o, 1 << osb->s_clustersize_bits);
+ cluster_align = !zero_len;
+ }
+
+ /*
+ * when final_size > inode->i_size, inode->i_size will be
+ * updated after direct write, so add the inode to orphan
+ * dir first.
+ */
+ if (final_size > i_size_read(inode)) {
+ ret = ocfs2_add_inode_to_orphan(osb, inode);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto out;
+ }
+ orphaned = true;
+ }
+
+ if (append_write) {
+ ret = ocfs2_inode_lock(inode, &di_bh, 1);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto clean_orphan;
+ }
+
+ if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
+ ret = ocfs2_zero_extend(inode, di_bh, offset);
+ else
+ ret = ocfs2_extend_no_holes(inode, di_bh, offset,
+ offset);
+ if (ret < 0) {
+ mlog_errno(ret);
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+ goto clean_orphan;
+ }
+
+ is_overwrite = ocfs2_is_overwrite(osb, inode, offset);
+ if (is_overwrite < 0) {
+ mlog_errno(is_overwrite);
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+ goto clean_orphan;
+ }
+
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+ di_bh = NULL;
+ }
+
+ written = __blockdev_direct_IO(WRITE, iocb, inode, inode->i_sb->s_bdev,
+ iter, offset,
+ ocfs2_direct_IO_get_blocks,
+ ocfs2_dio_end_io, NULL, 0);
+ if (unlikely(written < 0)) {
+ loff_t i_size = i_size_read(inode);
+
+ if (offset + count > i_size) {
+ ret = ocfs2_inode_lock(inode, &di_bh, 1);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto clean_orphan;
+ }
+
+ if (i_size == i_size_read(inode)) {
+ ret = ocfs2_truncate_file(inode, di_bh,
+ i_size);
+ if (ret < 0) {
+ if (ret != -ENOSPC)
+ mlog_errno(ret);
+
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+ goto clean_orphan;
+ }
+ }
+
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+
+ ret = jbd2_journal_force_commit(journal);
+ if (ret < 0)
+ mlog_errno(ret);
+ }
+ } else if (written < 0 && append_write && !is_overwrite &&
+ !cluster_align) {
+ u32 p_cpos = 0;
+ u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, offset);
+
+ ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos,
+ &num_clusters, &ext_flags);
+ if (ret < 0) {
+ mlog_errno(ret);
+ goto clean_orphan;
+ }
+
+ BUG_ON(!p_cpos || (ext_flags & OCFS2_EXT_UNWRITTEN));
+
+ ret = blkdev_issue_zeroout(osb->sb->s_bdev,
+ p_cpos << (osb->s_clustersize_bits - 9),
+ zero_len >> 9, GFP_KERNEL, false);
+ if (ret < 0)
+ mlog_errno(ret);
+ }
+
+clean_orphan:
+ if (orphaned) {
+ int tmp_ret;
+ int update_isize = written > 0 ? 1 : 0;
+ loff_t end = update_isize ? offset + written : 0;
+
+ tmp_ret = ocfs2_del_inode_from_orphan(osb, inode,
+ update_isize, end);
+ if (tmp_ret < 0) {
+ ret = tmp_ret;
+ goto out;
+ }
+
+ tmp_ret = jbd2_journal_force_commit(journal);
+ if (tmp_ret < 0) {
+ ret = tmp_ret;
+ mlog_errno(tmp_ret);
+ }
+ }
+
+out:
+ if (ret >= 0)
+ ret = written;
+ return ret;
+}
+
static ssize_t ocfs2_direct_IO(int rw,
struct kiocb *iocb,
struct iov_iter *iter,
@@ -604,6 +825,9 @@ static ssize_t ocfs2_direct_IO(int rw,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file)->i_mapping->host;
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ int full_coherency = !(osb->s_mount_opt &
+ OCFS2_MOUNT_COHERENCY_BUFFERED);
/*
* Fallback to buffered I/O if we see an inode without
@@ -612,14 +836,20 @@ static ssize_t ocfs2_direct_IO(int rw,
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
return 0;
- /* Fallback to buffered I/O if we are appending. */
- if (i_size_read(inode) <= offset)
+ /* Fallback to buffered I/O if we are appending and
+ * concurrent O_DIRECT writes are allowed.
+ */
+ if (i_size_read(inode) <= offset && !full_coherency)
return 0;
- return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
+ if (rw == READ)
+ return __blockdev_direct_IO(rw, iocb, inode,
+ inode->i_sb->s_bdev,
iter, offset,
ocfs2_direct_IO_get_blocks,
ocfs2_dio_end_io, NULL, 0);
+ else
+ return ocfs2_direct_IO_write(iocb, iter, offset);
}
static void ocfs2_figure_cluster_boundaries(struct ocfs2_super *osb,
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index e0f04d55fd05..46e0d4e857c7 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -295,7 +295,7 @@ out:
return ret;
}
-static int ocfs2_set_inode_size(handle_t *handle,
+int ocfs2_set_inode_size(handle_t *handle,
struct inode *inode,
struct buffer_head *fe_bh,
u64 new_i_size)
@@ -441,7 +441,7 @@ out:
return status;
}
-static int ocfs2_truncate_file(struct inode *inode,
+int ocfs2_truncate_file(struct inode *inode,
struct buffer_head *di_bh,
u64 new_i_size)
{
@@ -709,6 +709,13 @@ leave:
return status;
}
+int ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
+ u32 clusters_to_add, int mark_unwritten)
+{
+ return __ocfs2_extend_allocation(inode, logical_start,
+ clusters_to_add, mark_unwritten);
+}
+
/*
* While a write will already be ordering the data, a truncate will not.
* Thus, we need to explicitly order the zeroed pages.
@@ -2109,6 +2116,9 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
loff_t saved_pos = 0, end;
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ int full_coherency = !(osb->s_mount_opt &
+ OCFS2_MOUNT_COHERENCY_BUFFERED);
/*
* We start with a read level meta lock and only jump to an ex
@@ -2197,7 +2207,16 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
* one node could wind up truncating another
* nodes writes.
*/
- if (end > i_size_read(inode)) {
+ if (end > i_size_read(inode) && !full_coherency) {
+ *direct_io = 0;
+ break;
+ }
+
+ /*
+ * Fallback to old way if the feature bit is not set.
+ */
+ if (end > i_size_read(inode) &&
+ !ocfs2_supports_append_dio(osb)) {
*direct_io = 0;
break;
}
@@ -2210,7 +2229,13 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
*/
ret = ocfs2_check_range_for_holes(inode, saved_pos, count);
if (ret == 1) {
- *direct_io = 0;
+ /*
+ * Fallback to old way if the feature bit is not set.
+ * Otherwise try dio first and then complete the rest
+ * request through buffer io.
+ */
+ if (!ocfs2_supports_append_dio(osb))
+ *direct_io = 0;
ret = 0;
} else if (ret < 0)
mlog_errno(ret);
@@ -2243,6 +2268,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
u32 old_clusters;
struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file);
+ struct address_space *mapping = file->f_mapping;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
int full_coherency = !(osb->s_mount_opt &
OCFS2_MOUNT_COHERENCY_BUFFERED);
@@ -2357,11 +2383,51 @@ relock:
iov_iter_truncate(from, count);
if (direct_io) {
+ loff_t endbyte;
+ ssize_t written_buffered;
written = generic_file_direct_write(iocb, from, *ppos);
- if (written < 0) {
+ if (written < 0 || written == count) {
ret = written;
goto out_dio;
}
+
+ /*
+ * for completing the rest of the request.
+ */
+ *ppos += written;
+ count -= written;
+ written_buffered = generic_perform_write(file, from, *ppos);
+ /*
+ * If generic_file_buffered_write() returned a synchronous error
+ * then we want to return the number of bytes which were
+ * direct-written, or the error code if that was zero. Note
+ * that this differs from normal direct-io semantics, which
+ * will return -EFOO even if some bytes were written.
+ */
+ if (written_buffered < 0) {
+ ret = written_buffered;
+ goto out_dio;
+ }
+
+ iocb->ki_pos = *ppos + written_buffered;
+ /* We need to ensure that the page cache pages are written to
+ * disk and invalidated to preserve the expected O_DIRECT
+ * semantics.
+ */
+ endbyte = *ppos + written_buffered - 1;
+ ret = filemap_write_and_wait_range(file->f_mapping, *ppos,
+ endbyte);
+ if (ret == 0) {
+ written += written_buffered;
+ invalidate_mapping_pages(mapping,
+ *ppos >> PAGE_CACHE_SHIFT,
+ endbyte >> PAGE_CACHE_SHIFT);
+ } else {
+ /*
+ * We don't know how much we wrote, so just return
+ * the number of bytes which were direct-written
+ */
+ }
} else {
current->backing_dev_info = inode_to_bdi(inode);
written = generic_perform_write(file, from, *ppos);
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h
index 97bf761c9e7c..e8c62f22215c 100644
--- a/fs/ocfs2/file.h
+++ b/fs/ocfs2/file.h
@@ -51,13 +51,22 @@ int ocfs2_add_inode_data(struct ocfs2_super *osb,
struct ocfs2_alloc_context *data_ac,
struct ocfs2_alloc_context *meta_ac,
enum ocfs2_alloc_restarted *reason_ret);
+int ocfs2_set_inode_size(handle_t *handle,
+ struct inode *inode,
+ struct buffer_head *fe_bh,
+ u64 new_i_size);
int ocfs2_simple_size_update(struct inode *inode,
struct buffer_head *di_bh,
u64 new_i_size);
+int ocfs2_truncate_file(struct inode *inode,
+ struct buffer_head *di_bh,
+ u64 new_i_size);
int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh,
u64 new_i_size, u64 zero_to);
int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh,
loff_t zero_to);
+int ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
+ u32 clusters_to_add, int mark_unwritten);
int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index c8b25de9efbb..3025c0da6b8a 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -648,7 +648,7 @@ static int ocfs2_remove_inode(struct inode *inode,
if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
- orphan_dir_bh);
+ orphan_dir_bh, false);
if (status < 0) {
mlog_errno(status);
goto bail_commit;
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index ca3431ee7f24..5e86b247c821 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -81,6 +81,8 @@ struct ocfs2_inode_info
tid_t i_sync_tid;
tid_t i_datasync_tid;
+ wait_queue_head_t append_dio_wq;
+
struct dquot *i_dquot[MAXQUOTAS];
};
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index d10860fde165..ff531928269e 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -50,6 +50,8 @@
#include "sysfile.h"
#include "uptodate.h"
#include "quota.h"
+#include "file.h"
+#include "namei.h"
#include "buffer_head_io.h"
#include "ocfs2_trace.h"
@@ -69,13 +71,15 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
static int ocfs2_trylock_journal(struct ocfs2_super *osb,
int slot_num);
static int ocfs2_recover_orphans(struct ocfs2_super *osb,
- int slot);
+ int slot,
+ enum ocfs2_orphan_reco_type orphan_reco_type);
static int ocfs2_commit_thread(void *arg);
static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
int slot_num,
struct ocfs2_dinode *la_dinode,
struct ocfs2_dinode *tl_dinode,
- struct ocfs2_quota_recovery *qrec);
+ struct ocfs2_quota_recovery *qrec,
+ enum ocfs2_orphan_reco_type orphan_reco_type);
static inline int ocfs2_wait_on_mount(struct ocfs2_super *osb)
{
@@ -149,7 +153,8 @@ int ocfs2_compute_replay_slots(struct ocfs2_super *osb)
return 0;
}
-void ocfs2_queue_replay_slots(struct ocfs2_super *osb)
+void ocfs2_queue_replay_slots(struct ocfs2_super *osb,
+ enum ocfs2_orphan_reco_type orphan_reco_type)
{
struct ocfs2_replay_map *replay_map = osb->replay_map;
int i;
@@ -163,7 +168,8 @@ void ocfs2_queue_replay_slots(struct ocfs2_super *osb)
for (i = 0; i < replay_map->rm_slots; i++)
if (replay_map->rm_replay_slots[i])
ocfs2_queue_recovery_completion(osb->journal, i, NULL,
- NULL, NULL);
+ NULL, NULL,
+ orphan_reco_type);
replay_map->rm_state = REPLAY_DONE;
}
@@ -1174,6 +1180,7 @@ struct ocfs2_la_recovery_item {
struct ocfs2_dinode *lri_la_dinode;
struct ocfs2_dinode *lri_tl_dinode;
struct ocfs2_quota_recovery *lri_qrec;
+ enum ocfs2_orphan_reco_type lri_orphan_reco_type;
};
/* Does the second half of the recovery process. By this point, the
@@ -1195,6 +1202,7 @@ void ocfs2_complete_recovery(struct work_struct *work)
struct ocfs2_dinode *la_dinode, *tl_dinode;
struct ocfs2_la_recovery_item *item, *n;
struct ocfs2_quota_recovery *qrec;
+ enum ocfs2_orphan_reco_type orphan_reco_type;
LIST_HEAD(tmp_la_list);
trace_ocfs2_complete_recovery(
@@ -1212,6 +1220,7 @@ void ocfs2_complete_recovery(struct work_struct *work)
la_dinode = item->lri_la_dinode;
tl_dinode = item->lri_tl_dinode;
qrec = item->lri_qrec;
+ orphan_reco_type = item->lri_orphan_reco_type;
trace_ocfs2_complete_recovery_slot(item->lri_slot,
la_dinode ? le64_to_cpu(la_dinode->i_blkno) : 0,
@@ -1236,7 +1245,8 @@ void ocfs2_complete_recovery(struct work_struct *work)
kfree(tl_dinode);
}
- ret = ocfs2_recover_orphans(osb, item->lri_slot);
+ ret = ocfs2_recover_orphans(osb, item->lri_slot,
+ orphan_reco_type);
if (ret < 0)
mlog_errno(ret);
@@ -1261,7 +1271,8 @@ static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
int slot_num,
struct ocfs2_dinode *la_dinode,
struct ocfs2_dinode *tl_dinode,
- struct ocfs2_quota_recovery *qrec)
+ struct ocfs2_quota_recovery *qrec,
+ enum ocfs2_orphan_reco_type orphan_reco_type)
{
struct ocfs2_la_recovery_item *item;
@@ -1285,6 +1296,7 @@ static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
item->lri_slot = slot_num;
item->lri_tl_dinode = tl_dinode;
item->lri_qrec = qrec;
+ item->lri_orphan_reco_type = orphan_reco_type;
spin_lock(&journal->j_lock);
list_add_tail(&item->lri_list, &journal->j_la_cleanups);
@@ -1304,7 +1316,8 @@ void ocfs2_complete_mount_recovery(struct ocfs2_super *osb)
/* No need to queue up our truncate_log as regular cleanup will catch
* that */
ocfs2_queue_recovery_completion(journal, osb->slot_num,
- osb->local_alloc_copy, NULL, NULL);
+ osb->local_alloc_copy, NULL, NULL,
+ ORPHAN_NEED_TRUNCATE);
ocfs2_schedule_truncate_log_flush(osb, 0);
osb->local_alloc_copy = NULL;
@@ -1312,7 +1325,7 @@ void ocfs2_complete_mount_recovery(struct ocfs2_super *osb)
/* queue to recover orphan slots for all offline slots */
ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
- ocfs2_queue_replay_slots(osb);
+ ocfs2_queue_replay_slots(osb, ORPHAN_NEED_TRUNCATE);
ocfs2_free_replay_slots(osb);
}
@@ -1323,7 +1336,8 @@ void ocfs2_complete_quota_recovery(struct ocfs2_super *osb)
osb->slot_num,
NULL,
NULL,
- osb->quota_rec);
+ osb->quota_rec,
+ ORPHAN_NEED_TRUNCATE);
osb->quota_rec = NULL;
}
}
@@ -1360,7 +1374,7 @@ restart:
/* queue recovery for our own slot */
ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
- NULL, NULL);
+ NULL, NULL, ORPHAN_NO_NEED_TRUNCATE);
spin_lock(&osb->osb_lock);
while (rm->rm_used) {
@@ -1419,13 +1433,14 @@ skip_recovery:
continue;
}
ocfs2_queue_recovery_completion(osb->journal, rm_quota[i],
- NULL, NULL, qrec);
+ NULL, NULL, qrec,
+ ORPHAN_NEED_TRUNCATE);
}
ocfs2_super_unlock(osb, 1);
/* queue recovery for offline slots */
- ocfs2_queue_replay_slots(osb);
+ ocfs2_queue_replay_slots(osb, ORPHAN_NEED_TRUNCATE);
bail:
mutex_lock(&osb->recovery_lock);
@@ -1711,7 +1726,7 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
/* This will kfree the memory pointed to by la_copy and tl_copy */
ocfs2_queue_recovery_completion(osb->journal, slot_num, la_copy,
- tl_copy, NULL);
+ tl_copy, NULL, ORPHAN_NEED_TRUNCATE);
status = 0;
done:
@@ -1901,7 +1916,7 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
for (i = 0; i < osb->max_slots; i++)
ocfs2_queue_recovery_completion(osb->journal, i, NULL, NULL,
- NULL);
+ NULL, ORPHAN_NO_NEED_TRUNCATE);
/*
* We queued a recovery on orphan slots, increment the sequence
* number and update LVB so other node will skip the scan for a while
@@ -2000,6 +2015,13 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
if (IS_ERR(iter))
return 0;
+ /* Skip inodes which are already added to recover list, since dio may
+ * happen concurrently with unlink/rename */
+ if (OCFS2_I(iter)->ip_next_orphan) {
+ iput(iter);
+ return 0;
+ }
+
trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno);
/* No locking is required for the next_orphan queue as there
* is only ever a single process doing orphan recovery. */
@@ -2108,7 +2130,8 @@ static void ocfs2_clear_recovering_orphan_dir(struct ocfs2_super *osb,
* advertising our state to ocfs2_delete_inode().
*/
static int ocfs2_recover_orphans(struct ocfs2_super *osb,
- int slot)
+ int slot,
+ enum ocfs2_orphan_reco_type orphan_reco_type)
{
int ret = 0;
struct inode *inode = NULL;
@@ -2132,13 +2155,60 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
(unsigned long long)oi->ip_blkno);
iter = oi->ip_next_orphan;
+ oi->ip_next_orphan = NULL;
+
+ /*
+ * We need to take and drop the inode lock to
+ * force read inode from disk.
+ */
+ ret = ocfs2_inode_lock(inode, NULL, 0);
+ if (ret) {
+ mlog_errno(ret);
+ goto next;
+ }
+ ocfs2_inode_unlock(inode, 0);
+
+ if (inode->i_nlink == 0) {
+ spin_lock(&oi->ip_lock);
+ /* Set the proper information to get us going into
+ * ocfs2_delete_inode. */
+ oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
+ spin_unlock(&oi->ip_lock);
+ } else if (orphan_reco_type == ORPHAN_NEED_TRUNCATE) {
+ struct buffer_head *di_bh = NULL;
+
+ ret = ocfs2_rw_lock(inode, 1);
+ if (ret) {
+ mlog_errno(ret);
+ goto next;
+ }
+
+ ret = ocfs2_inode_lock(inode, &di_bh, 1);
+ if (ret < 0) {
+ ocfs2_rw_unlock(inode, 1);
+ mlog_errno(ret);
+ goto next;
+ }
+
+ ret = ocfs2_truncate_file(inode, di_bh,
+ i_size_read(inode));
+ ocfs2_inode_unlock(inode, 1);
+ ocfs2_rw_unlock(inode, 1);
+ brelse(di_bh);
+ if (ret < 0) {
+ if (ret != -ENOSPC)
+ mlog_errno(ret);
+ goto next;
+ }
+
+ ret = ocfs2_del_inode_from_orphan(osb, inode, 0, 0);
+ if (ret)
+ mlog_errno(ret);
- spin_lock(&oi->ip_lock);
- /* Set the proper information to get us going into
- * ocfs2_delete_inode. */
- oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
- spin_unlock(&oi->ip_lock);
+ wake_up(&OCFS2_I(inode)->append_dio_wq);
+ } /* else if ORPHAN_NO_NEED_TRUNCATE, do nothing */
+next:
iput(inode);
inode = iter;
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 7f8cde94abfe..f4cd3c3e9fb7 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -472,6 +472,11 @@ static inline int ocfs2_unlink_credits(struct super_block *sb)
* orphan dir index leaf */
#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 4)
+/* dinode + orphan dir dinode + extent tree leaf block + orphan dir entry +
+ * orphan dir index root + orphan dir index leaf */
+#define OCFS2_INODE_ADD_TO_ORPHAN_CREDITS (2 * OCFS2_INODE_UPDATE_CREDITS + 4)
+#define OCFS2_INODE_DEL_FROM_ORPHAN_CREDITS OCFS2_INODE_ADD_TO_ORPHAN_CREDITS
+
/* dinode update, old dir dinode update, new dir dinode update, old
* dir dir entry, new dir dir entry, dir entry update for renaming
* directory + target unlink + 3 x dir index leaves */
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 914c121ec890..b5c3a5ea3ee6 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -79,7 +79,8 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
struct inode **ret_orphan_dir,
u64 blkno,
char *name,
- struct ocfs2_dir_lookup_result *lookup);
+ struct ocfs2_dir_lookup_result *lookup,
+ bool dio);
static int ocfs2_orphan_add(struct ocfs2_super *osb,
handle_t *handle,
@@ -87,7 +88,8 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
struct buffer_head *fe_bh,
char *name,
struct ocfs2_dir_lookup_result *lookup,
- struct inode *orphan_dir_inode);
+ struct inode *orphan_dir_inode,
+ bool dio);
static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
handle_t *handle,
@@ -104,6 +106,8 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2);
/* An orphan dir name is an 8 byte value, printed as a hex string */
#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
+#define OCFS2_DIO_ORPHAN_PREFIX "dio-"
+#define OCFS2_DIO_ORPHAN_PREFIX_LEN 4
static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags)
@@ -952,7 +956,8 @@ static int ocfs2_unlink(struct inode *dir,
if (ocfs2_inode_is_unlinkable(inode)) {
status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
OCFS2_I(inode)->ip_blkno,
- orphan_name, &orphan_insert);
+ orphan_name, &orphan_insert,
+ false);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -1004,7 +1009,7 @@ static int ocfs2_unlink(struct inode *dir,
if (is_unlinkable) {
status = ocfs2_orphan_add(osb, handle, inode, fe_bh,
- orphan_name, &orphan_insert, orphan_dir);
+ orphan_name, &orphan_insert, orphan_dir, false);
if (status < 0)
mlog_errno(status);
}
@@ -1440,7 +1445,8 @@ static int ocfs2_rename(struct inode *old_dir,
if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) {
status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
OCFS2_I(new_inode)->ip_blkno,
- orphan_name, &orphan_insert);
+ orphan_name, &orphan_insert,
+ false);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1507,7 +1513,7 @@ static int ocfs2_rename(struct inode *old_dir,
if (should_add_orphan) {
status = ocfs2_orphan_add(osb, handle, new_inode,
newfe_bh, orphan_name,
- &orphan_insert, orphan_dir);
+ &orphan_insert, orphan_dir, false);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -2088,12 +2094,28 @@ static int __ocfs2_prepare_orphan_dir(struct inode *orphan_dir_inode,
struct buffer_head *orphan_dir_bh,
u64 blkno,
char *name,
- struct ocfs2_dir_lookup_result *lookup)
+ struct ocfs2_dir_lookup_result *lookup,
+ bool dio)
{
int ret;
struct ocfs2_super *osb = OCFS2_SB(orphan_dir_inode->i_sb);
+ int namelen = dio ?
+ (OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN) :
+ OCFS2_ORPHAN_NAMELEN;
+
+ if (dio) {
+ ret = snprintf(name, OCFS2_DIO_ORPHAN_PREFIX_LEN + 1, "%s",
+ OCFS2_DIO_ORPHAN_PREFIX);
+ if (ret != OCFS2_DIO_ORPHAN_PREFIX_LEN) {
+ ret = -EINVAL;
+ mlog_errno(ret);
+ return ret;
+ }
- ret = ocfs2_blkno_stringify(blkno, name);
+ ret = ocfs2_blkno_stringify(blkno,
+ name + OCFS2_DIO_ORPHAN_PREFIX_LEN);
+ } else
+ ret = ocfs2_blkno_stringify(blkno, name);
if (ret < 0) {
mlog_errno(ret);
return ret;
@@ -2101,7 +2123,7 @@ static int __ocfs2_prepare_orphan_dir(struct inode *orphan_dir_inode,
ret = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode,
orphan_dir_bh, name,
- OCFS2_ORPHAN_NAMELEN, lookup);
+ namelen, lookup);
if (ret < 0) {
mlog_errno(ret);
return ret;
@@ -2128,7 +2150,8 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
struct inode **ret_orphan_dir,
u64 blkno,
char *name,
- struct ocfs2_dir_lookup_result *lookup)
+ struct ocfs2_dir_lookup_result *lookup,
+ bool dio)
{
struct inode *orphan_dir_inode = NULL;
struct buffer_head *orphan_dir_bh = NULL;
@@ -2142,7 +2165,7 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
}
ret = __ocfs2_prepare_orphan_dir(orphan_dir_inode, orphan_dir_bh,
- blkno, name, lookup);
+ blkno, name, lookup, dio);
if (ret < 0) {
mlog_errno(ret);
goto out;
@@ -2170,12 +2193,16 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
struct buffer_head *fe_bh,
char *name,
struct ocfs2_dir_lookup_result *lookup,
- struct inode *orphan_dir_inode)
+ struct inode *orphan_dir_inode,
+ bool dio)
{
struct buffer_head *orphan_dir_bh = NULL;
int status = 0;
struct ocfs2_dinode *orphan_fe;
struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
+ int namelen = dio ?
+ (OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN) :
+ OCFS2_ORPHAN_NAMELEN;
trace_ocfs2_orphan_add_begin(
(unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -2219,7 +2246,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
ocfs2_journal_dirty(handle, orphan_dir_bh);
status = __ocfs2_add_entry(handle, orphan_dir_inode, name,
- OCFS2_ORPHAN_NAMELEN, inode,
+ namelen, inode,
OCFS2_I(inode)->ip_blkno,
orphan_dir_bh, lookup);
if (status < 0) {
@@ -2227,13 +2254,21 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
goto rollback;
}
- fe->i_flags |= cpu_to_le32(OCFS2_ORPHANED_FL);
- OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
+ if (dio) {
+ /* Update flag OCFS2_DIO_ORPHANED_FL and record the orphan
+ * slot.
+ */
+ fe->i_flags |= cpu_to_le32(OCFS2_DIO_ORPHANED_FL);
+ fe->i_dio_orphaned_slot = cpu_to_le16(osb->slot_num);
+ } else {
+ fe->i_flags |= cpu_to_le32(OCFS2_ORPHANED_FL);
+ OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
- /* Record which orphan dir our inode now resides
- * in. delete_inode will use this to determine which orphan
- * dir to lock. */
- fe->i_orphaned_slot = cpu_to_le16(osb->slot_num);
+ /* Record which orphan dir our inode now resides
+ * in. delete_inode will use this to determine which orphan
+ * dir to lock. */
+ fe->i_orphaned_slot = cpu_to_le16(osb->slot_num);
+ }
ocfs2_journal_dirty(handle, fe_bh);
@@ -2258,14 +2293,28 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
handle_t *handle,
struct inode *orphan_dir_inode,
struct inode *inode,
- struct buffer_head *orphan_dir_bh)
+ struct buffer_head *orphan_dir_bh,
+ bool dio)
{
- char name[OCFS2_ORPHAN_NAMELEN + 1];
+ const int namelen = OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN;
+ char name[namelen + 1];
struct ocfs2_dinode *orphan_fe;
int status = 0;
struct ocfs2_dir_lookup_result lookup = { NULL, };
- status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
+ if (dio) {
+ status = snprintf(name, OCFS2_DIO_ORPHAN_PREFIX_LEN + 1, "%s",
+ OCFS2_DIO_ORPHAN_PREFIX);
+ if (status != OCFS2_DIO_ORPHAN_PREFIX_LEN) {
+ status = -EINVAL;
+ mlog_errno(status);
+ return status;
+ }
+
+ status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno,
+ name + OCFS2_DIO_ORPHAN_PREFIX_LEN);
+ } else
+ status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -2273,10 +2322,10 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
trace_ocfs2_orphan_del(
(unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno,
- name, OCFS2_ORPHAN_NAMELEN);
+ name, namelen);
/* find it's spot in the orphan directory */
- status = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN, orphan_dir_inode,
+ status = ocfs2_find_entry(name, namelen, orphan_dir_inode,
&lookup);
if (status) {
mlog_errno(status);
@@ -2376,7 +2425,8 @@ static int ocfs2_prep_new_orphaned_file(struct inode *dir,
}
ret = __ocfs2_prepare_orphan_dir(orphan_dir, orphan_dir_bh,
- di_blkno, orphan_name, orphan_insert);
+ di_blkno, orphan_name, orphan_insert,
+ false);
if (ret < 0) {
mlog_errno(ret);
goto out;
@@ -2482,7 +2532,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir,
di = (struct ocfs2_dinode *)new_di_bh->b_data;
status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name,
- &orphan_insert, orphan_dir);
+ &orphan_insert, orphan_dir, false);
if (status < 0) {
mlog_errno(status);
goto leave;
@@ -2527,6 +2577,186 @@ leave:
return status;
}
+static int ocfs2_dio_orphan_recovered(struct inode *inode)
+{
+ int ret;
+ struct buffer_head *di_bh = NULL;
+ struct ocfs2_dinode *di = NULL;
+
+ ret = ocfs2_inode_lock(inode, &di_bh, 1);
+ if (ret < 0) {
+ mlog_errno(ret);
+ return 0;
+ }
+
+ di = (struct ocfs2_dinode *) di_bh->b_data;
+ ret = !(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL));
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+
+ return ret;
+}
+
+#define OCFS2_DIO_ORPHANED_FL_CHECK_INTERVAL 10000
+int ocfs2_add_inode_to_orphan(struct ocfs2_super *osb,
+ struct inode *inode)
+{
+ char orphan_name[OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN + 1];
+ struct inode *orphan_dir_inode = NULL;
+ struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
+ struct buffer_head *di_bh = NULL;
+ int status = 0;
+ handle_t *handle = NULL;
+ struct ocfs2_dinode *di = NULL;
+
+restart:
+ status = ocfs2_inode_lock(inode, &di_bh, 1);
+ if (status < 0) {
+ mlog_errno(status);
+ goto bail;
+ }
+
+ di = (struct ocfs2_dinode *) di_bh->b_data;
+ /*
+ * Another append dio crashed?
+ * If so, wait for recovery first.
+ */
+ if (unlikely(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL))) {
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+ wait_event_interruptible_timeout(OCFS2_I(inode)->append_dio_wq,
+ ocfs2_dio_orphan_recovered(inode),
+ msecs_to_jiffies(OCFS2_DIO_ORPHANED_FL_CHECK_INTERVAL));
+ goto restart;
+ }
+
+ status = ocfs2_prepare_orphan_dir(osb, &orphan_dir_inode,
+ OCFS2_I(inode)->ip_blkno,
+ orphan_name,
+ &orphan_insert,
+ true);
+ if (status < 0) {
+ mlog_errno(status);
+ goto bail_unlock_inode;
+ }
+
+ handle = ocfs2_start_trans(osb,
+ OCFS2_INODE_ADD_TO_ORPHAN_CREDITS);
+ if (IS_ERR(handle)) {
+ status = PTR_ERR(handle);
+ goto bail_unlock_orphan;
+ }
+
+ status = ocfs2_orphan_add(osb, handle, inode, di_bh, orphan_name,
+ &orphan_insert, orphan_dir_inode, true);
+ if (status)
+ mlog_errno(status);
+
+ ocfs2_commit_trans(osb, handle);
+
+bail_unlock_orphan:
+ ocfs2_inode_unlock(orphan_dir_inode, 1);
+ mutex_unlock(&orphan_dir_inode->i_mutex);
+ iput(orphan_dir_inode);
+
+ ocfs2_free_dir_lookup_result(&orphan_insert);
+
+bail_unlock_inode:
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+
+bail:
+ return status;
+}
+
+int ocfs2_del_inode_from_orphan(struct ocfs2_super *osb,
+ struct inode *inode, int update_isize,
+ loff_t end)
+{
+ struct inode *orphan_dir_inode = NULL;
+ struct buffer_head *orphan_dir_bh = NULL;
+ struct buffer_head *di_bh = NULL;
+ struct ocfs2_dinode *di = NULL;
+ handle_t *handle = NULL;
+ int status = 0;
+
+ status = ocfs2_inode_lock(inode, &di_bh, 1);
+ if (status < 0) {
+ mlog_errno(status);
+ goto bail;
+ }
+ di = (struct ocfs2_dinode *) di_bh->b_data;
+
+ orphan_dir_inode = ocfs2_get_system_file_inode(osb,
+ ORPHAN_DIR_SYSTEM_INODE,
+ le16_to_cpu(di->i_dio_orphaned_slot));
+ if (!orphan_dir_inode) {
+ status = -ENOENT;
+ mlog_errno(status);
+ goto bail_unlock_inode;
+ }
+
+ mutex_lock(&orphan_dir_inode->i_mutex);
+ status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
+ if (status < 0) {
+ mutex_unlock(&orphan_dir_inode->i_mutex);
+ iput(orphan_dir_inode);
+ mlog_errno(status);
+ goto bail_unlock_inode;
+ }
+
+ handle = ocfs2_start_trans(osb,
+ OCFS2_INODE_DEL_FROM_ORPHAN_CREDITS);
+ if (IS_ERR(handle)) {
+ status = PTR_ERR(handle);
+ goto bail_unlock_orphan;
+ }
+
+ BUG_ON(!(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL)));
+
+ status = ocfs2_orphan_del(osb, handle, orphan_dir_inode,
+ inode, orphan_dir_bh, true);
+ if (status < 0) {
+ mlog_errno(status);
+ goto bail_commit;
+ }
+
+ status = ocfs2_journal_access_di(handle,
+ INODE_CACHE(inode),
+ di_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (status < 0) {
+ mlog_errno(status);
+ goto bail_commit;
+ }
+
+ di->i_flags &= ~cpu_to_le32(OCFS2_DIO_ORPHANED_FL);
+ di->i_dio_orphaned_slot = 0;
+
+ if (update_isize) {
+ status = ocfs2_set_inode_size(handle, inode, di_bh, end);
+ if (status)
+ mlog_errno(status);
+ } else
+ ocfs2_journal_dirty(handle, di_bh);
+
+bail_commit:
+ ocfs2_commit_trans(osb, handle);
+
+bail_unlock_orphan:
+ ocfs2_inode_unlock(orphan_dir_inode, 1);
+ mutex_unlock(&orphan_dir_inode->i_mutex);
+ brelse(orphan_dir_bh);
+ iput(orphan_dir_inode);
+
+bail_unlock_inode:
+ ocfs2_inode_unlock(inode, 1);
+ brelse(di_bh);
+
+bail:
+ return status;
+}
+
int ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
struct inode *inode,
struct dentry *dentry)
@@ -2615,7 +2845,7 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
}
status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
- orphan_dir_bh);
+ orphan_dir_bh, false);
if (status < 0) {
mlog_errno(status);
goto out_commit;
diff --git a/fs/ocfs2/namei.h b/fs/ocfs2/namei.h
index e5d059d4f115..5ddecce172fa 100644
--- a/fs/ocfs2/namei.h
+++ b/fs/ocfs2/namei.h
@@ -34,10 +34,16 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
handle_t *handle,
struct inode *orphan_dir_inode,
struct inode *inode,
- struct buffer_head *orphan_dir_bh);
+ struct buffer_head *orphan_dir_bh,
+ bool dio);
int ocfs2_create_inode_in_orphan(struct inode *dir,
int mode,
struct inode **new_inode);
+int ocfs2_add_inode_to_orphan(struct ocfs2_super *osb,
+ struct inode *inode);
+int ocfs2_del_inode_from_orphan(struct ocfs2_super *osb,
+ struct inode *inode, int update_isize,
+ loff_t end);
int ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
struct inode *new_inode,
struct dentry *new_dentry);
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index fdbcbfed529e..8490c64d34fe 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -209,6 +209,11 @@ struct ocfs2_lock_res {
#endif
};
+enum ocfs2_orphan_reco_type {
+ ORPHAN_NO_NEED_TRUNCATE = 0,
+ ORPHAN_NEED_TRUNCATE,
+};
+
enum ocfs2_orphan_scan_state {
ORPHAN_SCAN_ACTIVE,
ORPHAN_SCAN_INACTIVE
@@ -495,6 +500,14 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb)
return 0;
}
+static inline int ocfs2_supports_append_dio(struct ocfs2_super *osb)
+{
+ if (osb->s_feature_ro_compat & OCFS2_FEATURE_RO_COMPAT_APPEND_DIO)
+ return 1;
+ return 0;
+}
+
+
static inline int ocfs2_supports_inline_data(struct ocfs2_super *osb)
{
if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
@@ -726,6 +739,16 @@ static inline unsigned int ocfs2_clusters_for_bytes(struct super_block *sb,
return clusters;
}
+static inline unsigned int ocfs2_bytes_to_clusters(struct super_block *sb,
+ u64 bytes)
+{
+ int cl_bits = OCFS2_SB(sb)->s_clustersize_bits;
+ unsigned int clusters;
+
+ clusters = (unsigned int)(bytes >> cl_bits);
+ return clusters;
+}
+
static inline u64 ocfs2_blocks_for_bytes(struct super_block *sb,
u64 bytes)
{
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 938387a10d5d..20e37a3ed26f 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -105,7 +105,8 @@
| OCFS2_FEATURE_INCOMPAT_CLUSTERINFO)
#define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
| OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
- | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
+ | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA \
+ | OCFS2_FEATURE_RO_COMPAT_APPEND_DIO)
/*
* Heartbeat-only devices are missing journals and other files. The
@@ -199,6 +200,11 @@
#define OCFS2_FEATURE_RO_COMPAT_USRQUOTA 0x0002
#define OCFS2_FEATURE_RO_COMPAT_GRPQUOTA 0x0004
+/*
+ * Append Direct IO support
+ */
+#define OCFS2_FEATURE_RO_COMPAT_APPEND_DIO 0x0008
+
/* The byte offset of the first backup block will be 1G.
* The following will be 4G, 16G, 64G, 256G and 1T.
*/
@@ -229,6 +235,8 @@
#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */
#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */
#define OCFS2_QUOTA_FL (0x00001000) /* Quota file */
+#define OCFS2_DIO_ORPHANED_FL (0X00002000) /* On the orphan list especially
+ * for dio */
/*
* Flags on ocfs2_dinode.i_dyn_features
@@ -729,7 +737,9 @@ struct ocfs2_dinode {
inode belongs to. Only valid
if allocated from a
discontiguous block group */
-/*A0*/ __le64 i_reserved2[3];
+/*A0*/ __le16 i_dio_orphaned_slot; /* only used for append dio write */
+ __le16 i_reserved1[3];
+ __le64 i_reserved2[2];
/*B8*/ union {
__le64 i_pad1; /* Generic way to refer to this
64bit union */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 87a1f7679d9b..26675185b886 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1746,6 +1746,8 @@ static void ocfs2_inode_init_once(void *data)
ocfs2_lock_res_init_once(&oi->ip_inode_lockres);
ocfs2_lock_res_init_once(&oi->ip_open_lockres);
+ init_waitqueue_head(&oi->append_dio_wq);
+
ocfs2_metadata_cache_init(INODE_CACHE(&oi->vfs_inode),
&ocfs2_inode_caching_ops);
diff --git a/fs/open.c b/fs/open.c
index 813be037b412..33f9cbf2610b 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -667,11 +667,8 @@ int open_check_o_direct(struct file *f)
{
/* NB: we're sure to have correct a_ops only after f_op->open */
if (f->f_flags & O_DIRECT) {
- if (!f->f_mapping->a_ops ||
- ((!f->f_mapping->a_ops->direct_IO) &&
- (!f->f_mapping->a_ops->get_xip_mem))) {
+ if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)
return -EINVAL;
- }
}
return 0;
}
@@ -971,8 +968,14 @@ struct file *file_open_name(struct filename *name, int flags, umode_t mode)
*/
struct file *filp_open(const char *filename, int flags, umode_t mode)
{
- struct filename name = {.name = filename};
- return file_open_name(&name, flags, mode);
+ struct filename *name = getname_kernel(filename);
+ struct file *file = ERR_CAST(name);
+
+ if (!IS_ERR(name)) {
+ file = file_open_name(name, flags, mode);
+ putname(name);
+ }
+ return file;
}
EXPORT_SYMBOL(filp_open);
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index de14e46fd807..3309f59d421b 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -350,29 +350,12 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
if (ret)
return ret;
- if (S_ISDIR(dp->mode)) {
- dp->proc_fops = &proc_dir_operations;
- dp->proc_iops = &proc_dir_inode_operations;
- dir->nlink++;
- } else if (S_ISLNK(dp->mode)) {
- dp->proc_iops = &proc_link_inode_operations;
- } else if (S_ISREG(dp->mode)) {
- BUG_ON(dp->proc_fops == NULL);
- dp->proc_iops = &proc_file_inode_operations;
- } else {
- WARN_ON(1);
- proc_free_inum(dp->low_ino);
- return -EINVAL;
- }
-
spin_lock(&proc_subdir_lock);
dp->parent = dir;
if (pde_subdir_insert(dir, dp) == false) {
WARN(1, "proc_dir_entry '%s/%s' already registered\n",
dir->name, dp->name);
spin_unlock(&proc_subdir_lock);
- if (S_ISDIR(dp->mode))
- dir->nlink--;
proc_free_inum(dp->low_ino);
return -EEXIST;
}
@@ -431,6 +414,7 @@ struct proc_dir_entry *proc_symlink(const char *name,
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
if (ent->data) {
strcpy((char*)ent->data,dest);
+ ent->proc_iops = &proc_link_inode_operations;
if (proc_register(parent, ent) < 0) {
kfree(ent->data);
kfree(ent);
@@ -456,8 +440,12 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
if (ent) {
ent->data = data;
+ ent->proc_fops = &proc_dir_operations;
+ ent->proc_iops = &proc_dir_inode_operations;
+ parent->nlink++;
if (proc_register(parent, ent) < 0) {
kfree(ent);
+ parent->nlink--;
ent = NULL;
}
}
@@ -493,6 +481,8 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
return NULL;
}
+ BUG_ON(proc_fops == NULL);
+
if ((mode & S_IALLUGO) == 0)
mode |= S_IRUGO;
pde = __proc_create(&parent, name, mode, 1);
@@ -500,6 +490,7 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
goto out;
pde->proc_fops = proc_fops;
pde->data = data;
+ pde->proc_iops = &proc_file_inode_operations;
if (proc_register(parent, pde) < 0)
goto out_free;
return pde;
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index a90d6d354199..4e61388ec03d 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -546,8 +546,8 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr)
nhdr_ptr = notes_section;
while (nhdr_ptr->n_namesz != 0) {
sz = sizeof(Elf64_Nhdr) +
- ((nhdr_ptr->n_namesz + 3) & ~3) +
- ((nhdr_ptr->n_descsz + 3) & ~3);
+ (((u64)nhdr_ptr->n_namesz + 3) & ~3) +
+ (((u64)nhdr_ptr->n_descsz + 3) & ~3);
if ((real_sz + sz) > max_sz) {
pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n",
nhdr_ptr->n_namesz, nhdr_ptr->n_descsz);
@@ -732,8 +732,8 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr)
nhdr_ptr = notes_section;
while (nhdr_ptr->n_namesz != 0) {
sz = sizeof(Elf32_Nhdr) +
- ((nhdr_ptr->n_namesz + 3) & ~3) +
- ((nhdr_ptr->n_descsz + 3) & ~3);
+ (((u64)nhdr_ptr->n_namesz + 3) & ~3) +
+ (((u64)nhdr_ptr->n_descsz + 3) & ~3);
if ((real_sz + sz) > max_sz) {
pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n",
nhdr_ptr->n_namesz, nhdr_ptr->n_descsz);
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 0f96f71ab32b..8db932da4009 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -44,6 +44,7 @@ static int show_sb_opts(struct seq_file *m, struct super_block *sb)
{ MS_SYNCHRONOUS, ",sync" },
{ MS_DIRSYNC, ",dirsync" },
{ MS_MANDLOCK, ",mand" },
+ { MS_LAZYTIME, ",lazytime" },
{ 0, NULL }
};
const struct proc_fs_info *fs_infop;
diff --git a/fs/read_write.c b/fs/read_write.c
index 4060691e78f7..8e1b68786d66 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -333,6 +333,52 @@ out_putf:
}
#endif
+ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos)
+{
+ struct kiocb kiocb;
+ ssize_t ret;
+
+ if (!file->f_op->read_iter)
+ return -EINVAL;
+
+ init_sync_kiocb(&kiocb, file);
+ kiocb.ki_pos = *ppos;
+ kiocb.ki_nbytes = iov_iter_count(iter);
+
+ iter->type |= READ;
+ ret = file->f_op->read_iter(&kiocb, iter);
+ if (ret == -EIOCBQUEUED)
+ ret = wait_on_sync_kiocb(&kiocb);
+
+ if (ret > 0)
+ *ppos = kiocb.ki_pos;
+ return ret;
+}
+EXPORT_SYMBOL(vfs_iter_read);
+
+ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos)
+{
+ struct kiocb kiocb;
+ ssize_t ret;
+
+ if (!file->f_op->write_iter)
+ return -EINVAL;
+
+ init_sync_kiocb(&kiocb, file);
+ kiocb.ki_pos = *ppos;
+ kiocb.ki_nbytes = iov_iter_count(iter);
+
+ iter->type |= WRITE;
+ ret = file->f_op->write_iter(&kiocb, iter);
+ if (ret == -EIOCBQUEUED)
+ ret = wait_on_sync_kiocb(&kiocb);
+
+ if (ret > 0)
+ *ppos = kiocb.ki_pos;
+ return ret;
+}
+EXPORT_SYMBOL(vfs_iter_write);
+
/*
* rw_verify_area doesn't like huge counts. We limit
* them to something that fits in "int" so that others
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index a7eec9888f10..e72401e1f995 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2766,7 +2766,7 @@ static int reiserfs_write_begin(struct file *file,
int old_ref = 0;
inode = mapping->host;
- *fsdata = 0;
+ *fsdata = NULL;
if (flags & AOP_FLAG_CONT_EXPAND &&
(pos & (inode->i_sb->s_blocksize - 1)) == 0) {
pos ++;
diff --git a/fs/splice.c b/fs/splice.c
index 75c6058eabf2..7968da96bebb 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -961,7 +961,6 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
splice_from_pipe_begin(&sd);
while (sd.total_len) {
struct iov_iter from;
- struct kiocb kiocb;
size_t left;
int n, idx;
@@ -1005,29 +1004,15 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
left -= this_len;
}
- /* ... iov_iter */
- from.type = ITER_BVEC | WRITE;
- from.bvec = array;
- from.nr_segs = n;
- from.count = sd.total_len - left;
- from.iov_offset = 0;
-
- /* ... and iocb */
- init_sync_kiocb(&kiocb, out);
- kiocb.ki_pos = sd.pos;
- kiocb.ki_nbytes = sd.total_len - left;
-
- /* now, send it */
- ret = out->f_op->write_iter(&kiocb, &from);
- if (-EIOCBQUEUED == ret)
- ret = wait_on_sync_kiocb(&kiocb);
-
+ iov_iter_bvec(&from, ITER_BVEC | WRITE, array, n,
+ sd.total_len - left);
+ ret = vfs_iter_write(out, &from, &sd.pos);
if (ret <= 0)
break;
sd.num_spliced += ret;
sd.total_len -= ret;
- *ppos = sd.pos = kiocb.ki_pos;
+ *ppos = sd.pos;
/* dismiss the fully eaten buffers, adjust the partial one */
while (ret) {
diff --git a/fs/super.c b/fs/super.c
index 1facd2c282e5..65a53efc1cf4 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -715,9 +715,9 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
if (remount_ro) {
- if (sb->s_pins.first) {
+ if (!hlist_empty(&sb->s_pins)) {
up_write(&sb->s_umount);
- sb_pin_kill(sb);
+ group_pin_kill(&sb->s_pins);
down_write(&sb->s_umount);
if (!sb->s_root)
return 0;
diff --git a/fs/sync.c b/fs/sync.c
index 01d9f18a70b5..fbc98ee62044 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -177,8 +177,16 @@ SYSCALL_DEFINE1(syncfs, int, fd)
*/
int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
{
+ struct inode *inode = file->f_mapping->host;
+
if (!file->f_op->fsync)
return -EINVAL;
+ if (!datasync && (inode->i_state & I_DIRTY_TIME)) {
+ spin_lock(&inode->i_lock);
+ inode->i_state &= ~I_DIRTY_TIME;
+ spin_unlock(&inode->i_lock);
+ mark_inode_dirty_sync(inode);
+ }
return file->f_op->fsync(file, start, end, datasync);
}
EXPORT_SYMBOL(vfs_fsync_range);
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index da73801301d5..8092d3759a5e 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -95,22 +95,18 @@
void lock_ufs(struct super_block *sb)
{
-#if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT)
struct ufs_sb_info *sbi = UFS_SB(sb);
mutex_lock(&sbi->mutex);
sbi->mutex_owner = current;
-#endif
}
void unlock_ufs(struct super_block *sb)
{
-#if defined(CONFIG_SMP) || defined (CONFIG_PREEMPT)
struct ufs_sb_info *sbi = UFS_SB(sb);
sbi->mutex_owner = NULL;
mutex_unlock(&sbi->mutex);
-#endif
}
static struct inode *ufs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation)
@@ -1415,9 +1411,11 @@ static struct kmem_cache * ufs_inode_cachep;
static struct inode *ufs_alloc_inode(struct super_block *sb)
{
struct ufs_inode_info *ei;
- ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_NOFS);
+
+ ei = kmem_cache_alloc(ufs_inode_cachep, GFP_NOFS);
if (!ei)
return NULL;
+
ei->vfs_inode.i_version = 1;
return &ei->vfs_inode;
}
diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
index ce37349860fe..7389c87116a0 100644
--- a/include/asm-generic/pci_iomap.h
+++ b/include/asm-generic/pci_iomap.h
@@ -15,6 +15,9 @@ struct pci_dev;
#ifdef CONFIG_PCI
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned long offset,
+ unsigned long maxlen);
/* Create a virtual mapping cookie for a port on a given PCI device.
* Do not call this directly, it exists to make it easier for architectures
* to override */
@@ -30,6 +33,13 @@ static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned lon
{
return NULL;
}
+
+static inline void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned long offset,
+ unsigned long maxlen)
+{
+ return NULL;
+}
#endif
#endif /* __ASM_GENERIC_IO_H */
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
new file mode 100644
index 000000000000..5a4f49005169
--- /dev/null
+++ b/include/drm/bridge/dw_hdmi.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DW_HDMI__
+#define __DW_HDMI__
+
+#include <drm/drmP.h>
+
+enum {
+ DW_HDMI_RES_8,
+ DW_HDMI_RES_10,
+ DW_HDMI_RES_12,
+ DW_HDMI_RES_MAX,
+};
+
+enum dw_hdmi_devtype {
+ IMX6Q_HDMI,
+ IMX6DL_HDMI,
+ RK3288_HDMI,
+};
+
+struct dw_hdmi_mpll_config {
+ unsigned long mpixelclock;
+ struct {
+ u16 cpce;
+ u16 gmp;
+ } res[DW_HDMI_RES_MAX];
+};
+
+struct dw_hdmi_curr_ctrl {
+ unsigned long mpixelclock;
+ u16 curr[DW_HDMI_RES_MAX];
+};
+
+struct dw_hdmi_sym_term {
+ unsigned long mpixelclock;
+ u16 sym_ctr; /*clock symbol and transmitter control*/
+ u16 term; /*transmission termination value*/
+};
+
+struct dw_hdmi_plat_data {
+ enum dw_hdmi_devtype dev_type;
+ const struct dw_hdmi_mpll_config *mpll_cfg;
+ const struct dw_hdmi_curr_ctrl *cur_ctr;
+ const struct dw_hdmi_sym_term *sym_term;
+ enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+ struct drm_display_mode *mode);
+};
+
+void dw_hdmi_unbind(struct device *dev, struct device *master, void *data);
+int dw_hdmi_bind(struct device *dev, struct device *master,
+ void *data, struct drm_encoder *encoder,
+ struct resource *iores, int irq,
+ const struct dw_hdmi_plat_data *plat_data);
+#endif /* __IMX_HDMI_H__ */
diff --git a/include/drm/bridge/ptn3460.h b/include/drm/bridge/ptn3460.h
index ff62344fec6c..b11f8e17e72f 100644
--- a/include/drm/bridge/ptn3460.h
+++ b/include/drm/bridge/ptn3460.h
@@ -15,6 +15,7 @@
#define _DRM_BRIDGE_PTN3460_H_
struct drm_device;
+struct drm_bridge;
struct drm_encoder;
struct i2c_client;
struct device_node;
@@ -23,6 +24,9 @@ struct device_node;
int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
struct i2c_client *client, struct device_node *node);
+
+void ptn3460_destroy(struct drm_bridge *bridge);
+
#else
static inline int ptn3460_init(struct drm_device *dev,
@@ -32,6 +36,10 @@ static inline int ptn3460_init(struct drm_device *dev,
return 0;
}
+static inline void ptn3460_destroy(struct drm_bridge *bridge)
+{
+}
+
#endif
#endif
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e1b2e8b98af7..e928625a9da0 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -143,6 +143,7 @@ void drm_err(const char *format, ...);
#define DRIVER_MODESET 0x2000
#define DRIVER_PRIME 0x4000
#define DRIVER_RENDER 0x8000
+#define DRIVER_ATOMIC 0x10000
/***********************************************************************/
/** \name Macros to make printk easier */
@@ -283,6 +284,8 @@ struct drm_file {
* in the plane list
*/
unsigned universal_planes:1;
+ /* true if client understands atomic properties */
+ unsigned atomic:1;
struct pid *pid;
kuid_t uid;
@@ -744,8 +747,6 @@ struct drm_device {
/** \name Context support */
/*@{ */
- bool irq_enabled; /**< True if irq handler is enabled */
- int irq;
__volatile__ long context_flag; /**< Context swapping flag */
int last_context; /**< Last current context */
@@ -753,6 +754,8 @@ struct drm_device {
/** \name VBLANK IRQ support */
/*@{ */
+ bool irq_enabled;
+ int irq;
/*
* At load time, disabling the vblank interrupt won't be allowed since
@@ -954,6 +957,7 @@ extern void drm_master_put(struct drm_master **master);
extern void drm_put_dev(struct drm_device *dev);
extern void drm_unplug_dev(struct drm_device *dev);
extern unsigned int drm_debug;
+extern bool drm_atomic;
/* Debugfs support */
#if defined(CONFIG_DEBUG_FS)
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index ad2229574dd9..51168a8b723a 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -38,16 +38,25 @@ void drm_atomic_state_free(struct drm_atomic_state *state);
struct drm_crtc_state * __must_check
drm_atomic_get_crtc_state(struct drm_atomic_state *state,
struct drm_crtc *crtc);
+int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
+ struct drm_crtc_state *state, struct drm_property *property,
+ uint64_t val);
struct drm_plane_state * __must_check
drm_atomic_get_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane);
+int drm_atomic_plane_set_property(struct drm_plane *plane,
+ struct drm_plane_state *state, struct drm_property *property,
+ uint64_t val);
struct drm_connector_state * __must_check
drm_atomic_get_connector_state(struct drm_atomic_state *state,
struct drm_connector *connector);
+int drm_atomic_connector_set_property(struct drm_connector *connector,
+ struct drm_connector_state *state, struct drm_property *property,
+ uint64_t val);
int __must_check
-drm_atomic_set_crtc_for_plane(struct drm_atomic_state *state,
- struct drm_plane *plane, struct drm_crtc *crtc);
+drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
+ struct drm_crtc *crtc);
void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
struct drm_framebuffer *fb);
int __must_check
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index f956b413311e..8039d54a7441 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -30,6 +30,10 @@
#include <drm/drm_crtc.h>
+int drm_atomic_helper_check_modeset(struct drm_device *dev,
+ struct drm_atomic_state *state);
+int drm_atomic_helper_check_planes(struct drm_device *dev,
+ struct drm_atomic_state *state);
int drm_atomic_helper_check(struct drm_device *dev,
struct drm_atomic_state *state);
int drm_atomic_helper_commit(struct drm_device *dev,
@@ -78,6 +82,8 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t flags);
+void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
+ int mode);
/* default implementations for state handling */
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
@@ -123,4 +129,41 @@ void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
#define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \
drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask)
+/*
+ * drm_atomic_plane_disabling - check whether a plane is being disabled
+ * @plane: plane object
+ * @old_state: previous atomic state
+ *
+ * Checks the atomic state of a plane to determine whether it's being disabled
+ * or not. This also WARNs if it detects an invalid state (both CRTC and FB
+ * need to either both be NULL or both be non-NULL).
+ *
+ * RETURNS:
+ * True if the plane is being disabled, false otherwise.
+ */
+static inline bool
+drm_atomic_plane_disabling(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ /*
+ * When disabling a plane, CRTC and FB should always be NULL together.
+ * Anything else should be considered a bug in the atomic core, so we
+ * gently warn about it.
+ */
+ WARN_ON((plane->state->crtc == NULL && plane->state->fb != NULL) ||
+ (plane->state->crtc != NULL && plane->state->fb == NULL));
+
+ /*
+ * When using the transitional helpers, old_state may be NULL. If so,
+ * we know nothing about the current state and have to assume that it
+ * might be enabled.
+ *
+ * When using the atomic helpers, old_state won't be NULL. Therefore
+ * this check assumes that either the driver will have reconstructed
+ * the correct state in ->reset() or that the driver will have taken
+ * appropriate measures to disable all planes.
+ */
+ return (!old_state || old_state->crtc) && !plane->state->crtc;
+}
+
#endif /* DRM_ATOMIC_HELPER_H_ */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b86329813ad3..920e21a8f3fd 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -31,6 +31,7 @@
#include <linux/idr.h>
#include <linux/fb.h>
#include <linux/hdmi.h>
+#include <linux/media-bus-format.h>
#include <uapi/drm/drm_mode.h>
#include <uapi/drm/drm_fourcc.h>
#include <drm/drm_modeset_lock.h>
@@ -63,8 +64,16 @@ struct drm_mode_object {
#define DRM_OBJECT_MAX_PROPERTY 24
struct drm_object_properties {
- int count;
- uint32_t ids[DRM_OBJECT_MAX_PROPERTY];
+ int count, atomic_count;
+ /* NOTE: if we ever start dynamically destroying properties (ie.
+ * not at drm_mode_config_cleanup() time), then we'd have to do
+ * a better job of detaching property from mode objects to avoid
+ * dangling property pointers:
+ */
+ struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY];
+ /* do not read/write values directly, but use drm_object_property_get_value()
+ * and drm_object_property_set_value():
+ */
uint64_t values[DRM_OBJECT_MAX_PROPERTY];
};
@@ -131,6 +140,9 @@ struct drm_display_info {
enum subpixel_order subpixel_order;
u32 color_formats;
+ const u32 *bus_formats;
+ unsigned int num_bus_formats;
+
/* Mask of supported hdmi deep color modes */
u8 edid_hdmi_dc_modes;
@@ -237,8 +249,11 @@ struct drm_atomic_state;
/**
* struct drm_crtc_state - mutable CRTC state
+ * @crtc: backpointer to the CRTC
* @enable: whether the CRTC should be enabled, gates all other state
+ * @active: whether the CRTC is actively displaying (used for DPMS)
* @mode_changed: for use by helpers and drivers when computing state updates
+ * @active_changed: for use by helpers and drivers when computing state updates
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
* @last_vblank_count: for helpers and drivers to capture the vblank of the
* update to ensure framebuffer cleanup isn't done too early
@@ -248,13 +263,23 @@ struct drm_atomic_state;
* @event: optional pointer to a DRM event to signal upon completion of the
* state update
* @state: backpointer to global drm_atomic_state
+ *
+ * Note that the distinction between @enable and @active is rather subtile:
+ * Flipping @active while @enable is set without changing anything else may
+ * never return in a failure from the ->atomic_check callback. Userspace assumes
+ * that a DPMS On will always succeed. In other words: @enable controls resource
+ * assignment, @active controls the actual hardware state.
*/
struct drm_crtc_state {
+ struct drm_crtc *crtc;
+
bool enable;
+ bool active;
/* computed state bits used by helpers and drivers */
bool planes_changed : 1;
bool mode_changed : 1;
+ bool active_changed : 1;
/* attached planes bitmask:
* WARNING: transitional helpers do not maintain plane_mask so
@@ -292,6 +317,9 @@ struct drm_crtc_state {
* @atomic_duplicate_state: duplicate the atomic state for this CRTC
* @atomic_destroy_state: destroy an atomic state for this CRTC
* @atomic_set_property: set a property on an atomic state for this CRTC
+ * (do not call directly, use drm_atomic_crtc_set_property())
+ * @atomic_get_property: get a property on an atomic state for this CRTC
+ * (do not call directly, use drm_atomic_crtc_get_property())
*
* The drm_crtc_funcs structure is the central CRTC management structure
* in the DRM. Each CRTC controls one or more connectors (note that the name
@@ -351,6 +379,10 @@ struct drm_crtc_funcs {
struct drm_crtc_state *state,
struct drm_property *property,
uint64_t val);
+ int (*atomic_get_property)(struct drm_crtc *crtc,
+ const struct drm_crtc_state *state,
+ struct drm_property *property,
+ uint64_t *val);
};
/**
@@ -449,11 +481,14 @@ struct drm_crtc {
/**
* struct drm_connector_state - mutable connector state
+ * @connector: backpointer to the connector
* @crtc: CRTC to connect connector to, NULL if disabled
* @best_encoder: can be used by helpers and drivers to select the encoder
* @state: backpointer to global drm_atomic_state
*/
struct drm_connector_state {
+ struct drm_connector *connector;
+
struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_connector() */
struct drm_encoder *best_encoder;
@@ -463,7 +498,7 @@ struct drm_connector_state {
/**
* struct drm_connector_funcs - control connectors on a given device
- * @dpms: set power state (see drm_crtc_funcs above)
+ * @dpms: set power state
* @save: save connector state
* @restore: restore connector state
* @reset: reset connector after state has been invalidated (e.g. resume)
@@ -475,6 +510,9 @@ struct drm_connector_state {
* @atomic_duplicate_state: duplicate the atomic state for this connector
* @atomic_destroy_state: destroy an atomic state for this connector
* @atomic_set_property: set a property on an atomic state for this connector
+ * (do not call directly, use drm_atomic_connector_set_property())
+ * @atomic_get_property: get a property on an atomic state for this connector
+ * (do not call directly, use drm_atomic_connector_get_property())
*
* Each CRTC may have one or more connectors attached to it. The functions
* below allow the core DRM code to control connectors, enumerate available modes,
@@ -508,6 +546,10 @@ struct drm_connector_funcs {
struct drm_connector_state *state,
struct drm_property *property,
uint64_t val);
+ int (*atomic_get_property)(struct drm_connector *connector,
+ const struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t *val);
};
/**
@@ -693,6 +735,7 @@ struct drm_connector {
/**
* struct drm_plane_state - mutable plane state
+ * @plane: backpointer to the plane
* @crtc: currently bound CRTC, NULL if disabled
* @fb: currently bound framebuffer
* @fence: optional fence to wait for before scanning out @fb
@@ -709,6 +752,8 @@ struct drm_connector {
* @state: backpointer to global drm_atomic_state
*/
struct drm_plane_state {
+ struct drm_plane *plane;
+
struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_plane() */
struct drm_framebuffer *fb; /* do not write directly, use drm_atomic_set_fb_for_plane() */
struct fence *fence;
@@ -721,6 +766,9 @@ struct drm_plane_state {
uint32_t src_x, src_y;
uint32_t src_h, src_w;
+ /* Plane rotation */
+ unsigned int rotation;
+
struct drm_atomic_state *state;
};
@@ -735,6 +783,9 @@ struct drm_plane_state {
* @atomic_duplicate_state: duplicate the atomic state for this plane
* @atomic_destroy_state: destroy an atomic state for this plane
* @atomic_set_property: set a property on an atomic state for this plane
+ * (do not call directly, use drm_atomic_plane_set_property())
+ * @atomic_get_property: get a property on an atomic state for this plane
+ * (do not call directly, use drm_atomic_plane_get_property())
*/
struct drm_plane_funcs {
int (*update_plane)(struct drm_plane *plane,
@@ -758,6 +809,10 @@ struct drm_plane_funcs {
struct drm_plane_state *state,
struct drm_property *property,
uint64_t val);
+ int (*atomic_get_property)(struct drm_plane *plane,
+ const struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t *val);
};
enum drm_plane_type {
@@ -813,15 +868,16 @@ struct drm_plane {
/**
* struct drm_bridge_funcs - drm_bridge control functions
+ * @attach: Called during drm_bridge_attach
* @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge
* @disable: Called right before encoder prepare, disables the bridge
* @post_disable: Called right after encoder prepare, for lockstepped disable
* @mode_set: Set this mode to the bridge
* @pre_enable: Called right before encoder commit, for lockstepped commit
* @enable: Called right after encoder commit, enables the bridge
- * @destroy: make object go away
*/
struct drm_bridge_funcs {
+ int (*attach)(struct drm_bridge *bridge);
bool (*mode_fixup)(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
@@ -832,22 +888,24 @@ struct drm_bridge_funcs {
struct drm_display_mode *adjusted_mode);
void (*pre_enable)(struct drm_bridge *bridge);
void (*enable)(struct drm_bridge *bridge);
- void (*destroy)(struct drm_bridge *bridge);
};
/**
* struct drm_bridge - central DRM bridge control structure
* @dev: DRM device this bridge belongs to
- * @head: list management
+ * @of_node: device node pointer to the bridge
+ * @list: to keep track of all added bridges
* @base: base mode object
* @funcs: control functions
* @driver_private: pointer to the bridge driver's internal context
*/
struct drm_bridge {
struct drm_device *dev;
- struct list_head head;
-
- struct drm_mode_object base;
+ struct drm_encoder *encoder;
+#ifdef CONFIG_OF
+ struct device_node *of_node;
+#endif
+ struct list_head list;
const struct drm_bridge_funcs *funcs;
void *driver_private;
@@ -856,7 +914,8 @@ struct drm_bridge {
/**
* struct struct drm_atomic_state - the global state object for atomic updates
* @dev: parent DRM device
- * @flags: state flags like async update
+ * @allow_modeset: allow full modeset
+ * @legacy_cursor_update: hint to enforce legacy cursor ioctl semantics
* @planes: pointer to array of plane pointers
* @plane_states: pointer to array of plane states pointers
* @crtcs: pointer to array of CRTC pointers
@@ -868,7 +927,8 @@ struct drm_bridge {
*/
struct drm_atomic_state {
struct drm_device *dev;
- uint32_t flags;
+ bool allow_modeset : 1;
+ bool legacy_cursor_update : 1;
struct drm_plane **planes;
struct drm_plane_state **plane_states;
struct drm_crtc **crtcs;
@@ -950,7 +1010,6 @@ struct drm_mode_group {
uint32_t num_crtcs;
uint32_t num_encoders;
uint32_t num_connectors;
- uint32_t num_bridges;
/* list of object IDs for this group */
uint32_t *id_list;
@@ -969,8 +1028,6 @@ struct drm_mode_group {
* @fb_list: list of framebuffers available
* @num_connector: number of connectors on this device
* @connector_list: list of connector objects
- * @num_bridge: number of bridges on this device
- * @bridge_list: list of bridge objects
* @num_encoder: number of encoders on this device
* @encoder_list: list of encoder objects
* @num_overlay_plane: number of overlay planes on this device
@@ -1015,8 +1072,6 @@ struct drm_mode_config {
int num_connector;
struct list_head connector_list;
- int num_bridge;
- struct list_head bridge_list;
int num_encoder;
struct list_head encoder_list;
@@ -1043,6 +1098,7 @@ struct drm_mode_config {
/* output poll support */
bool poll_enabled;
bool poll_running;
+ bool delayed_event;
struct delayed_work output_poll_work;
/* pointers to standard properties */
@@ -1053,6 +1109,17 @@ struct drm_mode_config {
struct drm_property *tile_property;
struct drm_property *plane_type_property;
struct drm_property *rotation_property;
+ struct drm_property *prop_src_x;
+ struct drm_property *prop_src_y;
+ struct drm_property *prop_src_w;
+ struct drm_property *prop_src_h;
+ struct drm_property *prop_crtc_x;
+ struct drm_property *prop_crtc_y;
+ struct drm_property *prop_crtc_w;
+ struct drm_property *prop_crtc_h;
+ struct drm_property *prop_fb_id;
+ struct drm_property *prop_crtc_id;
+ struct drm_property *prop_active;
/* DVI-I properties */
struct drm_property *dvi_i_subconnector_property;
@@ -1153,9 +1220,10 @@ extern unsigned int drm_connector_index(struct drm_connector *connector);
/* helper to unplug all connectors from sysfs for device */
extern void drm_connector_unplug_all(struct drm_device *dev);
-extern int drm_bridge_init(struct drm_device *dev, struct drm_bridge *bridge,
- const struct drm_bridge_funcs *funcs);
-extern void drm_bridge_cleanup(struct drm_bridge *bridge);
+extern int drm_bridge_add(struct drm_bridge *bridge);
+extern void drm_bridge_remove(struct drm_bridge *bridge);
+extern struct drm_bridge *of_drm_find_bridge(struct device_node *np);
+extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge);
extern int drm_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder,
@@ -1191,6 +1259,8 @@ extern int drm_plane_init(struct drm_device *dev,
extern void drm_plane_cleanup(struct drm_plane *plane);
extern unsigned int drm_plane_index(struct drm_plane *plane);
extern void drm_plane_force_disable(struct drm_plane *plane);
+extern void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
+ int *hdisplay, int *vdisplay);
extern int drm_crtc_check_viewport(const struct drm_crtc *crtc,
int x, int y,
const struct drm_display_mode *mode,
@@ -1224,6 +1294,10 @@ int drm_mode_connector_set_tile_property(struct drm_connector *connector);
extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
const struct edid *edid);
+extern int drm_display_info_set_bus_formats(struct drm_display_info *info,
+ const u32 *formats,
+ unsigned int num_formats);
+
static inline bool drm_property_type_is(struct drm_property *property,
uint32_t type)
{
@@ -1279,6 +1353,8 @@ struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
int64_t min, int64_t max);
struct drm_property *drm_property_create_object(struct drm_device *dev,
int flags, const char *name, uint32_t type);
+struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
+ const char *name);
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
extern int drm_property_add_enum(struct drm_property *property, int index,
uint64_t value, const char *name);
@@ -1290,6 +1366,10 @@ extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
extern int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
extern int drm_mode_create_dirty_info_property(struct drm_device *dev);
extern int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
+extern bool drm_property_change_valid_get(struct drm_property *property,
+ uint64_t value, struct drm_mode_object **ref);
+extern void drm_property_change_valid_put(struct drm_property *property,
+ struct drm_mode_object *ref);
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder);
@@ -1381,6 +1461,8 @@ extern int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
struct drm_property *property,
uint64_t value);
+extern int drm_mode_atomic_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
int *bpp);
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 7adbb65ea8ae..c250a22b39ab 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -39,17 +39,38 @@
#include <linux/fb.h>
+#include <drm/drm_crtc.h>
+
enum mode_set_atomic {
LEAVE_ATOMIC_MODE_SET,
ENTER_ATOMIC_MODE_SET,
};
/**
- * drm_crtc_helper_funcs - helper operations for CRTCs
- * @mode_fixup: try to fixup proposed mode for this connector
+ * struct drm_crtc_helper_funcs - helper operations for CRTCs
+ * @dpms: set power state
+ * @prepare: prepare the CRTC, called before @mode_set
+ * @commit: commit changes to CRTC, called after @mode_set
+ * @mode_fixup: try to fixup proposed mode for this CRTC
* @mode_set: set this mode
+ * @mode_set_nofb: set mode only (no scanout buffer attached)
+ * @mode_set_base: update the scanout buffer
+ * @mode_set_base_atomic: non-blocking mode set (used for kgdb support)
+ * @load_lut: load color palette
+ * @disable: disable CRTC when no longer in use
+ * @enable: enable CRTC
+ * @atomic_check: check for validity of an atomic state
+ * @atomic_begin: begin atomic update
+ * @atomic_flush: flush atomic update
*
* The helper operations are called by the mid-layer CRTC helper.
+ *
+ * Note that with atomic helpers @dpms, @prepare and @commit hooks are
+ * deprecated. Used @enable and @disable instead exclusively.
+ *
+ * With legacy crtc helpers there's a big semantic difference between @disable
+ * and the other hooks: @disable also needs to release any resources acquired in
+ * @mode_set (like shared PLLs).
*/
struct drm_crtc_helper_funcs {
/*
@@ -80,8 +101,8 @@ struct drm_crtc_helper_funcs {
/* reload the current crtc LUT */
void (*load_lut)(struct drm_crtc *crtc);
- /* disable crtc when not in use - more explicit than dpms off */
void (*disable)(struct drm_crtc *crtc);
+ void (*enable)(struct drm_crtc *crtc);
/* atomic helpers */
int (*atomic_check)(struct drm_crtc *crtc,
@@ -91,11 +112,28 @@ struct drm_crtc_helper_funcs {
};
/**
- * drm_encoder_helper_funcs - helper operations for encoders
+ * struct drm_encoder_helper_funcs - helper operations for encoders
+ * @dpms: set power state
+ * @save: save connector state
+ * @restore: restore connector state
* @mode_fixup: try to fixup proposed mode for this connector
+ * @prepare: part of the disable sequence, called before the CRTC modeset
+ * @commit: called after the CRTC modeset
* @mode_set: set this mode
+ * @get_crtc: return CRTC that the encoder is currently attached to
+ * @detect: connection status detection
+ * @disable: disable encoder when not in use (overrides DPMS off)
+ * @enable: enable encoder
+ * @atomic_check: check for validity of an atomic update
*
* The helper operations are called by the mid-layer CRTC helper.
+ *
+ * Note that with atomic helpers @dpms, @prepare and @commit hooks are
+ * deprecated. Used @enable and @disable instead exclusively.
+ *
+ * With legacy crtc helpers there's a big semantic difference between @disable
+ * and the other hooks: @disable also needs to release any resources acquired in
+ * @mode_set (like shared PLLs).
*/
struct drm_encoder_helper_funcs {
void (*dpms)(struct drm_encoder *encoder, int mode);
@@ -114,14 +152,21 @@ struct drm_encoder_helper_funcs {
/* detect for DAC style encoders */
enum drm_connector_status (*detect)(struct drm_encoder *encoder,
struct drm_connector *connector);
- /* disable encoder when not in use - more explicit than dpms off */
void (*disable)(struct drm_encoder *encoder);
+
+ void (*enable)(struct drm_encoder *encoder);
+
+ /* atomic helpers */
+ int (*atomic_check)(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state);
};
/**
- * drm_connector_helper_funcs - helper operations for connectors
+ * struct drm_connector_helper_funcs - helper operations for connectors
* @get_modes: get mode list for this connector
- * @mode_valid (optional): is this mode valid on the given connector?
+ * @mode_valid: is this mode valid on the given connector? (optional)
+ * @best_encoder: return the preferred encoder for this connector
*
* The helper operations are called by the mid-layer CRTC helper.
*/
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 11f8c84f98ce..7e25030a6aa2 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -586,6 +586,7 @@ struct drm_dp_link {
int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link);
int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link);
+int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link);
int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
int drm_dp_aux_register(struct drm_dp_aux *aux);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index b597068103aa..21b944c456f6 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -125,7 +125,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
-bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
+int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
int drm_fb_helper_debug_enter(struct fb_info *info);
int drm_fb_helper_debug_leave(struct fb_info *info);
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 91d0582f924e..d92f6dd1fb11 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -90,6 +90,9 @@ enum drm_mode_status {
#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */
#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */
+#define CRTC_NO_DBLSCAN (1 << 2) /* don't adjust doublescan */
+#define CRTC_NO_VSCAN (1 << 3) /* don't adjust doublescan */
+#define CRTC_STEREO_DOUBLE_ONLY (CRTC_NO_DBLSCAN | CRTC_NO_VSCAN)
#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
@@ -197,6 +200,8 @@ struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
int GTF_K, int GTF_2J);
void drm_display_mode_from_videomode(const struct videomode *vm,
struct drm_display_mode *dmode);
+void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
+ struct videomode *vm);
int of_get_drm_display_mode(struct device_node *np,
struct drm_display_mode *dmode,
int index);
@@ -217,9 +222,9 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2);
/* for use by the crtc helper probe functions */
-void drm_mode_validate_size(struct drm_device *dev,
- struct list_head *mode_list,
- int maxX, int maxY);
+enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode);
+enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode,
+ int maxX, int maxY);
void drm_mode_prune_invalid(struct drm_device *dev,
struct list_head *mode_list, bool verbose);
void drm_mode_sort(struct list_head *mode_list);
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h
index a185392cafeb..31c11d36fae6 100644
--- a/include/drm/drm_plane_helper.h
+++ b/include/drm/drm_plane_helper.h
@@ -52,7 +52,8 @@ extern int drm_crtc_init(struct drm_device *dev,
* @prepare_fb: prepare a framebuffer for use by the plane
* @cleanup_fb: cleanup a framebuffer when it's no longer used by the plane
* @atomic_check: check that a given atomic state is valid and can be applied
- * @atomic_update: apply an atomic state to the plane
+ * @atomic_update: apply an atomic state to the plane (mandatory)
+ * @atomic_disable: disable the plane
*
* The helper operations are called by the mid-layer CRTC helper.
*/
@@ -66,6 +67,8 @@ struct drm_plane_helper_funcs {
struct drm_plane_state *state);
void (*atomic_update)(struct drm_plane *plane,
struct drm_plane_state *old_state);
+ void (*atomic_disable)(struct drm_plane *plane,
+ struct drm_plane_state *old_state);
};
static inline void drm_plane_helper_add(struct drm_plane *plane,
diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h
index 8dc0913f1775..99da0d117a7d 100644
--- a/include/dt-bindings/clock/exynos5420.h
+++ b/include/dt-bindings/clock/exynos5420.h
@@ -204,6 +204,12 @@
#define CLK_MOUT_MAUDIO0 643
#define CLK_MOUT_USER_ACLK333 644
#define CLK_MOUT_SW_ACLK333 645
+#define CLK_MOUT_USER_ACLK200_DISP1 646
+#define CLK_MOUT_SW_ACLK200 647
+#define CLK_MOUT_USER_ACLK300_DISP1 648
+#define CLK_MOUT_SW_ACLK300 649
+#define CLK_MOUT_USER_ACLK400_DISP1 650
+#define CLK_MOUT_SW_ACLK400 651
/* divider clocks */
#define CLK_DOUT_PIXEL 768
diff --git a/include/dt-bindings/clock/r8a7790-clock.h b/include/dt-bindings/clock/r8a7790-clock.h
index c27b3b5133b9..91940271cf83 100644
--- a/include/dt-bindings/clock/r8a7790-clock.h
+++ b/include/dt-bindings/clock/r8a7790-clock.h
@@ -97,6 +97,7 @@
#define R8A7790_CLK_LVDS0 26
/* MSTP8 */
+#define R8A7790_CLK_MLB 2
#define R8A7790_CLK_VIN3 8
#define R8A7790_CLK_VIN2 9
#define R8A7790_CLK_VIN1 10
diff --git a/include/dt-bindings/clock/r8a7791-clock.h b/include/dt-bindings/clock/r8a7791-clock.h
index 3ea2bbc0da3f..f096f3f6c16a 100644
--- a/include/dt-bindings/clock/r8a7791-clock.h
+++ b/include/dt-bindings/clock/r8a7791-clock.h
@@ -91,6 +91,8 @@
#define R8A7791_CLK_LVDS0 26
/* MSTP8 */
+#define R8A7791_CLK_IPMMU_SGX 0
+#define R8A7791_CLK_MLB 2
#define R8A7791_CLK_VIN2 9
#define R8A7791_CLK_VIN1 10
#define R8A7791_CLK_VIN0 11
diff --git a/include/dt-bindings/clock/r8a7794-clock.h b/include/dt-bindings/clock/r8a7794-clock.h
index aa9c286e60c0..d63323032d6e 100644
--- a/include/dt-bindings/clock/r8a7794-clock.h
+++ b/include/dt-bindings/clock/r8a7794-clock.h
@@ -48,15 +48,25 @@
#define R8A7794_CLK_SCIFB1 7
#define R8A7794_CLK_MSIOF1 8
#define R8A7794_CLK_SCIFB2 16
+#define R8A7794_CLK_SYS_DMAC1 18
+#define R8A7794_CLK_SYS_DMAC0 19
/* MSTP3 */
+#define R8A7794_CLK_SDHI2 11
+#define R8A7794_CLK_SDHI1 12
+#define R8A7794_CLK_SDHI0 14
+#define R8A7794_CLK_MMCIF0 15
#define R8A7794_CLK_CMT1 29
+#define R8A7794_CLK_USBDMAC0 30
+#define R8A7794_CLK_USBDMAC1 31
/* MSTP5 */
#define R8A7794_CLK_THERMAL 22
#define R8A7794_CLK_PWM 23
/* MSTP7 */
+#define R8A7794_CLK_EHCI 3
+#define R8A7794_CLK_HSUSB 4
#define R8A7794_CLK_HSCIF2 13
#define R8A7794_CLK_SCIF5 14
#define R8A7794_CLK_SCIF4 15
@@ -80,6 +90,13 @@
#define R8A7794_CLK_GPIO2 10
#define R8A7794_CLK_GPIO1 11
#define R8A7794_CLK_GPIO0 12
+#define R8A7794_CLK_QSPI_MOD 17
+#define R8A7794_CLK_I2C5 25
+#define R8A7794_CLK_I2C4 27
+#define R8A7794_CLK_I2C3 28
+#define R8A7794_CLK_I2C2 29
+#define R8A7794_CLK_I2C1 30
+#define R8A7794_CLK_I2C0 31
/* MSTP11 */
#define R8A7794_CLK_SCIFA3 6
diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h
index 1c34c24efe08..dea419708d73 100644
--- a/include/dt-bindings/clock/rk3288-cru.h
+++ b/include/dt-bindings/clock/rk3288-cru.h
@@ -80,6 +80,9 @@
#define SCLK_SDIO0_SAMPLE 119
#define SCLK_SDIO1_SAMPLE 120
#define SCLK_EMMC_SAMPLE 121
+#define SCLK_USBPHY480M_SRC 122
+#define SCLK_PVTM_CORE 123
+#define SCLK_PVTM_GPU 124
#define SCLK_MAC 151
#define SCLK_MACREF_OUT 152
@@ -157,6 +160,7 @@
#define PCLK_PUBL0 365
#define PCLK_DDRUPCTL1 366
#define PCLK_PUBL1 367
+#define PCLK_WDT 368
/* hclk gates */
#define HCLK_GPS 448
diff --git a/include/dt-bindings/clock/sh73a0-clock.h b/include/dt-bindings/clock/sh73a0-clock.h
new file mode 100644
index 000000000000..1dd3eb2b7d90
--- /dev/null
+++ b/include/dt-bindings/clock/sh73a0-clock.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2014 Ulrich Hecht
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_SH73A0_H__
+#define __DT_BINDINGS_CLOCK_SH73A0_H__
+
+/* CPG */
+#define SH73A0_CLK_MAIN 0
+#define SH73A0_CLK_PLL0 1
+#define SH73A0_CLK_PLL1 2
+#define SH73A0_CLK_PLL2 3
+#define SH73A0_CLK_PLL3 4
+#define SH73A0_CLK_DSI0PHY 5
+#define SH73A0_CLK_DSI1PHY 6
+#define SH73A0_CLK_ZG 7
+#define SH73A0_CLK_M3 8
+#define SH73A0_CLK_B 9
+#define SH73A0_CLK_M1 10
+#define SH73A0_CLK_M2 11
+#define SH73A0_CLK_Z 12
+#define SH73A0_CLK_ZX 13
+#define SH73A0_CLK_HP 14
+
+/* MSTP0 */
+#define SH73A0_CLK_IIC2 1
+
+/* MSTP1 */
+#define SH73A0_CLK_CEU1 29
+#define SH73A0_CLK_CSI2_RX1 28
+#define SH73A0_CLK_CEU0 27
+#define SH73A0_CLK_CSI2_RX0 26
+#define SH73A0_CLK_TMU0 25
+#define SH73A0_CLK_DSITX0 18
+#define SH73A0_CLK_IIC0 16
+#define SH73A0_CLK_SGX 12
+#define SH73A0_CLK_LCDC0 0
+
+/* MSTP2 */
+#define SH73A0_CLK_SCIFA7 19
+#define SH73A0_CLK_SY_DMAC 18
+#define SH73A0_CLK_MP_DMAC 17
+#define SH73A0_CLK_SCIFA5 7
+#define SH73A0_CLK_SCIFB 6
+#define SH73A0_CLK_SCIFA0 4
+#define SH73A0_CLK_SCIFA1 3
+#define SH73A0_CLK_SCIFA2 2
+#define SH73A0_CLK_SCIFA3 1
+#define SH73A0_CLK_SCIFA4 0
+
+/* MSTP3 */
+#define SH73A0_CLK_SCIFA6 31
+#define SH73A0_CLK_CMT1 29
+#define SH73A0_CLK_FSI 28
+#define SH73A0_CLK_IRDA 25
+#define SH73A0_CLK_IIC1 23
+#define SH73A0_CLK_USB 22
+#define SH73A0_CLK_FLCTL 15
+#define SH73A0_CLK_SDHI0 14
+#define SH73A0_CLK_SDHI1 13
+#define SH73A0_CLK_MMCIF0 12
+#define SH73A0_CLK_SDHI2 11
+#define SH73A0_CLK_TPU0 4
+#define SH73A0_CLK_TPU1 3
+#define SH73A0_CLK_TPU2 2
+#define SH73A0_CLK_TPU3 1
+#define SH73A0_CLK_TPU4 0
+
+/* MSTP4 */
+#define SH73A0_CLK_IIC3 11
+#define SH73A0_CLK_IIC4 10
+#define SH73A0_CLK_KEYSC 3
+
+#endif
diff --git a/include/dt-bindings/clock/stih418-clks.h b/include/dt-bindings/clock/stih418-clks.h
new file mode 100644
index 000000000000..b62aa0b20217
--- /dev/null
+++ b/include/dt-bindings/clock/stih418-clks.h
@@ -0,0 +1,34 @@
+/*
+ * This header provides constants clk index STMicroelectronics
+ * STiH418 SoC.
+ */
+#ifndef _DT_BINDINGS_CLK_STIH418
+#define _DT_BINDINGS_CLK_STIH418
+
+#include "stih410-clks.h"
+
+/* STiH418 introduces new clock outputs compared to STiH410 */
+
+/* CLOCKGEN C0 */
+#define CLK_PROC_BDISP_0 14
+#define CLK_PROC_BDISP_1 15
+#define CLK_TX_ICN_1 23
+#define CLK_ETH_PHYREF 27
+#define CLK_PP_HEVC 35
+#define CLK_CLUST_HEVC 36
+#define CLK_HWPE_HEVC 37
+#define CLK_FC_HEVC 38
+#define CLK_PROC_MIXER 39
+#define CLK_PROC_SC 40
+#define CLK_AVSP_HEVC 41
+
+/* CLOCKGEN D2 */
+#undef CLK_PIX_PIP
+#undef CLK_PIX_GDP1
+#undef CLK_PIX_GDP2
+#undef CLK_PIX_GDP3
+#undef CLK_PIX_GDP4
+
+#define CLK_TMDS_HDMI_DIV2 5
+#define CLK_VP9 47
+#endif
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index 801c0ac50c47..979d24a6799f 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -192,6 +192,7 @@
#define VF610_PLL5_BYPASS 179
#define VF610_PLL6_BYPASS 180
#define VF610_PLL7_BYPASS 181
-#define VF610_CLK_END 182
+#define VF610_CLK_SNVS 182
+#define VF610_CLK_END 183
#endif /* __DT_BINDINGS_CLOCK_VF610_H */
diff --git a/include/dt-bindings/dma/sun4i-a10.h b/include/dt-bindings/dma/sun4i-a10.h
new file mode 100644
index 000000000000..8caba9ef7e9d
--- /dev/null
+++ b/include/dt-bindings/dma/sun4i-a10.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2014 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __DT_BINDINGS_DMA_SUN4I_A10_H_
+#define __DT_BINDINGS_DMA_SUN4I_A10_H_
+
+#define SUN4I_DMA_NORMAL 0
+#define SUN4I_DMA_DEDICATED 1
+
+#endif /* __DT_BINDINGS_DMA_SUN4I_A10_H_ */
diff --git a/include/dt-bindings/mfd/qcom-rpm.h b/include/dt-bindings/mfd/qcom-rpm.h
new file mode 100644
index 000000000000..388a6f3d6165
--- /dev/null
+++ b/include/dt-bindings/mfd/qcom-rpm.h
@@ -0,0 +1,154 @@
+/*
+ * This header provides constants for the Qualcomm RPM bindings.
+ */
+
+#ifndef _DT_BINDINGS_MFD_QCOM_RPM_H
+#define _DT_BINDINGS_MFD_QCOM_RPM_H
+
+/*
+ * Constants use to identify individual resources in the RPM.
+ */
+#define QCOM_RPM_APPS_FABRIC_ARB 1
+#define QCOM_RPM_APPS_FABRIC_CLK 2
+#define QCOM_RPM_APPS_FABRIC_HALT 3
+#define QCOM_RPM_APPS_FABRIC_IOCTL 4
+#define QCOM_RPM_APPS_FABRIC_MODE 5
+#define QCOM_RPM_APPS_L2_CACHE_CTL 6
+#define QCOM_RPM_CFPB_CLK 7
+#define QCOM_RPM_CXO_BUFFERS 8
+#define QCOM_RPM_CXO_CLK 9
+#define QCOM_RPM_DAYTONA_FABRIC_CLK 10
+#define QCOM_RPM_DDR_DMM 11
+#define QCOM_RPM_EBI1_CLK 12
+#define QCOM_RPM_HDMI_SWITCH 13
+#define QCOM_RPM_MMFPB_CLK 14
+#define QCOM_RPM_MM_FABRIC_ARB 15
+#define QCOM_RPM_MM_FABRIC_CLK 16
+#define QCOM_RPM_MM_FABRIC_HALT 17
+#define QCOM_RPM_MM_FABRIC_IOCTL 18
+#define QCOM_RPM_MM_FABRIC_MODE 19
+#define QCOM_RPM_PLL_4 20
+#define QCOM_RPM_PM8058_LDO0 21
+#define QCOM_RPM_PM8058_LDO1 22
+#define QCOM_RPM_PM8058_LDO2 23
+#define QCOM_RPM_PM8058_LDO3 24
+#define QCOM_RPM_PM8058_LDO4 25
+#define QCOM_RPM_PM8058_LDO5 26
+#define QCOM_RPM_PM8058_LDO6 27
+#define QCOM_RPM_PM8058_LDO7 28
+#define QCOM_RPM_PM8058_LDO8 29
+#define QCOM_RPM_PM8058_LDO9 30
+#define QCOM_RPM_PM8058_LDO10 31
+#define QCOM_RPM_PM8058_LDO11 32
+#define QCOM_RPM_PM8058_LDO12 33
+#define QCOM_RPM_PM8058_LDO13 34
+#define QCOM_RPM_PM8058_LDO14 35
+#define QCOM_RPM_PM8058_LDO15 36
+#define QCOM_RPM_PM8058_LDO16 37
+#define QCOM_RPM_PM8058_LDO17 38
+#define QCOM_RPM_PM8058_LDO18 39
+#define QCOM_RPM_PM8058_LDO19 40
+#define QCOM_RPM_PM8058_LDO20 41
+#define QCOM_RPM_PM8058_LDO21 42
+#define QCOM_RPM_PM8058_LDO22 43
+#define QCOM_RPM_PM8058_LDO23 44
+#define QCOM_RPM_PM8058_LDO24 45
+#define QCOM_RPM_PM8058_LDO25 46
+#define QCOM_RPM_PM8058_LVS0 47
+#define QCOM_RPM_PM8058_LVS1 48
+#define QCOM_RPM_PM8058_NCP 49
+#define QCOM_RPM_PM8058_SMPS0 50
+#define QCOM_RPM_PM8058_SMPS1 51
+#define QCOM_RPM_PM8058_SMPS2 52
+#define QCOM_RPM_PM8058_SMPS3 53
+#define QCOM_RPM_PM8058_SMPS4 54
+#define QCOM_RPM_PM8821_LDO1 55
+#define QCOM_RPM_PM8821_SMPS1 56
+#define QCOM_RPM_PM8821_SMPS2 57
+#define QCOM_RPM_PM8901_LDO0 58
+#define QCOM_RPM_PM8901_LDO1 59
+#define QCOM_RPM_PM8901_LDO2 60
+#define QCOM_RPM_PM8901_LDO3 61
+#define QCOM_RPM_PM8901_LDO4 62
+#define QCOM_RPM_PM8901_LDO5 63
+#define QCOM_RPM_PM8901_LDO6 64
+#define QCOM_RPM_PM8901_LVS0 65
+#define QCOM_RPM_PM8901_LVS1 66
+#define QCOM_RPM_PM8901_LVS2 67
+#define QCOM_RPM_PM8901_LVS3 68
+#define QCOM_RPM_PM8901_MVS 69
+#define QCOM_RPM_PM8901_SMPS0 70
+#define QCOM_RPM_PM8901_SMPS1 71
+#define QCOM_RPM_PM8901_SMPS2 72
+#define QCOM_RPM_PM8901_SMPS3 73
+#define QCOM_RPM_PM8901_SMPS4 74
+#define QCOM_RPM_PM8921_CLK1 75
+#define QCOM_RPM_PM8921_CLK2 76
+#define QCOM_RPM_PM8921_LDO1 77
+#define QCOM_RPM_PM8921_LDO2 78
+#define QCOM_RPM_PM8921_LDO3 79
+#define QCOM_RPM_PM8921_LDO4 80
+#define QCOM_RPM_PM8921_LDO5 81
+#define QCOM_RPM_PM8921_LDO6 82
+#define QCOM_RPM_PM8921_LDO7 83
+#define QCOM_RPM_PM8921_LDO8 84
+#define QCOM_RPM_PM8921_LDO9 85
+#define QCOM_RPM_PM8921_LDO10 86
+#define QCOM_RPM_PM8921_LDO11 87
+#define QCOM_RPM_PM8921_LDO12 88
+#define QCOM_RPM_PM8921_LDO13 89
+#define QCOM_RPM_PM8921_LDO14 90
+#define QCOM_RPM_PM8921_LDO15 91
+#define QCOM_RPM_PM8921_LDO16 92
+#define QCOM_RPM_PM8921_LDO17 93
+#define QCOM_RPM_PM8921_LDO18 94
+#define QCOM_RPM_PM8921_LDO19 95
+#define QCOM_RPM_PM8921_LDO20 96
+#define QCOM_RPM_PM8921_LDO21 97
+#define QCOM_RPM_PM8921_LDO22 98
+#define QCOM_RPM_PM8921_LDO23 99
+#define QCOM_RPM_PM8921_LDO24 100
+#define QCOM_RPM_PM8921_LDO25 101
+#define QCOM_RPM_PM8921_LDO26 102
+#define QCOM_RPM_PM8921_LDO27 103
+#define QCOM_RPM_PM8921_LDO28 104
+#define QCOM_RPM_PM8921_LDO29 105
+#define QCOM_RPM_PM8921_LVS1 106
+#define QCOM_RPM_PM8921_LVS2 107
+#define QCOM_RPM_PM8921_LVS3 108
+#define QCOM_RPM_PM8921_LVS4 109
+#define QCOM_RPM_PM8921_LVS5 110
+#define QCOM_RPM_PM8921_LVS6 111
+#define QCOM_RPM_PM8921_LVS7 112
+#define QCOM_RPM_PM8921_MVS 113
+#define QCOM_RPM_PM8921_NCP 114
+#define QCOM_RPM_PM8921_SMPS1 115
+#define QCOM_RPM_PM8921_SMPS2 116
+#define QCOM_RPM_PM8921_SMPS3 117
+#define QCOM_RPM_PM8921_SMPS4 118
+#define QCOM_RPM_PM8921_SMPS5 119
+#define QCOM_RPM_PM8921_SMPS6 120
+#define QCOM_RPM_PM8921_SMPS7 121
+#define QCOM_RPM_PM8921_SMPS8 122
+#define QCOM_RPM_PXO_CLK 123
+#define QCOM_RPM_QDSS_CLK 124
+#define QCOM_RPM_SFPB_CLK 125
+#define QCOM_RPM_SMI_CLK 126
+#define QCOM_RPM_SYS_FABRIC_ARB 127
+#define QCOM_RPM_SYS_FABRIC_CLK 128
+#define QCOM_RPM_SYS_FABRIC_HALT 129
+#define QCOM_RPM_SYS_FABRIC_IOCTL 130
+#define QCOM_RPM_SYS_FABRIC_MODE 131
+#define QCOM_RPM_USB_OTG_SWITCH 132
+#define QCOM_RPM_VDDMIN_GPIO 133
+
+/*
+ * Constants used to select force mode for regulators.
+ */
+#define QCOM_RPM_FORCE_MODE_NONE 0
+#define QCOM_RPM_FORCE_MODE_LPM 1
+#define QCOM_RPM_FORCE_MODE_HPM 2
+#define QCOM_RPM_FORCE_MODE_AUTO 3
+#define QCOM_RPM_FORCE_MODE_BYPASS 4
+
+#endif
diff --git a/include/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h
index 1c75b8ca5228..13949259705a 100644
--- a/include/dt-bindings/pinctrl/omap.h
+++ b/include/dt-bindings/pinctrl/omap.h
@@ -61,6 +61,7 @@
#define OMAP3430_CORE2_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x25d8) (val)
#define OMAP3630_CORE2_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x25a0) (val)
#define OMAP3_WKUP_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x2a00) (val)
+#define DM816X_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
#define AM33XX_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
#define AM4372_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x0800) (val)
#define DRA7XX_CORE_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x3400) (val)
diff --git a/include/dt-bindings/pinctrl/sun4i-a10.h b/include/dt-bindings/pinctrl/sun4i-a10.h
new file mode 100644
index 000000000000..f7553c143b40
--- /dev/null
+++ b/include/dt-bindings/pinctrl/sun4i-a10.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2014 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __DT_BINDINGS_PINCTRL_SUN4I_A10_H_
+#define __DT_BINDINGS_PINCTRL_SUN4I_A10_H_
+
+#define SUN4I_PINCTRL_10_MA 0
+#define SUN4I_PINCTRL_20_MA 1
+#define SUN4I_PINCTRL_30_MA 2
+#define SUN4I_PINCTRL_40_MA 3
+
+#define SUN4I_PINCTRL_NO_PULL 0
+#define SUN4I_PINCTRL_PULL_UP 1
+#define SUN4I_PINCTRL_PULL_DOWN 2
+
+#endif /* __DT_BINDINGS_PINCTRL_SUN4I_A10_H_ */
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 599f3bd2d6c5..c2e7e3a83965 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -127,7 +127,6 @@ extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1,
extern void __audit_syscall_exit(int ret_success, long ret_value);
extern struct filename *__audit_reusename(const __user char *uptr);
extern void __audit_getname(struct filename *name);
-extern void audit_putname(struct filename *name);
#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */
#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */
@@ -352,8 +351,6 @@ static inline struct filename *audit_reusename(const __user char *name)
}
static inline void audit_getname(struct filename *name)
{ }
-static inline void audit_putname(struct filename *name)
-{ }
static inline void __audit_inode(struct filename *name,
const struct dentry *dentry,
unsigned int flags)
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index d94077fea1f8..aff923ae8c4b 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -55,6 +55,7 @@ struct bdi_writeback {
struct list_head b_dirty; /* dirty inodes */
struct list_head b_io; /* parked for writeback */
struct list_head b_more_io; /* parked for more writeback */
+ struct list_head b_dirty_time; /* time stamps are dirty */
spinlock_t list_lock; /* protects the b_* lists */
};
diff --git a/include/linux/bcm47xx_wdt.h b/include/linux/bcm47xx_wdt.h
index b708786d4cbf..5582c211f594 100644
--- a/include/linux/bcm47xx_wdt.h
+++ b/include/linux/bcm47xx_wdt.h
@@ -16,6 +16,7 @@ struct bcm47xx_wdt {
struct watchdog_device wdd;
struct notifier_block notifier;
+ struct notifier_block restart_handler;
struct timer_list soft_timer;
atomic_t soft_ticks;
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index ab70f3bc44ad..f551a9299ac9 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -50,6 +50,15 @@ struct cpuidle_state {
int index);
int (*enter_dead) (struct cpuidle_device *dev, int index);
+
+ /*
+ * CPUs execute ->enter_freeze with the local tick or entire timekeeping
+ * suspended, so it must not re-enable interrupts at any point (even
+ * temporarily) or attempt to change states of clock event devices.
+ */
+ void (*enter_freeze) (struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index);
};
/* Idle State Flags */
@@ -141,7 +150,7 @@ extern void cpuidle_resume(void);
extern int cpuidle_enable_device(struct cpuidle_device *dev);
extern void cpuidle_disable_device(struct cpuidle_device *dev);
extern int cpuidle_play_dead(void);
-extern void cpuidle_use_deepest_state(bool enable);
+extern void cpuidle_enter_freeze(void);
extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
#else
@@ -174,7 +183,7 @@ static inline int cpuidle_enable_device(struct cpuidle_device *dev)
{return -ENODEV; }
static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
static inline int cpuidle_play_dead(void) {return -ENODEV; }
-static inline void cpuidle_use_deepest_state(bool enable) {}
+static inline void cpuidle_enter_freeze(void) { }
static inline struct cpuidle_driver *cpuidle_get_cpu_driver(
struct cpuidle_device *dev) {return NULL; }
#endif
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 5a813988e6d4..92c08cf7670e 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -319,9 +319,6 @@ static inline unsigned d_count(const struct dentry *dentry)
return dentry->d_lockref.count;
}
-/* validate "insecure" dentry pointer */
-extern int d_validate(struct dentry *, struct dentry *);
-
/*
* helper function for dentry_operations.d_dname() members
*/
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index da4c4983adbe..cb25af461054 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -51,11 +51,21 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
+struct dentry *debugfs_create_file_size(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops,
+ loff_t file_size);
+
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
const char *dest);
+struct dentry *debugfs_create_automount(const char *name,
+ struct dentry *parent,
+ struct vfsmount *(*f)(void *),
+ void *data);
+
void debugfs_remove(struct dentry *dentry);
void debugfs_remove_recursive(struct dentry *dentry);
@@ -124,6 +134,14 @@ static inline struct dentry *debugfs_create_file(const char *name, umode_t mode,
return ERR_PTR(-ENODEV);
}
+static inline struct dentry *debugfs_create_file_size(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops,
+ loff_t file_size)
+{
+ return ERR_PTR(-ENODEV);
+}
+
static inline struct dentry *debugfs_create_dir(const char *name,
struct dentry *parent)
{
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 40cd75e21ea2..b6997a0cb528 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -189,25 +189,6 @@ enum dma_ctrl_flags {
};
/**
- * enum dma_ctrl_cmd - DMA operations that can optionally be exercised
- * on a running channel.
- * @DMA_TERMINATE_ALL: terminate all ongoing transfers
- * @DMA_PAUSE: pause ongoing transfers
- * @DMA_RESUME: resume paused transfer
- * @DMA_SLAVE_CONFIG: this command is only implemented by DMA controllers
- * that need to runtime reconfigure the slave channels (as opposed to passing
- * configuration data in statically from the platform). An additional
- * argument of struct dma_slave_config must be passed in with this
- * command.
- */
-enum dma_ctrl_cmd {
- DMA_TERMINATE_ALL,
- DMA_PAUSE,
- DMA_RESUME,
- DMA_SLAVE_CONFIG,
-};
-
-/**
* enum sum_check_bits - bit position of pq_check_flags
*/
enum sum_check_bits {
@@ -298,6 +279,9 @@ enum dma_slave_buswidth {
DMA_SLAVE_BUSWIDTH_3_BYTES = 3,
DMA_SLAVE_BUSWIDTH_4_BYTES = 4,
DMA_SLAVE_BUSWIDTH_8_BYTES = 8,
+ DMA_SLAVE_BUSWIDTH_16_BYTES = 16,
+ DMA_SLAVE_BUSWIDTH_32_BYTES = 32,
+ DMA_SLAVE_BUSWIDTH_64_BYTES = 64,
};
/**
@@ -336,9 +320,8 @@ enum dma_slave_buswidth {
* This struct is passed in as configuration data to a DMA engine
* in order to set up a certain channel for DMA transport at runtime.
* The DMA device/engine has to provide support for an additional
- * command in the channel config interface, DMA_SLAVE_CONFIG
- * and this struct will then be passed in as an argument to the
- * DMA engine device_control() function.
+ * callback in the dma_device structure, device_config and this struct
+ * will then be passed in as an argument to the function.
*
* The rationale for adding configuration information to this struct is as
* follows: if it is likely that more than one DMA slave controllers in
@@ -387,7 +370,7 @@ enum dma_residue_granularity {
/* struct dma_slave_caps - expose capabilities of a slave channel only
*
* @src_addr_widths: bit mask of src addr widths the channel supports
- * @dstn_addr_widths: bit mask of dstn addr widths the channel supports
+ * @dst_addr_widths: bit mask of dstn addr widths the channel supports
* @directions: bit mask of slave direction the channel supported
* since the enum dma_transfer_direction is not defined as bits for each
* type of direction, the dma controller should fill (1 << <TYPE>) and same
@@ -398,7 +381,7 @@ enum dma_residue_granularity {
*/
struct dma_slave_caps {
u32 src_addr_widths;
- u32 dstn_addr_widths;
+ u32 dst_addr_widths;
u32 directions;
bool cmd_pause;
bool cmd_terminate;
@@ -594,6 +577,14 @@ struct dma_tx_state {
* @fill_align: alignment shift for memset operations
* @dev_id: unique device ID
* @dev: struct device reference for dma mapping api
+ * @src_addr_widths: bit mask of src addr widths the device supports
+ * @dst_addr_widths: bit mask of dst addr widths the device supports
+ * @directions: bit mask of slave direction the device supports since
+ * the enum dma_transfer_direction is not defined as bits for
+ * each type of direction, the dma controller should fill (1 <<
+ * <TYPE>) and same should be checked by controller as well
+ * @residue_granularity: granularity of the transfer residue reported
+ * by tx_status
* @device_alloc_chan_resources: allocate resources and return the
* number of allocated descriptors
* @device_free_chan_resources: release DMA channel's resources
@@ -608,14 +599,19 @@ struct dma_tx_state {
* The function takes a buffer of size buf_len. The callback function will
* be called after period_len bytes have been transferred.
* @device_prep_interleaved_dma: Transfer expression in a generic way.
- * @device_control: manipulate all pending operations on a channel, returns
- * zero or error code
+ * @device_config: Pushes a new configuration to a channel, return 0 or an error
+ * code
+ * @device_pause: Pauses any transfer happening on a channel. Returns
+ * 0 or an error code
+ * @device_resume: Resumes any transfer on a channel previously
+ * paused. Returns 0 or an error code
+ * @device_terminate_all: Aborts all transfers on a channel. Returns 0
+ * or an error code
* @device_tx_status: poll for transaction completion, the optional
* txstate parameter can be supplied with a pointer to get a
* struct with auxiliary transfer status information, otherwise the call
* will just return a simple status code
* @device_issue_pending: push pending transactions to hardware
- * @device_slave_caps: return the slave channel capabilities
*/
struct dma_device {
@@ -635,14 +631,19 @@ struct dma_device {
int dev_id;
struct device *dev;
+ u32 src_addr_widths;
+ u32 dst_addr_widths;
+ u32 directions;
+ enum dma_residue_granularity residue_granularity;
+
int (*device_alloc_chan_resources)(struct dma_chan *chan);
void (*device_free_chan_resources)(struct dma_chan *chan);
struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
- struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+ struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_xor)(
- struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
+ struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
unsigned int src_cnt, size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_xor_val)(
struct dma_chan *chan, dma_addr_t *src, unsigned int src_cnt,
@@ -674,31 +675,26 @@ struct dma_device {
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
struct dma_chan *chan, struct dma_interleaved_template *xt,
unsigned long flags);
- int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- unsigned long arg);
+
+ int (*device_config)(struct dma_chan *chan,
+ struct dma_slave_config *config);
+ int (*device_pause)(struct dma_chan *chan);
+ int (*device_resume)(struct dma_chan *chan);
+ int (*device_terminate_all)(struct dma_chan *chan);
enum dma_status (*device_tx_status)(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate);
void (*device_issue_pending)(struct dma_chan *chan);
- int (*device_slave_caps)(struct dma_chan *chan, struct dma_slave_caps *caps);
};
-static inline int dmaengine_device_control(struct dma_chan *chan,
- enum dma_ctrl_cmd cmd,
- unsigned long arg)
-{
- if (chan->device->device_control)
- return chan->device->device_control(chan, cmd, arg);
-
- return -ENOSYS;
-}
-
static inline int dmaengine_slave_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
- return dmaengine_device_control(chan, DMA_SLAVE_CONFIG,
- (unsigned long)config);
+ if (chan->device->device_config)
+ return chan->device->device_config(chan, config);
+
+ return -ENOSYS;
}
static inline bool is_slave_direction(enum dma_transfer_direction direction)
@@ -765,34 +761,28 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg(
src_sg, src_nents, flags);
}
-static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
-{
- if (!chan || !caps)
- return -EINVAL;
-
- /* check if the channel supports slave transactions */
- if (!test_bit(DMA_SLAVE, chan->device->cap_mask.bits))
- return -ENXIO;
-
- if (chan->device->device_slave_caps)
- return chan->device->device_slave_caps(chan, caps);
-
- return -ENXIO;
-}
-
static inline int dmaengine_terminate_all(struct dma_chan *chan)
{
- return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
+ if (chan->device->device_terminate_all)
+ return chan->device->device_terminate_all(chan);
+
+ return -ENOSYS;
}
static inline int dmaengine_pause(struct dma_chan *chan)
{
- return dmaengine_device_control(chan, DMA_PAUSE, 0);
+ if (chan->device->device_pause)
+ return chan->device->device_pause(chan);
+
+ return -ENOSYS;
}
static inline int dmaengine_resume(struct dma_chan *chan)
{
- return dmaengine_device_control(chan, DMA_RESUME, 0);
+ if (chan->device->device_resume)
+ return chan->device->device_resume(chan);
+
+ return -ENOSYS;
}
static inline enum dma_status dmaengine_tx_status(struct dma_chan *chan,
@@ -1059,6 +1049,7 @@ struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
const char *name);
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
void dma_release_channel(struct dma_chan *chan);
+int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
#else
static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
{
@@ -1093,6 +1084,11 @@ static inline struct dma_chan *dma_request_slave_channel(struct device *dev,
static inline void dma_release_channel(struct dma_chan *chan)
{
}
+static inline int dma_get_slave_caps(struct dma_chan *chan,
+ struct dma_slave_caps *caps)
+{
+ return -ENXIO;
+}
#endif
/* --- DMA device --- */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a5a303e8a33c..b4d71b5e1ff2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -51,6 +51,7 @@ struct swap_info_struct;
struct seq_file;
struct workqueue_struct;
struct iov_iter;
+struct vm_fault;
extern void __init inode_init(void);
extern void __init inode_init_early(void);
@@ -361,8 +362,6 @@ struct address_space_operations {
int (*releasepage) (struct page *, gfp_t);
void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, loff_t offset);
- int (*get_xip_mem)(struct address_space *, pgoff_t, int,
- void **, unsigned long *);
/*
* migrate the contents of a page to the specified target. If
* migrate_mode is MIGRATE_ASYNC, it must not block.
@@ -1674,6 +1673,11 @@ struct super_operations {
#define S_IMA 1024 /* Inode has an associated IMA struct */
#define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */
#define S_NOSEC 4096 /* no suid or xattr security attributes */
+#ifdef CONFIG_FS_DAX
+#define S_DAX 8192 /* Direct Access, avoiding the page cache */
+#else
+#define S_DAX 0 /* Make all the DAX code disappear */
+#endif
/*
* Note that nosuid etc flags are inode-specific: setting some file-system
@@ -1711,6 +1715,7 @@ struct super_operations {
#define IS_IMA(inode) ((inode)->i_flags & S_IMA)
#define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT)
#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
+#define IS_DAX(inode) ((inode)->i_flags & S_DAX)
#define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
(inode)->i_rdev == WHITEOUT_DEV)
@@ -1782,8 +1787,12 @@ struct super_operations {
#define __I_DIO_WAKEUP 9
#define I_DIO_WAKEUP (1 << I_DIO_WAKEUP)
#define I_LINKABLE (1 << 10)
+#define I_DIRTY_TIME (1 << 11)
+#define __I_DIRTY_TIME_EXPIRED 12
+#define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED)
#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
+#define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)
extern void __mark_inode_dirty(struct inode *, int);
static inline void mark_inode_dirty(struct inode *inode)
@@ -1946,6 +1955,7 @@ extern int current_umask(void);
extern void ihold(struct inode * inode);
extern void iput(struct inode *);
+extern int generic_update_time(struct inode *, struct timespec *, int);
static inline struct inode *file_inode(const struct file *f)
{
@@ -2133,6 +2143,7 @@ struct filename {
const char *name; /* pointer to actual string */
const __user char *uptr; /* original userland pointer */
struct audit_names *aname;
+ int refcnt;
bool separate; /* should "name" be freed? */
};
@@ -2154,6 +2165,7 @@ extern int filp_close(struct file *, fl_owner_t id);
extern struct filename *getname_flags(const char __user *, int, int *);
extern struct filename *getname(const char __user *);
extern struct filename *getname_kernel(const char *);
+extern void putname(struct filename *name);
enum {
FILE_CREATED = 1,
@@ -2174,15 +2186,8 @@ extern void __init vfs_caches_init(unsigned long);
extern struct kmem_cache *names_cachep;
-extern void final_putname(struct filename *name);
-
#define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL)
#define __putname(name) kmem_cache_free(names_cachep, (void *)(name))
-#ifndef CONFIG_AUDITSYSCALL
-#define putname(name) final_putname(name)
-#else
-extern void putname(struct filename *name);
-#endif
#ifdef CONFIG_BLOCK
extern int register_blkdev(unsigned int, const char *);
@@ -2489,6 +2494,11 @@ extern struct inode *ilookup(struct super_block *sb, unsigned long ino);
extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *);
extern struct inode * iget_locked(struct super_block *, unsigned long);
+extern struct inode *find_inode_nowait(struct super_block *,
+ unsigned long,
+ int (*match)(struct inode *,
+ unsigned long, void *),
+ void *data);
extern int insert_inode_locked4(struct inode *, unsigned long, int (*test)(struct inode *, void *), void *);
extern int insert_inode_locked(struct inode *);
#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -2545,6 +2555,9 @@ extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t l
extern ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
extern ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
+ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos);
+ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos);
+
/* fs/block_dev.c */
extern ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to);
extern ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from);
@@ -2578,19 +2591,13 @@ extern loff_t fixed_size_llseek(struct file *file, loff_t offset,
extern int generic_file_open(struct inode * inode, struct file * filp);
extern int nonseekable_open(struct inode * inode, struct file * filp);
-#ifdef CONFIG_FS_XIP
-extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len,
- loff_t *ppos);
-extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);
-extern ssize_t xip_file_write(struct file *filp, const char __user *buf,
- size_t len, loff_t *ppos);
-extern int xip_truncate_page(struct address_space *mapping, loff_t from);
-#else
-static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
-{
- return 0;
-}
-#endif
+ssize_t dax_do_io(int rw, struct kiocb *, struct inode *, struct iov_iter *,
+ loff_t, get_block_t, dio_iodone_t, int flags);
+int dax_clear_blocks(struct inode *, sector_t block, long size);
+int dax_zero_page_range(struct inode *, loff_t from, unsigned len, get_block_t);
+int dax_truncate_page(struct inode *, loff_t from, get_block_t);
+int dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t);
+#define dax_mkwrite(vma, vmf, gb) dax_fault(vma, vmf, gb)
#ifdef CONFIG_BLOCK
typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
@@ -2747,6 +2754,11 @@ extern int generic_show_options(struct seq_file *m, struct dentry *root);
extern void save_mount_options(struct super_block *sb, char *options);
extern void replace_mount_options(struct super_block *sb, char *options);
+static inline bool io_is_direct(struct file *filp)
+{
+ return (filp->f_flags & O_DIRECT) || IS_DAX(file_inode(filp));
+}
+
static inline ino_t parent_ino(struct dentry *dentry)
{
ino_t res;
diff --git a/include/linux/fs_pin.h b/include/linux/fs_pin.h
index f66525e72ccf..9dc4e0384bfb 100644
--- a/include/linux/fs_pin.h
+++ b/include/linux/fs_pin.h
@@ -1,17 +1,22 @@
-#include <linux/fs.h>
+#include <linux/wait.h>
struct fs_pin {
- atomic_long_t count;
- union {
- struct {
- struct hlist_node s_list;
- struct hlist_node m_list;
- };
- struct rcu_head rcu;
- };
+ wait_queue_head_t wait;
+ int done;
+ struct hlist_node s_list;
+ struct hlist_node m_list;
void (*kill)(struct fs_pin *);
};
-void pin_put(struct fs_pin *);
+struct vfsmount;
+
+static inline void init_fs_pin(struct fs_pin *p, void (*kill)(struct fs_pin *))
+{
+ init_waitqueue_head(&p->wait);
+ p->kill = kill;
+}
+
void pin_remove(struct fs_pin *);
+void pin_insert_group(struct fs_pin *, struct vfsmount *, struct hlist_head *);
void pin_insert(struct fs_pin *, struct vfsmount *);
+void pin_kill(struct fs_pin *);
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index bb9840fd1e18..464f33814a94 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -250,17 +250,29 @@ void host1x_job_unpin(struct host1x_job *job);
struct host1x_device;
struct host1x_driver {
+ struct device_driver driver;
+
const struct of_device_id *subdevs;
struct list_head list;
- const char *name;
int (*probe)(struct host1x_device *device);
int (*remove)(struct host1x_device *device);
+ void (*shutdown)(struct host1x_device *device);
};
-int host1x_driver_register(struct host1x_driver *driver);
+static inline struct host1x_driver *
+to_host1x_driver(struct device_driver *driver)
+{
+ return container_of(driver, struct host1x_driver, driver);
+}
+
+int host1x_driver_register_full(struct host1x_driver *driver,
+ struct module *owner);
void host1x_driver_unregister(struct host1x_driver *driver);
+#define host1x_driver_register(driver) \
+ host1x_driver_register_full(driver, THIS_MODULE)
+
struct host1x_device {
struct host1x_driver *driver;
struct list_head list;
@@ -272,6 +284,8 @@ struct host1x_device {
struct mutex clients_lock;
struct list_head clients;
+
+ bool registered;
};
static inline struct host1x_device *to_host1x_device(struct device *dev)
diff --git a/include/linux/irqchip/irq-omap-intc.h b/include/linux/irqchip/irq-omap-intc.h
index e06b370cfc0d..2e3d1afeb674 100644
--- a/include/linux/irqchip/irq-omap-intc.h
+++ b/include/linux/irqchip/irq-omap-intc.h
@@ -18,9 +18,7 @@
#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H
#define __INCLUDE_LINUX_IRQCHIP_IRQ_OMAP_INTC_H
-void omap2_init_irq(void);
void omap3_init_irq(void);
-void ti81xx_init_irq(void);
int omap_irq_pending(void);
void omap_intc_save_context(void);
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 9d957b7ae095..e60a745ac198 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -1,6 +1,19 @@
#ifndef LINUX_KEXEC_H
#define LINUX_KEXEC_H
+#define IND_DESTINATION_BIT 0
+#define IND_INDIRECTION_BIT 1
+#define IND_DONE_BIT 2
+#define IND_SOURCE_BIT 3
+
+#define IND_DESTINATION (1 << IND_DESTINATION_BIT)
+#define IND_INDIRECTION (1 << IND_INDIRECTION_BIT)
+#define IND_DONE (1 << IND_DONE_BIT)
+#define IND_SOURCE (1 << IND_SOURCE_BIT)
+#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
+
+#if !defined(__ASSEMBLY__)
+
#include <uapi/linux/kexec.h>
#ifdef CONFIG_KEXEC
@@ -64,10 +77,6 @@
*/
typedef unsigned long kimage_entry_t;
-#define IND_DESTINATION 0x1
-#define IND_INDIRECTION 0x2
-#define IND_DONE 0x4
-#define IND_SOURCE 0x8
struct kexec_segment {
/*
@@ -122,8 +131,6 @@ struct kimage {
kimage_entry_t *entry;
kimage_entry_t *last_entry;
- unsigned long destination;
-
unsigned long start;
struct page *control_code_page;
struct page *swap_page;
@@ -313,4 +320,7 @@ struct task_struct;
static inline void crash_kexec(struct pt_regs *regs) { }
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
#endif /* CONFIG_KEXEC */
+
+#endif /* !defined(__ASSEBMLY__) */
+
#endif /* LINUX_KEXEC_H */
diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h
index 495203ff221c..acd5b12565cc 100644
--- a/include/linux/lguest_launcher.h
+++ b/include/linux/lguest_launcher.h
@@ -8,52 +8,13 @@
*
* The Guest needs devices to do anything useful. Since we don't let it touch
* real devices (think of the damage it could do!) we provide virtual devices.
- * We could emulate a PCI bus with various devices on it, but that is a fairly
- * complex burden for the Host and suboptimal for the Guest, so we have our own
- * simple lguest bus and we use "virtio" drivers. These drivers need a set of
- * routines from us which will actually do the virtual I/O, but they handle all
- * the net/block/console stuff themselves. This means that if we want to add
- * a new device, we simply need to write a new virtio driver and create support
- * for it in the Launcher: this code won't need to change.
+ * We emulate a PCI bus with virtio devices on it; we used to have our own
+ * lguest bus which was far simpler, but this tests the virtio 1.0 standard.
*
* Virtio devices are also used by kvm, so we can simply reuse their optimized
* device drivers. And one day when everyone uses virtio, my plan will be
* complete. Bwahahahah!
- *
- * Devices are described by a simplified ID, a status byte, and some "config"
- * bytes which describe this device's configuration. This is placed by the
- * Launcher just above the top of physical memory:
- */
-struct lguest_device_desc {
- /* The device type: console, network, disk etc. Type 0 terminates. */
- __u8 type;
- /* The number of virtqueues (first in config array) */
- __u8 num_vq;
- /*
- * The number of bytes of feature bits. Multiply by 2: one for host
- * features and one for Guest acknowledgements.
- */
- __u8 feature_len;
- /* The number of bytes of the config array after virtqueues. */
- __u8 config_len;
- /* A status byte, written by the Guest. */
- __u8 status;
- __u8 config[0];
-};
-
-/*D:135
- * This is how we expect the device configuration field for a virtqueue
- * to be laid out in config space.
*/
-struct lguest_vqconfig {
- /* The number of entries in the virtio_ring */
- __u16 num;
- /* The interrupt we get when something happens. */
- __u16 irq;
- /* The page number of the virtio ring for this device. */
- __u32 pfn;
-};
-/*:*/
/* Write command first word is a request. */
enum lguest_req
@@ -62,12 +23,22 @@ enum lguest_req
LHREQ_GETDMA, /* No longer used */
LHREQ_IRQ, /* + irq */
LHREQ_BREAK, /* No longer used */
- LHREQ_EVENTFD, /* + address, fd. */
+ LHREQ_EVENTFD, /* No longer used. */
+ LHREQ_GETREG, /* + offset within struct pt_regs (then read value). */
+ LHREQ_SETREG, /* + offset within struct pt_regs, value. */
+ LHREQ_TRAP, /* + trap number to deliver to guest. */
};
/*
- * The alignment to use between consumer and producer parts of vring.
- * x86 pagesize for historical reasons.
+ * This is what read() of the lguest fd populates. trap ==
+ * LGUEST_TRAP_ENTRY for an LHCALL_NOTIFY (addr is the
+ * argument), 14 for a page fault in the MMIO region (addr is
+ * the trap address, insn is the instruction), or 13 for a GPF
+ * (insn is the instruction).
*/
-#define LGUEST_VRING_ALIGN 4096
+struct lguest_pending {
+ __u8 trap;
+ __u8 insn[7];
+ __u32 addr;
+};
#endif /* _LINUX_LGUEST_LAUNCHER */
diff --git a/include/linux/lockref.h b/include/linux/lockref.h
index 4bfde0e99ed5..b10b122dd099 100644
--- a/include/linux/lockref.h
+++ b/include/linux/lockref.h
@@ -28,12 +28,13 @@ struct lockref {
#endif
struct {
spinlock_t lock;
- unsigned int count;
+ int count;
};
};
};
extern void lockref_get(struct lockref *);
+extern int lockref_put_return(struct lockref *);
extern int lockref_get_not_zero(struct lockref *);
extern int lockref_get_or_lock(struct lockref *);
extern int lockref_put_or_lock(struct lockref *);
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 81589d176ae8..dfabd6db7ddf 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -124,10 +124,27 @@ enum {
#define AXP288_PMIC_ADC_H 0x56
#define AXP288_PMIC_ADC_L 0x57
#define AXP288_ADC_TS_PIN_CTRL 0x84
-
#define AXP288_PMIC_ADC_EN 0x84
-#define AXP288_FG_TUNE5 0xed
+/* Fuel Gauge */
+#define AXP288_FG_RDC1_REG 0xba
+#define AXP288_FG_RDC0_REG 0xbb
+#define AXP288_FG_OCVH_REG 0xbc
+#define AXP288_FG_OCVL_REG 0xbd
+#define AXP288_FG_OCV_CURVE_REG 0xc0
+#define AXP288_FG_DES_CAP1_REG 0xe0
+#define AXP288_FG_DES_CAP0_REG 0xe1
+#define AXP288_FG_CC_MTR1_REG 0xe2
+#define AXP288_FG_CC_MTR0_REG 0xe3
+#define AXP288_FG_OCV_CAP_REG 0xe4
+#define AXP288_FG_CC_CAP_REG 0xe5
+#define AXP288_FG_LOW_CAP_REG 0xe6
+#define AXP288_FG_TUNE0 0xe8
+#define AXP288_FG_TUNE1 0xe9
+#define AXP288_FG_TUNE2 0xea
+#define AXP288_FG_TUNE3 0xeb
+#define AXP288_FG_TUNE4 0xec
+#define AXP288_FG_TUNE5 0xed
/* Regulators IDs */
enum {
@@ -236,4 +253,26 @@ struct axp20x_dev {
const struct regmap_irq_chip *regmap_irq_chip;
};
+#define BATTID_LEN 64
+#define OCV_CURVE_SIZE 32
+#define MAX_THERM_CURVE_SIZE 25
+#define PD_DEF_MIN_TEMP 0
+#define PD_DEF_MAX_TEMP 55
+
+struct axp20x_fg_pdata {
+ char battid[BATTID_LEN + 1];
+ int design_cap;
+ int min_volt;
+ int max_volt;
+ int max_temp;
+ int min_temp;
+ int cap1;
+ int cap0;
+ int rdc1;
+ int rdc0;
+ int ocv_curve[OCV_CURVE_SIZE];
+ int tcsz;
+ int thermistor_curve[MAX_THERM_CURVE_SIZE][2];
+};
+
#endif /* __LINUX_MFD_AXP20X_H */
diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h
index b92a3262f8f6..79f4d822ba13 100644
--- a/include/linux/mfd/da9063/core.h
+++ b/include/linux/mfd/da9063/core.h
@@ -36,6 +36,7 @@ enum da9063_models {
enum da9063_variant_codes {
PMIC_DA9063_AD = 0x3,
PMIC_DA9063_BB = 0x5,
+ PMIC_DA9063_CA = 0x6,
};
/* Interrupts */
diff --git a/include/linux/mfd/da9150/core.h b/include/linux/mfd/da9150/core.h
new file mode 100644
index 000000000000..76e668933a77
--- /dev/null
+++ b/include/linux/mfd/da9150/core.h
@@ -0,0 +1,68 @@
+/*
+ * DA9150 MFD Driver - Core Data
+ *
+ * Copyright (c) 2014 Dialog Semiconductor
+ *
+ * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __DA9150_CORE_H
+#define __DA9150_CORE_H
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+
+/* I2C address paging */
+#define DA9150_REG_PAGE_SHIFT 8
+#define DA9150_REG_PAGE_MASK 0xFF
+
+/* IRQs */
+#define DA9150_NUM_IRQ_REGS 4
+#define DA9150_IRQ_VBUS 0
+#define DA9150_IRQ_CHG 1
+#define DA9150_IRQ_TCLASS 2
+#define DA9150_IRQ_TJUNC 3
+#define DA9150_IRQ_VFAULT 4
+#define DA9150_IRQ_CONF 5
+#define DA9150_IRQ_DAT 6
+#define DA9150_IRQ_DTYPE 7
+#define DA9150_IRQ_ID 8
+#define DA9150_IRQ_ADP 9
+#define DA9150_IRQ_SESS_END 10
+#define DA9150_IRQ_SESS_VLD 11
+#define DA9150_IRQ_FG 12
+#define DA9150_IRQ_GP 13
+#define DA9150_IRQ_TBAT 14
+#define DA9150_IRQ_GPIOA 15
+#define DA9150_IRQ_GPIOB 16
+#define DA9150_IRQ_GPIOC 17
+#define DA9150_IRQ_GPIOD 18
+#define DA9150_IRQ_GPADC 19
+#define DA9150_IRQ_WKUP 20
+
+struct da9150_pdata {
+ int irq_base;
+};
+
+struct da9150 {
+ struct device *dev;
+ struct regmap *regmap;
+ struct regmap_irq_chip_data *regmap_irq_data;
+ int irq;
+ int irq_base;
+};
+
+/* Device I/O */
+u8 da9150_reg_read(struct da9150 *da9150, u16 reg);
+void da9150_reg_write(struct da9150 *da9150, u16 reg, u8 val);
+void da9150_set_bits(struct da9150 *da9150, u16 reg, u8 mask, u8 val);
+
+void da9150_bulk_read(struct da9150 *da9150, u16 reg, int count, u8 *buf);
+void da9150_bulk_write(struct da9150 *da9150, u16 reg, int count, const u8 *buf);
+#endif /* __DA9150_CORE_H */
diff --git a/include/linux/mfd/da9150/registers.h b/include/linux/mfd/da9150/registers.h
new file mode 100644
index 000000000000..27ca6ee4d840
--- /dev/null
+++ b/include/linux/mfd/da9150/registers.h
@@ -0,0 +1,1155 @@
+/*
+ * DA9150 MFD Driver - Registers
+ *
+ * Copyright (c) 2014 Dialog Semiconductor
+ *
+ * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __DA9150_REGISTERS_H
+#define __DA9150_REGISTERS_H
+
+#include <linux/bitops.h>
+
+/* Registers */
+#define DA9150_PAGE_CON 0x000
+#define DA9150_STATUS_A 0x068
+#define DA9150_STATUS_B 0x069
+#define DA9150_STATUS_C 0x06A
+#define DA9150_STATUS_D 0x06B
+#define DA9150_STATUS_E 0x06C
+#define DA9150_STATUS_F 0x06D
+#define DA9150_STATUS_G 0x06E
+#define DA9150_STATUS_H 0x06F
+#define DA9150_STATUS_I 0x070
+#define DA9150_STATUS_J 0x071
+#define DA9150_STATUS_K 0x072
+#define DA9150_STATUS_L 0x073
+#define DA9150_STATUS_N 0x074
+#define DA9150_FAULT_LOG_A 0x076
+#define DA9150_FAULT_LOG_B 0x077
+#define DA9150_EVENT_E 0x078
+#define DA9150_EVENT_F 0x079
+#define DA9150_EVENT_G 0x07A
+#define DA9150_EVENT_H 0x07B
+#define DA9150_IRQ_MASK_E 0x07C
+#define DA9150_IRQ_MASK_F 0x07D
+#define DA9150_IRQ_MASK_G 0x07E
+#define DA9150_IRQ_MASK_H 0x07F
+#define DA9150_PAGE_CON_1 0x080
+#define DA9150_CONFIG_A 0x0E0
+#define DA9150_CONFIG_B 0x0E1
+#define DA9150_CONFIG_C 0x0E2
+#define DA9150_CONFIG_D 0x0E3
+#define DA9150_CONFIG_E 0x0E4
+#define DA9150_CONTROL_A 0x0E5
+#define DA9150_CONTROL_B 0x0E6
+#define DA9150_CONTROL_C 0x0E7
+#define DA9150_GPIO_A_B 0x0E8
+#define DA9150_GPIO_C_D 0x0E9
+#define DA9150_GPIO_MODE_CONT 0x0EA
+#define DA9150_GPIO_CTRL_B 0x0EB
+#define DA9150_GPIO_CTRL_A 0x0EC
+#define DA9150_GPIO_CTRL_C 0x0ED
+#define DA9150_GPIO_CFG_A 0x0EE
+#define DA9150_GPIO_CFG_B 0x0EF
+#define DA9150_GPIO_CFG_C 0x0F0
+#define DA9150_GPADC_MAN 0x0F2
+#define DA9150_GPADC_RES_A 0x0F4
+#define DA9150_GPADC_RES_B 0x0F5
+#define DA9150_PAGE_CON_2 0x100
+#define DA9150_OTP_CONT_SHARED 0x101
+#define DA9150_INTERFACE_SHARED 0x105
+#define DA9150_CONFIG_A_SHARED 0x106
+#define DA9150_CONFIG_D_SHARED 0x109
+#define DA9150_ADETVB_CFG_C 0x150
+#define DA9150_ADETD_STAT 0x151
+#define DA9150_ADET_CMPSTAT 0x152
+#define DA9150_ADET_CTRL_A 0x153
+#define DA9150_ADETVB_CFG_B 0x154
+#define DA9150_ADETVB_CFG_A 0x155
+#define DA9150_ADETAC_CFG_A 0x156
+#define DA9150_ADDETAC_CFG_B 0x157
+#define DA9150_ADETAC_CFG_C 0x158
+#define DA9150_ADETAC_CFG_D 0x159
+#define DA9150_ADETVB_CFG_D 0x15A
+#define DA9150_ADETID_CFG_A 0x15B
+#define DA9150_ADET_RID_PT_CHG_H 0x15C
+#define DA9150_ADET_RID_PT_CHG_L 0x15D
+#define DA9150_PPR_TCTR_B 0x160
+#define DA9150_PPR_BKCTRL_A 0x163
+#define DA9150_PPR_BKCFG_A 0x164
+#define DA9150_PPR_BKCFG_B 0x165
+#define DA9150_PPR_CHGCTRL_A 0x166
+#define DA9150_PPR_CHGCTRL_B 0x167
+#define DA9150_PPR_CHGCTRL_C 0x168
+#define DA9150_PPR_TCTR_A 0x169
+#define DA9150_PPR_CHGCTRL_D 0x16A
+#define DA9150_PPR_CHGCTRL_E 0x16B
+#define DA9150_PPR_CHGCTRL_F 0x16C
+#define DA9150_PPR_CHGCTRL_G 0x16D
+#define DA9150_PPR_CHGCTRL_H 0x16E
+#define DA9150_PPR_CHGCTRL_I 0x16F
+#define DA9150_PPR_CHGCTRL_J 0x170
+#define DA9150_PPR_CHGCTRL_K 0x171
+#define DA9150_PPR_CHGCTRL_L 0x172
+#define DA9150_PPR_CHGCTRL_M 0x173
+#define DA9150_PPR_THYST_A 0x174
+#define DA9150_PPR_THYST_B 0x175
+#define DA9150_PPR_THYST_C 0x176
+#define DA9150_PPR_THYST_D 0x177
+#define DA9150_PPR_THYST_E 0x178
+#define DA9150_PPR_THYST_F 0x179
+#define DA9150_PPR_THYST_G 0x17A
+#define DA9150_PAGE_CON_3 0x180
+#define DA9150_PAGE_CON_4 0x200
+#define DA9150_PAGE_CON_5 0x280
+#define DA9150_PAGE_CON_6 0x300
+#define DA9150_COREBTLD_STAT_A 0x302
+#define DA9150_COREBTLD_CTRL_A 0x303
+#define DA9150_CORE_CONFIG_A 0x304
+#define DA9150_CORE_CONFIG_C 0x305
+#define DA9150_CORE_CONFIG_B 0x306
+#define DA9150_CORE_CFG_DATA_A 0x307
+#define DA9150_CORE_CFG_DATA_B 0x308
+#define DA9150_CORE_CMD_A 0x309
+#define DA9150_CORE_DATA_A 0x30A
+#define DA9150_CORE_DATA_B 0x30B
+#define DA9150_CORE_DATA_C 0x30C
+#define DA9150_CORE_DATA_D 0x30D
+#define DA9150_CORE2WIRE_STAT_A 0x310
+#define DA9150_CORE2WIRE_CTRL_A 0x311
+#define DA9150_FW_CTRL_A 0x312
+#define DA9150_FW_CTRL_C 0x313
+#define DA9150_FW_CTRL_D 0x314
+#define DA9150_FG_CTRL_A 0x315
+#define DA9150_FG_CTRL_B 0x316
+#define DA9150_FW_CTRL_E 0x317
+#define DA9150_FW_CTRL_B 0x318
+#define DA9150_GPADC_CMAN 0x320
+#define DA9150_GPADC_CRES_A 0x322
+#define DA9150_GPADC_CRES_B 0x323
+#define DA9150_CC_CFG_A 0x328
+#define DA9150_CC_CFG_B 0x329
+#define DA9150_CC_ICHG_RES_A 0x32A
+#define DA9150_CC_ICHG_RES_B 0x32B
+#define DA9150_CC_IAVG_RES_A 0x32C
+#define DA9150_CC_IAVG_RES_B 0x32D
+#define DA9150_TAUX_CTRL_A 0x330
+#define DA9150_TAUX_RELOAD_H 0x332
+#define DA9150_TAUX_RELOAD_L 0x333
+#define DA9150_TAUX_VALUE_H 0x334
+#define DA9150_TAUX_VALUE_L 0x335
+#define DA9150_AUX_DATA_0 0x338
+#define DA9150_AUX_DATA_1 0x339
+#define DA9150_AUX_DATA_2 0x33A
+#define DA9150_AUX_DATA_3 0x33B
+#define DA9150_BIF_CTRL 0x340
+#define DA9150_TBAT_CTRL_A 0x342
+#define DA9150_TBAT_CTRL_B 0x343
+#define DA9150_TBAT_RES_A 0x344
+#define DA9150_TBAT_RES_B 0x345
+
+/* DA9150_PAGE_CON = 0x000 */
+#define DA9150_PAGE_SHIFT 0
+#define DA9150_PAGE_MASK (0x3f << 0)
+#define DA9150_I2C_PAGE_SHIFT 1
+#define DA9150_I2C_PAGE_MASK (0x1f << 1)
+#define DA9150_WRITE_MODE_SHIFT 6
+#define DA9150_WRITE_MODE_MASK BIT(6)
+#define DA9150_REVERT_SHIFT 7
+#define DA9150_REVERT_MASK BIT(7)
+
+/* DA9150_STATUS_A = 0x068 */
+#define DA9150_WKUP_STAT_SHIFT 2
+#define DA9150_WKUP_STAT_MASK (0x0f << 2)
+#define DA9150_SLEEP_STAT_SHIFT 6
+#define DA9150_SLEEP_STAT_MASK (0x03 << 6)
+
+/* DA9150_STATUS_B = 0x069 */
+#define DA9150_VFAULT_STAT_SHIFT 0
+#define DA9150_VFAULT_STAT_MASK BIT(0)
+#define DA9150_TFAULT_STAT_SHIFT 1
+#define DA9150_TFAULT_STAT_MASK BIT(1)
+
+/* DA9150_STATUS_C = 0x06A */
+#define DA9150_VDD33_STAT_SHIFT 0
+#define DA9150_VDD33_STAT_MASK BIT(0)
+#define DA9150_VDD33_SLEEP_SHIFT 1
+#define DA9150_VDD33_SLEEP_MASK BIT(1)
+#define DA9150_LFOSC_STAT_SHIFT 7
+#define DA9150_LFOSC_STAT_MASK BIT(7)
+
+/* DA9150_STATUS_D = 0x06B */
+#define DA9150_GPIOA_STAT_SHIFT 0
+#define DA9150_GPIOA_STAT_MASK BIT(0)
+#define DA9150_GPIOB_STAT_SHIFT 1
+#define DA9150_GPIOB_STAT_MASK BIT(1)
+#define DA9150_GPIOC_STAT_SHIFT 2
+#define DA9150_GPIOC_STAT_MASK BIT(2)
+#define DA9150_GPIOD_STAT_SHIFT 3
+#define DA9150_GPIOD_STAT_MASK BIT(3)
+
+/* DA9150_STATUS_E = 0x06C */
+#define DA9150_DTYPE_SHIFT 0
+#define DA9150_DTYPE_MASK (0x1f << 0)
+#define DA9150_DTYPE_DT_NIL (0x00 << 0)
+#define DA9150_DTYPE_DT_USB_OTG BIT(0)
+#define DA9150_DTYPE_DT_USB_STD (0x02 << 0)
+#define DA9150_DTYPE_DT_USB_CHG (0x03 << 0)
+#define DA9150_DTYPE_DT_ACA_CHG (0x04 << 0)
+#define DA9150_DTYPE_DT_ACA_OTG (0x05 << 0)
+#define DA9150_DTYPE_DT_ACA_DOC (0x06 << 0)
+#define DA9150_DTYPE_DT_DED_CHG (0x07 << 0)
+#define DA9150_DTYPE_DT_CR5_CHG (0x08 << 0)
+#define DA9150_DTYPE_DT_CR4_CHG (0x0c << 0)
+#define DA9150_DTYPE_DT_PT_CHG (0x11 << 0)
+#define DA9150_DTYPE_DT_NN_ACC (0x16 << 0)
+#define DA9150_DTYPE_DT_NN_CHG (0x17 << 0)
+
+/* DA9150_STATUS_F = 0x06D */
+#define DA9150_SESS_VLD_SHIFT 0
+#define DA9150_SESS_VLD_MASK BIT(0)
+#define DA9150_ID_ERR_SHIFT 1
+#define DA9150_ID_ERR_MASK BIT(1)
+#define DA9150_PT_CHG_SHIFT 2
+#define DA9150_PT_CHG_MASK BIT(2)
+
+/* DA9150_STATUS_G = 0x06E */
+#define DA9150_RID_SHIFT 0
+#define DA9150_RID_MASK (0xff << 0)
+
+/* DA9150_STATUS_H = 0x06F */
+#define DA9150_VBUS_STAT_SHIFT 0
+#define DA9150_VBUS_STAT_MASK (0x07 << 0)
+#define DA9150_VBUS_STAT_OFF (0x00 << 0)
+#define DA9150_VBUS_STAT_WAIT BIT(0)
+#define DA9150_VBUS_STAT_CHG (0x02 << 0)
+#define DA9150_VBUS_TRED_SHIFT 3
+#define DA9150_VBUS_TRED_MASK BIT(3)
+#define DA9150_VBUS_DROP_STAT_SHIFT 4
+#define DA9150_VBUS_DROP_STAT_MASK (0x0f << 4)
+
+/* DA9150_STATUS_I = 0x070 */
+#define DA9150_VBUS_ISET_STAT_SHIFT 0
+#define DA9150_VBUS_ISET_STAT_MASK (0x1f << 0)
+#define DA9150_VBUS_OT_SHIFT 7
+#define DA9150_VBUS_OT_MASK BIT(7)
+
+/* DA9150_STATUS_J = 0x071 */
+#define DA9150_CHG_STAT_SHIFT 0
+#define DA9150_CHG_STAT_MASK (0x0f << 0)
+#define DA9150_CHG_STAT_OFF (0x00 << 0)
+#define DA9150_CHG_STAT_SUSP BIT(0)
+#define DA9150_CHG_STAT_ACT (0x02 << 0)
+#define DA9150_CHG_STAT_PRE (0x03 << 0)
+#define DA9150_CHG_STAT_CC (0x04 << 0)
+#define DA9150_CHG_STAT_CV (0x05 << 0)
+#define DA9150_CHG_STAT_FULL (0x06 << 0)
+#define DA9150_CHG_STAT_TEMP (0x07 << 0)
+#define DA9150_CHG_STAT_TIME (0x08 << 0)
+#define DA9150_CHG_STAT_BAT (0x09 << 0)
+#define DA9150_CHG_TEMP_SHIFT 4
+#define DA9150_CHG_TEMP_MASK (0x07 << 4)
+#define DA9150_CHG_TEMP_UNDER (0x06 << 4)
+#define DA9150_CHG_TEMP_OVER (0x07 << 4)
+#define DA9150_CHG_IEND_STAT_SHIFT 7
+#define DA9150_CHG_IEND_STAT_MASK BIT(7)
+
+/* DA9150_STATUS_K = 0x072 */
+#define DA9150_CHG_IAV_H_SHIFT 0
+#define DA9150_CHG_IAV_H_MASK (0xff << 0)
+
+/* DA9150_STATUS_L = 0x073 */
+#define DA9150_CHG_IAV_L_SHIFT 5
+#define DA9150_CHG_IAV_L_MASK (0x07 << 5)
+
+/* DA9150_STATUS_N = 0x074 */
+#define DA9150_CHG_TIME_SHIFT 1
+#define DA9150_CHG_TIME_MASK BIT(1)
+#define DA9150_CHG_TRED_SHIFT 2
+#define DA9150_CHG_TRED_MASK BIT(2)
+#define DA9150_CHG_TJUNC_CLASS_SHIFT 3
+#define DA9150_CHG_TJUNC_CLASS_MASK (0x07 << 3)
+#define DA9150_CHG_TJUNC_CLASS_6 (0x06 << 3)
+#define DA9150_EBS_STAT_SHIFT 6
+#define DA9150_EBS_STAT_MASK BIT(6)
+#define DA9150_CHG_BAT_REMOVED_SHIFT 7
+#define DA9150_CHG_BAT_REMOVED_MASK BIT(7)
+
+/* DA9150_FAULT_LOG_A = 0x076 */
+#define DA9150_TEMP_FAULT_SHIFT 0
+#define DA9150_TEMP_FAULT_MASK BIT(0)
+#define DA9150_VSYS_FAULT_SHIFT 1
+#define DA9150_VSYS_FAULT_MASK BIT(1)
+#define DA9150_START_FAULT_SHIFT 2
+#define DA9150_START_FAULT_MASK BIT(2)
+#define DA9150_EXT_FAULT_SHIFT 3
+#define DA9150_EXT_FAULT_MASK BIT(3)
+#define DA9150_POR_FAULT_SHIFT 4
+#define DA9150_POR_FAULT_MASK BIT(4)
+
+/* DA9150_FAULT_LOG_B = 0x077 */
+#define DA9150_VBUS_FAULT_SHIFT 0
+#define DA9150_VBUS_FAULT_MASK BIT(0)
+#define DA9150_OTG_FAULT_SHIFT 1
+#define DA9150_OTG_FAULT_MASK BIT(1)
+
+/* DA9150_EVENT_E = 0x078 */
+#define DA9150_E_VBUS_SHIFT 0
+#define DA9150_E_VBUS_MASK BIT(0)
+#define DA9150_E_CHG_SHIFT 1
+#define DA9150_E_CHG_MASK BIT(1)
+#define DA9150_E_TCLASS_SHIFT 2
+#define DA9150_E_TCLASS_MASK BIT(2)
+#define DA9150_E_TJUNC_SHIFT 3
+#define DA9150_E_TJUNC_MASK BIT(3)
+#define DA9150_E_VFAULT_SHIFT 4
+#define DA9150_E_VFAULT_MASK BIT(4)
+#define DA9150_EVENTS_H_SHIFT 5
+#define DA9150_EVENTS_H_MASK BIT(5)
+#define DA9150_EVENTS_G_SHIFT 6
+#define DA9150_EVENTS_G_MASK BIT(6)
+#define DA9150_EVENTS_F_SHIFT 7
+#define DA9150_EVENTS_F_MASK BIT(7)
+
+/* DA9150_EVENT_F = 0x079 */
+#define DA9150_E_CONF_SHIFT 0
+#define DA9150_E_CONF_MASK BIT(0)
+#define DA9150_E_DAT_SHIFT 1
+#define DA9150_E_DAT_MASK BIT(1)
+#define DA9150_E_DTYPE_SHIFT 3
+#define DA9150_E_DTYPE_MASK BIT(3)
+#define DA9150_E_ID_SHIFT 4
+#define DA9150_E_ID_MASK BIT(4)
+#define DA9150_E_ADP_SHIFT 5
+#define DA9150_E_ADP_MASK BIT(5)
+#define DA9150_E_SESS_END_SHIFT 6
+#define DA9150_E_SESS_END_MASK BIT(6)
+#define DA9150_E_SESS_VLD_SHIFT 7
+#define DA9150_E_SESS_VLD_MASK BIT(7)
+
+/* DA9150_EVENT_G = 0x07A */
+#define DA9150_E_FG_SHIFT 0
+#define DA9150_E_FG_MASK BIT(0)
+#define DA9150_E_GP_SHIFT 1
+#define DA9150_E_GP_MASK BIT(1)
+#define DA9150_E_TBAT_SHIFT 2
+#define DA9150_E_TBAT_MASK BIT(2)
+#define DA9150_E_GPIOA_SHIFT 3
+#define DA9150_E_GPIOA_MASK BIT(3)
+#define DA9150_E_GPIOB_SHIFT 4
+#define DA9150_E_GPIOB_MASK BIT(4)
+#define DA9150_E_GPIOC_SHIFT 5
+#define DA9150_E_GPIOC_MASK BIT(5)
+#define DA9150_E_GPIOD_SHIFT 6
+#define DA9150_E_GPIOD_MASK BIT(6)
+#define DA9150_E_GPADC_SHIFT 7
+#define DA9150_E_GPADC_MASK BIT(7)
+
+/* DA9150_EVENT_H = 0x07B */
+#define DA9150_E_WKUP_SHIFT 0
+#define DA9150_E_WKUP_MASK BIT(0)
+
+/* DA9150_IRQ_MASK_E = 0x07C */
+#define DA9150_M_VBUS_SHIFT 0
+#define DA9150_M_VBUS_MASK BIT(0)
+#define DA9150_M_CHG_SHIFT 1
+#define DA9150_M_CHG_MASK BIT(1)
+#define DA9150_M_TJUNC_SHIFT 3
+#define DA9150_M_TJUNC_MASK BIT(3)
+#define DA9150_M_VFAULT_SHIFT 4
+#define DA9150_M_VFAULT_MASK BIT(4)
+
+/* DA9150_IRQ_MASK_F = 0x07D */
+#define DA9150_M_CONF_SHIFT 0
+#define DA9150_M_CONF_MASK BIT(0)
+#define DA9150_M_DAT_SHIFT 1
+#define DA9150_M_DAT_MASK BIT(1)
+#define DA9150_M_DTYPE_SHIFT 3
+#define DA9150_M_DTYPE_MASK BIT(3)
+#define DA9150_M_ID_SHIFT 4
+#define DA9150_M_ID_MASK BIT(4)
+#define DA9150_M_ADP_SHIFT 5
+#define DA9150_M_ADP_MASK BIT(5)
+#define DA9150_M_SESS_END_SHIFT 6
+#define DA9150_M_SESS_END_MASK BIT(6)
+#define DA9150_M_SESS_VLD_SHIFT 7
+#define DA9150_M_SESS_VLD_MASK BIT(7)
+
+/* DA9150_IRQ_MASK_G = 0x07E */
+#define DA9150_M_FG_SHIFT 0
+#define DA9150_M_FG_MASK BIT(0)
+#define DA9150_M_GP_SHIFT 1
+#define DA9150_M_GP_MASK BIT(1)
+#define DA9150_M_TBAT_SHIFT 2
+#define DA9150_M_TBAT_MASK BIT(2)
+#define DA9150_M_GPIOA_SHIFT 3
+#define DA9150_M_GPIOA_MASK BIT(3)
+#define DA9150_M_GPIOB_SHIFT 4
+#define DA9150_M_GPIOB_MASK BIT(4)
+#define DA9150_M_GPIOC_SHIFT 5
+#define DA9150_M_GPIOC_MASK BIT(5)
+#define DA9150_M_GPIOD_SHIFT 6
+#define DA9150_M_GPIOD_MASK BIT(6)
+#define DA9150_M_GPADC_SHIFT 7
+#define DA9150_M_GPADC_MASK BIT(7)
+
+/* DA9150_IRQ_MASK_H = 0x07F */
+#define DA9150_M_WKUP_SHIFT 0
+#define DA9150_M_WKUP_MASK BIT(0)
+
+/* DA9150_PAGE_CON_1 = 0x080 */
+#define DA9150_PAGE_SHIFT 0
+#define DA9150_PAGE_MASK (0x3f << 0)
+#define DA9150_WRITE_MODE_SHIFT 6
+#define DA9150_WRITE_MODE_MASK BIT(6)
+#define DA9150_REVERT_SHIFT 7
+#define DA9150_REVERT_MASK BIT(7)
+
+/* DA9150_CONFIG_A = 0x0E0 */
+#define DA9150_RESET_DUR_SHIFT 0
+#define DA9150_RESET_DUR_MASK (0x03 << 0)
+#define DA9150_RESET_EXT_SHIFT 2
+#define DA9150_RESET_EXT_MASK (0x03 << 2)
+#define DA9150_START_MAX_SHIFT 4
+#define DA9150_START_MAX_MASK (0x03 << 4)
+#define DA9150_PS_WAIT_EN_SHIFT 6
+#define DA9150_PS_WAIT_EN_MASK BIT(6)
+#define DA9150_PS_DISABLE_DIRECT_SHIFT 7
+#define DA9150_PS_DISABLE_DIRECT_MASK BIT(7)
+
+/* DA9150_CONFIG_B = 0x0E1 */
+#define DA9150_VFAULT_ADJ_SHIFT 0
+#define DA9150_VFAULT_ADJ_MASK (0x0f << 0)
+#define DA9150_VFAULT_HYST_SHIFT 4
+#define DA9150_VFAULT_HYST_MASK (0x07 << 4)
+#define DA9150_VFAULT_EN_SHIFT 7
+#define DA9150_VFAULT_EN_MASK BIT(7)
+
+/* DA9150_CONFIG_C = 0x0E2 */
+#define DA9150_VSYS_MIN_SHIFT 3
+#define DA9150_VSYS_MIN_MASK (0x1f << 3)
+
+/* DA9150_CONFIG_D = 0x0E3 */
+#define DA9150_LFOSC_EXT_SHIFT 0
+#define DA9150_LFOSC_EXT_MASK BIT(0)
+#define DA9150_VDD33_DWN_SHIFT 1
+#define DA9150_VDD33_DWN_MASK BIT(1)
+#define DA9150_WKUP_PM_EN_SHIFT 2
+#define DA9150_WKUP_PM_EN_MASK BIT(2)
+#define DA9150_WKUP_CE_SEL_SHIFT 3
+#define DA9150_WKUP_CE_SEL_MASK (0x03 << 3)
+#define DA9150_WKUP_CLK32K_EN_SHIFT 5
+#define DA9150_WKUP_CLK32K_EN_MASK BIT(5)
+#define DA9150_DISABLE_DEL_SHIFT 7
+#define DA9150_DISABLE_DEL_MASK BIT(7)
+
+/* DA9150_CONFIG_E = 0x0E4 */
+#define DA9150_PM_SPKSUP_DIS_SHIFT 0
+#define DA9150_PM_SPKSUP_DIS_MASK BIT(0)
+#define DA9150_PM_MERGE_SHIFT 1
+#define DA9150_PM_MERGE_MASK BIT(1)
+#define DA9150_PM_SR_OFF_SHIFT 2
+#define DA9150_PM_SR_OFF_MASK BIT(2)
+#define DA9150_PM_TIMEOUT_EN_SHIFT 3
+#define DA9150_PM_TIMEOUT_EN_MASK BIT(3)
+#define DA9150_PM_DLY_SEL_SHIFT 4
+#define DA9150_PM_DLY_SEL_MASK (0x07 << 4)
+#define DA9150_PM_OUT_DLY_SEL_SHIFT 7
+#define DA9150_PM_OUT_DLY_SEL_MASK BIT(7)
+
+/* DA9150_CONTROL_A = 0x0E5 */
+#define DA9150_VDD33_SL_SHIFT 0
+#define DA9150_VDD33_SL_MASK BIT(0)
+#define DA9150_VDD33_LPM_SHIFT 1
+#define DA9150_VDD33_LPM_MASK (0x03 << 1)
+#define DA9150_VDD33_EN_SHIFT 3
+#define DA9150_VDD33_EN_MASK BIT(3)
+#define DA9150_GPI_LPM_SHIFT 6
+#define DA9150_GPI_LPM_MASK BIT(6)
+#define DA9150_PM_IF_LPM_SHIFT 7
+#define DA9150_PM_IF_LPM_MASK BIT(7)
+
+/* DA9150_CONTROL_B = 0x0E6 */
+#define DA9150_LPM_SHIFT 0
+#define DA9150_LPM_MASK BIT(0)
+#define DA9150_RESET_SHIFT 1
+#define DA9150_RESET_MASK BIT(1)
+#define DA9150_RESET_USRCONF_EN_SHIFT 2
+#define DA9150_RESET_USRCONF_EN_MASK BIT(2)
+
+/* DA9150_CONTROL_C = 0x0E7 */
+#define DA9150_DISABLE_SHIFT 0
+#define DA9150_DISABLE_MASK BIT(0)
+
+/* DA9150_GPIO_A_B = 0x0E8 */
+#define DA9150_GPIOA_PIN_SHIFT 0
+#define DA9150_GPIOA_PIN_MASK (0x07 << 0)
+#define DA9150_GPIOA_PIN_GPI (0x00 << 0)
+#define DA9150_GPIOA_PIN_GPO_OD BIT(0)
+#define DA9150_GPIOA_TYPE_SHIFT 3
+#define DA9150_GPIOA_TYPE_MASK BIT(3)
+#define DA9150_GPIOB_PIN_SHIFT 4
+#define DA9150_GPIOB_PIN_MASK (0x07 << 4)
+#define DA9150_GPIOB_PIN_GPI (0x00 << 4)
+#define DA9150_GPIOB_PIN_GPO_OD BIT(4)
+#define DA9150_GPIOB_TYPE_SHIFT 7
+#define DA9150_GPIOB_TYPE_MASK BIT(7)
+
+/* DA9150_GPIO_C_D = 0x0E9 */
+#define DA9150_GPIOC_PIN_SHIFT 0
+#define DA9150_GPIOC_PIN_MASK (0x07 << 0)
+#define DA9150_GPIOC_PIN_GPI (0x00 << 0)
+#define DA9150_GPIOC_PIN_GPO_OD BIT(0)
+#define DA9150_GPIOC_TYPE_SHIFT 3
+#define DA9150_GPIOC_TYPE_MASK BIT(3)
+#define DA9150_GPIOD_PIN_SHIFT 4
+#define DA9150_GPIOD_PIN_MASK (0x07 << 4)
+#define DA9150_GPIOD_PIN_GPI (0x00 << 4)
+#define DA9150_GPIOD_PIN_GPO_OD BIT(4)
+#define DA9150_GPIOD_TYPE_SHIFT 7
+#define DA9150_GPIOD_TYPE_MASK BIT(7)
+
+/* DA9150_GPIO_MODE_CONT = 0x0EA */
+#define DA9150_GPIOA_MODE_SHIFT 0
+#define DA9150_GPIOA_MODE_MASK BIT(0)
+#define DA9150_GPIOB_MODE_SHIFT 1
+#define DA9150_GPIOB_MODE_MASK BIT(1)
+#define DA9150_GPIOC_MODE_SHIFT 2
+#define DA9150_GPIOC_MODE_MASK BIT(2)
+#define DA9150_GPIOD_MODE_SHIFT 3
+#define DA9150_GPIOD_MODE_MASK BIT(3)
+#define DA9150_GPIOA_CONT_SHIFT 4
+#define DA9150_GPIOA_CONT_MASK BIT(4)
+#define DA9150_GPIOB_CONT_SHIFT 5
+#define DA9150_GPIOB_CONT_MASK BIT(5)
+#define DA9150_GPIOC_CONT_SHIFT 6
+#define DA9150_GPIOC_CONT_MASK BIT(6)
+#define DA9150_GPIOD_CONT_SHIFT 7
+#define DA9150_GPIOD_CONT_MASK BIT(7)
+
+/* DA9150_GPIO_CTRL_B = 0x0EB */
+#define DA9150_WAKE_PIN_SHIFT 0
+#define DA9150_WAKE_PIN_MASK (0x03 << 0)
+#define DA9150_WAKE_MODE_SHIFT 2
+#define DA9150_WAKE_MODE_MASK BIT(2)
+#define DA9150_WAKE_CONT_SHIFT 3
+#define DA9150_WAKE_CONT_MASK BIT(3)
+#define DA9150_WAKE_DLY_SHIFT 4
+#define DA9150_WAKE_DLY_MASK BIT(4)
+
+/* DA9150_GPIO_CTRL_A = 0x0EC */
+#define DA9150_GPIOA_ANAEN_SHIFT 0
+#define DA9150_GPIOA_ANAEN_MASK BIT(0)
+#define DA9150_GPIOB_ANAEN_SHIFT 1
+#define DA9150_GPIOB_ANAEN_MASK BIT(1)
+#define DA9150_GPIOC_ANAEN_SHIFT 2
+#define DA9150_GPIOC_ANAEN_MASK BIT(2)
+#define DA9150_GPIOD_ANAEN_SHIFT 3
+#define DA9150_GPIOD_ANAEN_MASK BIT(3)
+#define DA9150_GPIO_ANAEN 0x01
+#define DA9150_GPIO_ANAEN_MASK 0x0F
+#define DA9150_CHGLED_PIN_SHIFT 5
+#define DA9150_CHGLED_PIN_MASK (0x07 << 5)
+
+/* DA9150_GPIO_CTRL_C = 0x0ED */
+#define DA9150_CHGBL_DUR_SHIFT 0
+#define DA9150_CHGBL_DUR_MASK (0x03 << 0)
+#define DA9150_CHGBL_DBL_SHIFT 2
+#define DA9150_CHGBL_DBL_MASK BIT(2)
+#define DA9150_CHGBL_FRQ_SHIFT 3
+#define DA9150_CHGBL_FRQ_MASK (0x03 << 3)
+#define DA9150_CHGBL_FLKR_SHIFT 5
+#define DA9150_CHGBL_FLKR_MASK BIT(5)
+
+/* DA9150_GPIO_CFG_A = 0x0EE */
+#define DA9150_CE_LPM_DEB_SHIFT 0
+#define DA9150_CE_LPM_DEB_MASK (0x07 << 0)
+
+/* DA9150_GPIO_CFG_B = 0x0EF */
+#define DA9150_GPIOA_PUPD_SHIFT 0
+#define DA9150_GPIOA_PUPD_MASK BIT(0)
+#define DA9150_GPIOB_PUPD_SHIFT 1
+#define DA9150_GPIOB_PUPD_MASK BIT(1)
+#define DA9150_GPIOC_PUPD_SHIFT 2
+#define DA9150_GPIOC_PUPD_MASK BIT(2)
+#define DA9150_GPIOD_PUPD_SHIFT 3
+#define DA9150_GPIOD_PUPD_MASK BIT(3)
+#define DA9150_GPIO_PUPD_MASK (0xF << 0)
+#define DA9150_GPI_DEB_SHIFT 4
+#define DA9150_GPI_DEB_MASK (0x07 << 4)
+#define DA9150_LPM_EN_SHIFT 7
+#define DA9150_LPM_EN_MASK BIT(7)
+
+/* DA9150_GPIO_CFG_C = 0x0F0 */
+#define DA9150_GPI_V_SHIFT 0
+#define DA9150_GPI_V_MASK BIT(0)
+#define DA9150_VDDIO_INT_SHIFT 1
+#define DA9150_VDDIO_INT_MASK BIT(1)
+#define DA9150_FAULT_PIN_SHIFT 3
+#define DA9150_FAULT_PIN_MASK (0x07 << 3)
+#define DA9150_FAULT_TYPE_SHIFT 6
+#define DA9150_FAULT_TYPE_MASK BIT(6)
+#define DA9150_NIRQ_PUPD_SHIFT 7
+#define DA9150_NIRQ_PUPD_MASK BIT(7)
+
+/* DA9150_GPADC_MAN = 0x0F2 */
+#define DA9150_GPADC_EN_SHIFT 0
+#define DA9150_GPADC_EN_MASK BIT(0)
+#define DA9150_GPADC_MUX_SHIFT 1
+#define DA9150_GPADC_MUX_MASK (0x1f << 1)
+
+/* DA9150_GPADC_RES_A = 0x0F4 */
+#define DA9150_GPADC_RES_H_SHIFT 0
+#define DA9150_GPADC_RES_H_MASK (0xff << 0)
+
+/* DA9150_GPADC_RES_B = 0x0F5 */
+#define DA9150_GPADC_RUN_SHIFT 0
+#define DA9150_GPADC_RUN_MASK BIT(0)
+#define DA9150_GPADC_RES_L_SHIFT 6
+#define DA9150_GPADC_RES_L_MASK (0x03 << 6)
+#define DA9150_GPADC_RES_L_BITS 2
+
+/* DA9150_PAGE_CON_2 = 0x100 */
+#define DA9150_PAGE_SHIFT 0
+#define DA9150_PAGE_MASK (0x3f << 0)
+#define DA9150_WRITE_MODE_SHIFT 6
+#define DA9150_WRITE_MODE_MASK BIT(6)
+#define DA9150_REVERT_SHIFT 7
+#define DA9150_REVERT_MASK BIT(7)
+
+/* DA9150_OTP_CONT_SHARED = 0x101 */
+#define DA9150_PC_DONE_SHIFT 3
+#define DA9150_PC_DONE_MASK BIT(3)
+
+/* DA9150_INTERFACE_SHARED = 0x105 */
+#define DA9150_IF_BASE_ADDR_SHIFT 4
+#define DA9150_IF_BASE_ADDR_MASK (0x0f << 4)
+
+/* DA9150_CONFIG_A_SHARED = 0x106 */
+#define DA9150_NIRQ_VDD_SHIFT 1
+#define DA9150_NIRQ_VDD_MASK BIT(1)
+#define DA9150_NIRQ_PIN_SHIFT 2
+#define DA9150_NIRQ_PIN_MASK BIT(2)
+#define DA9150_NIRQ_TYPE_SHIFT 3
+#define DA9150_NIRQ_TYPE_MASK BIT(3)
+#define DA9150_PM_IF_V_SHIFT 4
+#define DA9150_PM_IF_V_MASK BIT(4)
+#define DA9150_PM_IF_FMP_SHIFT 5
+#define DA9150_PM_IF_FMP_MASK BIT(5)
+#define DA9150_PM_IF_HSM_SHIFT 6
+#define DA9150_PM_IF_HSM_MASK BIT(6)
+
+/* DA9150_CONFIG_D_SHARED = 0x109 */
+#define DA9150_NIRQ_MODE_SHIFT 1
+#define DA9150_NIRQ_MODE_MASK BIT(1)
+
+/* DA9150_ADETVB_CFG_C = 0x150 */
+#define DA9150_TADP_RISE_SHIFT 0
+#define DA9150_TADP_RISE_MASK (0xff << 0)
+
+/* DA9150_ADETD_STAT = 0x151 */
+#define DA9150_DCD_STAT_SHIFT 0
+#define DA9150_DCD_STAT_MASK BIT(0)
+#define DA9150_PCD_STAT_SHIFT 1
+#define DA9150_PCD_STAT_MASK (0x03 << 1)
+#define DA9150_SCD_STAT_SHIFT 3
+#define DA9150_SCD_STAT_MASK (0x03 << 3)
+#define DA9150_DP_STAT_SHIFT 5
+#define DA9150_DP_STAT_MASK BIT(5)
+#define DA9150_DM_STAT_SHIFT 6
+#define DA9150_DM_STAT_MASK BIT(6)
+
+/* DA9150_ADET_CMPSTAT = 0x152 */
+#define DA9150_DP_COMP_SHIFT 1
+#define DA9150_DP_COMP_MASK BIT(1)
+#define DA9150_DM_COMP_SHIFT 2
+#define DA9150_DM_COMP_MASK BIT(2)
+#define DA9150_ADP_SNS_COMP_SHIFT 3
+#define DA9150_ADP_SNS_COMP_MASK BIT(3)
+#define DA9150_ADP_PRB_COMP_SHIFT 4
+#define DA9150_ADP_PRB_COMP_MASK BIT(4)
+#define DA9150_ID_COMP_SHIFT 5
+#define DA9150_ID_COMP_MASK BIT(5)
+
+/* DA9150_ADET_CTRL_A = 0x153 */
+#define DA9150_AID_DAT_SHIFT 0
+#define DA9150_AID_DAT_MASK BIT(0)
+#define DA9150_AID_ID_SHIFT 1
+#define DA9150_AID_ID_MASK BIT(1)
+#define DA9150_AID_TRIG_SHIFT 2
+#define DA9150_AID_TRIG_MASK BIT(2)
+
+/* DA9150_ADETVB_CFG_B = 0x154 */
+#define DA9150_VB_MODE_SHIFT 0
+#define DA9150_VB_MODE_MASK (0x03 << 0)
+#define DA9150_VB_MODE_VB_SESS BIT(0)
+
+#define DA9150_TADP_PRB_SHIFT 2
+#define DA9150_TADP_PRB_MASK BIT(2)
+#define DA9150_DAT_RPD_EXT_SHIFT 5
+#define DA9150_DAT_RPD_EXT_MASK BIT(5)
+#define DA9150_CONF_RPD_SHIFT 6
+#define DA9150_CONF_RPD_MASK BIT(6)
+#define DA9150_CONF_SRP_SHIFT 7
+#define DA9150_CONF_SRP_MASK BIT(7)
+
+/* DA9150_ADETVB_CFG_A = 0x155 */
+#define DA9150_AID_MODE_SHIFT 0
+#define DA9150_AID_MODE_MASK (0x03 << 0)
+#define DA9150_AID_EXT_POL_SHIFT 2
+#define DA9150_AID_EXT_POL_MASK BIT(2)
+
+/* DA9150_ADETAC_CFG_A = 0x156 */
+#define DA9150_ISET_CDP_SHIFT 0
+#define DA9150_ISET_CDP_MASK (0x1f << 0)
+#define DA9150_CONF_DBP_SHIFT 5
+#define DA9150_CONF_DBP_MASK BIT(5)
+
+/* DA9150_ADDETAC_CFG_B = 0x157 */
+#define DA9150_ISET_DCHG_SHIFT 0
+#define DA9150_ISET_DCHG_MASK (0x1f << 0)
+#define DA9150_CONF_GPIOA_SHIFT 5
+#define DA9150_CONF_GPIOA_MASK BIT(5)
+#define DA9150_CONF_GPIOB_SHIFT 6
+#define DA9150_CONF_GPIOB_MASK BIT(6)
+#define DA9150_AID_VB_SHIFT 7
+#define DA9150_AID_VB_MASK BIT(7)
+
+/* DA9150_ADETAC_CFG_C = 0x158 */
+#define DA9150_ISET_DEF_SHIFT 0
+#define DA9150_ISET_DEF_MASK (0x1f << 0)
+#define DA9150_CONF_MODE_SHIFT 5
+#define DA9150_CONF_MODE_MASK (0x03 << 5)
+#define DA9150_AID_CR_DIS_SHIFT 7
+#define DA9150_AID_CR_DIS_MASK BIT(7)
+
+/* DA9150_ADETAC_CFG_D = 0x159 */
+#define DA9150_ISET_UNIT_SHIFT 0
+#define DA9150_ISET_UNIT_MASK (0x1f << 0)
+#define DA9150_AID_UNCLAMP_SHIFT 5
+#define DA9150_AID_UNCLAMP_MASK BIT(5)
+
+/* DA9150_ADETVB_CFG_D = 0x15A */
+#define DA9150_ID_MODE_SHIFT 0
+#define DA9150_ID_MODE_MASK (0x03 << 0)
+#define DA9150_DAT_MODE_SHIFT 2
+#define DA9150_DAT_MODE_MASK (0x0f << 2)
+#define DA9150_DAT_SWP_SHIFT 6
+#define DA9150_DAT_SWP_MASK BIT(6)
+#define DA9150_DAT_CLAMP_EXT_SHIFT 7
+#define DA9150_DAT_CLAMP_EXT_MASK BIT(7)
+
+/* DA9150_ADETID_CFG_A = 0x15B */
+#define DA9150_TID_POLL_SHIFT 0
+#define DA9150_TID_POLL_MASK (0x07 << 0)
+#define DA9150_RID_CONV_SHIFT 3
+#define DA9150_RID_CONV_MASK BIT(3)
+
+/* DA9150_ADET_RID_PT_CHG_H = 0x15C */
+#define DA9150_RID_PT_CHG_H_SHIFT 0
+#define DA9150_RID_PT_CHG_H_MASK (0xff << 0)
+
+/* DA9150_ADET_RID_PT_CHG_L = 0x15D */
+#define DA9150_RID_PT_CHG_L_SHIFT 6
+#define DA9150_RID_PT_CHG_L_MASK (0x03 << 6)
+
+/* DA9150_PPR_TCTR_B = 0x160 */
+#define DA9150_CHG_TCTR_VAL_SHIFT 0
+#define DA9150_CHG_TCTR_VAL_MASK (0xff << 0)
+
+/* DA9150_PPR_BKCTRL_A = 0x163 */
+#define DA9150_VBUS_MODE_SHIFT 0
+#define DA9150_VBUS_MODE_MASK (0x03 << 0)
+#define DA9150_VBUS_MODE_CHG BIT(0)
+#define DA9150_VBUS_MODE_OTG (0x02 << 0)
+#define DA9150_VBUS_LPM_SHIFT 2
+#define DA9150_VBUS_LPM_MASK (0x03 << 2)
+#define DA9150_VBUS_SUSP_SHIFT 4
+#define DA9150_VBUS_SUSP_MASK BIT(4)
+#define DA9150_VBUS_PWM_SHIFT 5
+#define DA9150_VBUS_PWM_MASK BIT(5)
+#define DA9150_VBUS_ISO_SHIFT 6
+#define DA9150_VBUS_ISO_MASK BIT(6)
+#define DA9150_VBUS_LDO_SHIFT 7
+#define DA9150_VBUS_LDO_MASK BIT(7)
+
+/* DA9150_PPR_BKCFG_A = 0x164 */
+#define DA9150_VBUS_ISET_SHIFT 0
+#define DA9150_VBUS_ISET_MASK (0x1f << 0)
+#define DA9150_VBUS_IMAX_SHIFT 5
+#define DA9150_VBUS_IMAX_MASK BIT(5)
+#define DA9150_VBUS_IOTG_SHIFT 6
+#define DA9150_VBUS_IOTG_MASK (0x03 << 6)
+
+/* DA9150_PPR_BKCFG_B = 0x165 */
+#define DA9150_VBUS_DROP_SHIFT 0
+#define DA9150_VBUS_DROP_MASK (0x0f << 0)
+#define DA9150_VBUS_FAULT_DIS_SHIFT 6
+#define DA9150_VBUS_FAULT_DIS_MASK BIT(6)
+#define DA9150_OTG_FAULT_DIS_SHIFT 7
+#define DA9150_OTG_FAULT_DIS_MASK BIT(7)
+
+/* DA9150_PPR_CHGCTRL_A = 0x166 */
+#define DA9150_CHG_EN_SHIFT 0
+#define DA9150_CHG_EN_MASK BIT(0)
+
+/* DA9150_PPR_CHGCTRL_B = 0x167 */
+#define DA9150_CHG_VBAT_SHIFT 0
+#define DA9150_CHG_VBAT_MASK (0x1f << 0)
+#define DA9150_CHG_VDROP_SHIFT 6
+#define DA9150_CHG_VDROP_MASK (0x03 << 6)
+
+/* DA9150_PPR_CHGCTRL_C = 0x168 */
+#define DA9150_CHG_VFAULT_SHIFT 0
+#define DA9150_CHG_VFAULT_MASK (0x0f << 0)
+#define DA9150_CHG_IPRE_SHIFT 4
+#define DA9150_CHG_IPRE_MASK (0x03 << 4)
+
+/* DA9150_PPR_TCTR_A = 0x169 */
+#define DA9150_CHG_TCTR_SHIFT 0
+#define DA9150_CHG_TCTR_MASK (0x07 << 0)
+#define DA9150_CHG_TCTR_MODE_SHIFT 4
+#define DA9150_CHG_TCTR_MODE_MASK BIT(4)
+
+/* DA9150_PPR_CHGCTRL_D = 0x16A */
+#define DA9150_CHG_IBAT_SHIFT 0
+#define DA9150_CHG_IBAT_MASK (0xff << 0)
+
+/* DA9150_PPR_CHGCTRL_E = 0x16B */
+#define DA9150_CHG_IEND_SHIFT 0
+#define DA9150_CHG_IEND_MASK (0xff << 0)
+
+/* DA9150_PPR_CHGCTRL_F = 0x16C */
+#define DA9150_CHG_VCOLD_SHIFT 0
+#define DA9150_CHG_VCOLD_MASK (0x1f << 0)
+#define DA9150_TBAT_TQA_EN_SHIFT 6
+#define DA9150_TBAT_TQA_EN_MASK BIT(6)
+#define DA9150_TBAT_TDP_EN_SHIFT 7
+#define DA9150_TBAT_TDP_EN_MASK BIT(7)
+
+/* DA9150_PPR_CHGCTRL_G = 0x16D */
+#define DA9150_CHG_VWARM_SHIFT 0
+#define DA9150_CHG_VWARM_MASK (0x1f << 0)
+
+/* DA9150_PPR_CHGCTRL_H = 0x16E */
+#define DA9150_CHG_VHOT_SHIFT 0
+#define DA9150_CHG_VHOT_MASK (0x1f << 0)
+
+/* DA9150_PPR_CHGCTRL_I = 0x16F */
+#define DA9150_CHG_ICOLD_SHIFT 0
+#define DA9150_CHG_ICOLD_MASK (0xff << 0)
+
+/* DA9150_PPR_CHGCTRL_J = 0x170 */
+#define DA9150_CHG_IWARM_SHIFT 0
+#define DA9150_CHG_IWARM_MASK (0xff << 0)
+
+/* DA9150_PPR_CHGCTRL_K = 0x171 */
+#define DA9150_CHG_IHOT_SHIFT 0
+#define DA9150_CHG_IHOT_MASK (0xff << 0)
+
+/* DA9150_PPR_CHGCTRL_L = 0x172 */
+#define DA9150_CHG_IBAT_TRED_SHIFT 0
+#define DA9150_CHG_IBAT_TRED_MASK (0xff << 0)
+
+/* DA9150_PPR_CHGCTRL_M = 0x173 */
+#define DA9150_CHG_VFLOAT_SHIFT 0
+#define DA9150_CHG_VFLOAT_MASK (0x0f << 0)
+#define DA9150_CHG_LPM_SHIFT 5
+#define DA9150_CHG_LPM_MASK BIT(5)
+#define DA9150_CHG_NBLO_SHIFT 6
+#define DA9150_CHG_NBLO_MASK BIT(6)
+#define DA9150_EBS_EN_SHIFT 7
+#define DA9150_EBS_EN_MASK BIT(7)
+
+/* DA9150_PPR_THYST_A = 0x174 */
+#define DA9150_TBAT_T1_SHIFT 0
+#define DA9150_TBAT_T1_MASK (0xff << 0)
+
+/* DA9150_PPR_THYST_B = 0x175 */
+#define DA9150_TBAT_T2_SHIFT 0
+#define DA9150_TBAT_T2_MASK (0xff << 0)
+
+/* DA9150_PPR_THYST_C = 0x176 */
+#define DA9150_TBAT_T3_SHIFT 0
+#define DA9150_TBAT_T3_MASK (0xff << 0)
+
+/* DA9150_PPR_THYST_D = 0x177 */
+#define DA9150_TBAT_T4_SHIFT 0
+#define DA9150_TBAT_T4_MASK (0xff << 0)
+
+/* DA9150_PPR_THYST_E = 0x178 */
+#define DA9150_TBAT_T5_SHIFT 0
+#define DA9150_TBAT_T5_MASK (0xff << 0)
+
+/* DA9150_PPR_THYST_F = 0x179 */
+#define DA9150_TBAT_H1_SHIFT 0
+#define DA9150_TBAT_H1_MASK (0xff << 0)
+
+/* DA9150_PPR_THYST_G = 0x17A */
+#define DA9150_TBAT_H5_SHIFT 0
+#define DA9150_TBAT_H5_MASK (0xff << 0)
+
+/* DA9150_PAGE_CON_3 = 0x180 */
+#define DA9150_PAGE_SHIFT 0
+#define DA9150_PAGE_MASK (0x3f << 0)
+#define DA9150_WRITE_MODE_SHIFT 6
+#define DA9150_WRITE_MODE_MASK BIT(6)
+#define DA9150_REVERT_SHIFT 7
+#define DA9150_REVERT_MASK BIT(7)
+
+/* DA9150_PAGE_CON_4 = 0x200 */
+#define DA9150_PAGE_SHIFT 0
+#define DA9150_PAGE_MASK (0x3f << 0)
+#define DA9150_WRITE_MODE_SHIFT 6
+#define DA9150_WRITE_MODE_MASK BIT(6)
+#define DA9150_REVERT_SHIFT 7
+#define DA9150_REVERT_MASK BIT(7)
+
+/* DA9150_PAGE_CON_5 = 0x280 */
+#define DA9150_PAGE_SHIFT 0
+#define DA9150_PAGE_MASK (0x3f << 0)
+#define DA9150_WRITE_MODE_SHIFT 6
+#define DA9150_WRITE_MODE_MASK BIT(6)
+#define DA9150_REVERT_SHIFT 7
+#define DA9150_REVERT_MASK BIT(7)
+
+/* DA9150_PAGE_CON_6 = 0x300 */
+#define DA9150_PAGE_SHIFT 0
+#define DA9150_PAGE_MASK (0x3f << 0)
+#define DA9150_WRITE_MODE_SHIFT 6
+#define DA9150_WRITE_MODE_MASK BIT(6)
+#define DA9150_REVERT_SHIFT 7
+#define DA9150_REVERT_MASK BIT(7)
+
+/* DA9150_COREBTLD_STAT_A = 0x302 */
+#define DA9150_BOOTLD_STAT_SHIFT 0
+#define DA9150_BOOTLD_STAT_MASK (0x03 << 0)
+#define DA9150_CORE_LOCKUP_SHIFT 2
+#define DA9150_CORE_LOCKUP_MASK BIT(2)
+
+/* DA9150_COREBTLD_CTRL_A = 0x303 */
+#define DA9150_CORE_RESET_SHIFT 0
+#define DA9150_CORE_RESET_MASK BIT(0)
+#define DA9150_CORE_STOP_SHIFT 1
+#define DA9150_CORE_STOP_MASK BIT(1)
+
+/* DA9150_CORE_CONFIG_A = 0x304 */
+#define DA9150_CORE_MEMMUX_SHIFT 0
+#define DA9150_CORE_MEMMUX_MASK (0x03 << 0)
+#define DA9150_WDT_AUTO_START_SHIFT 2
+#define DA9150_WDT_AUTO_START_MASK BIT(2)
+#define DA9150_WDT_AUTO_LOCK_SHIFT 3
+#define DA9150_WDT_AUTO_LOCK_MASK BIT(3)
+#define DA9150_WDT_HLT_NO_CLK_SHIFT 4
+#define DA9150_WDT_HLT_NO_CLK_MASK BIT(4)
+
+/* DA9150_CORE_CONFIG_C = 0x305 */
+#define DA9150_CORE_SW_SIZE_SHIFT 0
+#define DA9150_CORE_SW_SIZE_MASK (0xff << 0)
+
+/* DA9150_CORE_CONFIG_B = 0x306 */
+#define DA9150_BOOTLD_EN_SHIFT 0
+#define DA9150_BOOTLD_EN_MASK BIT(0)
+#define DA9150_CORE_EN_SHIFT 2
+#define DA9150_CORE_EN_MASK BIT(2)
+#define DA9150_CORE_SW_SRC_SHIFT 3
+#define DA9150_CORE_SW_SRC_MASK (0x07 << 3)
+#define DA9150_DEEP_SLEEP_EN_SHIFT 7
+#define DA9150_DEEP_SLEEP_EN_MASK BIT(7)
+
+/* DA9150_CORE_CFG_DATA_A = 0x307 */
+#define DA9150_CORE_CFG_DT_A_SHIFT 0
+#define DA9150_CORE_CFG_DT_A_MASK (0xff << 0)
+
+/* DA9150_CORE_CFG_DATA_B = 0x308 */
+#define DA9150_CORE_CFG_DT_B_SHIFT 0
+#define DA9150_CORE_CFG_DT_B_MASK (0xff << 0)
+
+/* DA9150_CORE_CMD_A = 0x309 */
+#define DA9150_CORE_CMD_SHIFT 0
+#define DA9150_CORE_CMD_MASK (0xff << 0)
+
+/* DA9150_CORE_DATA_A = 0x30A */
+#define DA9150_CORE_DATA_0_SHIFT 0
+#define DA9150_CORE_DATA_0_MASK (0xff << 0)
+
+/* DA9150_CORE_DATA_B = 0x30B */
+#define DA9150_CORE_DATA_1_SHIFT 0
+#define DA9150_CORE_DATA_1_MASK (0xff << 0)
+
+/* DA9150_CORE_DATA_C = 0x30C */
+#define DA9150_CORE_DATA_2_SHIFT 0
+#define DA9150_CORE_DATA_2_MASK (0xff << 0)
+
+/* DA9150_CORE_DATA_D = 0x30D */
+#define DA9150_CORE_DATA_3_SHIFT 0
+#define DA9150_CORE_DATA_3_MASK (0xff << 0)
+
+/* DA9150_CORE2WIRE_STAT_A = 0x310 */
+#define DA9150_FW_FWDL_ERR_SHIFT 7
+#define DA9150_FW_FWDL_ERR_MASK BIT(7)
+
+/* DA9150_CORE2WIRE_CTRL_A = 0x311 */
+#define DA9150_FW_FWDL_EN_SHIFT 0
+#define DA9150_FW_FWDL_EN_MASK BIT(0)
+#define DA9150_FG_QIF_EN_SHIFT 1
+#define DA9150_FG_QIF_EN_MASK BIT(1)
+#define DA9150_CORE_BASE_ADDR_SHIFT 4
+#define DA9150_CORE_BASE_ADDR_MASK (0x0f << 4)
+
+/* DA9150_FW_CTRL_A = 0x312 */
+#define DA9150_FW_SEAL_SHIFT 0
+#define DA9150_FW_SEAL_MASK (0xff << 0)
+
+/* DA9150_FW_CTRL_C = 0x313 */
+#define DA9150_FW_FWDL_CRC_SHIFT 0
+#define DA9150_FW_FWDL_CRC_MASK (0xff << 0)
+
+/* DA9150_FW_CTRL_D = 0x314 */
+#define DA9150_FW_FWDL_BASE_SHIFT 0
+#define DA9150_FW_FWDL_BASE_MASK (0x0f << 0)
+
+/* DA9150_FG_CTRL_A = 0x315 */
+#define DA9150_FG_QIF_CODE_SHIFT 0
+#define DA9150_FG_QIF_CODE_MASK (0xff << 0)
+
+/* DA9150_FG_CTRL_B = 0x316 */
+#define DA9150_FG_QIF_VALUE_SHIFT 0
+#define DA9150_FG_QIF_VALUE_MASK (0xff << 0)
+
+/* DA9150_FW_CTRL_E = 0x317 */
+#define DA9150_FW_FWDL_SEG_SHIFT 0
+#define DA9150_FW_FWDL_SEG_MASK (0xff << 0)
+
+/* DA9150_FW_CTRL_B = 0x318 */
+#define DA9150_FW_FWDL_VALUE_SHIFT 0
+#define DA9150_FW_FWDL_VALUE_MASK (0xff << 0)
+
+/* DA9150_GPADC_CMAN = 0x320 */
+#define DA9150_GPADC_CEN_SHIFT 0
+#define DA9150_GPADC_CEN_MASK BIT(0)
+#define DA9150_GPADC_CMUX_SHIFT 1
+#define DA9150_GPADC_CMUX_MASK (0x1f << 1)
+
+/* DA9150_GPADC_CRES_A = 0x322 */
+#define DA9150_GPADC_CRES_H_SHIFT 0
+#define DA9150_GPADC_CRES_H_MASK (0xff << 0)
+
+/* DA9150_GPADC_CRES_B = 0x323 */
+#define DA9150_GPADC_CRUN_SHIFT 0
+#define DA9150_GPADC_CRUN_MASK BIT(0)
+#define DA9150_GPADC_CRES_L_SHIFT 6
+#define DA9150_GPADC_CRES_L_MASK (0x03 << 6)
+
+/* DA9150_CC_CFG_A = 0x328 */
+#define DA9150_CC_EN_SHIFT 0
+#define DA9150_CC_EN_MASK BIT(0)
+#define DA9150_CC_TIMEBASE_SHIFT 1
+#define DA9150_CC_TIMEBASE_MASK (0x03 << 1)
+#define DA9150_CC_CFG_SHIFT 5
+#define DA9150_CC_CFG_MASK (0x03 << 5)
+#define DA9150_CC_ENDLESS_MODE_SHIFT 7
+#define DA9150_CC_ENDLESS_MODE_MASK BIT(7)
+
+/* DA9150_CC_CFG_B = 0x329 */
+#define DA9150_CC_OPT_SHIFT 0
+#define DA9150_CC_OPT_MASK (0x03 << 0)
+#define DA9150_CC_PREAMP_SHIFT 2
+#define DA9150_CC_PREAMP_MASK (0x03 << 2)
+
+/* DA9150_CC_ICHG_RES_A = 0x32A */
+#define DA9150_CC_ICHG_RES_H_SHIFT 0
+#define DA9150_CC_ICHG_RES_H_MASK (0xff << 0)
+
+/* DA9150_CC_ICHG_RES_B = 0x32B */
+#define DA9150_CC_ICHG_RES_L_SHIFT 3
+#define DA9150_CC_ICHG_RES_L_MASK (0x1f << 3)
+
+/* DA9150_CC_IAVG_RES_A = 0x32C */
+#define DA9150_CC_IAVG_RES_H_SHIFT 0
+#define DA9150_CC_IAVG_RES_H_MASK (0xff << 0)
+
+/* DA9150_CC_IAVG_RES_B = 0x32D */
+#define DA9150_CC_IAVG_RES_L_SHIFT 0
+#define DA9150_CC_IAVG_RES_L_MASK (0xff << 0)
+
+/* DA9150_TAUX_CTRL_A = 0x330 */
+#define DA9150_TAUX_EN_SHIFT 0
+#define DA9150_TAUX_EN_MASK BIT(0)
+#define DA9150_TAUX_MOD_SHIFT 1
+#define DA9150_TAUX_MOD_MASK BIT(1)
+#define DA9150_TAUX_UPDATE_SHIFT 2
+#define DA9150_TAUX_UPDATE_MASK BIT(2)
+
+/* DA9150_TAUX_RELOAD_H = 0x332 */
+#define DA9150_TAUX_RLD_H_SHIFT 0
+#define DA9150_TAUX_RLD_H_MASK (0xff << 0)
+
+/* DA9150_TAUX_RELOAD_L = 0x333 */
+#define DA9150_TAUX_RLD_L_SHIFT 3
+#define DA9150_TAUX_RLD_L_MASK (0x1f << 3)
+
+/* DA9150_TAUX_VALUE_H = 0x334 */
+#define DA9150_TAUX_VAL_H_SHIFT 0
+#define DA9150_TAUX_VAL_H_MASK (0xff << 0)
+
+/* DA9150_TAUX_VALUE_L = 0x335 */
+#define DA9150_TAUX_VAL_L_SHIFT 3
+#define DA9150_TAUX_VAL_L_MASK (0x1f << 3)
+
+/* DA9150_AUX_DATA_0 = 0x338 */
+#define DA9150_AUX_DAT_0_SHIFT 0
+#define DA9150_AUX_DAT_0_MASK (0xff << 0)
+
+/* DA9150_AUX_DATA_1 = 0x339 */
+#define DA9150_AUX_DAT_1_SHIFT 0
+#define DA9150_AUX_DAT_1_MASK (0xff << 0)
+
+/* DA9150_AUX_DATA_2 = 0x33A */
+#define DA9150_AUX_DAT_2_SHIFT 0
+#define DA9150_AUX_DAT_2_MASK (0xff << 0)
+
+/* DA9150_AUX_DATA_3 = 0x33B */
+#define DA9150_AUX_DAT_3_SHIFT 0
+#define DA9150_AUX_DAT_3_MASK (0xff << 0)
+
+/* DA9150_BIF_CTRL = 0x340 */
+#define DA9150_BIF_ISRC_EN_SHIFT 0
+#define DA9150_BIF_ISRC_EN_MASK BIT(0)
+
+/* DA9150_TBAT_CTRL_A = 0x342 */
+#define DA9150_TBAT_EN_SHIFT 0
+#define DA9150_TBAT_EN_MASK BIT(0)
+#define DA9150_TBAT_SW1_SHIFT 1
+#define DA9150_TBAT_SW1_MASK BIT(1)
+#define DA9150_TBAT_SW2_SHIFT 2
+#define DA9150_TBAT_SW2_MASK BIT(2)
+
+/* DA9150_TBAT_CTRL_B = 0x343 */
+#define DA9150_TBAT_SW_FRC_SHIFT 0
+#define DA9150_TBAT_SW_FRC_MASK BIT(0)
+#define DA9150_TBAT_STAT_SW1_SHIFT 1
+#define DA9150_TBAT_STAT_SW1_MASK BIT(1)
+#define DA9150_TBAT_STAT_SW2_SHIFT 2
+#define DA9150_TBAT_STAT_SW2_MASK BIT(2)
+#define DA9150_TBAT_HIGH_CURR_SHIFT 3
+#define DA9150_TBAT_HIGH_CURR_MASK BIT(3)
+
+/* DA9150_TBAT_RES_A = 0x344 */
+#define DA9150_TBAT_RES_H_SHIFT 0
+#define DA9150_TBAT_RES_H_MASK (0xff << 0)
+
+/* DA9150_TBAT_RES_B = 0x345 */
+#define DA9150_TBAT_RES_DIS_SHIFT 0
+#define DA9150_TBAT_RES_DIS_MASK BIT(0)
+#define DA9150_TBAT_RES_L_SHIFT 6
+#define DA9150_TBAT_RES_L_MASK (0x03 << 6)
+
+#endif /* __DA9150_REGISTERS_H */
diff --git a/include/linux/mfd/max77686-private.h b/include/linux/mfd/max77686-private.h
index 960b92ad450d..f5043490d67c 100644
--- a/include/linux/mfd/max77686-private.h
+++ b/include/linux/mfd/max77686-private.h
@@ -447,7 +447,6 @@ struct max77686_dev {
struct regmap_irq_chip_data *rtc_irq_data;
int irq;
- bool wakeup;
struct mutex irqlock;
int irq_masks_cur[MAX77686_IRQ_GROUP_NR];
int irq_masks_cache[MAX77686_IRQ_GROUP_NR];
diff --git a/include/linux/mfd/max77686.h b/include/linux/mfd/max77686.h
index 553f7d09258a..bb995ab9a575 100644
--- a/include/linux/mfd/max77686.h
+++ b/include/linux/mfd/max77686.h
@@ -119,12 +119,6 @@ enum max77802_regulators {
MAX77802_REG_MAX,
};
-struct max77686_regulator_data {
- int id;
- struct regulator_init_data *initdata;
- struct device_node *of_node;
-};
-
enum max77686_opmode {
MAX77686_OPMODE_NORMAL,
MAX77686_OPMODE_LP,
@@ -136,26 +130,4 @@ struct max77686_opmode_data {
int mode;
};
-struct max77686_platform_data {
- int ono;
- int wakeup;
-
- /* ---- PMIC ---- */
- struct max77686_regulator_data *regulators;
- int num_regulators;
-
- struct max77686_opmode_data *opmode_data;
-
- /*
- * GPIO-DVS feature is not enabled with the current version of
- * MAX77686 driver. Buck2/3/4_voltages[0] is used as the default
- * voltage at probe. DVS/SELB gpios are set as OUTPUT-LOW.
- */
- int buck234_gpio_dvs[3]; /* GPIO of [0]DVS1, [1]DVS2, [2]DVS3 */
- int buck234_gpio_selb[3]; /* [0]SELB2, [1]SELB3, [2]SELB4 */
- unsigned int buck2_voltage[8]; /* buckx_voltage in uV */
- unsigned int buck3_voltage[8];
- unsigned int buck4_voltage[8];
-};
-
#endif /* __LINUX_MFD_MAX77686_H */
diff --git a/include/linux/mfd/qcom_rpm.h b/include/linux/mfd/qcom_rpm.h
new file mode 100644
index 000000000000..742ebf1b76ca
--- /dev/null
+++ b/include/linux/mfd/qcom_rpm.h
@@ -0,0 +1,13 @@
+#ifndef __QCOM_RPM_H__
+#define __QCOM_RPM_H__
+
+#include <linux/types.h>
+
+struct qcom_rpm;
+
+#define QCOM_RPM_ACTIVE_STATE 0
+#define QCOM_RPM_SLEEP_STATE 1
+
+int qcom_rpm_write(struct qcom_rpm *rpm, int state, int resource, u32 *buf, size_t count);
+
+#endif
diff --git a/include/linux/mfd/rt5033-private.h b/include/linux/mfd/rt5033-private.h
new file mode 100644
index 000000000000..1b63fc2f42d1
--- /dev/null
+++ b/include/linux/mfd/rt5033-private.h
@@ -0,0 +1,260 @@
+/*
+ * MFD core driver for Richtek RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#ifndef __RT5033_PRIVATE_H__
+#define __RT5033_PRIVATE_H__
+
+enum rt5033_reg {
+ RT5033_REG_CHG_STAT = 0x00,
+ RT5033_REG_CHG_CTRL1 = 0x01,
+ RT5033_REG_CHG_CTRL2 = 0x02,
+ RT5033_REG_DEVICE_ID = 0x03,
+ RT5033_REG_CHG_CTRL3 = 0x04,
+ RT5033_REG_CHG_CTRL4 = 0x05,
+ RT5033_REG_CHG_CTRL5 = 0x06,
+ RT5033_REG_RT_CTRL0 = 0x07,
+ RT5033_REG_CHG_RESET = 0x08,
+ /* Reserved 0x09~0x18 */
+ RT5033_REG_RT_CTRL1 = 0x19,
+ /* Reserved 0x1A~0x20 */
+ RT5033_REG_FLED_FUNCTION1 = 0x21,
+ RT5033_REG_FLED_FUNCTION2 = 0x22,
+ RT5033_REG_FLED_STROBE_CTRL1 = 0x23,
+ RT5033_REG_FLED_STROBE_CTRL2 = 0x24,
+ RT5033_REG_FLED_CTRL1 = 0x25,
+ RT5033_REG_FLED_CTRL2 = 0x26,
+ RT5033_REG_FLED_CTRL3 = 0x27,
+ RT5033_REG_FLED_CTRL4 = 0x28,
+ RT5033_REG_FLED_CTRL5 = 0x29,
+ /* Reserved 0x2A~0x40 */
+ RT5033_REG_CTRL = 0x41,
+ RT5033_REG_BUCK_CTRL = 0x42,
+ RT5033_REG_LDO_CTRL = 0x43,
+ /* Reserved 0x44~0x46 */
+ RT5033_REG_MANUAL_RESET_CTRL = 0x47,
+ /* Reserved 0x48~0x5F */
+ RT5033_REG_CHG_IRQ1 = 0x60,
+ RT5033_REG_CHG_IRQ2 = 0x61,
+ RT5033_REG_CHG_IRQ3 = 0x62,
+ RT5033_REG_CHG_IRQ1_CTRL = 0x63,
+ RT5033_REG_CHG_IRQ2_CTRL = 0x64,
+ RT5033_REG_CHG_IRQ3_CTRL = 0x65,
+ RT5033_REG_LED_IRQ_STAT = 0x66,
+ RT5033_REG_LED_IRQ_CTRL = 0x67,
+ RT5033_REG_PMIC_IRQ_STAT = 0x68,
+ RT5033_REG_PMIC_IRQ_CTRL = 0x69,
+ RT5033_REG_SHDN_CTRL = 0x6A,
+ RT5033_REG_OFF_EVENT = 0x6B,
+
+ RT5033_REG_END,
+};
+
+/* RT5033 Charger state register */
+#define RT5033_CHG_STAT_MASK 0x20
+#define RT5033_CHG_STAT_DISCHARGING 0x00
+#define RT5033_CHG_STAT_FULL 0x10
+#define RT5033_CHG_STAT_CHARGING 0x20
+#define RT5033_CHG_STAT_NOT_CHARGING 0x30
+#define RT5033_CHG_STAT_TYPE_MASK 0x60
+#define RT5033_CHG_STAT_TYPE_PRE 0x20
+#define RT5033_CHG_STAT_TYPE_FAST 0x60
+
+/* RT5033 CHGCTRL1 register */
+#define RT5033_CHGCTRL1_IAICR_MASK 0xe0
+#define RT5033_CHGCTRL1_MODE_MASK 0x01
+
+/* RT5033 CHGCTRL2 register */
+#define RT5033_CHGCTRL2_CV_MASK 0xfc
+
+/* RT5033 CHGCTRL3 register */
+#define RT5033_CHGCTRL3_CFO_EN_MASK 0x40
+#define RT5033_CHGCTRL3_TIMER_MASK 0x38
+#define RT5033_CHGCTRL3_TIMER_EN_MASK 0x01
+
+/* RT5033 CHGCTRL4 register */
+#define RT5033_CHGCTRL4_EOC_MASK 0x07
+#define RT5033_CHGCTRL4_IPREC_MASK 0x18
+
+/* RT5033 CHGCTRL5 register */
+#define RT5033_CHGCTRL5_VPREC_MASK 0x0f
+#define RT5033_CHGCTRL5_ICHG_MASK 0xf0
+#define RT5033_CHGCTRL5_ICHG_SHIFT 0x04
+#define RT5033_CHG_MAX_CURRENT 0x0d
+
+/* RT5033 RT CTRL1 register */
+#define RT5033_RT_CTRL1_UUG_MASK 0x02
+#define RT5033_RT_HZ_MASK 0x01
+
+/* RT5033 control register */
+#define RT5033_CTRL_FCCM_BUCK_MASK 0x00
+#define RT5033_CTRL_BUCKOMS_MASK 0x01
+#define RT5033_CTRL_LDOOMS_MASK 0x02
+#define RT5033_CTRL_SLDOOMS_MASK 0x03
+#define RT5033_CTRL_EN_BUCK_MASK 0x04
+#define RT5033_CTRL_EN_LDO_MASK 0x05
+#define RT5033_CTRL_EN_SAFE_LDO_MASK 0x06
+#define RT5033_CTRL_LDO_SLEEP_MASK 0x07
+
+/* RT5033 BUCK control register */
+#define RT5033_BUCK_CTRL_MASK 0x1f
+
+/* RT5033 LDO control register */
+#define RT5033_LDO_CTRL_MASK 0x1f
+
+/* RT5033 charger property - model, manufacturer */
+
+#define RT5033_CHARGER_MODEL "RT5033WSC Charger"
+#define RT5033_MANUFACTURER "Richtek Technology Corporation"
+
+/*
+ * RT5033 charger fast-charge current lmits (as in CHGCTRL1 register),
+ * AICR mode limits the input current for example,
+ * the AIRC 100 mode limits the input current to 100 mA.
+ */
+#define RT5033_AICR_100_MODE 0x20
+#define RT5033_AICR_500_MODE 0x40
+#define RT5033_AICR_700_MODE 0x60
+#define RT5033_AICR_900_MODE 0x80
+#define RT5033_AICR_1500_MODE 0xc0
+#define RT5033_AICR_2000_MODE 0xe0
+#define RT5033_AICR_MODE_MASK 0xe0
+
+/* RT5033 use internal timer need to set time */
+#define RT5033_FAST_CHARGE_TIMER4 0x00
+#define RT5033_FAST_CHARGE_TIMER6 0x01
+#define RT5033_FAST_CHARGE_TIMER8 0x02
+#define RT5033_FAST_CHARGE_TIMER9 0x03
+#define RT5033_FAST_CHARGE_TIMER12 0x04
+#define RT5033_FAST_CHARGE_TIMER14 0x05
+#define RT5033_FAST_CHARGE_TIMER16 0x06
+
+#define RT5033_INT_TIMER_ENABLE 0x01
+
+/* RT5033 charger termination enable mask */
+#define RT5033_TE_ENABLE_MASK 0x08
+
+/*
+ * RT5033 charger opa mode. RT50300 have two opa mode charger mode
+ * and boost mode for OTG
+ */
+
+#define RT5033_CHARGER_MODE 0x00
+#define RT5033_BOOST_MODE 0x01
+
+/* RT5033 charger termination enable */
+#define RT5033_TE_ENABLE 0x08
+
+/* RT5033 charger CFO enable */
+#define RT5033_CFO_ENABLE 0x40
+
+/* RT5033 charger constant charge voltage (as in CHGCTRL2 register), uV */
+#define RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN 3650000U
+#define RT5033_CHARGER_CONST_VOLTAGE_STEP_NUM 25000U
+#define RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX 4400000U
+
+/* RT5033 charger pre-charge current limits (as in CHGCTRL4 register), uA */
+#define RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN 350000U
+#define RT5033_CHARGER_PRE_CURRENT_STEP_NUM 100000U
+#define RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX 650000U
+
+/* RT5033 charger fast-charge current (as in CHGCTRL5 register), uA */
+#define RT5033_CHARGER_FAST_CURRENT_MIN 700000U
+#define RT5033_CHARGER_FAST_CURRENT_STEP_NUM 100000U
+#define RT5033_CHARGER_FAST_CURRENT_MAX 2000000U
+
+/*
+ * RT5033 charger const-charge end of charger current (
+ * as in CHGCTRL4 register), uA
+ */
+#define RT5033_CHARGER_EOC_MIN 150000U
+#define RT5033_CHARGER_EOC_REF 300000U
+#define RT5033_CHARGER_EOC_STEP_NUM1 50000U
+#define RT5033_CHARGER_EOC_STEP_NUM2 100000U
+#define RT5033_CHARGER_EOC_MAX 600000U
+
+/*
+ * RT5033 charger pre-charge threshold volt limits
+ * (as in CHGCTRL5 register), uV
+ */
+
+#define RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN 2300000U
+#define RT5033_CHARGER_PRE_THRESHOLD_STEP_NUM 100000U
+#define RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX 3800000U
+
+/*
+ * RT5033 charger enable UUG, If UUG enable MOS auto control by H/W charger
+ * circuit.
+ */
+#define RT5033_CHARGER_UUG_ENABLE 0x02
+
+/* RT5033 charger High impedance mode */
+#define RT5033_CHARGER_HZ_DISABLE 0x00
+#define RT5033_CHARGER_HZ_ENABLE 0x01
+
+/* RT5033 regulator BUCK output voltage uV */
+#define RT5033_REGULATOR_BUCK_VOLTAGE_MIN 1000000U
+#define RT5033_REGULATOR_BUCK_VOLTAGE_MAX 3000000U
+#define RT5033_REGULATOR_BUCK_VOLTAGE_STEP 100000U
+#define RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM 32
+
+/* RT5033 regulator LDO output voltage uV */
+#define RT5033_REGULATOR_LDO_VOLTAGE_MIN 1200000U
+#define RT5033_REGULATOR_LDO_VOLTAGE_MAX 3000000U
+#define RT5033_REGULATOR_LDO_VOLTAGE_STEP 100000U
+#define RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM 32
+
+/* RT5033 regulator SAFE LDO output voltage uV */
+#define RT5033_REGULATOR_SAFE_LDO_VOLTAGE 4900000U
+
+enum rt5033_fuel_reg {
+ RT5033_FUEL_REG_OCV_H = 0x00,
+ RT5033_FUEL_REG_OCV_L = 0x01,
+ RT5033_FUEL_REG_VBAT_H = 0x02,
+ RT5033_FUEL_REG_VBAT_L = 0x03,
+ RT5033_FUEL_REG_SOC_H = 0x04,
+ RT5033_FUEL_REG_SOC_L = 0x05,
+ RT5033_FUEL_REG_CTRL_H = 0x06,
+ RT5033_FUEL_REG_CTRL_L = 0x07,
+ RT5033_FUEL_REG_CRATE = 0x08,
+ RT5033_FUEL_REG_DEVICE_ID = 0x09,
+ RT5033_FUEL_REG_AVG_VOLT_H = 0x0A,
+ RT5033_FUEL_REG_AVG_VOLT_L = 0x0B,
+ RT5033_FUEL_REG_CONFIG_H = 0x0C,
+ RT5033_FUEL_REG_CONFIG_L = 0x0D,
+ /* Reserved 0x0E~0x0F */
+ RT5033_FUEL_REG_IRQ_CTRL = 0x10,
+ RT5033_FUEL_REG_IRQ_FLAG = 0x11,
+ RT5033_FUEL_VMIN = 0x12,
+ RT5033_FUEL_SMIN = 0x13,
+ /* Reserved 0x14~0x1F */
+ RT5033_FUEL_VGCOMP1 = 0x20,
+ RT5033_FUEL_VGCOMP2 = 0x21,
+ RT5033_FUEL_VGCOMP3 = 0x22,
+ RT5033_FUEL_VGCOMP4 = 0x23,
+ /* Reserved 0x24~0xFD */
+ RT5033_FUEL_MFA_H = 0xFE,
+ RT5033_FUEL_MFA_L = 0xFF,
+
+ RT5033_FUEL_REG_END,
+};
+
+/* RT5033 fuel gauge battery present property */
+#define RT5033_FUEL_BAT_PRESENT 0x02
+
+/* RT5033 PMIC interrupts */
+#define RT5033_PMIC_IRQ_BUCKOCP 2
+#define RT5033_PMIC_IRQ_BUCKLV 3
+#define RT5033_PMIC_IRQ_SAFELDOLV 4
+#define RT5033_PMIC_IRQ_LDOLV 5
+#define RT5033_PMIC_IRQ_OT 6
+#define RT5033_PMIC_IRQ_VDDA_UV 7
+
+#endif /* __RT5033_PRIVATE_H__ */
diff --git a/include/linux/mfd/rt5033.h b/include/linux/mfd/rt5033.h
new file mode 100644
index 000000000000..010cff49a98e
--- /dev/null
+++ b/include/linux/mfd/rt5033.h
@@ -0,0 +1,62 @@
+/*
+ * MFD core driver for the RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#ifndef __RT5033_H__
+#define __RT5033_H__
+
+#include <linux/regulator/consumer.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/power_supply.h>
+
+/* RT5033 regulator IDs */
+enum rt5033_regulators {
+ RT5033_BUCK = 0,
+ RT5033_LDO,
+ RT5033_SAFE_LDO,
+
+ RT5033_REGULATOR_NUM,
+};
+
+struct rt5033_dev {
+ struct device *dev;
+
+ struct regmap *regmap;
+ struct regmap_irq_chip_data *irq_data;
+ int irq;
+ bool wakeup;
+};
+
+struct rt5033_battery {
+ struct i2c_client *client;
+ struct rt5033_dev *rt5033;
+ struct regmap *regmap;
+ struct power_supply psy;
+};
+
+/* RT5033 charger platform data */
+struct rt5033_charger_data {
+ unsigned int pre_uamp;
+ unsigned int pre_uvolt;
+ unsigned int const_uvolt;
+ unsigned int eoc_uamp;
+ unsigned int fast_uamp;
+};
+
+struct rt5033_charger {
+ struct device *dev;
+ struct rt5033_dev *rt5033;
+ struct power_supply psy;
+
+ struct rt5033_charger_data *chg;
+};
+
+#endif /* __RT5033_H__ */
diff --git a/include/linux/mfd/syscon/atmel-matrix.h b/include/linux/mfd/syscon/atmel-matrix.h
new file mode 100644
index 000000000000..8293c3e2a82a
--- /dev/null
+++ b/include/linux/mfd/syscon/atmel-matrix.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _LINUX_MFD_SYSCON_ATMEL_MATRIX_H
+#define _LINUX_MFD_SYSCON_ATMEL_MATRIX_H
+
+#define AT91SAM9260_MATRIX_MCFG 0x00
+#define AT91SAM9260_MATRIX_SCFG 0x40
+#define AT91SAM9260_MATRIX_PRS 0x80
+#define AT91SAM9260_MATRIX_MRCR 0x100
+#define AT91SAM9260_MATRIX_EBICSA 0x11c
+
+#define AT91SAM9261_MATRIX_MRCR 0x0
+#define AT91SAM9261_MATRIX_SCFG 0x4
+#define AT91SAM9261_MATRIX_TCR 0x24
+#define AT91SAM9261_MATRIX_EBICSA 0x30
+#define AT91SAM9261_MATRIX_USBPUCR 0x34
+
+#define AT91SAM9263_MATRIX_MCFG 0x00
+#define AT91SAM9263_MATRIX_SCFG 0x40
+#define AT91SAM9263_MATRIX_PRS 0x80
+#define AT91SAM9263_MATRIX_MRCR 0x100
+#define AT91SAM9263_MATRIX_TCR 0x114
+#define AT91SAM9263_MATRIX_EBI0CSA 0x120
+#define AT91SAM9263_MATRIX_EBI1CSA 0x124
+
+#define AT91SAM9RL_MATRIX_MCFG 0x00
+#define AT91SAM9RL_MATRIX_SCFG 0x40
+#define AT91SAM9RL_MATRIX_PRS 0x80
+#define AT91SAM9RL_MATRIX_MRCR 0x100
+#define AT91SAM9RL_MATRIX_TCR 0x114
+#define AT91SAM9RL_MATRIX_EBICSA 0x120
+
+#define AT91SAM9G45_MATRIX_MCFG 0x00
+#define AT91SAM9G45_MATRIX_SCFG 0x40
+#define AT91SAM9G45_MATRIX_PRS 0x80
+#define AT91SAM9G45_MATRIX_MRCR 0x100
+#define AT91SAM9G45_MATRIX_TCR 0x110
+#define AT91SAM9G45_MATRIX_DDRMPR 0x118
+#define AT91SAM9G45_MATRIX_EBICSA 0x128
+
+#define AT91SAM9N12_MATRIX_MCFG 0x00
+#define AT91SAM9N12_MATRIX_SCFG 0x40
+#define AT91SAM9N12_MATRIX_PRS 0x80
+#define AT91SAM9N12_MATRIX_MRCR 0x100
+#define AT91SAM9N12_MATRIX_EBICSA 0x118
+
+#define AT91SAM9X5_MATRIX_MCFG 0x00
+#define AT91SAM9X5_MATRIX_SCFG 0x40
+#define AT91SAM9X5_MATRIX_PRS 0x80
+#define AT91SAM9X5_MATRIX_MRCR 0x100
+#define AT91SAM9X5_MATRIX_EBICSA 0x120
+
+#define SAMA5D3_MATRIX_MCFG 0x00
+#define SAMA5D3_MATRIX_SCFG 0x40
+#define SAMA5D3_MATRIX_PRS 0x80
+#define SAMA5D3_MATRIX_MRCR 0x100
+
+#define AT91_MATRIX_MCFG(o, x) ((o) + ((x) * 0x4))
+#define AT91_MATRIX_ULBT GENMASK(2, 0)
+#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
+#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
+#define AT91_MATRIX_ULBT_FOUR (2 << 0)
+#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
+#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
+
+#define AT91_MATRIX_SCFG(o, x) ((o) + ((x) * 0x4))
+#define AT91_MATRIX_SLOT_CYCLE GENMASK(7, 0)
+#define AT91_MATRIX_DEFMSTR_TYPE GENMASK(17, 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
+#define AT91_MATRIX_FIXED_DEFMSTR GENMASK(20, 18)
+#define AT91_MATRIX_ARBT GENMASK(25, 24)
+#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
+#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
+
+#define AT91_MATRIX_ITCM_SIZE GENMASK(3, 0)
+#define AT91_MATRIX_ITCM_0 (0 << 0)
+#define AT91_MATRIX_ITCM_16 (5 << 0)
+#define AT91_MATRIX_ITCM_32 (6 << 0)
+#define AT91_MATRIX_ITCM_64 (7 << 0)
+#define AT91_MATRIX_DTCM_SIZE GENMASK(7, 4)
+#define AT91_MATRIX_DTCM_0 (0 << 4)
+#define AT91_MATRIX_DTCM_16 (5 << 4)
+#define AT91_MATRIX_DTCM_32 (6 << 4)
+#define AT91_MATRIX_DTCM_64 (7 << 4)
+
+#define AT91_MATRIX_PRAS(o, x) ((o) + ((x) * 0x8))
+#define AT91_MATRIX_PRBS(o, x) ((o) + ((x) * 0x8) + 0x4)
+#define AT91_MATRIX_MPR(x) GENMASK(((x) * 0x4) + 1, ((x) * 0x4))
+
+#define AT91_MATRIX_RCB(x) BIT(x)
+
+#define AT91_MATRIX_CSA(cs, val) (val << (cs))
+#define AT91_MATRIX_DBPUC BIT(8)
+#define AT91_MATRIX_DBPDC BIT(9)
+#define AT91_MATRIX_VDDIOMSEL BIT(16)
+#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
+#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
+#define AT91_MATRIX_EBI_IOSR BIT(17)
+#define AT91_MATRIX_DDR_IOSR BIT(18)
+#define AT91_MATRIX_NFD0_SELECT BIT(24)
+#define AT91_MATRIX_DDR_MP_EN BIT(25)
+#define AT91_MATRIX_EBI_NUM_CS 8
+
+#define AT91_MATRIX_USBPUCR_PUON BIT(30)
+
+#endif /* _LINUX_MFD_SYSCON_ATMEL_MATRIX_H */
diff --git a/include/linux/mfd/syscon/atmel-smc.h b/include/linux/mfd/syscon/atmel-smc.h
new file mode 100644
index 000000000000..be6ebe64eebe
--- /dev/null
+++ b/include/linux/mfd/syscon/atmel-smc.h
@@ -0,0 +1,173 @@
+/*
+ * Atmel SMC (Static Memory Controller) register offsets and bit definitions.
+ *
+ * Copyright (C) 2014 Atmel
+ * Copyright (C) 2014 Free Electrons
+ *
+ * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_MFD_SYSCON_ATMEL_SMC_H_
+#define _LINUX_MFD_SYSCON_ATMEL_SMC_H_
+
+#include <linux/kernel.h>
+#include <linux/regmap.h>
+
+#define AT91SAM9_SMC_GENERIC 0x00
+#define AT91SAM9_SMC_GENERIC_BLK_SZ 0x10
+
+#define SAMA5_SMC_GENERIC 0x600
+#define SAMA5_SMC_GENERIC_BLK_SZ 0x14
+
+#define AT91SAM9_SMC_SETUP(o) ((o) + 0x00)
+#define AT91SAM9_SMC_NWESETUP(x) (x)
+#define AT91SAM9_SMC_NCS_WRSETUP(x) ((x) << 8)
+#define AT91SAM9_SMC_NRDSETUP(x) ((x) << 16)
+#define AT91SAM9_SMC_NCS_NRDSETUP(x) ((x) << 24)
+
+#define AT91SAM9_SMC_PULSE(o) ((o) + 0x04)
+#define AT91SAM9_SMC_NWEPULSE(x) (x)
+#define AT91SAM9_SMC_NCS_WRPULSE(x) ((x) << 8)
+#define AT91SAM9_SMC_NRDPULSE(x) ((x) << 16)
+#define AT91SAM9_SMC_NCS_NRDPULSE(x) ((x) << 24)
+
+#define AT91SAM9_SMC_CYCLE(o) ((o) + 0x08)
+#define AT91SAM9_SMC_NWECYCLE(x) (x)
+#define AT91SAM9_SMC_NRDCYCLE(x) ((x) << 16)
+
+#define AT91SAM9_SMC_MODE(o) ((o) + 0x0c)
+#define SAMA5_SMC_MODE(o) ((o) + 0x10)
+#define AT91_SMC_READMODE BIT(0)
+#define AT91_SMC_READMODE_NCS (0 << 0)
+#define AT91_SMC_READMODE_NRD (1 << 0)
+#define AT91_SMC_WRITEMODE BIT(1)
+#define AT91_SMC_WRITEMODE_NCS (0 << 1)
+#define AT91_SMC_WRITEMODE_NWE (1 << 1)
+#define AT91_SMC_EXNWMODE GENMASK(5, 4)
+#define AT91_SMC_EXNWMODE_DISABLE (0 << 4)
+#define AT91_SMC_EXNWMODE_FROZEN (2 << 4)
+#define AT91_SMC_EXNWMODE_READY (3 << 4)
+#define AT91_SMC_BAT BIT(8)
+#define AT91_SMC_BAT_SELECT (0 << 8)
+#define AT91_SMC_BAT_WRITE (1 << 8)
+#define AT91_SMC_DBW GENMASK(13, 12)
+#define AT91_SMC_DBW_8 (0 << 12)
+#define AT91_SMC_DBW_16 (1 << 12)
+#define AT91_SMC_DBW_32 (2 << 12)
+#define AT91_SMC_TDF GENMASK(19, 16)
+#define AT91_SMC_TDF_(x) ((((x) - 1) << 16) & AT91_SMC_TDF)
+#define AT91_SMC_TDF_MAX 16
+#define AT91_SMC_TDFMODE_OPTIMIZED BIT(20)
+#define AT91_SMC_PMEN BIT(24)
+#define AT91_SMC_PS GENMASK(29, 28)
+#define AT91_SMC_PS_4 (0 << 28)
+#define AT91_SMC_PS_8 (1 << 28)
+#define AT91_SMC_PS_16 (2 << 28)
+#define AT91_SMC_PS_32 (3 << 28)
+
+
+/*
+ * This function converts a setup timing expressed in nanoseconds into an
+ * encoded value that can be written in the SMC_SETUP register.
+ *
+ * The following formula is described in atmel datasheets (section
+ * "SMC Setup Register"):
+ *
+ * setup length = (128* SETUP[5] + SETUP[4:0])
+ *
+ * where setup length is the timing expressed in cycles.
+ */
+static inline u32 at91sam9_smc_setup_ns_to_cycles(unsigned int clk_rate,
+ u32 timing_ns)
+{
+ u32 clk_period = DIV_ROUND_UP(NSEC_PER_SEC, clk_rate);
+ u32 coded_cycles = 0;
+ u32 cycles;
+
+ cycles = DIV_ROUND_UP(timing_ns, clk_period);
+ if (cycles / 32) {
+ coded_cycles |= 1 << 5;
+ if (cycles < 128)
+ cycles = 0;
+ }
+
+ coded_cycles |= cycles % 32;
+
+ return coded_cycles;
+}
+
+/*
+ * This function converts a pulse timing expressed in nanoseconds into an
+ * encoded value that can be written in the SMC_PULSE register.
+ *
+ * The following formula is described in atmel datasheets (section
+ * "SMC Pulse Register"):
+ *
+ * pulse length = (256* PULSE[6] + PULSE[5:0])
+ *
+ * where pulse length is the timing expressed in cycles.
+ */
+static inline u32 at91sam9_smc_pulse_ns_to_cycles(unsigned int clk_rate,
+ u32 timing_ns)
+{
+ u32 clk_period = DIV_ROUND_UP(NSEC_PER_SEC, clk_rate);
+ u32 coded_cycles = 0;
+ u32 cycles;
+
+ cycles = DIV_ROUND_UP(timing_ns, clk_period);
+ if (cycles / 64) {
+ coded_cycles |= 1 << 6;
+ if (cycles < 256)
+ cycles = 0;
+ }
+
+ coded_cycles |= cycles % 64;
+
+ return coded_cycles;
+}
+
+/*
+ * This function converts a cycle timing expressed in nanoseconds into an
+ * encoded value that can be written in the SMC_CYCLE register.
+ *
+ * The following formula is described in atmel datasheets (section
+ * "SMC Cycle Register"):
+ *
+ * cycle length = (CYCLE[8:7]*256 + CYCLE[6:0])
+ *
+ * where cycle length is the timing expressed in cycles.
+ */
+static inline u32 at91sam9_smc_cycle_ns_to_cycles(unsigned int clk_rate,
+ u32 timing_ns)
+{
+ u32 clk_period = DIV_ROUND_UP(NSEC_PER_SEC, clk_rate);
+ u32 coded_cycles = 0;
+ u32 cycles;
+
+ cycles = DIV_ROUND_UP(timing_ns, clk_period);
+ if (cycles / 128) {
+ coded_cycles = cycles / 256;
+ cycles %= 256;
+ if (cycles >= 128) {
+ coded_cycles++;
+ cycles = 0;
+ }
+
+ if (coded_cycles > 0x3) {
+ coded_cycles = 0x3;
+ cycles = 0x7f;
+ }
+
+ coded_cycles <<= 7;
+ }
+
+ coded_cycles |= cycles % 128;
+
+ return coded_cycles;
+}
+
+#endif /* _LINUX_MFD_SYSCON_ATMEL_SMC_H_ */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9bee7ec0c31f..47a93928b90f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -224,6 +224,7 @@ struct vm_fault {
pgoff_t pgoff; /* Logical page offset based on vma */
void __user *virtual_address; /* Faulting virtual address */
+ struct page *cow_page; /* Handler may choose to COW */
struct page *page; /* ->fault handlers should return a
* page here, unless VM_FAULT_NOPAGE
* is set (which is also implied by
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 2e75ab00dbf2..e530533b94be 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -364,8 +364,6 @@ struct ssb_device_id {
} __attribute__((packed, aligned(2)));
#define SSB_DEVICE(_vendor, _coreid, _revision) \
{ .vendor = _vendor, .coreid = _coreid, .revision = _revision, }
-#define SSB_DEVTABLE_END \
- { 0, },
#define SSB_ANY_VENDOR 0xFFFF
#define SSB_ANY_ID 0xFFFF
@@ -380,8 +378,6 @@ struct bcma_device_id {
} __attribute__((packed,aligned(2)));
#define BCMA_CORE(_manuf, _id, _rev, _class) \
{ .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
-#define BCMA_CORETABLE_END \
- { 0, },
#define BCMA_ANY_MANUF 0xFFFF
#define BCMA_ANY_ID 0xFFFF
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 3301c4c289d6..f17fa75809aa 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -227,6 +227,7 @@ struct mtd_info {
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
int (*_suspend) (struct mtd_info *mtd);
void (*_resume) (struct mtd_info *mtd);
+ void (*_reboot) (struct mtd_info *mtd);
/*
* If the driver is something smart, like UBI, it may need to maintain
* its own reference counting. The below functions are only for driver.
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 63aeccf9ddc8..4720b86ee73d 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -56,6 +56,10 @@
/* Used for Spansion flashes only. */
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
+/* Used for Micron flashes only. */
+#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
+#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
+
/* Status Register bits. */
#define SR_WIP 1 /* Write in progress */
#define SR_WEL 2 /* Write enable latch */
@@ -67,6 +71,9 @@
#define SR_QUAD_EN_MX 0x40 /* Macronix Quad I/O */
+/* Enhanced Volatile Configuration Register bits */
+#define EVCR_QUAD_EN_MICRON 0x80 /* Micron Quad I/O */
+
/* Flag Status Register bits */
#define FSR_READY 0x80
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d115256ed5a2..5897b4ea5a3f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1923,13 +1923,8 @@ struct napi_gro_cb {
/* Number of segments aggregated. */
u16 count;
- /* This is non-zero if the packet may be of the same flow. */
- u8 same_flow;
-
- /* Free the skb? */
- u8 free;
-#define NAPI_GRO_FREE 1
-#define NAPI_GRO_FREE_STOLEN_HEAD 2
+ /* Start offset for remote checksum offload */
+ u16 gro_remcsum_start;
/* jiffies when first packet was created/queued */
unsigned long age;
@@ -1937,6 +1932,9 @@ struct napi_gro_cb {
/* Used in ipv6_gro_receive() and foo-over-udp */
u16 proto;
+ /* This is non-zero if the packet may be of the same flow. */
+ u8 same_flow:1;
+
/* Used in udp_gro_receive */
u8 udp_mark:1;
@@ -1946,9 +1944,16 @@ struct napi_gro_cb {
/* Number of checksums via CHECKSUM_UNNECESSARY */
u8 csum_cnt:3;
+ /* Free the skb? */
+ u8 free:2;
+#define NAPI_GRO_FREE 1
+#define NAPI_GRO_FREE_STOLEN_HEAD 2
+
/* Used in foo-over-udp, set in udp[46]_gro_receive */
u8 is_ipv6:1;
+ /* 7 bit hole */
+
/* used to support CHECKSUM_COMPLETE for tunneling protocols */
__wsum csum;
@@ -2242,11 +2247,20 @@ static inline void skb_gro_postpull_rcsum(struct sk_buff *skb,
__sum16 __skb_gro_checksum_complete(struct sk_buff *skb);
+static inline bool skb_at_gro_remcsum_start(struct sk_buff *skb)
+{
+ return (NAPI_GRO_CB(skb)->gro_remcsum_start - skb_headroom(skb) ==
+ skb_gro_offset(skb));
+}
+
static inline bool __skb_gro_checksum_validate_needed(struct sk_buff *skb,
bool zero_okay,
__sum16 check)
{
- return (skb->ip_summed != CHECKSUM_PARTIAL &&
+ return ((skb->ip_summed != CHECKSUM_PARTIAL ||
+ skb_checksum_start_offset(skb) <
+ skb_gro_offset(skb)) &&
+ !skb_at_gro_remcsum_start(skb) &&
NAPI_GRO_CB(skb)->csum_cnt == 0 &&
(!zero_okay || check));
}
@@ -2321,20 +2335,48 @@ do { \
compute_pseudo(skb, proto)); \
} while (0)
+struct gro_remcsum {
+ int offset;
+ __wsum delta;
+};
+
+static inline void skb_gro_remcsum_init(struct gro_remcsum *grc)
+{
+ grc->delta = 0;
+}
+
static inline void skb_gro_remcsum_process(struct sk_buff *skb, void *ptr,
- int start, int offset)
+ int start, int offset,
+ struct gro_remcsum *grc,
+ bool nopartial)
{
__wsum delta;
BUG_ON(!NAPI_GRO_CB(skb)->csum_valid);
+ if (!nopartial) {
+ NAPI_GRO_CB(skb)->gro_remcsum_start =
+ ((unsigned char *)ptr + start) - skb->head;
+ return;
+ }
+
delta = remcsum_adjust(ptr, NAPI_GRO_CB(skb)->csum, start, offset);
/* Adjust skb->csum since we changed the packet */
- skb->csum = csum_add(skb->csum, delta);
NAPI_GRO_CB(skb)->csum = csum_add(NAPI_GRO_CB(skb)->csum, delta);
+
+ grc->offset = (ptr + offset) - (void *)skb->head;
+ grc->delta = delta;
}
+static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,
+ struct gro_remcsum *grc)
+{
+ if (!grc->delta)
+ return;
+
+ remcsum_unadjust((__sum16 *)(skb->head + grc->offset), grc->delta);
+}
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2cdc9d422bed..2b621982938d 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -202,6 +202,13 @@ struct pmu {
*/
int (*event_init) (struct perf_event *event);
+ /*
+ * Notification that the event was mapped or unmapped. Called
+ * in the context of the mapping task.
+ */
+ void (*event_mapped) (struct perf_event *event); /*optional*/
+ void (*event_unmapped) (struct perf_event *event); /*optional*/
+
#define PERF_EF_START 0x01 /* start the counter when adding */
#define PERF_EF_RELOAD 0x02 /* reload the counter when starting */
#define PERF_EF_UPDATE 0x04 /* update the counter when stopping */
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index b9cf6c51b181..918b117a7cd3 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -19,7 +19,7 @@ struct pidmap {
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)
#define PIDMAP_ENTRIES ((PID_MAX_LIMIT+BITS_PER_PAGE-1)/BITS_PER_PAGE)
-struct bsd_acct_struct;
+struct fs_pin;
struct pid_namespace {
struct kref kref;
@@ -37,7 +37,7 @@ struct pid_namespace {
struct dentry *proc_thread_self;
#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
- struct bsd_acct_struct *bacct;
+ struct fs_pin *bacct;
#endif
struct user_namespace *user_ns;
struct work_struct proc_work;
diff --git a/include/linux/platform_data/cpuidle-exynos.h b/include/linux/platform_data/cpuidle-exynos.h
new file mode 100644
index 000000000000..bfa40e4c5d5f
--- /dev/null
+++ b/include/linux/platform_data/cpuidle-exynos.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __CPUIDLE_EXYNOS_H
+#define __CPUIDLE_EXYNOS_H
+
+struct cpuidle_exynos_data {
+ int (*cpu0_enter_aftr)(void);
+ int (*cpu1_powerdown)(void);
+ void (*pre_enter_aftr)(void);
+ void (*post_enter_aftr)(void);
+};
+
+#endif
diff --git a/include/linux/platform_data/dma-dw.h b/include/linux/platform_data/dma-dw.h
index d8155c005242..87ac14c584f2 100644
--- a/include/linux/platform_data/dma-dw.h
+++ b/include/linux/platform_data/dma-dw.h
@@ -13,10 +13,12 @@
#include <linux/device.h>
+#define DW_DMA_MAX_NR_MASTERS 4
+
/**
* struct dw_dma_slave - Controller-specific information about a slave
*
- * @dma_dev: required DMA master device. Depricated.
+ * @dma_dev: required DMA master device
* @src_id: src request line
* @dst_id: dst request line
* @src_master: src master for transfers on allocated channel.
@@ -53,7 +55,7 @@ struct dw_dma_platform_data {
unsigned char chan_priority;
unsigned short block_size;
unsigned char nr_masters;
- unsigned char data_width[4];
+ unsigned char data_width[DW_DMA_MAX_NR_MASTERS];
};
#endif /* _PLATFORM_DATA_DMA_DW_H */
diff --git a/include/linux/platform_data/dma-mmp_tdma.h b/include/linux/platform_data/dma-mmp_tdma.h
index 66574ea39f97..0c72886030ef 100644
--- a/include/linux/platform_data/dma-mmp_tdma.h
+++ b/include/linux/platform_data/dma-mmp_tdma.h
@@ -28,6 +28,13 @@ struct sram_platdata {
int granularity;
};
+#ifdef CONFIG_ARM
extern struct gen_pool *sram_get_gpool(char *pool_name);
+#else
+static inline struct gen_pool *sram_get_gpool(char *pool_name)
+{
+ return NULL;
+}
+#endif
#endif /* __DMA_MMP_TDMA_H */
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 57e75ae9910f..fb31765e935a 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -51,7 +51,7 @@ struct rb_root {
#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
-/* 'empty' nodes are nodes that are known not to be inserted in an rbree */
+/* 'empty' nodes are nodes that are known not to be inserted in an rbtree */
#define RB_EMPTY_NODE(node) \
((node)->__rb_parent_color == (unsigned long)(node))
#define RB_CLEAR_NODE(node) \
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index b38f559130d5..c4c559a45dc8 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -198,7 +198,7 @@ int page_referenced(struct page *, int is_locked,
int try_to_unmap(struct page *, enum ttu_flags flags);
/*
- * Called from mm/filemap_xip.c to unmap empty zero page
+ * Used by uprobes to replace a userspace page safely
*/
pte_t *__page_check_address(struct page *, struct mm_struct *,
unsigned long, spinlock_t **, int);
diff --git a/include/linux/rtc/ds1685.h b/include/linux/rtc/ds1685.h
new file mode 100644
index 000000000000..e6337a56d741
--- /dev/null
+++ b/include/linux/rtc/ds1685.h
@@ -0,0 +1,375 @@
+/*
+ * Definitions for the registers, addresses, and platform data of the
+ * DS1685/DS1687-series RTC chips.
+ *
+ * This Driver also works for the DS17X85/DS17X87 RTC chips. Functionally
+ * similar to the DS1685/DS1687, they support a few extra features which
+ * include larger, battery-backed NV-SRAM, burst-mode access, and an RTC
+ * write counter.
+ *
+ * Copyright (C) 2011-2014 Joshua Kinard <kumba@gentoo.org>.
+ * Copyright (C) 2009 Matthias Fuchs <matthias.fuchs@esd-electronics.com>.
+ *
+ * References:
+ * DS1685/DS1687 3V/5V Real-Time Clocks, 19-5215, Rev 4/10.
+ * DS17x85/DS17x87 3V/5V Real-Time Clocks, 19-5222, Rev 4/10.
+ * DS1689/DS1693 3V/5V Serialized Real-Time Clocks, Rev 112105.
+ * Application Note 90, Using the Multiplex Bus RTC Extended Features.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_RTC_DS1685_H_
+#define _LINUX_RTC_DS1685_H_
+
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+
+/**
+ * struct ds1685_priv - DS1685 private data structure.
+ * @dev: pointer to the rtc_device structure.
+ * @regs: iomapped base address pointer of the RTC registers.
+ * @regstep: padding/step size between registers (optional).
+ * @baseaddr: base address of the RTC device.
+ * @size: resource size.
+ * @lock: private lock variable for spin locking/unlocking.
+ * @work: private workqueue.
+ * @irq: IRQ number assigned to the RTC device.
+ * @prepare_poweroff: pointer to platform pre-poweroff function.
+ * @wake_alarm: pointer to platform wake alarm function.
+ * @post_ram_clear: pointer to platform post ram-clear function.
+ */
+struct ds1685_priv {
+ struct rtc_device *dev;
+ void __iomem *regs;
+ u32 regstep;
+ resource_size_t baseaddr;
+ size_t size;
+ spinlock_t lock;
+ struct work_struct work;
+ int irq_num;
+ bool bcd_mode;
+ bool no_irq;
+ bool uie_unsupported;
+ bool alloc_io_resources;
+ u8 (*read)(struct ds1685_priv *, int);
+ void (*write)(struct ds1685_priv *, int, u8);
+ void (*prepare_poweroff)(void);
+ void (*wake_alarm)(void);
+ void (*post_ram_clear)(void);
+};
+
+
+/**
+ * struct ds1685_rtc_platform_data - platform data structure.
+ * @plat_prepare_poweroff: platform-specific pre-poweroff function.
+ * @plat_wake_alarm: platform-specific wake alarm function.
+ * @plat_post_ram_clear: platform-specific post ram-clear function.
+ *
+ * If your platform needs to use a custom padding/step size between
+ * registers, or uses one or more of the extended interrupts and needs special
+ * handling, then include this header file in your platform definition and
+ * set regstep and the plat_* pointers as appropriate.
+ */
+struct ds1685_rtc_platform_data {
+ const u32 regstep;
+ const bool bcd_mode;
+ const bool no_irq;
+ const bool uie_unsupported;
+ const bool alloc_io_resources;
+ u8 (*plat_read)(struct ds1685_priv *, int);
+ void (*plat_write)(struct ds1685_priv *, int, u8);
+ void (*plat_prepare_poweroff)(void);
+ void (*plat_wake_alarm)(void);
+ void (*plat_post_ram_clear)(void);
+};
+
+
+/*
+ * Time Registers.
+ */
+#define RTC_SECS 0x00 /* Seconds 00-59 */
+#define RTC_SECS_ALARM 0x01 /* Alarm Seconds 00-59 */
+#define RTC_MINS 0x02 /* Minutes 00-59 */
+#define RTC_MINS_ALARM 0x03 /* Alarm Minutes 00-59 */
+#define RTC_HRS 0x04 /* Hours 01-12 AM/PM || 00-23 */
+#define RTC_HRS_ALARM 0x05 /* Alarm Hours 01-12 AM/PM || 00-23 */
+#define RTC_WDAY 0x06 /* Day of Week 01-07 */
+#define RTC_MDAY 0x07 /* Day of Month 01-31 */
+#define RTC_MONTH 0x08 /* Month 01-12 */
+#define RTC_YEAR 0x09 /* Year 00-99 */
+#define RTC_CENTURY 0x48 /* Century 00-99 */
+#define RTC_MDAY_ALARM 0x49 /* Alarm Day of Month 01-31 */
+
+
+/*
+ * Bit masks for the Time registers in BCD Mode (DM = 0).
+ */
+#define RTC_SECS_BCD_MASK 0x7f /* - x x x x x x x */
+#define RTC_MINS_BCD_MASK 0x7f /* - x x x x x x x */
+#define RTC_HRS_12_BCD_MASK 0x1f /* - - - x x x x x */
+#define RTC_HRS_24_BCD_MASK 0x3f /* - - x x x x x x */
+#define RTC_MDAY_BCD_MASK 0x3f /* - - x x x x x x */
+#define RTC_MONTH_BCD_MASK 0x1f /* - - - x x x x x */
+#define RTC_YEAR_BCD_MASK 0xff /* x x x x x x x x */
+
+/*
+ * Bit masks for the Time registers in BIN Mode (DM = 1).
+ */
+#define RTC_SECS_BIN_MASK 0x3f /* - - x x x x x x */
+#define RTC_MINS_BIN_MASK 0x3f /* - - x x x x x x */
+#define RTC_HRS_12_BIN_MASK 0x0f /* - - - - x x x x */
+#define RTC_HRS_24_BIN_MASK 0x1f /* - - - x x x x x */
+#define RTC_MDAY_BIN_MASK 0x1f /* - - - x x x x x */
+#define RTC_MONTH_BIN_MASK 0x0f /* - - - - x x x x */
+#define RTC_YEAR_BIN_MASK 0x7f /* - x x x x x x x */
+
+/*
+ * Bit masks common for the Time registers in BCD or BIN Mode.
+ */
+#define RTC_WDAY_MASK 0x07 /* - - - - - x x x */
+#define RTC_CENTURY_MASK 0xff /* x x x x x x x x */
+#define RTC_MDAY_ALARM_MASK 0xff /* x x x x x x x x */
+#define RTC_HRS_AMPM_MASK BIT(7) /* Mask for the AM/PM bit */
+
+
+
+/*
+ * Control Registers.
+ */
+#define RTC_CTRL_A 0x0a /* Control Register A */
+#define RTC_CTRL_B 0x0b /* Control Register B */
+#define RTC_CTRL_C 0x0c /* Control Register C */
+#define RTC_CTRL_D 0x0d /* Control Register D */
+#define RTC_EXT_CTRL_4A 0x4a /* Extended Control Register 4A */
+#define RTC_EXT_CTRL_4B 0x4b /* Extended Control Register 4B */
+
+
+/*
+ * Bit names in Control Register A.
+ */
+#define RTC_CTRL_A_UIP BIT(7) /* Update In Progress */
+#define RTC_CTRL_A_DV2 BIT(6) /* Countdown Chain */
+#define RTC_CTRL_A_DV1 BIT(5) /* Oscillator Enable */
+#define RTC_CTRL_A_DV0 BIT(4) /* Bank Select */
+#define RTC_CTRL_A_RS2 BIT(2) /* Rate-Selection Bit 2 */
+#define RTC_CTRL_A_RS3 BIT(3) /* Rate-Selection Bit 3 */
+#define RTC_CTRL_A_RS1 BIT(1) /* Rate-Selection Bit 1 */
+#define RTC_CTRL_A_RS0 BIT(0) /* Rate-Selection Bit 0 */
+#define RTC_CTRL_A_RS_MASK 0x0f /* RS3 + RS2 + RS1 + RS0 */
+
+/*
+ * Bit names in Control Register B.
+ */
+#define RTC_CTRL_B_SET BIT(7) /* SET Bit */
+#define RTC_CTRL_B_PIE BIT(6) /* Periodic-Interrupt Enable */
+#define RTC_CTRL_B_AIE BIT(5) /* Alarm-Interrupt Enable */
+#define RTC_CTRL_B_UIE BIT(4) /* Update-Ended Interrupt-Enable */
+#define RTC_CTRL_B_SQWE BIT(3) /* Square-Wave Enable */
+#define RTC_CTRL_B_DM BIT(2) /* Data Mode */
+#define RTC_CTRL_B_2412 BIT(1) /* 12-Hr/24-Hr Mode */
+#define RTC_CTRL_B_DSE BIT(0) /* Daylight Savings Enable */
+#define RTC_CTRL_B_PAU_MASK 0x70 /* PIE + AIE + UIE */
+
+
+/*
+ * Bit names in Control Register C.
+ *
+ * BIT(0), BIT(1), BIT(2), & BIT(3) are unused, always return 0, and cannot
+ * be written to.
+ */
+#define RTC_CTRL_C_IRQF BIT(7) /* Interrupt-Request Flag */
+#define RTC_CTRL_C_PF BIT(6) /* Periodic-Interrupt Flag */
+#define RTC_CTRL_C_AF BIT(5) /* Alarm-Interrupt Flag */
+#define RTC_CTRL_C_UF BIT(4) /* Update-Ended Interrupt Flag */
+#define RTC_CTRL_C_PAU_MASK 0x70 /* PF + AF + UF */
+
+
+/*
+ * Bit names in Control Register D.
+ *
+ * BIT(0) through BIT(6) are unused, always return 0, and cannot
+ * be written to.
+ */
+#define RTC_CTRL_D_VRT BIT(7) /* Valid RAM and Time */
+
+
+/*
+ * Bit names in Extended Control Register 4A.
+ *
+ * On the DS1685/DS1687/DS1689/DS1693, BIT(4) and BIT(5) are reserved for
+ * future use. They can be read from and written to, but have no effect
+ * on the RTC's operation.
+ *
+ * On the DS17x85/DS17x87, BIT(5) is Burst-Mode Enable (BME), and allows
+ * access to the extended NV-SRAM by automatically incrementing the address
+ * register when they are read from or written to.
+ */
+#define RTC_CTRL_4A_VRT2 BIT(7) /* Auxillary Battery Status */
+#define RTC_CTRL_4A_INCR BIT(6) /* Increment-in-Progress Status */
+#define RTC_CTRL_4A_PAB BIT(3) /* Power-Active Bar Control */
+#define RTC_CTRL_4A_RF BIT(2) /* RAM-Clear Flag */
+#define RTC_CTRL_4A_WF BIT(1) /* Wake-Up Alarm Flag */
+#define RTC_CTRL_4A_KF BIT(0) /* Kickstart Flag */
+#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
+#define RTC_CTRL_4A_BME BIT(5) /* Burst-Mode Enable */
+#endif
+#define RTC_CTRL_4A_RWK_MASK 0x07 /* RF + WF + KF */
+
+
+/*
+ * Bit names in Extended Control Register 4B.
+ */
+#define RTC_CTRL_4B_ABE BIT(7) /* Auxillary Battery Enable */
+#define RTC_CTRL_4B_E32K BIT(6) /* Enable 32.768Hz on SQW Pin */
+#define RTC_CTRL_4B_CS BIT(5) /* Crystal Select */
+#define RTC_CTRL_4B_RCE BIT(4) /* RAM Clear-Enable */
+#define RTC_CTRL_4B_PRS BIT(3) /* PAB Reset-Select */
+#define RTC_CTRL_4B_RIE BIT(2) /* RAM Clear-Interrupt Enable */
+#define RTC_CTRL_4B_WIE BIT(1) /* Wake-Up Alarm-Interrupt Enable */
+#define RTC_CTRL_4B_KSE BIT(0) /* Kickstart Interrupt-Enable */
+#define RTC_CTRL_4B_RWK_MASK 0x07 /* RIE + WIE + KSE */
+
+
+/*
+ * Misc register names in Bank 1.
+ *
+ * The DV0 bit in Control Register A must be set to 1 for these registers
+ * to become available, including Extended Control Registers 4A & 4B.
+ */
+#define RTC_BANK1_SSN_MODEL 0x40 /* Model Number */
+#define RTC_BANK1_SSN_BYTE_1 0x41 /* 1st Byte of Serial Number */
+#define RTC_BANK1_SSN_BYTE_2 0x42 /* 2nd Byte of Serial Number */
+#define RTC_BANK1_SSN_BYTE_3 0x43 /* 3rd Byte of Serial Number */
+#define RTC_BANK1_SSN_BYTE_4 0x44 /* 4th Byte of Serial Number */
+#define RTC_BANK1_SSN_BYTE_5 0x45 /* 5th Byte of Serial Number */
+#define RTC_BANK1_SSN_BYTE_6 0x46 /* 6th Byte of Serial Number */
+#define RTC_BANK1_SSN_CRC 0x47 /* Serial CRC Byte */
+#define RTC_BANK1_RAM_DATA_PORT 0x53 /* Extended RAM Data Port */
+
+
+/*
+ * Model-specific registers in Bank 1.
+ *
+ * The addresses below differ depending on the model of the RTC chip
+ * selected in the kernel configuration. Not all of these features are
+ * supported in the main driver at present.
+ *
+ * DS1685/DS1687 - Extended NV-SRAM address (LSB only).
+ * DS1689/DS1693 - Vcc, Vbat, Pwr Cycle Counters & Customer-specific S/N.
+ * DS17x85/DS17x87 - Extended NV-SRAM addresses (MSB & LSB) & Write counter.
+ */
+#if defined(CONFIG_RTC_DRV_DS1685)
+#define RTC_BANK1_RAM_ADDR 0x50 /* NV-SRAM Addr */
+#elif defined(CONFIG_RTC_DRV_DS1689)
+#define RTC_BANK1_VCC_CTR_LSB 0x54 /* Vcc Counter Addr (LSB) */
+#define RTC_BANK1_VCC_CTR_MSB 0x57 /* Vcc Counter Addr (MSB) */
+#define RTC_BANK1_VBAT_CTR_LSB 0x58 /* Vbat Counter Addr (LSB) */
+#define RTC_BANK1_VBAT_CTR_MSB 0x5b /* Vbat Counter Addr (MSB) */
+#define RTC_BANK1_PWR_CTR_LSB 0x5c /* Pwr Cycle Counter Addr (LSB) */
+#define RTC_BANK1_PWR_CTR_MSB 0x5d /* Pwr Cycle Counter Addr (MSB) */
+#define RTC_BANK1_UNIQ_SN 0x60 /* Customer-specific S/N */
+#else /* DS17x85/DS17x87 */
+#define RTC_BANK1_RAM_ADDR_LSB 0x50 /* NV-SRAM Addr (LSB) */
+#define RTC_BANK1_RAM_ADDR_MSB 0x51 /* NV-SRAM Addr (MSB) */
+#define RTC_BANK1_WRITE_CTR 0x5e /* RTC Write Counter */
+#endif
+
+
+/*
+ * Model numbers.
+ *
+ * The DS1688/DS1691 and DS1689/DS1693 chips share the same model number
+ * and the manual doesn't indicate any major differences. As such, they
+ * are regarded as the same chip in this driver.
+ */
+#define RTC_MODEL_DS1685 0x71 /* DS1685/DS1687 */
+#define RTC_MODEL_DS17285 0x72 /* DS17285/DS17287 */
+#define RTC_MODEL_DS1689 0x73 /* DS1688/DS1691/DS1689/DS1693 */
+#define RTC_MODEL_DS17485 0x74 /* DS17485/DS17487 */
+#define RTC_MODEL_DS17885 0x78 /* DS17885/DS17887 */
+
+
+/*
+ * Periodic Interrupt Rates / Square-Wave Output Frequency
+ *
+ * Periodic rates are selected by setting the RS3-RS0 bits in Control
+ * Register A and enabled via either the E32K bit in Extended Control
+ * Register 4B or the SQWE bit in Control Register B.
+ *
+ * E32K overrides the settings of RS3-RS0 and outputs a frequency of 32768Hz
+ * on the SQW pin of the RTC chip. While there are 16 possible selections,
+ * the 1-of-16 decoder is only able to divide the base 32768Hz signal into 13
+ * smaller frequencies. The values 0x01 and 0x02 are not used and are
+ * synonymous with 0x08 and 0x09, respectively.
+ *
+ * When E32K is set to a logic 1, periodic interrupts are disabled and reading
+ * /dev/rtc will return -EINVAL. This also applies if the periodic interrupt
+ * frequency is set to 0Hz.
+ *
+ * Not currently used by the rtc-ds1685 driver because the RTC core removed
+ * support for hardware-generated periodic-interrupts in favour of
+ * hrtimer-generated interrupts. But these defines are kept around for use
+ * in userland, as documentation to the hardware, and possible future use if
+ * hardware-generated periodic interrupts are ever added back.
+ */
+ /* E32K RS3 RS2 RS1 RS0 */
+#define RTC_SQW_8192HZ 0x03 /* 0 0 0 1 1 */
+#define RTC_SQW_4096HZ 0x04 /* 0 0 1 0 0 */
+#define RTC_SQW_2048HZ 0x05 /* 0 0 1 0 1 */
+#define RTC_SQW_1024HZ 0x06 /* 0 0 1 1 0 */
+#define RTC_SQW_512HZ 0x07 /* 0 0 1 1 1 */
+#define RTC_SQW_256HZ 0x08 /* 0 1 0 0 0 */
+#define RTC_SQW_128HZ 0x09 /* 0 1 0 0 1 */
+#define RTC_SQW_64HZ 0x0a /* 0 1 0 1 0 */
+#define RTC_SQW_32HZ 0x0b /* 0 1 0 1 1 */
+#define RTC_SQW_16HZ 0x0c /* 0 1 1 0 0 */
+#define RTC_SQW_8HZ 0x0d /* 0 1 1 0 1 */
+#define RTC_SQW_4HZ 0x0e /* 0 1 1 1 0 */
+#define RTC_SQW_2HZ 0x0f /* 0 1 1 1 1 */
+#define RTC_SQW_0HZ 0x00 /* 0 0 0 0 0 */
+#define RTC_SQW_32768HZ 32768 /* 1 - - - - */
+#define RTC_MAX_USER_FREQ 8192
+
+
+/*
+ * NVRAM data & addresses:
+ * - 50 bytes of NVRAM are available just past the clock registers.
+ * - 64 additional bytes are available in Bank0.
+ *
+ * Extended, battery-backed NV-SRAM:
+ * - DS1685/DS1687 - 128 bytes.
+ * - DS1689/DS1693 - 0 bytes.
+ * - DS17285/DS17287 - 2048 bytes.
+ * - DS17485/DS17487 - 4096 bytes.
+ * - DS17885/DS17887 - 8192 bytes.
+ */
+#define NVRAM_TIME_BASE 0x0e /* NVRAM Addr in Time regs */
+#define NVRAM_BANK0_BASE 0x40 /* NVRAM Addr in Bank0 regs */
+#define NVRAM_SZ_TIME 50
+#define NVRAM_SZ_BANK0 64
+#if defined(CONFIG_RTC_DRV_DS1685)
+# define NVRAM_SZ_EXTND 128
+#elif defined(CONFIG_RTC_DRV_DS1689)
+# define NVRAM_SZ_EXTND 0
+#elif defined(CONFIG_RTC_DRV_DS17285)
+# define NVRAM_SZ_EXTND 2048
+#elif defined(CONFIG_RTC_DRV_DS17485)
+# define NVRAM_SZ_EXTND 4096
+#elif defined(CONFIG_RTC_DRV_DS17885)
+# define NVRAM_SZ_EXTND 8192
+#endif
+#define NVRAM_TOTAL_SZ_BANK0 (NVRAM_SZ_TIME + NVRAM_SZ_BANK0)
+#define NVRAM_TOTAL_SZ (NVRAM_TOTAL_SZ_BANK0 + NVRAM_SZ_EXTND)
+
+
+/*
+ * Function Prototypes.
+ */
+extern void __noreturn
+ds1685_rtc_poweroff(struct platform_device *pdev);
+
+#endif /* _LINUX_RTC_DS1685_H_ */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1bb36edb66b9..30007afe70b3 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -83,11 +83,15 @@
*
* CHECKSUM_PARTIAL:
*
- * This is identical to the case for output below. This may occur on a packet
+ * A checksum is set up to be offloaded to a device as described in the
+ * output description for CHECKSUM_PARTIAL. This may occur on a packet
* received directly from another Linux OS, e.g., a virtualized Linux kernel
- * on the same host. The packet can be treated in the same way as
- * CHECKSUM_UNNECESSARY, except that on output (i.e., forwarding) the
- * checksum must be filled in by the OS or the hardware.
+ * on the same host, or it may be set in the input path in GRO or remote
+ * checksum offload. For the purposes of checksum verification, the checksum
+ * referred to by skb->csum_start + skb->csum_offset and any preceding
+ * checksums in the packet are considered verified. Any checksums in the
+ * packet that are after the checksum being offloaded are not considered to
+ * be verified.
*
* B. Checksumming on output.
*
@@ -2915,7 +2919,10 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb);
static inline int skb_csum_unnecessary(const struct sk_buff *skb)
{
- return ((skb->ip_summed & CHECKSUM_UNNECESSARY) || skb->csum_valid);
+ return ((skb->ip_summed == CHECKSUM_UNNECESSARY) ||
+ skb->csum_valid ||
+ (skb->ip_summed == CHECKSUM_PARTIAL &&
+ skb_checksum_start_offset(skb) >= 0));
}
/**
@@ -3097,16 +3104,29 @@ do { \
compute_pseudo(skb, proto)); \
} while (0)
+static inline void skb_remcsum_adjust_partial(struct sk_buff *skb, void *ptr,
+ u16 start, u16 offset)
+{
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum_start = ((unsigned char *)ptr + start) - skb->head;
+ skb->csum_offset = offset - start;
+}
+
/* Update skbuf and packet to reflect the remote checksum offload operation.
* When called, ptr indicates the starting point for skb->csum when
* ip_summed is CHECKSUM_COMPLETE. If we need create checksum complete
* here, skb_postpull_rcsum is done so skb->csum start is ptr.
*/
static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
- int start, int offset)
+ int start, int offset, bool nopartial)
{
__wsum delta;
+ if (!nopartial) {
+ skb_remcsum_adjust_partial(skb, ptr, start, offset);
+ return;
+ }
+
if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
__skb_checksum_complete(skb);
skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 3388c1b6f7d8..5efe743ce1e8 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -201,6 +201,21 @@ struct platform_freeze_ops {
*/
extern void suspend_set_ops(const struct platform_suspend_ops *ops);
extern int suspend_valid_only_mem(suspend_state_t state);
+
+/* Suspend-to-idle state machnine. */
+enum freeze_state {
+ FREEZE_STATE_NONE, /* Not suspended/suspending. */
+ FREEZE_STATE_ENTER, /* Enter suspend-to-idle. */
+ FREEZE_STATE_WAKE, /* Wake up from suspend-to-idle. */
+};
+
+extern enum freeze_state __read_mostly suspend_freeze_state;
+
+static inline bool idle_should_freeze(void)
+{
+ return unlikely(suspend_freeze_state == FREEZE_STATE_ENTER);
+}
+
extern void freeze_set_ops(const struct platform_freeze_ops *ops);
extern void freeze_wake(void);
@@ -228,6 +243,7 @@ extern int pm_suspend(suspend_state_t state);
static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}
static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
+static inline bool idle_should_freeze(void) { return false; }
static inline void freeze_set_ops(const struct platform_freeze_ops *ops) {}
static inline void freeze_wake(void) {}
#endif /* !CONFIG_SUSPEND */
diff --git a/include/linux/tick.h b/include/linux/tick.h
index eda850ca757a..9c085dc12ae9 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -79,6 +79,9 @@ extern void __init tick_init(void);
extern int tick_is_oneshot_available(void);
extern struct tick_device *tick_get_device(int cpu);
+extern void tick_freeze(void);
+extern void tick_unfreeze(void);
+
# ifdef CONFIG_HIGH_RES_TIMERS
extern int tick_init_highres(void);
extern int tick_program_event(ktime_t expires, int force);
@@ -119,6 +122,8 @@ static inline int tick_oneshot_mode_active(void) { return 0; }
#else /* CONFIG_GENERIC_CLOCKEVENTS */
static inline void tick_init(void) { }
+static inline void tick_freeze(void) { }
+static inline void tick_unfreeze(void) { }
static inline void tick_cancel_sched_timer(int cpu) { }
static inline void tick_clock_notify(void) { }
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
@@ -226,5 +231,4 @@ static inline void tick_nohz_task_switch(struct task_struct *tsk)
__tick_nohz_task_switch(tsk);
}
-
#endif
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 3e0cb4ea3905..07a022641996 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -88,7 +88,9 @@ size_t iov_iter_zero(size_t bytes, struct iov_iter *);
unsigned long iov_iter_alignment(const struct iov_iter *i);
void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov,
unsigned long nr_segs, size_t count);
-void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *iov,
+void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *kvec,
+ unsigned long nr_segs, size_t count);
+void iov_iter_bvec(struct iov_iter *i, int direction, const struct bio_vec *bvec,
unsigned long nr_segs, size_t count);
ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
size_t maxsize, unsigned maxpages, size_t *start);
diff --git a/include/linux/virtio_mmio.h b/include/linux/virtio_mmio.h
index 5c7b6f0daef8..c4b09689ab64 100644
--- a/include/linux/virtio_mmio.h
+++ b/include/linux/virtio_mmio.h
@@ -51,23 +51,29 @@
/* Virtio vendor ID - Read Only */
#define VIRTIO_MMIO_VENDOR_ID 0x00c
-/* Bitmask of the features supported by the host
+/* Bitmask of the features supported by the device (host)
* (32 bits per set) - Read Only */
-#define VIRTIO_MMIO_HOST_FEATURES 0x010
+#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
-/* Host features set selector - Write Only */
-#define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014
+/* Device (host) features set selector - Write Only */
+#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014
-/* Bitmask of features activated by the guest
+/* Bitmask of features activated by the driver (guest)
* (32 bits per set) - Write Only */
-#define VIRTIO_MMIO_GUEST_FEATURES 0x020
+#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
/* Activated features set selector - Write Only */
-#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024
+#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024
+
+
+#ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */
/* Guest's memory page size in bytes - Write Only */
#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028
+#endif
+
+
/* Queue selector - Write Only */
#define VIRTIO_MMIO_QUEUE_SEL 0x030
@@ -77,12 +83,21 @@
/* Queue size for the currently selected queue - Write Only */
#define VIRTIO_MMIO_QUEUE_NUM 0x038
+
+#ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */
+
/* Used Ring alignment for the currently selected queue - Write Only */
#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c
/* Guest's PFN for the currently selected queue - Read Write */
#define VIRTIO_MMIO_QUEUE_PFN 0x040
+#endif
+
+
+/* Ready bit for the currently selected queue - Read Write */
+#define VIRTIO_MMIO_QUEUE_READY 0x044
+
/* Queue notifier - Write Only */
#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050
@@ -95,6 +110,21 @@
/* Device status register - Read Write */
#define VIRTIO_MMIO_STATUS 0x070
+/* Selected queue's Descriptor Table address, 64 bits in two halves */
+#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080
+#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084
+
+/* Selected queue's Available Ring address, 64 bits in two halves */
+#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090
+#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094
+
+/* Selected queue's Used Ring address, 64 bits in two halves */
+#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0
+#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4
+
+/* Configuration atomicity value */
+#define VIRTIO_MMIO_CONFIG_GENERATION 0x0fc
+
/* The config space is defined by each driver as
* the per-driver configuration space - Read Write */
#define VIRTIO_MMIO_CONFIG 0x100
diff --git a/include/net/checksum.h b/include/net/checksum.h
index e339a9513e29..0a55ac715077 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -167,4 +167,9 @@ static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
return delta;
}
+static inline void remcsum_unadjust(__sum16 *psum, __wsum delta)
+{
+ *psum = csum_fold(csum_sub(delta, *psum));
+}
+
#endif
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 2927d6244481..eabd3a038674 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -128,13 +128,15 @@ struct vxlan_sock {
#define VXLAN_F_REMCSUM_TX 0x200
#define VXLAN_F_REMCSUM_RX 0x400
#define VXLAN_F_GBP 0x800
+#define VXLAN_F_REMCSUM_NOPARTIAL 0x1000
/* Flags that are used in the receive patch. These flags must match in
* order for a socket to be shareable
*/
#define VXLAN_F_RCV_FLAGS (VXLAN_F_GBP | \
VXLAN_F_UDP_ZERO_CSUM6_RX | \
- VXLAN_F_REMCSUM_RX)
+ VXLAN_F_REMCSUM_RX | \
+ VXLAN_F_REMCSUM_NOPARTIAL)
struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
vxlan_rcv_t *rcv, void *data,
diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h
index 8e1249474e84..b5f7b5f8d008 100644
--- a/include/soc/tegra/fuse.h
+++ b/include/soc/tegra/fuse.h
@@ -21,6 +21,7 @@
#define TEGRA30 0x30
#define TEGRA114 0x35
#define TEGRA124 0x40
+#define TEGRA132 0x13
#define TEGRA_FUSE_SKU_CALIB_0 0xf0
#define TEGRA30_FUSE_SATA_CALIB 0x124
diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h
index 30fe2078a547..03909101d4e7 100644
--- a/include/soc/tegra/pm.h
+++ b/include/soc/tegra/pm.h
@@ -17,7 +17,7 @@ enum tegra_suspend_mode {
TEGRA_MAX_SUSPEND_MODE,
};
-#ifdef CONFIG_PM_SLEEP
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
enum tegra_suspend_mode
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode);
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 6cfb841fea7c..6e5abd6d38a2 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -73,6 +73,36 @@ struct extent_status;
{ FALLOC_FL_ZERO_RANGE, "ZERO_RANGE"})
+TRACE_EVENT(ext4_other_inode_update_time,
+ TP_PROTO(struct inode *inode, ino_t orig_ino),
+
+ TP_ARGS(inode, orig_ino),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( ino_t, ino )
+ __field( ino_t, orig_ino )
+ __field( uid_t, uid )
+ __field( gid_t, gid )
+ __field( __u16, mode )
+ ),
+
+ TP_fast_assign(
+ __entry->orig_ino = orig_ino;
+ __entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->uid = i_uid_read(inode);
+ __entry->gid = i_gid_read(inode);
+ __entry->mode = inode->i_mode;
+ ),
+
+ TP_printk("dev %d,%d orig_ino %lu ino %lu mode 0%o uid %u gid %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ (unsigned long) __entry->orig_ino,
+ (unsigned long) __entry->ino, __entry->mode,
+ __entry->uid, __entry->gid)
+);
+
TRACE_EVENT(ext4_free_inode,
TP_PROTO(struct inode *inode),
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
index 0e9310905413..5a14ead59696 100644
--- a/include/trace/events/writeback.h
+++ b/include/trace/events/writeback.h
@@ -18,6 +18,8 @@
{I_FREEING, "I_FREEING"}, \
{I_CLEAR, "I_CLEAR"}, \
{I_SYNC, "I_SYNC"}, \
+ {I_DIRTY_TIME, "I_DIRTY_TIME"}, \
+ {I_DIRTY_TIME_EXPIRED, "I_DIRTY_TIME_EXPIRED"}, \
{I_REFERENCED, "I_REFERENCED"} \
)
@@ -68,6 +70,7 @@ DECLARE_EVENT_CLASS(writeback_dirty_inode_template,
TP_STRUCT__entry (
__array(char, name, 32)
__field(unsigned long, ino)
+ __field(unsigned long, state)
__field(unsigned long, flags)
),
@@ -78,16 +81,25 @@ DECLARE_EVENT_CLASS(writeback_dirty_inode_template,
strncpy(__entry->name,
bdi->dev ? dev_name(bdi->dev) : "(unknown)", 32);
__entry->ino = inode->i_ino;
+ __entry->state = inode->i_state;
__entry->flags = flags;
),
- TP_printk("bdi %s: ino=%lu flags=%s",
+ TP_printk("bdi %s: ino=%lu state=%s flags=%s",
__entry->name,
__entry->ino,
+ show_inode_state(__entry->state),
show_inode_state(__entry->flags)
)
);
+DEFINE_EVENT(writeback_dirty_inode_template, writeback_mark_inode_dirty,
+
+ TP_PROTO(struct inode *inode, int flags),
+
+ TP_ARGS(inode, flags)
+);
+
DEFINE_EVENT(writeback_dirty_inode_template, writeback_dirty_inode_start,
TP_PROTO(struct inode *inode, int flags),
@@ -596,6 +608,52 @@ DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode,
TP_ARGS(inode, wbc, nr_to_write)
);
+DECLARE_EVENT_CLASS(writeback_lazytime_template,
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field(unsigned long, ino )
+ __field(unsigned long, state )
+ __field( __u16, mode )
+ __field(unsigned long, dirtied_when )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
+ __entry->state = inode->i_state;
+ __entry->mode = inode->i_mode;
+ __entry->dirtied_when = inode->dirtied_when;
+ ),
+
+ TP_printk("dev %d,%d ino %lu dirtied %lu state %s mode 0%o",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->ino, __entry->dirtied_when,
+ show_inode_state(__entry->state), __entry->mode)
+);
+
+DEFINE_EVENT(writeback_lazytime_template, writeback_lazytime,
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode)
+);
+
+DEFINE_EVENT(writeback_lazytime_template, writeback_lazytime_iput,
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode)
+);
+
+DEFINE_EVENT(writeback_lazytime_template, writeback_dirty_inode_enqueue,
+
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode)
+);
+
#endif /* _TRACE_WRITEBACK_H */
/* This part must be outside protection */
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index b0b855613641..01b2d6d0e355 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -654,6 +654,13 @@ struct drm_get_cap {
*/
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+/**
+ * DRM_CLIENT_CAP_ATOMIC
+ *
+ * If set to 1, the DRM core will expose atomic properties to userspace
+ */
+#define DRM_CLIENT_CAP_ATOMIC 3
+
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
struct drm_set_client_cap {
__u64 capability;
@@ -777,6 +784,7 @@ struct drm_prime_handle {
#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2)
+#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic)
/**
* Device specific ioctls should only be in their respective headers
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 646ae5f39f42..a284f11a8ef5 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -109,9 +109,6 @@
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
-/* special NV12 tiled format */
-#define DRM_FORMAT_NV12MT fourcc_code('T', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane 64x32 macroblocks */
-
/*
* 3 plane YCbCr
* index 0: Y plane, [7:0] Y
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 86574b0005ff..ca788e01dab2 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -272,6 +272,13 @@ struct drm_mode_get_connector {
#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1)
#define DRM_MODE_PROP_SIGNED_RANGE DRM_MODE_PROP_TYPE(2)
+/* the PROP_ATOMIC flag is used to hide properties from userspace that
+ * is not aware of atomic properties. This is mostly to work around
+ * older userspace (DDX drivers) that read/write each prop they find,
+ * witout being aware that this could be triggering a lengthy modeset.
+ */
+#define DRM_MODE_PROP_ATOMIC 0x80000000
+
struct drm_mode_property_enum {
__u64 value;
char name[DRM_PROP_NAME_LEN];
@@ -338,7 +345,7 @@ struct drm_mode_fb_cmd2 {
/*
* In case of planar formats, this ioctl allows up to 4
- * buffer objects with offets and pitches per plane.
+ * buffer objects with offsets and pitches per plane.
* The pitch and offset order is dictated by the fourcc,
* e.g. NV12 (http://fourcc.org/yuv.php#NV12) is described as:
*
@@ -346,9 +353,9 @@ struct drm_mode_fb_cmd2 {
* followed by an interleaved U/V plane containing
* 8 bit 2x2 subsampled colour difference samples.
*
- * So it would consist of Y as offset[0] and UV as
- * offeset[1]. Note that offset[0] will generally
- * be 0.
+ * So it would consist of Y as offsets[0] and UV as
+ * offsets[1]. Note that offsets[0] will generally
+ * be 0 (but this is not required).
*/
__u32 handles[4];
__u32 pitches[4]; /* pitch for each plane */
@@ -519,4 +526,27 @@ struct drm_mode_destroy_dumb {
uint32_t handle;
};
+/* page-flip flags are valid, plus: */
+#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
+#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
+#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
+
+#define DRM_MODE_ATOMIC_FLAGS (\
+ DRM_MODE_PAGE_FLIP_EVENT |\
+ DRM_MODE_PAGE_FLIP_ASYNC |\
+ DRM_MODE_ATOMIC_TEST_ONLY |\
+ DRM_MODE_ATOMIC_NONBLOCK |\
+ DRM_MODE_ATOMIC_ALLOW_MODESET)
+
+struct drm_mode_atomic {
+ __u32 flags;
+ __u32 count_objs;
+ __u64 objs_ptr;
+ __u64 count_props_ptr;
+ __u64 props_ptr;
+ __u64 prop_values_ptr;
+ __u64 reserved;
+ __u64 user_data;
+};
+
#endif
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 250262265ee3..6eed16b92a24 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -224,6 +224,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_REG_READ 0x31
#define DRM_I915_GET_RESET_STATS 0x32
#define DRM_I915_GEM_USERPTR 0x33
+#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
+#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -275,6 +277,8 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
#define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
#define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr)
+#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
+#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -341,6 +345,8 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_HAS_WT 27
#define I915_PARAM_CMD_PARSER_VERSION 28
#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
+#define I915_PARAM_MMAP_VERSION 30
+#define I915_PARAM_HAS_BSD2 31
typedef struct drm_i915_getparam {
int param;
@@ -488,6 +494,14 @@ struct drm_i915_gem_mmap {
* This is a fixed-size type for 32/64 compatibility.
*/
__u64 addr_ptr;
+
+ /**
+ * Flags for extended behaviour.
+ *
+ * Added in version 2.
+ */
+ __u64 flags;
+#define I915_MMAP_WC 0x1
};
struct drm_i915_gem_mmap_gtt {
@@ -737,7 +751,13 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_HANDLE_LUT (1<<12)
-#define __I915_EXEC_UNKNOWN_FLAGS -(I915_EXEC_HANDLE_LUT<<1)
+/** Used for switching BSD rings on the platforms with two BSD rings */
+#define I915_EXEC_BSD_MASK (3<<13)
+#define I915_EXEC_BSD_DEFAULT (0<<13) /* default ping-pong mode */
+#define I915_EXEC_BSD_RING1 (1<<13)
+#define I915_EXEC_BSD_RING2 (2<<13)
+
+#define __I915_EXEC_UNKNOWN_FLAGS -(1<<15)
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
@@ -1073,4 +1093,12 @@ struct drm_i915_gem_userptr {
__u32 handle;
};
+struct drm_i915_gem_context_param {
+ __u32 ctx_id;
+ __u32 size;
+ __u64 param;
+#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1
+ __u64 value;
+};
+
#endif /* _UAPI_I915_DRM_H_ */
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 7b8141bf59a7..68ceb97c458c 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -370,7 +370,6 @@ header-y += snmp.h
header-y += sock_diag.h
header-y += socket.h
header-y += sockios.h
-header-y += som.h
header-y += sonet.h
header-y += sonypi.h
header-y += soundcard.h
diff --git a/include/uapi/linux/fou.h b/include/uapi/linux/fou.h
index 8df06894da23..c303588bb767 100644
--- a/include/uapi/linux/fou.h
+++ b/include/uapi/linux/fou.h
@@ -14,6 +14,7 @@ enum {
FOU_ATTR_AF, /* u8 */
FOU_ATTR_IPPROTO, /* u8 */
FOU_ATTR_TYPE, /* u8 */
+ FOU_ATTR_REMCSUM_NOPARTIAL, /* flag */
__FOU_ATTR_MAX,
};
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 3735fa0a6784..9b964a5920af 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -90,6 +90,7 @@ struct inodes_stat_t {
#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
#define MS_I_VERSION (1<<23) /* Update inode I_version field */
#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
+#define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
/* These sb flags are internal to the kernel */
#define MS_NOSEC (1<<28)
@@ -100,7 +101,8 @@ struct inodes_stat_t {
/*
* Superblock flags that can be altered by MS_REMOUNT
*/
-#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|\
+ MS_LAZYTIME)
/*
* Old magic mount flag and mask
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 0deee3eeddbf..dfd0bb22e554 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -374,6 +374,7 @@ enum {
IFLA_VXLAN_REMCSUM_TX,
IFLA_VXLAN_REMCSUM_RX,
IFLA_VXLAN_GBP,
+ IFLA_VXLAN_REMCSUM_NOPARTIAL,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 6925f5b42f89..99048e501b88 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -55,12 +55,6 @@ struct kexec_segment {
size_t memsz;
};
-/* Load a new kernel image as described by the kexec_segment array
- * consisting of passed number of segments at the entry-point address.
- * The flags allow different useage types.
- */
-extern int kexec_load(void *, size_t, struct kexec_segment *,
- unsigned long int);
#endif /* __KERNEL__ */
#endif /* _UAPILINUX_KEXEC_H */
diff --git a/include/uapi/linux/som.h b/include/uapi/linux/som.h
deleted file mode 100644
index 166594e4e7be..000000000000
--- a/include/uapi/linux/som.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#ifndef _LINUX_SOM_H
-#define _LINUX_SOM_H
-
-/* File format definition for SOM executables / shared libraries */
-
-/* we need struct timespec */
-#include <linux/time.h>
-
-#define SOM_PAGESIZE 4096
-
-/* this is the SOM header */
-struct som_hdr {
- short system_id; /* magic number - system */
- short a_magic; /* magic number - file type */
- unsigned int version_id; /* versiod ID: YYMMDDHH */
- struct timespec file_time; /* system clock */
- unsigned int entry_space; /* space for entry point */
- unsigned int entry_subspace; /* subspace for entry point */
- unsigned int entry_offset; /* offset of entry point */
- unsigned int aux_header_location; /* auxiliary header location */
- unsigned int aux_header_size; /* auxiliary header size */
- unsigned int som_length; /* length of entire SOM */
- unsigned int presumed_dp; /* compiler's DP value */
- unsigned int space_location; /* space dictionary location */
- unsigned int space_total; /* number of space entries */
- unsigned int subspace_location; /* subspace entries location */
- unsigned int subspace_total; /* number of subspace entries */
- unsigned int loader_fixup_location; /* MPE/iX loader fixup */
- unsigned int loader_fixup_total; /* number of fixup records */
- unsigned int space_strings_location; /* (sub)space names */
- unsigned int space_strings_size; /* size of strings area */
- unsigned int init_array_location; /* reserved */
- unsigned int init_array_total; /* reserved */
- unsigned int compiler_location; /* module dictionary */
- unsigned int compiler_total; /* number of modules */
- unsigned int symbol_location; /* symbol dictionary */
- unsigned int symbol_total; /* number of symbols */
- unsigned int fixup_request_location; /* fixup requests */
- unsigned int fixup_request_total; /* number of fixup requests */
- unsigned int symbol_strings_location;/* module & symbol names area */
- unsigned int symbol_strings_size; /* size of strings area */
- unsigned int unloadable_sp_location; /* unloadable spaces location */
- unsigned int unloadable_sp_size; /* size of data */
- unsigned int checksum;
-};
-
-/* values for system_id */
-
-#define SOM_SID_PARISC_1_0 0x020b
-#define SOM_SID_PARISC_1_1 0x0210
-#define SOM_SID_PARISC_2_0 0x0214
-
-/* values for a_magic */
-
-#define SOM_LIB_EXEC 0x0104
-#define SOM_RELOCATABLE 0x0106
-#define SOM_EXEC_NONSHARE 0x0107
-#define SOM_EXEC_SHARE 0x0108
-#define SOM_EXEC_DEMAND 0x010B
-#define SOM_LIB_DYN 0x010D
-#define SOM_LIB_SHARE 0x010E
-#define SOM_LIB_RELOC 0x0619
-
-/* values for version_id. Decimal not hex, yes. Grr. */
-
-#define SOM_ID_OLD 85082112
-#define SOM_ID_NEW 87102412
-
-struct aux_id {
- unsigned int mandatory :1; /* the linker must understand this */
- unsigned int copy :1; /* Must be copied by the linker */
- unsigned int append :1; /* Must be merged by the linker */
- unsigned int ignore :1; /* Discard section if unknown */
- unsigned int reserved :12;
- unsigned int type :16; /* Header type */
- unsigned int length; /* length of _following_ data */
-};
-
-/* The Exec Auxiliary Header. Called The HP-UX Header within HP apparently. */
-struct som_exec_auxhdr {
- struct aux_id som_auxhdr;
- int exec_tsize; /* Text size in bytes */
- int exec_tmem; /* Address to load text at */
- int exec_tfile; /* Location of text in file */
- int exec_dsize; /* Data size in bytes */
- int exec_dmem; /* Address to load data at */
- int exec_dfile; /* Location of data in file */
- int exec_bsize; /* Uninitialised data (bss) */
- int exec_entry; /* Address to start executing */
- int exec_flags; /* loader flags */
- int exec_bfill; /* initialisation value for bss */
-};
-
-/* Oh, the things people do to avoid casts. Shame it'll break with gcc's
- * new aliasing rules really.
- */
-union name_pt {
- char * n_name;
- unsigned int n_strx;
-};
-
-/* The Space Dictionary */
-struct space_dictionary_record {
- union name_pt name; /* index to subspace name */
- unsigned int is_loadable :1; /* loadable */
- unsigned int is_defined :1; /* defined within file */
- unsigned int is_private :1; /* not sharable */
- unsigned int has_intermediate_code :1; /* contains intermediate code */
- unsigned int is_tspecific :1; /* thread specific */
- unsigned int reserved :11; /* for future expansion */
- unsigned int sort_key :8; /* for linker */
- unsigned int reserved2 :8; /* for future expansion */
-
- int space_number; /* index */
- int subspace_index; /* index into subspace dict */
- unsigned int subspace_quantity; /* number of subspaces */
- int loader_fix_index; /* for loader */
- unsigned int loader_fix_quantity; /* for loader */
- int init_pointer_index; /* data pointer array index */
- unsigned int init_pointer_quantity; /* number of data pointers */
-};
-
-/* The Subspace Dictionary */
-struct subspace_dictionary_record {
- int space_index;
- unsigned int access_control_bits :7;
- unsigned int memory_resident :1;
- unsigned int dup_common :1;
- unsigned int is_common :1;
- unsigned int quadrant :2;
- unsigned int initially_frozen :1;
- unsigned int is_first :1;
- unsigned int code_only :1;
- unsigned int sort_key :8;
- unsigned int replicate_init :1;
- unsigned int continuation :1;
- unsigned int is_tspecific :1;
- unsigned int is_comdat :1;
- unsigned int reserved :4;
-
- int file_loc_init_value;
- unsigned int initialization_length;
- unsigned int subspace_start;
- unsigned int subspace_length;
-
- unsigned int reserved2 :5;
- unsigned int alignment :27;
-
- union name_pt name;
- int fixup_request_index;
- unsigned int fixup_request_quantity;
-};
-
-#endif /* _LINUX_SOM_H */
diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h
index be40f7059e93..4b0488f20b2e 100644
--- a/include/uapi/linux/virtio_balloon.h
+++ b/include/uapi/linux/virtio_balloon.h
@@ -36,8 +36,7 @@
/* Size of a PFN in the balloon interface. */
#define VIRTIO_BALLOON_PFN_SHIFT 12
-struct virtio_balloon_config
-{
+struct virtio_balloon_config {
/* Number of pages host wants Guest to give up. */
__le32 num_pages;
/* Number of pages we've actually got in balloon. */
diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h
index 247c8ba8544a..3c53eec4ae22 100644
--- a/include/uapi/linux/virtio_blk.h
+++ b/include/uapi/linux/virtio_blk.h
@@ -31,22 +31,25 @@
#include <linux/virtio_types.h>
/* Feature bits */
-#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */
#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/
-#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
-#define VIRTIO_BLK_F_WCE 9 /* Writeback mode enabled after reset */
#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */
-#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
#define VIRTIO_BLK_F_MQ 12 /* support more than one vq */
+/* Legacy feature bits */
+#ifndef VIRTIO_BLK_NO_LEGACY
+#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
+#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
+#define VIRTIO_BLK_F_WCE 9 /* Writeback mode enabled after reset */
+#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
#ifndef __KERNEL__
/* Old (deprecated) name for VIRTIO_BLK_F_WCE. */
#define VIRTIO_BLK_F_FLUSH VIRTIO_BLK_F_WCE
#endif
+#endif /* !VIRTIO_BLK_NO_LEGACY */
#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
@@ -100,8 +103,10 @@ struct virtio_blk_config {
#define VIRTIO_BLK_T_IN 0
#define VIRTIO_BLK_T_OUT 1
+#ifndef VIRTIO_BLK_NO_LEGACY
/* This bit says it's a scsi command, not an actual read or write. */
#define VIRTIO_BLK_T_SCSI_CMD 2
+#endif /* VIRTIO_BLK_NO_LEGACY */
/* Cache flush command */
#define VIRTIO_BLK_T_FLUSH 4
@@ -109,8 +114,10 @@ struct virtio_blk_config {
/* Get device ID command */
#define VIRTIO_BLK_T_GET_ID 8
+#ifndef VIRTIO_BLK_NO_LEGACY
/* Barrier before this op. */
#define VIRTIO_BLK_T_BARRIER 0x80000000
+#endif /* !VIRTIO_BLK_NO_LEGACY */
/* This is the first element of the read scatter-gather list. */
struct virtio_blk_outhdr {
@@ -122,12 +129,14 @@ struct virtio_blk_outhdr {
__virtio64 sector;
};
+#ifndef VIRTIO_BLK_NO_LEGACY
struct virtio_scsi_inhdr {
__virtio32 errors;
__virtio32 data_len;
__virtio32 sense_len;
__virtio32 residual;
};
+#endif /* !VIRTIO_BLK_NO_LEGACY */
/* And this is the final byte of the write scatter-gather list. */
#define VIRTIO_BLK_S_OK 0
diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h
index a6d0cdeaacd4..c18264df9504 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -49,12 +49,14 @@
#define VIRTIO_TRANSPORT_F_START 28
#define VIRTIO_TRANSPORT_F_END 33
+#ifndef VIRTIO_CONFIG_NO_LEGACY
/* Do we get callbacks when the ring is completely used, even if we've
* suppressed them? */
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
/* Can the device handle any descriptor layout? */
#define VIRTIO_F_ANY_LAYOUT 27
+#endif /* VIRTIO_CONFIG_NO_LEGACY */
/* v1.0 compliant. */
#define VIRTIO_F_VERSION_1 32
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index b5f1677b291c..7bbee79ca293 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -35,7 +35,6 @@
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
-#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */
#define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */
@@ -56,6 +55,10 @@
* Steering */
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
+#ifndef VIRTIO_NET_NO_LEGACY
+#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */
+#endif /* VIRTIO_NET_NO_LEGACY */
+
#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */
#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */
@@ -71,19 +74,39 @@ struct virtio_net_config {
__u16 max_virtqueue_pairs;
} __attribute__((packed));
+/*
+ * This header comes first in the scatter-gather list. If you don't
+ * specify GSO or CSUM features, you can simply ignore the header.
+ *
+ * This is bitwise-equivalent to the legacy struct virtio_net_hdr_mrg_rxbuf,
+ * only flattened.
+ */
+struct virtio_net_hdr_v1 {
+#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start, csum_offset */
+#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */
+ __u8 flags;
+#define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame */
+#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */
+#define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */
+#define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */
+#define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */
+ __u8 gso_type;
+ __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
+ __virtio16 gso_size; /* Bytes to append to hdr_len per frame */
+ __virtio16 csum_start; /* Position to start checksumming from */
+ __virtio16 csum_offset; /* Offset after that to place checksum */
+ __virtio16 num_buffers; /* Number of merged rx buffers */
+};
+
+#ifndef VIRTIO_NET_NO_LEGACY
/* This header comes first in the scatter-gather list.
- * If VIRTIO_F_ANY_LAYOUT is not negotiated, it must
+ * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, it must
* be the first element of the scatter-gather list. If you don't
* specify GSO or CSUM features, you can simply ignore the header. */
struct virtio_net_hdr {
-#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 // Use csum_start, csum_offset
-#define VIRTIO_NET_HDR_F_DATA_VALID 2 // Csum is valid
+ /* See VIRTIO_NET_HDR_F_* */
__u8 flags;
-#define VIRTIO_NET_HDR_GSO_NONE 0 // Not a GSO frame
-#define VIRTIO_NET_HDR_GSO_TCPV4 1 // GSO frame, IPv4 TCP (TSO)
-#define VIRTIO_NET_HDR_GSO_UDP 3 // GSO frame, IPv4 UDP (UFO)
-#define VIRTIO_NET_HDR_GSO_TCPV6 4 // GSO frame, IPv6 TCP
-#define VIRTIO_NET_HDR_GSO_ECN 0x80 // TCP has ECN set
+ /* See VIRTIO_NET_HDR_GSO_* */
__u8 gso_type;
__virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
__virtio16 gso_size; /* Bytes to append to hdr_len per frame */
@@ -97,6 +120,7 @@ struct virtio_net_hdr_mrg_rxbuf {
struct virtio_net_hdr hdr;
__virtio16 num_buffers; /* Number of merged rx buffers */
};
+#endif /* ...VIRTIO_NET_NO_LEGACY */
/*
* Control virtqueue data structures
diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h
index 35b552c7f330..75301468359f 100644
--- a/include/uapi/linux/virtio_pci.h
+++ b/include/uapi/linux/virtio_pci.h
@@ -39,7 +39,7 @@
#ifndef _LINUX_VIRTIO_PCI_H
#define _LINUX_VIRTIO_PCI_H
-#include <linux/virtio_config.h>
+#include <linux/types.h>
#ifndef VIRTIO_PCI_NO_LEGACY
@@ -99,4 +99,95 @@
/* Vector value used to disable MSI for queue */
#define VIRTIO_MSI_NO_VECTOR 0xffff
+#ifndef VIRTIO_PCI_NO_MODERN
+
+/* IDs for different capabilities. Must all exist. */
+
+/* Common configuration */
+#define VIRTIO_PCI_CAP_COMMON_CFG 1
+/* Notifications */
+#define VIRTIO_PCI_CAP_NOTIFY_CFG 2
+/* ISR access */
+#define VIRTIO_PCI_CAP_ISR_CFG 3
+/* Device specific configuration */
+#define VIRTIO_PCI_CAP_DEVICE_CFG 4
+/* PCI configuration access */
+#define VIRTIO_PCI_CAP_PCI_CFG 5
+
+/* This is the PCI capability header: */
+struct virtio_pci_cap {
+ __u8 cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */
+ __u8 cap_next; /* Generic PCI field: next ptr. */
+ __u8 cap_len; /* Generic PCI field: capability length */
+ __u8 cfg_type; /* Identifies the structure. */
+ __u8 bar; /* Where to find it. */
+ __u8 padding[3]; /* Pad to full dword. */
+ __le32 offset; /* Offset within bar. */
+ __le32 length; /* Length of the structure, in bytes. */
+};
+
+struct virtio_pci_notify_cap {
+ struct virtio_pci_cap cap;
+ __le32 notify_off_multiplier; /* Multiplier for queue_notify_off. */
+};
+
+/* Fields in VIRTIO_PCI_CAP_COMMON_CFG: */
+struct virtio_pci_common_cfg {
+ /* About the whole device. */
+ __le32 device_feature_select; /* read-write */
+ __le32 device_feature; /* read-only */
+ __le32 guest_feature_select; /* read-write */
+ __le32 guest_feature; /* read-write */
+ __le16 msix_config; /* read-write */
+ __le16 num_queues; /* read-only */
+ __u8 device_status; /* read-write */
+ __u8 config_generation; /* read-only */
+
+ /* About a specific virtqueue. */
+ __le16 queue_select; /* read-write */
+ __le16 queue_size; /* read-write, power of 2. */
+ __le16 queue_msix_vector; /* read-write */
+ __le16 queue_enable; /* read-write */
+ __le16 queue_notify_off; /* read-only */
+ __le32 queue_desc_lo; /* read-write */
+ __le32 queue_desc_hi; /* read-write */
+ __le32 queue_avail_lo; /* read-write */
+ __le32 queue_avail_hi; /* read-write */
+ __le32 queue_used_lo; /* read-write */
+ __le32 queue_used_hi; /* read-write */
+};
+
+/* Macro versions of offsets for the Old Timers! */
+#define VIRTIO_PCI_CAP_VNDR 0
+#define VIRTIO_PCI_CAP_NEXT 1
+#define VIRTIO_PCI_CAP_LEN 2
+#define VIRTIO_PCI_CAP_CFG_TYPE 3
+#define VIRTIO_PCI_CAP_BAR 4
+#define VIRTIO_PCI_CAP_OFFSET 8
+#define VIRTIO_PCI_CAP_LENGTH 12
+
+#define VIRTIO_PCI_NOTIFY_CAP_MULT 16
+
+#define VIRTIO_PCI_COMMON_DFSELECT 0
+#define VIRTIO_PCI_COMMON_DF 4
+#define VIRTIO_PCI_COMMON_GFSELECT 8
+#define VIRTIO_PCI_COMMON_GF 12
+#define VIRTIO_PCI_COMMON_MSIX 16
+#define VIRTIO_PCI_COMMON_NUMQ 18
+#define VIRTIO_PCI_COMMON_STATUS 20
+#define VIRTIO_PCI_COMMON_CFGGENERATION 21
+#define VIRTIO_PCI_COMMON_Q_SELECT 22
+#define VIRTIO_PCI_COMMON_Q_SIZE 24
+#define VIRTIO_PCI_COMMON_Q_MSIX 26
+#define VIRTIO_PCI_COMMON_Q_ENABLE 28
+#define VIRTIO_PCI_COMMON_Q_NOFF 30
+#define VIRTIO_PCI_COMMON_Q_DESCLO 32
+#define VIRTIO_PCI_COMMON_Q_DESCHI 36
+#define VIRTIO_PCI_COMMON_Q_AVAILLO 40
+#define VIRTIO_PCI_COMMON_Q_AVAILHI 44
+#define VIRTIO_PCI_COMMON_Q_USEDLO 48
+#define VIRTIO_PCI_COMMON_Q_USEDHI 52
+
+#endif /* VIRTIO_PCI_NO_MODERN */
+
#endif
diff --git a/include/video/exynos7_decon.h b/include/video/exynos7_decon.h
new file mode 100644
index 000000000000..a62b11b613f6
--- /dev/null
+++ b/include/video/exynos7_decon.h
@@ -0,0 +1,349 @@
+/* include/video/exynos7_decon.h
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Ajay Kumar <ajaykumar.rs@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/* VIDCON0 */
+#define VIDCON0 0x00
+
+#define VIDCON0_SWRESET (1 << 28)
+#define VIDCON0_DECON_STOP_STATUS (1 << 2)
+#define VIDCON0_ENVID (1 << 1)
+#define VIDCON0_ENVID_F (1 << 0)
+
+/* VIDOUTCON0 */
+#define VIDOUTCON0 0x4
+
+#define VIDOUTCON0_DUAL_MASK (0x3 << 24)
+#define VIDOUTCON0_DUAL_ON (0x3 << 24)
+#define VIDOUTCON0_DISP_IF_1_ON (0x2 << 24)
+#define VIDOUTCON0_DISP_IF_0_ON (0x1 << 24)
+#define VIDOUTCON0_DUAL_OFF (0x0 << 24)
+#define VIDOUTCON0_IF_SHIFT 23
+#define VIDOUTCON0_IF_MASK (0x1 << 23)
+#define VIDOUTCON0_RGBIF (0x0 << 23)
+#define VIDOUTCON0_I80IF (0x1 << 23)
+
+/* VIDCON3 */
+#define VIDCON3 0x8
+
+/* VIDCON4 */
+#define VIDCON4 0xC
+#define VIDCON4_FIFOCNT_START_EN (1 << 0)
+
+/* VCLKCON0 */
+#define VCLKCON0 0x10
+#define VCLKCON0_CLKVALUP (1 << 8)
+#define VCLKCON0_VCLKFREE (1 << 0)
+
+/* VCLKCON */
+#define VCLKCON1 0x14
+#define VCLKCON1_CLKVAL_NUM_VCLK(val) (((val) & 0xff) << 0)
+#define VCLKCON2 0x18
+
+/* SHADOWCON */
+#define SHADOWCON 0x30
+
+#define SHADOWCON_WINx_PROTECT(_win) (1 << (10 + (_win)))
+
+/* WINCONx */
+#define WINCON(_win) (0x50 + ((_win) * 4))
+
+#define WINCONx_BUFSTATUS (0x3 << 30)
+#define WINCONx_BUFSEL_MASK (0x3 << 28)
+#define WINCONx_BUFSEL_SHIFT 28
+#define WINCONx_TRIPLE_BUF_MODE (0x1 << 18)
+#define WINCONx_DOUBLE_BUF_MODE (0x0 << 18)
+#define WINCONx_BURSTLEN_16WORD (0x0 << 11)
+#define WINCONx_BURSTLEN_8WORD (0x1 << 11)
+#define WINCONx_BURSTLEN_MASK (0x1 << 11)
+#define WINCONx_BURSTLEN_SHIFT 11
+#define WINCONx_BLD_PLANE (0 << 8)
+#define WINCONx_BLD_PIX (1 << 8)
+#define WINCONx_ALPHA_MUL (1 << 7)
+
+#define WINCONx_BPPMODE_MASK (0xf << 2)
+#define WINCONx_BPPMODE_SHIFT 2
+#define WINCONx_BPPMODE_16BPP_565 (0x8 << 2)
+#define WINCONx_BPPMODE_24BPP_BGRx (0x7 << 2)
+#define WINCONx_BPPMODE_24BPP_RGBx (0x6 << 2)
+#define WINCONx_BPPMODE_24BPP_xBGR (0x5 << 2)
+#define WINCONx_BPPMODE_24BPP_xRGB (0x4 << 2)
+#define WINCONx_BPPMODE_32BPP_BGRA (0x3 << 2)
+#define WINCONx_BPPMODE_32BPP_RGBA (0x2 << 2)
+#define WINCONx_BPPMODE_32BPP_ABGR (0x1 << 2)
+#define WINCONx_BPPMODE_32BPP_ARGB (0x0 << 2)
+#define WINCONx_ALPHA_SEL (1 << 1)
+#define WINCONx_ENWIN (1 << 0)
+
+#define WINCON1_ALPHA_MUL_F (1 << 7)
+#define WINCON2_ALPHA_MUL_F (1 << 7)
+#define WINCON3_ALPHA_MUL_F (1 << 7)
+#define WINCON4_ALPHA_MUL_F (1 << 7)
+
+/* VIDOSDxH: The height for the OSD image(READ ONLY)*/
+#define VIDOSD_H(_x) (0x80 + ((_x) * 4))
+
+/* Frame buffer start addresses: VIDWxxADD0n */
+#define VIDW_BUF_START(_win) (0x80 + ((_win) * 0x10))
+#define VIDW_BUF_START1(_win) (0x84 + ((_win) * 0x10))
+#define VIDW_BUF_START2(_win) (0x88 + ((_win) * 0x10))
+
+#define VIDW_WHOLE_X(_win) (0x0130 + ((_win) * 8))
+#define VIDW_WHOLE_Y(_win) (0x0134 + ((_win) * 8))
+#define VIDW_OFFSET_X(_win) (0x0170 + ((_win) * 8))
+#define VIDW_OFFSET_Y(_win) (0x0174 + ((_win) * 8))
+#define VIDW_BLKOFFSET(_win) (0x01B0 + ((_win) * 4))
+#define VIDW_BLKSIZE(win) (0x0200 + ((_win) * 4))
+
+/* Interrupt controls register */
+#define VIDINTCON2 0x228
+
+#define VIDINTCON1_INTEXTRA1_EN (1 << 1)
+#define VIDINTCON1_INTEXTRA0_EN (1 << 0)
+
+/* Interrupt controls and status register */
+#define VIDINTCON3 0x22C
+
+#define VIDINTCON1_INTEXTRA1_PEND (1 << 1)
+#define VIDINTCON1_INTEXTRA0_PEND (1 << 0)
+
+/* VIDOSDxA ~ VIDOSDxE */
+#define VIDOSD_BASE 0x230
+
+#define OSD_STRIDE 0x20
+
+#define VIDOSD_A(_win) (VIDOSD_BASE + \
+ ((_win) * OSD_STRIDE) + 0x00)
+#define VIDOSD_B(_win) (VIDOSD_BASE + \
+ ((_win) * OSD_STRIDE) + 0x04)
+#define VIDOSD_C(_win) (VIDOSD_BASE + \
+ ((_win) * OSD_STRIDE) + 0x08)
+#define VIDOSD_D(_win) (VIDOSD_BASE + \
+ ((_win) * OSD_STRIDE) + 0x0C)
+#define VIDOSD_E(_win) (VIDOSD_BASE + \
+ ((_win) * OSD_STRIDE) + 0x10)
+
+#define VIDOSDxA_TOPLEFT_X_MASK (0x1fff << 13)
+#define VIDOSDxA_TOPLEFT_X_SHIFT 13
+#define VIDOSDxA_TOPLEFT_X_LIMIT 0x1fff
+#define VIDOSDxA_TOPLEFT_X(_x) (((_x) & 0x1fff) << 13)
+
+#define VIDOSDxA_TOPLEFT_Y_MASK (0x1fff << 0)
+#define VIDOSDxA_TOPLEFT_Y_SHIFT 0
+#define VIDOSDxA_TOPLEFT_Y_LIMIT 0x1fff
+#define VIDOSDxA_TOPLEFT_Y(_x) (((_x) & 0x1fff) << 0)
+
+#define VIDOSDxB_BOTRIGHT_X_MASK (0x1fff << 13)
+#define VIDOSDxB_BOTRIGHT_X_SHIFT 13
+#define VIDOSDxB_BOTRIGHT_X_LIMIT 0x1fff
+#define VIDOSDxB_BOTRIGHT_X(_x) (((_x) & 0x1fff) << 13)
+
+#define VIDOSDxB_BOTRIGHT_Y_MASK (0x1fff << 0)
+#define VIDOSDxB_BOTRIGHT_Y_SHIFT 0
+#define VIDOSDxB_BOTRIGHT_Y_LIMIT 0x1fff
+#define VIDOSDxB_BOTRIGHT_Y(_x) (((_x) & 0x1fff) << 0)
+
+#define VIDOSDxC_ALPHA0_R_F(_x) (((_x) & 0xFF) << 16)
+#define VIDOSDxC_ALPHA0_G_F(_x) (((_x) & 0xFF) << 8)
+#define VIDOSDxC_ALPHA0_B_F(_x) (((_x) & 0xFF) << 0)
+
+#define VIDOSDxD_ALPHA1_R_F(_x) (((_x) & 0xFF) << 16)
+#define VIDOSDxD_ALPHA1_G_F(_x) (((_x) & 0xFF) << 8)
+#define VIDOSDxD_ALPHA1_B_F(_x) (((_x) & 0xFF) >> 0)
+
+/* Window MAP (Color map) */
+#define WINxMAP(_win) (0x340 + ((_win) * 4))
+
+#define WINxMAP_MAP (1 << 24)
+#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0)
+#define WINxMAP_MAP_COLOUR_SHIFT 0
+#define WINxMAP_MAP_COLOUR_LIMIT 0xffffff
+#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0)
+
+/* Window colour-key control registers */
+#define WKEYCON 0x370
+
+#define WKEYCON0 0x00
+#define WKEYCON1 0x04
+#define WxKEYCON0_KEYBL_EN (1 << 26)
+#define WxKEYCON0_KEYEN_F (1 << 25)
+#define WxKEYCON0_DIRCON (1 << 24)
+#define WxKEYCON0_COMPKEY_MASK (0xffffff << 0)
+#define WxKEYCON0_COMPKEY_SHIFT 0
+#define WxKEYCON0_COMPKEY_LIMIT 0xffffff
+#define WxKEYCON0_COMPKEY(_x) ((_x) << 0)
+#define WxKEYCON1_COLVAL_MASK (0xffffff << 0)
+#define WxKEYCON1_COLVAL_SHIFT 0
+#define WxKEYCON1_COLVAL_LIMIT 0xffffff
+#define WxKEYCON1_COLVAL(_x) ((_x) << 0)
+
+/* color key control register for hardware window 1 ~ 4. */
+#define WKEYCON0_BASE(x) ((WKEYCON + WKEYCON0) + ((x - 1) * 8))
+/* color key value register for hardware window 1 ~ 4. */
+#define WKEYCON1_BASE(x) ((WKEYCON + WKEYCON1) + ((x - 1) * 8))
+
+/* Window KEY Alpha value */
+#define WxKEYALPHA(_win) (0x3A0 + (((_win) - 1) * 0x4))
+
+#define Wx_KEYALPHA_R_F_SHIFT 16
+#define Wx_KEYALPHA_G_F_SHIFT 8
+#define Wx_KEYALPHA_B_F_SHIFT 0
+
+/* Blending equation */
+#define BLENDE(_win) (0x03C0 + ((_win) * 4))
+#define BLENDE_COEF_ZERO 0x0
+#define BLENDE_COEF_ONE 0x1
+#define BLENDE_COEF_ALPHA_A 0x2
+#define BLENDE_COEF_ONE_MINUS_ALPHA_A 0x3
+#define BLENDE_COEF_ALPHA_B 0x4
+#define BLENDE_COEF_ONE_MINUS_ALPHA_B 0x5
+#define BLENDE_COEF_ALPHA0 0x6
+#define BLENDE_COEF_A 0xA
+#define BLENDE_COEF_ONE_MINUS_A 0xB
+#define BLENDE_COEF_B 0xC
+#define BLENDE_COEF_ONE_MINUS_B 0xD
+#define BLENDE_Q_FUNC(_v) ((_v) << 18)
+#define BLENDE_P_FUNC(_v) ((_v) << 12)
+#define BLENDE_B_FUNC(_v) ((_v) << 6)
+#define BLENDE_A_FUNC(_v) ((_v) << 0)
+
+/* Blending equation control */
+#define BLENDCON 0x3D8
+#define BLENDCON_NEW_MASK (1 << 0)
+#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
+#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0)
+
+/* Interrupt control register */
+#define VIDINTCON0 0x500
+
+#define VIDINTCON0_WAKEUP_MASK (0x3f << 26)
+#define VIDINTCON0_INTEXTRAEN (1 << 21)
+
+#define VIDINTCON0_FRAMESEL0_SHIFT 15
+#define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15)
+#define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15)
+#define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15)
+#define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15)
+#define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15)
+
+#define VIDINTCON0_INT_FRAME (1 << 11)
+
+#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 3)
+#define VIDINTCON0_FIFOLEVEL_SHIFT 3
+#define VIDINTCON0_FIFOLEVEL_EMPTY (0x0 << 3)
+#define VIDINTCON0_FIFOLEVEL_TO25PC (0x1 << 3)
+#define VIDINTCON0_FIFOLEVEL_TO50PC (0x2 << 3)
+#define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 3)
+
+#define VIDINTCON0_FIFOSEL_MAIN_EN (1 << 1)
+#define VIDINTCON0_INT_FIFO (1 << 1)
+
+#define VIDINTCON0_INT_ENABLE (1 << 0)
+
+/* Interrupt controls and status register */
+#define VIDINTCON1 0x504
+
+#define VIDINTCON1_INT_EXTRA (1 << 3)
+#define VIDINTCON1_INT_I80 (1 << 2)
+#define VIDINTCON1_INT_FRAME (1 << 1)
+#define VIDINTCON1_INT_FIFO (1 << 0)
+
+/* VIDCON1 */
+#define VIDCON1(_x) (0x0600 + ((_x) * 0x50))
+#define VIDCON1_LINECNT_GET(_v) (((_v) >> 17) & 0x1fff)
+#define VIDCON1_VCLK_MASK (0x3 << 9)
+#define VIDCON1_VCLK_HOLD (0x0 << 9)
+#define VIDCON1_VCLK_RUN (0x1 << 9)
+#define VIDCON1_VCLK_RUN_VDEN_DISABLE (0x3 << 9)
+#define VIDCON1_RGB_ORDER_O_MASK (0x7 << 4)
+#define VIDCON1_RGB_ORDER_O_RGB (0x0 << 4)
+#define VIDCON1_RGB_ORDER_O_GBR (0x1 << 4)
+#define VIDCON1_RGB_ORDER_O_BRG (0x2 << 4)
+#define VIDCON1_RGB_ORDER_O_BGR (0x4 << 4)
+#define VIDCON1_RGB_ORDER_O_RBG (0x5 << 4)
+#define VIDCON1_RGB_ORDER_O_GRB (0x6 << 4)
+
+/* VIDTCON0 */
+#define VIDTCON0 0x610
+
+#define VIDTCON0_VBPD_MASK (0xffff << 16)
+#define VIDTCON0_VBPD_SHIFT 16
+#define VIDTCON0_VBPD_LIMIT 0xffff
+#define VIDTCON0_VBPD(_x) ((_x) << 16)
+
+#define VIDTCON0_VFPD_MASK (0xffff << 0)
+#define VIDTCON0_VFPD_SHIFT 0
+#define VIDTCON0_VFPD_LIMIT 0xffff
+#define VIDTCON0_VFPD(_x) ((_x) << 0)
+
+/* VIDTCON1 */
+#define VIDTCON1 0x614
+
+#define VIDTCON1_VSPW_MASK (0xffff << 16)
+#define VIDTCON1_VSPW_SHIFT 16
+#define VIDTCON1_VSPW_LIMIT 0xffff
+#define VIDTCON1_VSPW(_x) ((_x) << 16)
+
+/* VIDTCON2 */
+#define VIDTCON2 0x618
+
+#define VIDTCON2_HBPD_MASK (0xffff << 16)
+#define VIDTCON2_HBPD_SHIFT 16
+#define VIDTCON2_HBPD_LIMIT 0xffff
+#define VIDTCON2_HBPD(_x) ((_x) << 16)
+
+#define VIDTCON2_HFPD_MASK (0xffff << 0)
+#define VIDTCON2_HFPD_SHIFT 0
+#define VIDTCON2_HFPD_LIMIT 0xffff
+#define VIDTCON2_HFPD(_x) ((_x) << 0)
+
+/* VIDTCON3 */
+#define VIDTCON3 0x61C
+
+#define VIDTCON3_HSPW_MASK (0xffff << 16)
+#define VIDTCON3_HSPW_SHIFT 16
+#define VIDTCON3_HSPW_LIMIT 0xffff
+#define VIDTCON3_HSPW(_x) ((_x) << 16)
+
+/* VIDTCON4 */
+#define VIDTCON4 0x620
+
+#define VIDTCON4_LINEVAL_MASK (0xfff << 16)
+#define VIDTCON4_LINEVAL_SHIFT 16
+#define VIDTCON4_LINEVAL_LIMIT 0xfff
+#define VIDTCON4_LINEVAL(_x) (((_x) & 0xfff) << 16)
+
+#define VIDTCON4_HOZVAL_MASK (0xfff << 0)
+#define VIDTCON4_HOZVAL_SHIFT 0
+#define VIDTCON4_HOZVAL_LIMIT 0xfff
+#define VIDTCON4_HOZVAL(_x) (((_x) & 0xfff) << 0)
+
+/* LINECNT OP THRSHOLD*/
+#define LINECNT_OP_THRESHOLD 0x630
+
+/* CRCCTRL */
+#define CRCCTRL 0x6C8
+#define CRCCTRL_CRCCLKEN (0x1 << 2)
+#define CRCCTRL_CRCSTART_F (0x1 << 1)
+#define CRCCTRL_CRCEN (0x1 << 0)
+
+/* DECON_CMU */
+#define DECON_CMU 0x704
+
+#define DECON_CMU_ALL_CLKGATE_ENABLE 0x3
+#define DECON_CMU_SE_CLKGATE_ENABLE (0x1 << 2)
+#define DECON_CMU_SFR_CLKGATE_ENABLE (0x1 << 1)
+#define DECON_CMU_MEM_CLKGATE_ENABLE (0x1 << 0)
+
+/* DECON_UPDATE */
+#define DECON_UPDATE 0x710
+
+#define DECON_UPDATE_SLAVE_SYNC (1 << 4)
+#define DECON_UPDATE_STANDALONE_F (1 << 0)
diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h
index c74bf4a0520e..73390c120cad 100644
--- a/include/video/imx-ipu-v3.h
+++ b/include/video/imx-ipu-v3.h
@@ -17,6 +17,7 @@
#include <linux/bitmap.h>
#include <linux/fb.h>
#include <media/v4l2-mediabus.h>
+#include <video/videomode.h>
struct ipu_soc;
@@ -32,28 +33,15 @@ enum ipuv3_type {
* Bitfield of Display Interface signal polarities.
*/
struct ipu_di_signal_cfg {
- unsigned datamask_en:1;
- unsigned interlaced:1;
- unsigned odd_field_first:1;
- unsigned clksel_en:1;
- unsigned clkidle_en:1;
unsigned data_pol:1; /* true = inverted */
unsigned clk_pol:1; /* true = rising edge */
unsigned enable_pol:1;
- unsigned Hsync_pol:1; /* true = active high */
- unsigned Vsync_pol:1;
- u16 width;
- u16 height;
+ struct videomode mode;
+
u32 pixel_fmt;
- u16 h_start_width;
- u16 h_sync_width;
- u16 h_end_width;
- u16 v_start_width;
- u16 v_sync_width;
- u16 v_end_width;
u32 v_to_h_sync;
- unsigned long pixelclock;
+
#define IPU_DI_CLKMODE_SYNC (1 << 0)
#define IPU_DI_CLKMODE_EXT (1 << 1)
unsigned long clkflags;
@@ -236,6 +224,7 @@ void ipu_di_put(struct ipu_di *);
int ipu_di_disable(struct ipu_di *);
int ipu_di_enable(struct ipu_di *);
int ipu_di_get_num(struct ipu_di *);
+int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode);
int ipu_di_init_sync_panel(struct ipu_di *, struct ipu_di_signal_cfg *sig);
/*
diff --git a/ipc/sem.c b/ipc/sem.c
index 6115146563f9..92842113c6a9 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1941,7 +1941,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
queue.sleeper = current;
sleep_again:
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_INTERRUPTIBLE);
sem_unlock(sma, locknum);
rcu_read_unlock();
diff --git a/kernel/acct.c b/kernel/acct.c
index 33738ef972f3..e6c10d1a4058 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -76,10 +76,11 @@ int acct_parm[3] = {4, 2, 30};
/*
* External references and all of the globals.
*/
-static void do_acct_process(struct bsd_acct_struct *acct);
struct bsd_acct_struct {
struct fs_pin pin;
+ atomic_long_t count;
+ struct rcu_head rcu;
struct mutex lock;
int active;
unsigned long needcheck;
@@ -89,6 +90,8 @@ struct bsd_acct_struct {
struct completion done;
};
+static void do_acct_process(struct bsd_acct_struct *acct);
+
/*
* Check the amount of free space and suspend/resume accordingly.
*/
@@ -124,32 +127,56 @@ out:
return acct->active;
}
+static void acct_put(struct bsd_acct_struct *p)
+{
+ if (atomic_long_dec_and_test(&p->count))
+ kfree_rcu(p, rcu);
+}
+
+static inline struct bsd_acct_struct *to_acct(struct fs_pin *p)
+{
+ return p ? container_of(p, struct bsd_acct_struct, pin) : NULL;
+}
+
static struct bsd_acct_struct *acct_get(struct pid_namespace *ns)
{
struct bsd_acct_struct *res;
again:
smp_rmb();
rcu_read_lock();
- res = ACCESS_ONCE(ns->bacct);
+ res = to_acct(ACCESS_ONCE(ns->bacct));
if (!res) {
rcu_read_unlock();
return NULL;
}
- if (!atomic_long_inc_not_zero(&res->pin.count)) {
+ if (!atomic_long_inc_not_zero(&res->count)) {
rcu_read_unlock();
cpu_relax();
goto again;
}
rcu_read_unlock();
mutex_lock(&res->lock);
- if (!res->ns) {
+ if (res != to_acct(ACCESS_ONCE(ns->bacct))) {
mutex_unlock(&res->lock);
- pin_put(&res->pin);
+ acct_put(res);
goto again;
}
return res;
}
+static void acct_pin_kill(struct fs_pin *pin)
+{
+ struct bsd_acct_struct *acct = to_acct(pin);
+ mutex_lock(&acct->lock);
+ do_acct_process(acct);
+ schedule_work(&acct->work);
+ wait_for_completion(&acct->done);
+ cmpxchg(&acct->ns->bacct, pin, NULL);
+ mutex_unlock(&acct->lock);
+ pin_remove(pin);
+ acct_put(acct);
+}
+
static void close_work(struct work_struct *work)
{
struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work);
@@ -160,44 +187,13 @@ static void close_work(struct work_struct *work)
complete(&acct->done);
}
-static void acct_kill(struct bsd_acct_struct *acct,
- struct bsd_acct_struct *new)
-{
- if (acct) {
- struct pid_namespace *ns = acct->ns;
- do_acct_process(acct);
- INIT_WORK(&acct->work, close_work);
- init_completion(&acct->done);
- schedule_work(&acct->work);
- wait_for_completion(&acct->done);
- pin_remove(&acct->pin);
- ns->bacct = new;
- acct->ns = NULL;
- atomic_long_dec(&acct->pin.count);
- mutex_unlock(&acct->lock);
- pin_put(&acct->pin);
- }
-}
-
-static void acct_pin_kill(struct fs_pin *pin)
-{
- struct bsd_acct_struct *acct;
- acct = container_of(pin, struct bsd_acct_struct, pin);
- mutex_lock(&acct->lock);
- if (!acct->ns) {
- mutex_unlock(&acct->lock);
- pin_put(pin);
- acct = NULL;
- }
- acct_kill(acct, NULL);
-}
-
static int acct_on(struct filename *pathname)
{
struct file *file;
struct vfsmount *mnt, *internal;
struct pid_namespace *ns = task_active_pid_ns(current);
- struct bsd_acct_struct *acct, *old;
+ struct bsd_acct_struct *acct;
+ struct fs_pin *old;
int err;
acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
@@ -238,21 +234,21 @@ static int acct_on(struct filename *pathname)
mnt = file->f_path.mnt;
file->f_path.mnt = internal;
- atomic_long_set(&acct->pin.count, 1);
- acct->pin.kill = acct_pin_kill;
+ atomic_long_set(&acct->count, 1);
+ init_fs_pin(&acct->pin, acct_pin_kill);
acct->file = file;
acct->needcheck = jiffies;
acct->ns = ns;
mutex_init(&acct->lock);
+ INIT_WORK(&acct->work, close_work);
+ init_completion(&acct->done);
mutex_lock_nested(&acct->lock, 1); /* nobody has seen it yet */
pin_insert(&acct->pin, mnt);
- old = acct_get(ns);
- if (old)
- acct_kill(old, acct);
- else
- ns->bacct = acct;
+ rcu_read_lock();
+ old = xchg(&ns->bacct, &acct->pin);
mutex_unlock(&acct->lock);
+ pin_kill(old);
mnt_drop_write(mnt);
mntput(mnt);
return 0;
@@ -288,7 +284,8 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
mutex_unlock(&acct_on_mutex);
putname(tmp);
} else {
- acct_kill(acct_get(task_active_pid_ns(current)), NULL);
+ rcu_read_lock();
+ pin_kill(task_active_pid_ns(current)->bacct);
}
return error;
@@ -296,7 +293,8 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
void acct_exit_ns(struct pid_namespace *ns)
{
- acct_kill(acct_get(ns), NULL);
+ rcu_read_lock();
+ pin_kill(ns->bacct);
}
/*
@@ -576,7 +574,7 @@ static void slow_acct_process(struct pid_namespace *ns)
if (acct) {
do_acct_process(acct);
mutex_unlock(&acct->lock);
- pin_put(&acct->pin);
+ acct_put(acct);
}
}
}
diff --git a/kernel/audit.h b/kernel/audit.h
index 3cdffad5a1d9..1caa0d345d90 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -24,12 +24,6 @@
#include <linux/skbuff.h>
#include <uapi/linux/mqueue.h>
-/* 0 = no checking
- 1 = put_count checking
- 2 = verbose put_count checking
-*/
-#define AUDIT_DEBUG 0
-
/* AUDIT_NAMES is the number of slots we reserve in the audit_context
* for saving names from getname(). If we get more names we will allocate
* a name dynamically and also add those to the list anchored by names_list. */
@@ -74,9 +68,8 @@ struct audit_cap_data {
};
};
-/* When fs/namei.c:getname() is called, we store the pointer in name and
- * we don't let putname() free it (instead we free all of the saved
- * pointers at syscall exit time).
+/* When fs/namei.c:getname() is called, we store the pointer in name and bump
+ * the refcnt in the associated filename struct.
*
* Further, in fs/namei.c:path_lookup() we store the inode and device.
*/
@@ -86,7 +79,6 @@ struct audit_names {
struct filename *name;
int name_len; /* number of chars to log */
bool hidden; /* don't log this record */
- bool name_put; /* call __putname()? */
unsigned long ino;
dev_t dev;
@@ -208,11 +200,6 @@ struct audit_context {
};
int fds[2];
struct audit_proctitle proctitle;
-
-#if AUDIT_DEBUG
- int put_count;
- int ino_count;
-#endif
};
extern u32 audit_ever_enabled;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 072566dd0caf..dc4ae70a7413 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -866,33 +866,10 @@ static inline void audit_free_names(struct audit_context *context)
{
struct audit_names *n, *next;
-#if AUDIT_DEBUG == 2
- if (context->put_count + context->ino_count != context->name_count) {
- int i = 0;
-
- pr_err("%s:%d(:%d): major=%d in_syscall=%d"
- " name_count=%d put_count=%d ino_count=%d"
- " [NOT freeing]\n", __FILE__, __LINE__,
- context->serial, context->major, context->in_syscall,
- context->name_count, context->put_count,
- context->ino_count);
- list_for_each_entry(n, &context->names_list, list) {
- pr_err("names[%d] = %p = %s\n", i++, n->name,
- n->name->name ?: "(null)");
- }
- dump_stack();
- return;
- }
-#endif
-#if AUDIT_DEBUG
- context->put_count = 0;
- context->ino_count = 0;
-#endif
-
list_for_each_entry_safe(n, next, &context->names_list, list) {
list_del(&n->list);
- if (n->name && n->name_put)
- final_putname(n->name);
+ if (n->name)
+ putname(n->name);
if (n->should_free)
kfree(n);
}
@@ -1711,9 +1688,6 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,
list_add_tail(&aname->list, &context->names_list);
context->name_count++;
-#if AUDIT_DEBUG
- context->ino_count++;
-#endif
return aname;
}
@@ -1734,8 +1708,10 @@ __audit_reusename(const __user char *uptr)
list_for_each_entry(n, &context->names_list, list) {
if (!n->name)
continue;
- if (n->name->uptr == uptr)
+ if (n->name->uptr == uptr) {
+ n->name->refcnt++;
return n->name;
+ }
}
return NULL;
}
@@ -1752,19 +1728,8 @@ void __audit_getname(struct filename *name)
struct audit_context *context = current->audit_context;
struct audit_names *n;
- if (!context->in_syscall) {
-#if AUDIT_DEBUG == 2
- pr_err("%s:%d(:%d): ignoring getname(%p)\n",
- __FILE__, __LINE__, context->serial, name);
- dump_stack();
-#endif
+ if (!context->in_syscall)
return;
- }
-
-#if AUDIT_DEBUG
- /* The filename _must_ have a populated ->name */
- BUG_ON(!name->name);
-#endif
n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
if (!n)
@@ -1772,56 +1737,13 @@ void __audit_getname(struct filename *name)
n->name = name;
n->name_len = AUDIT_NAME_FULL;
- n->name_put = true;
name->aname = n;
+ name->refcnt++;
if (!context->pwd.dentry)
get_fs_pwd(current->fs, &context->pwd);
}
-/* audit_putname - intercept a putname request
- * @name: name to intercept and delay for putname
- *
- * If we have stored the name from getname in the audit context,
- * then we delay the putname until syscall exit.
- * Called from include/linux/fs.h:putname().
- */
-void audit_putname(struct filename *name)
-{
- struct audit_context *context = current->audit_context;
-
- BUG_ON(!context);
- if (!name->aname || !context->in_syscall) {
-#if AUDIT_DEBUG == 2
- pr_err("%s:%d(:%d): final_putname(%p)\n",
- __FILE__, __LINE__, context->serial, name);
- if (context->name_count) {
- struct audit_names *n;
- int i = 0;
-
- list_for_each_entry(n, &context->names_list, list)
- pr_err("name[%d] = %p = %s\n", i++, n->name,
- n->name->name ?: "(null)");
- }
-#endif
- final_putname(name);
- }
-#if AUDIT_DEBUG
- else {
- ++context->put_count;
- if (context->put_count > context->name_count) {
- pr_err("%s:%d(:%d): major=%d in_syscall=%d putname(%p)"
- " name_count=%d put_count=%d\n",
- __FILE__, __LINE__,
- context->serial, context->major,
- context->in_syscall, name->name,
- context->name_count, context->put_count);
- dump_stack();
- }
- }
-#endif
-}
-
/**
* __audit_inode - store the inode and device from a lookup
* @name: name being audited
@@ -1842,10 +1764,6 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
if (!name)
goto out_alloc;
-#if AUDIT_DEBUG
- /* The struct filename _must_ have a populated ->name */
- BUG_ON(!name->name);
-#endif
/*
* If we have a pointer to an audit_names entry already, then we can
* just use it directly if the type is correct.
@@ -1863,7 +1781,17 @@ void __audit_inode(struct filename *name, const struct dentry *dentry,
}
list_for_each_entry_reverse(n, &context->names_list, list) {
- if (!n->name || strcmp(n->name->name, name->name))
+ if (n->ino) {
+ /* valid inode number, use that for the comparison */
+ if (n->ino != inode->i_ino ||
+ n->dev != inode->i_sb->s_dev)
+ continue;
+ } else if (n->name) {
+ /* inode number has not been set, check the name */
+ if (strcmp(n->name->name, name->name))
+ continue;
+ } else
+ /* no inode and no name (?!) ... this is odd ... */
continue;
/* match the correct record type */
@@ -1882,44 +1810,11 @@ out_alloc:
n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
if (!n)
return;
- /* unfortunately, while we may have a path name to record with the
- * inode, we can't always rely on the string lasting until the end of
- * the syscall so we need to create our own copy, it may fail due to
- * memory allocation issues, but we do our best */
if (name) {
- /* we can't use getname_kernel() due to size limits */
- size_t len = strlen(name->name) + 1;
- struct filename *new = __getname();
-
- if (unlikely(!new))
- goto out;
-
- if (len <= (PATH_MAX - sizeof(*new))) {
- new->name = (char *)(new) + sizeof(*new);
- new->separate = false;
- } else if (len <= PATH_MAX) {
- /* this looks odd, but is due to final_putname() */
- struct filename *new2;
-
- new2 = kmalloc(sizeof(*new2), GFP_KERNEL);
- if (unlikely(!new2)) {
- __putname(new);
- goto out;
- }
- new2->name = (char *)new;
- new2->separate = true;
- new = new2;
- } else {
- /* we should never get here, but let's be safe */
- __putname(new);
- goto out;
- }
- strlcpy((char *)new->name, name->name, len);
- new->uptr = NULL;
- new->aname = n;
- n->name = new;
- n->name_put = true;
+ n->name = name;
+ name->refcnt++;
}
+
out:
if (parent) {
n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
@@ -1970,11 +1865,16 @@ void __audit_inode_child(const struct inode *parent,
/* look for a parent entry first */
list_for_each_entry(n, &context->names_list, list) {
- if (!n->name || n->type != AUDIT_TYPE_PARENT)
+ if (!n->name ||
+ (n->type != AUDIT_TYPE_PARENT &&
+ n->type != AUDIT_TYPE_UNKNOWN))
continue;
- if (n->ino == parent->i_ino &&
- !audit_compare_dname_path(dname, n->name->name, n->name_len)) {
+ if (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev &&
+ !audit_compare_dname_path(dname,
+ n->name->name, n->name_len)) {
+ if (n->type == AUDIT_TYPE_UNKNOWN)
+ n->type = AUDIT_TYPE_PARENT;
found_parent = n;
break;
}
@@ -1983,11 +1883,8 @@ void __audit_inode_child(const struct inode *parent,
/* is there a matching child entry? */
list_for_each_entry(n, &context->names_list, list) {
/* can only match entries that have a name */
- if (!n->name || n->type != type)
- continue;
-
- /* if we found a parent, make sure this one is a child of it */
- if (found_parent && (n->name != found_parent->name))
+ if (!n->name ||
+ (n->type != type && n->type != AUDIT_TYPE_UNKNOWN))
continue;
if (!strcmp(dname, n->name->name) ||
@@ -1995,6 +1892,8 @@ void __audit_inode_child(const struct inode *parent,
found_parent ?
found_parent->name_len :
AUDIT_NAME_FULL)) {
+ if (n->type == AUDIT_TYPE_UNKNOWN)
+ n->type = type;
found_child = n;
break;
}
@@ -2019,10 +1918,10 @@ void __audit_inode_child(const struct inode *parent,
if (found_parent) {
found_child->name = found_parent->name;
found_child->name_len = AUDIT_NAME_FULL;
- /* don't call __putname() */
- found_child->name_put = false;
+ found_child->name->refcnt++;
}
}
+
if (inode)
audit_copy_inode(found_child, dentry, inode);
else
@@ -2405,7 +2304,6 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
struct audit_aux_data_bprm_fcaps *ax;
struct audit_context *context = current->audit_context;
struct cpu_vfs_cap_data vcaps;
- struct dentry *dentry;
ax = kmalloc(sizeof(*ax), GFP_KERNEL);
if (!ax)
@@ -2415,9 +2313,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
ax->d.next = context->aux;
context->aux = (void *)ax;
- dentry = dget(bprm->file->f_path.dentry);
- get_vfs_caps_from_disk(dentry, &vcaps);
- dput(dentry);
+ get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
ax->fcap.permitted = vcaps.permitted;
ax->fcap.inheritable = vcaps.inheritable;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 8812d8e35f5b..f04daabfd1cf 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4101,7 +4101,8 @@ unlock:
rcu_read_unlock();
}
-void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
+void __weak arch_perf_update_userpage(
+ struct perf_event *event, struct perf_event_mmap_page *userpg, u64 now)
{
}
@@ -4151,7 +4152,7 @@ void perf_event_update_userpage(struct perf_event *event)
userpg->time_running = running +
atomic64_read(&event->child_total_time_running);
- arch_perf_update_userpage(userpg, now);
+ arch_perf_update_userpage(event, userpg, now);
barrier();
++userpg->lock;
@@ -4293,6 +4294,9 @@ static void perf_mmap_open(struct vm_area_struct *vma)
atomic_inc(&event->mmap_count);
atomic_inc(&event->rb->mmap_count);
+
+ if (event->pmu->event_mapped)
+ event->pmu->event_mapped(event);
}
/*
@@ -4312,6 +4316,9 @@ static void perf_mmap_close(struct vm_area_struct *vma)
int mmap_locked = rb->mmap_locked;
unsigned long size = perf_data_size(rb);
+ if (event->pmu->event_unmapped)
+ event->pmu->event_unmapped(event);
+
atomic_dec(&rb->mmap_count);
if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex))
@@ -4513,6 +4520,9 @@ unlock:
vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &perf_mmap_vmops;
+ if (event->pmu->event_mapped)
+ event->pmu->event_mapped(event);
+
return ret;
}
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 80692373abd6..196a06fbc122 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -243,6 +243,9 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
return -EINVAL;
desc->affinity_hint = m;
irq_put_desc_unlock(desc, flags);
+ /* set the initial affinity to prevent every interrupt being on CPU0 */
+ if (m)
+ __irq_set_affinity(irq, m, false);
return 0;
}
EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
diff --git a/kernel/kexec.c b/kernel/kexec.c
index c85277639b34..38c25b1f2fd5 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -444,7 +444,7 @@ arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
}
/*
- * Free up memory used by kernel, initrd, and comand line. This is temporary
+ * Free up memory used by kernel, initrd, and command line. This is temporary
* memory allocation which is not needed any more after these buffers have
* been loaded into separate segments and have been copied elsewhere.
*/
@@ -856,8 +856,6 @@ static int kimage_set_destination(struct kimage *image,
destination &= PAGE_MASK;
result = kimage_add_entry(image, destination | IND_DESTINATION);
- if (result == 0)
- image->destination = destination;
return result;
}
@@ -869,8 +867,6 @@ static int kimage_add_page(struct kimage *image, unsigned long page)
page &= PAGE_MASK;
result = kimage_add_entry(image, page | IND_SOURCE);
- if (result == 0)
- image->destination += PAGE_SIZE;
return result;
}
@@ -1288,19 +1284,22 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
if (nr_segments > 0) {
unsigned long i;
- /* Loading another kernel to reboot into */
- if ((flags & KEXEC_ON_CRASH) == 0)
- result = kimage_alloc_init(&image, entry, nr_segments,
- segments, flags);
- /* Loading another kernel to switch to if this one crashes */
- else if (flags & KEXEC_ON_CRASH) {
- /* Free any current crash dump kernel before
+ if (flags & KEXEC_ON_CRASH) {
+ /*
+ * Loading another kernel to switch to if this one
+ * crashes. Free any current crash dump kernel before
* we corrupt it.
*/
+
kimage_free(xchg(&kexec_crash_image, NULL));
result = kimage_alloc_init(&image, entry, nr_segments,
segments, flags);
crash_map_reserved_pages();
+ } else {
+ /* Loading another kernel to reboot into. */
+
+ result = kimage_alloc_init(&image, entry, nr_segments,
+ segments, flags);
}
if (result)
goto out;
diff --git a/kernel/module.c b/kernel/module.c
index 8426ad48362c..b34813f725e9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3025,8 +3025,13 @@ static void do_free_init(struct rcu_head *head)
kfree(m);
}
-/* This is where the real work happens */
-static int do_init_module(struct module *mod)
+/*
+ * This is where the real work happens.
+ *
+ * Keep it uninlined to provide a reliable breakpoint target, e.g. for the gdb
+ * helper command 'lx-symbols'.
+ */
+static noinline int do_init_module(struct module *mod)
{
int ret = 0;
struct mod_initfree *freeinit;
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index c347e3ce3a55..b7d6b3a721b1 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -37,7 +37,9 @@ const char *pm_states[PM_SUSPEND_MAX];
static const struct platform_suspend_ops *suspend_ops;
static const struct platform_freeze_ops *freeze_ops;
static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
-static bool suspend_freeze_wake;
+
+enum freeze_state __read_mostly suspend_freeze_state;
+static DEFINE_SPINLOCK(suspend_freeze_lock);
void freeze_set_ops(const struct platform_freeze_ops *ops)
{
@@ -48,22 +50,49 @@ void freeze_set_ops(const struct platform_freeze_ops *ops)
static void freeze_begin(void)
{
- suspend_freeze_wake = false;
+ suspend_freeze_state = FREEZE_STATE_NONE;
}
static void freeze_enter(void)
{
- cpuidle_use_deepest_state(true);
+ spin_lock_irq(&suspend_freeze_lock);
+ if (pm_wakeup_pending())
+ goto out;
+
+ suspend_freeze_state = FREEZE_STATE_ENTER;
+ spin_unlock_irq(&suspend_freeze_lock);
+
+ get_online_cpus();
cpuidle_resume();
- wait_event(suspend_freeze_wait_head, suspend_freeze_wake);
+
+ /* Push all the CPUs into the idle loop. */
+ wake_up_all_idle_cpus();
+ pr_debug("PM: suspend-to-idle\n");
+ /* Make the current CPU wait so it can enter the idle loop too. */
+ wait_event(suspend_freeze_wait_head,
+ suspend_freeze_state == FREEZE_STATE_WAKE);
+ pr_debug("PM: resume from suspend-to-idle\n");
+
cpuidle_pause();
- cpuidle_use_deepest_state(false);
+ put_online_cpus();
+
+ spin_lock_irq(&suspend_freeze_lock);
+
+ out:
+ suspend_freeze_state = FREEZE_STATE_NONE;
+ spin_unlock_irq(&suspend_freeze_lock);
}
void freeze_wake(void)
{
- suspend_freeze_wake = true;
- wake_up(&suspend_freeze_wait_head);
+ unsigned long flags;
+
+ spin_lock_irqsave(&suspend_freeze_lock, flags);
+ if (suspend_freeze_state > FREEZE_STATE_NONE) {
+ suspend_freeze_state = FREEZE_STATE_WAKE;
+ wake_up(&suspend_freeze_wait_head);
+ }
+ spin_unlock_irqrestore(&suspend_freeze_lock, flags);
}
EXPORT_SYMBOL_GPL(freeze_wake);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 1eb9d90c3af9..227fec36b12a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1077,7 +1077,6 @@ int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
}
#if defined CONFIG_COMPAT
-#include <linux/compat.h>
int compat_ptrace_request(struct task_struct *child, compat_long_t request,
compat_ulong_t addr, compat_ulong_t data)
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index aaf1c1d5cf5d..94b2d7b88a27 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -7,6 +7,7 @@
#include <linux/tick.h>
#include <linux/mm.h>
#include <linux/stackprotector.h>
+#include <linux/suspend.h>
#include <asm/tlb.h>
@@ -105,6 +106,21 @@ static void cpuidle_idle_call(void)
rcu_idle_enter();
/*
+ * Suspend-to-idle ("freeze") is a system state in which all user space
+ * has been frozen, all I/O devices have been suspended and the only
+ * activity happens here and in iterrupts (if any). In that case bypass
+ * the cpuidle governor and go stratight for the deepest idle state
+ * available. Possibly also suspend the local tick and the entire
+ * timekeeping to prevent timer interrupts from kicking us out of idle
+ * until a proper wakeup interrupt happens.
+ */
+ if (idle_should_freeze()) {
+ cpuidle_enter_freeze();
+ local_irq_enable();
+ goto exit_idle;
+ }
+
+ /*
* Ask the cpuidle framework to choose a convenient idle state.
* Fall back to the default arch idle method on errors.
*/
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 4ef9687ac115..4f44028943e6 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -629,7 +629,9 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
switch (action) {
case SECCOMP_RET_ERRNO:
- /* Set the low-order 16-bits as a errno. */
+ /* Set low-order bits as an errno, capped at MAX_ERRNO. */
+ if (data > MAX_ERRNO)
+ data = MAX_ERRNO;
syscall_set_return_value(current, task_pt_regs(current),
-data, 0);
goto skip;
diff --git a/kernel/signal.c b/kernel/signal.c
index 33a52759cc0e..a390499943e4 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3550,7 +3550,7 @@ SYSCALL_DEFINE2(signal, int, sig, __sighandler_t, handler)
SYSCALL_DEFINE0(pause)
{
while (!signal_pending(current)) {
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_INTERRUPTIBLE);
schedule();
}
return -ERESTARTNOHAND;
@@ -3563,7 +3563,7 @@ int sigsuspend(sigset_t *set)
current->saved_sigmask = current->blocked;
set_current_blocked(set);
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_INTERRUPTIBLE);
schedule();
set_restore_sigmask();
return -ERESTARTNOHAND;
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 7efeedf53ebd..f7c515595b42 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -394,6 +394,56 @@ void tick_resume(void)
}
}
+static DEFINE_RAW_SPINLOCK(tick_freeze_lock);
+static unsigned int tick_freeze_depth;
+
+/**
+ * tick_freeze - Suspend the local tick and (possibly) timekeeping.
+ *
+ * Check if this is the last online CPU executing the function and if so,
+ * suspend timekeeping. Otherwise suspend the local tick.
+ *
+ * Call with interrupts disabled. Must be balanced with %tick_unfreeze().
+ * Interrupts must not be enabled before the subsequent %tick_unfreeze().
+ */
+void tick_freeze(void)
+{
+ raw_spin_lock(&tick_freeze_lock);
+
+ tick_freeze_depth++;
+ if (tick_freeze_depth == num_online_cpus()) {
+ timekeeping_suspend();
+ } else {
+ tick_suspend();
+ tick_suspend_broadcast();
+ }
+
+ raw_spin_unlock(&tick_freeze_lock);
+}
+
+/**
+ * tick_unfreeze - Resume the local tick and (possibly) timekeeping.
+ *
+ * Check if this is the first CPU executing the function and if so, resume
+ * timekeeping. Otherwise resume the local tick.
+ *
+ * Call with interrupts disabled. Must be balanced with %tick_freeze().
+ * Interrupts must not be enabled after the preceding %tick_freeze().
+ */
+void tick_unfreeze(void)
+{
+ raw_spin_lock(&tick_freeze_lock);
+
+ if (tick_freeze_depth == num_online_cpus())
+ timekeeping_resume();
+ else
+ tick_resume();
+
+ tick_freeze_depth--;
+
+ raw_spin_unlock(&tick_freeze_lock);
+}
+
/**
* tick_init - initialize the tick control
*/
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b124af259800..91db94136c10 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -230,9 +230,7 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
/**
* update_fast_timekeeper - Update the fast and NMI safe monotonic timekeeper.
- * @tk: The timekeeper from which we take the update
- * @tkf: The fast timekeeper to update
- * @tbase: The time base for the fast timekeeper (mono/raw)
+ * @tkr: Timekeeping readout base from which we take the update
*
* We want to use this from any context including NMI and tracing /
* instrumenting the timekeeping code itself.
@@ -244,11 +242,11 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
* smp_wmb(); <- Ensure that the last base[1] update is visible
* tkf->seq++;
* smp_wmb(); <- Ensure that the seqcount update is visible
- * update(tkf->base[0], tk);
+ * update(tkf->base[0], tkr);
* smp_wmb(); <- Ensure that the base[0] update is visible
* tkf->seq++;
* smp_wmb(); <- Ensure that the seqcount update is visible
- * update(tkf->base[1], tk);
+ * update(tkf->base[1], tkr);
*
* The reader side does:
*
@@ -269,7 +267,7 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
* slightly wrong timestamp (a few nanoseconds). See
* @ktime_get_mono_fast_ns.
*/
-static void update_fast_timekeeper(struct timekeeper *tk)
+static void update_fast_timekeeper(struct tk_read_base *tkr)
{
struct tk_read_base *base = tk_fast_mono.base;
@@ -277,7 +275,7 @@ static void update_fast_timekeeper(struct timekeeper *tk)
raw_write_seqcount_latch(&tk_fast_mono.seq);
/* Update base[0] */
- memcpy(base, &tk->tkr, sizeof(*base));
+ memcpy(base, tkr, sizeof(*base));
/* Force readers back to base[0] */
raw_write_seqcount_latch(&tk_fast_mono.seq);
@@ -334,6 +332,35 @@ u64 notrace ktime_get_mono_fast_ns(void)
}
EXPORT_SYMBOL_GPL(ktime_get_mono_fast_ns);
+/* Suspend-time cycles value for halted fast timekeeper. */
+static cycle_t cycles_at_suspend;
+
+static cycle_t dummy_clock_read(struct clocksource *cs)
+{
+ return cycles_at_suspend;
+}
+
+/**
+ * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource.
+ * @tk: Timekeeper to snapshot.
+ *
+ * It generally is unsafe to access the clocksource after timekeeping has been
+ * suspended, so take a snapshot of the readout base of @tk and use it as the
+ * fast timekeeper's readout base while suspended. It will return the same
+ * number of cycles every time until timekeeping is resumed at which time the
+ * proper readout base for the fast timekeeper will be restored automatically.
+ */
+static void halt_fast_timekeeper(struct timekeeper *tk)
+{
+ static struct tk_read_base tkr_dummy;
+ struct tk_read_base *tkr = &tk->tkr;
+
+ memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy));
+ cycles_at_suspend = tkr->read(tkr->clock);
+ tkr_dummy.read = dummy_clock_read;
+ update_fast_timekeeper(&tkr_dummy);
+}
+
#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
static inline void update_vsyscall(struct timekeeper *tk)
@@ -462,7 +489,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
memcpy(&shadow_timekeeper, &tk_core.timekeeper,
sizeof(tk_core.timekeeper));
- update_fast_timekeeper(tk);
+ update_fast_timekeeper(&tk->tkr);
}
/**
@@ -1170,7 +1197,7 @@ void timekeeping_inject_sleeptime64(struct timespec64 *delta)
* xtime/wall_to_monotonic/jiffies/etc are
* still managed by arch specific suspend/resume code.
*/
-static void timekeeping_resume(void)
+void timekeeping_resume(void)
{
struct timekeeper *tk = &tk_core.timekeeper;
struct clocksource *clock = tk->tkr.clock;
@@ -1251,7 +1278,7 @@ static void timekeeping_resume(void)
hrtimers_resume();
}
-static int timekeeping_suspend(void)
+int timekeeping_suspend(void)
{
struct timekeeper *tk = &tk_core.timekeeper;
unsigned long flags;
@@ -1296,6 +1323,7 @@ static int timekeeping_suspend(void)
}
timekeeping_update(tk, TK_MIRROR);
+ halt_fast_timekeeper(tk);
write_seqcount_end(&tk_core.seq);
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h
index adc1fc98bde3..1d91416055d5 100644
--- a/kernel/time/timekeeping.h
+++ b/kernel/time/timekeeping.h
@@ -16,5 +16,7 @@ extern int timekeeping_inject_offset(struct timespec *ts);
extern s32 timekeeping_get_tai_offset(void);
extern void timekeeping_set_tai_offset(s32 tai_offset);
extern void timekeeping_clocktai(struct timespec *ts);
+extern int timekeeping_suspend(void);
+extern void timekeeping_resume(void);
#endif
diff --git a/lib/Kconfig b/lib/Kconfig
index cd177caf3876..cb9758e0ba0c 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -14,7 +14,7 @@ config BITREVERSE
tristate
config HAVE_ARCH_BITREVERSE
- boolean
+ bool
default n
depends on BITREVERSE
help
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ecb3516f6546..c5cefb3c009c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -167,6 +167,17 @@ config DEBUG_INFO_DWARF4
But it significantly improves the success of resolving
variables in gdb on optimized code.
+config GDB_SCRIPTS
+ bool "Provide GDB scripts for kernel debugging"
+ depends on DEBUG_INFO
+ help
+ This creates the required links to GDB helper scripts in the
+ build directory. If you load vmlinux into gdb, the helper
+ scripts will be automatically imported by gdb as well, and
+ additional functions are available to analyze a Linux kernel
+ instance. See Documentation/gdb-kernel-debugging.txt for further
+ details.
+
config ENABLE_WARN_DEPRECATED
bool "Enable __deprecated logic"
default y
diff --git a/lib/lockref.c b/lib/lockref.c
index d2233de9a86e..ecb9a665ec19 100644
--- a/lib/lockref.c
+++ b/lib/lockref.c
@@ -60,7 +60,7 @@ void lockref_get(struct lockref *lockref)
EXPORT_SYMBOL(lockref_get);
/**
- * lockref_get_not_zero - Increments count unless the count is 0
+ * lockref_get_not_zero - Increments count unless the count is 0 or dead
* @lockref: pointer to lockref structure
* Return: 1 if count updated successfully or 0 if count was zero
*/
@@ -70,7 +70,7 @@ int lockref_get_not_zero(struct lockref *lockref)
CMPXCHG_LOOP(
new.count++;
- if (!old.count)
+ if (old.count <= 0)
return 0;
,
return 1;
@@ -78,7 +78,7 @@ int lockref_get_not_zero(struct lockref *lockref)
spin_lock(&lockref->lock);
retval = 0;
- if (lockref->count) {
+ if (lockref->count > 0) {
lockref->count++;
retval = 1;
}
@@ -88,7 +88,7 @@ int lockref_get_not_zero(struct lockref *lockref)
EXPORT_SYMBOL(lockref_get_not_zero);
/**
- * lockref_get_or_lock - Increments count unless the count is 0
+ * lockref_get_or_lock - Increments count unless the count is 0 or dead
* @lockref: pointer to lockref structure
* Return: 1 if count updated successfully or 0 if count was zero
* and we got the lock instead.
@@ -97,14 +97,14 @@ int lockref_get_or_lock(struct lockref *lockref)
{
CMPXCHG_LOOP(
new.count++;
- if (!old.count)
+ if (old.count <= 0)
break;
,
return 1;
);
spin_lock(&lockref->lock);
- if (!lockref->count)
+ if (lockref->count <= 0)
return 0;
lockref->count++;
spin_unlock(&lockref->lock);
@@ -113,6 +113,26 @@ int lockref_get_or_lock(struct lockref *lockref)
EXPORT_SYMBOL(lockref_get_or_lock);
/**
+ * lockref_put_return - Decrement reference count if possible
+ * @lockref: pointer to lockref structure
+ *
+ * Decrement the reference count and return the new value.
+ * If the lockref was dead or locked, return an error.
+ */
+int lockref_put_return(struct lockref *lockref)
+{
+ CMPXCHG_LOOP(
+ new.count--;
+ if (old.count <= 0)
+ return -1;
+ ,
+ return new.count;
+ );
+ return -1;
+}
+EXPORT_SYMBOL(lockref_put_return);
+
+/**
* lockref_put_or_lock - decrements count unless count <= 1 before decrement
* @lockref: pointer to lockref structure
* Return: 1 if count updated successfully or 0 if count <= 1 and lock taken
@@ -158,7 +178,7 @@ int lockref_get_not_dead(struct lockref *lockref)
CMPXCHG_LOOP(
new.count++;
- if ((int)old.count < 0)
+ if (old.count < 0)
return 0;
,
return 1;
@@ -166,7 +186,7 @@ int lockref_get_not_dead(struct lockref *lockref)
spin_lock(&lockref->lock);
retval = 0;
- if ((int) lockref->count >= 0) {
+ if (lockref->count >= 0) {
lockref->count++;
retval = 1;
}
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
index 0d83ea8a9605..bcce5f149310 100644
--- a/lib/pci_iomap.c
+++ b/lib/pci_iomap.c
@@ -10,10 +10,11 @@
#ifdef CONFIG_PCI
/**
- * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * pci_iomap_range - create a virtual mapping cookie for a PCI BAR
* @dev: PCI device that owns the BAR
* @bar: BAR number
- * @maxlen: length of the memory to map
+ * @offset: map memory at the given offset in BAR
+ * @maxlen: max length of the memory to map
*
* Using this function you will get a __iomem address to your device BAR.
* You can access it using ioread*() and iowrite*(). These functions hide
@@ -21,16 +22,21 @@
* you expect from them in the correct way.
*
* @maxlen specifies the maximum length to map. If you want to get access to
- * the complete BAR without checking for its length first, pass %0 here.
+ * the complete BAR from offset to the end, pass %0 here.
* */
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+void __iomem *pci_iomap_range(struct pci_dev *dev,
+ int bar,
+ unsigned long offset,
+ unsigned long maxlen)
{
resource_size_t start = pci_resource_start(dev, bar);
resource_size_t len = pci_resource_len(dev, bar);
unsigned long flags = pci_resource_flags(dev, bar);
- if (!len || !start)
+ if (len <= offset || !start)
return NULL;
+ len -= offset;
+ start += offset;
if (maxlen && len > maxlen)
len = maxlen;
if (flags & IORESOURCE_IO)
@@ -43,6 +49,25 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
/* What? */
return NULL;
}
+EXPORT_SYMBOL(pci_iomap_range);
+/**
+ * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * @dev: PCI device that owns the BAR
+ * @bar: BAR number
+ * @maxlen: length of the memory to map
+ *
+ * Using this function you will get a __iomem address to your device BAR.
+ * You can access it using ioread*() and iowrite*(). These functions hide
+ * the details if this is a MMIO or PIO address space and will just do what
+ * you expect from them in the correct way.
+ *
+ * @maxlen specifies the maximum length to map. If you want to get access to
+ * the complete BAR without checking for its length first, pass %0 here.
+ * */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+ return pci_iomap_range(dev, bar, 0, maxlen);
+}
EXPORT_SYMBOL(pci_iomap);
#endif /* CONFIG_PCI */
diff --git a/mm/Makefile b/mm/Makefile
index 088c68e9ec35..3c1caa2693bd 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -55,7 +55,6 @@ obj-$(CONFIG_KMEMCHECK) += kmemcheck.o
obj-$(CONFIG_KASAN) += kasan/
obj-$(CONFIG_FAILSLAB) += failslab.o
obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
-obj-$(CONFIG_FS_XIP) += filemap_xip.o
obj-$(CONFIG_MIGRATION) += migrate.o
obj-$(CONFIG_QUICKLIST) += quicklist.o
obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += huge_memory.o
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 7690ec77c722..6dc4580df2af 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -49,10 +49,10 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
unsigned long background_thresh;
unsigned long dirty_thresh;
unsigned long bdi_thresh;
- unsigned long nr_dirty, nr_io, nr_more_io;
+ unsigned long nr_dirty, nr_io, nr_more_io, nr_dirty_time;
struct inode *inode;
- nr_dirty = nr_io = nr_more_io = 0;
+ nr_dirty = nr_io = nr_more_io = nr_dirty_time = 0;
spin_lock(&wb->list_lock);
list_for_each_entry(inode, &wb->b_dirty, i_wb_list)
nr_dirty++;
@@ -60,6 +60,9 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
nr_io++;
list_for_each_entry(inode, &wb->b_more_io, i_wb_list)
nr_more_io++;
+ list_for_each_entry(inode, &wb->b_dirty_time, i_wb_list)
+ if (inode->i_state & I_DIRTY_TIME)
+ nr_dirty_time++;
spin_unlock(&wb->list_lock);
global_dirty_limits(&background_thresh, &dirty_thresh);
@@ -78,6 +81,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
"b_dirty: %10lu\n"
"b_io: %10lu\n"
"b_more_io: %10lu\n"
+ "b_dirty_time: %10lu\n"
"bdi_list: %10u\n"
"state: %10lx\n",
(unsigned long) K(bdi_stat(bdi, BDI_WRITEBACK)),
@@ -91,6 +95,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
nr_dirty,
nr_io,
nr_more_io,
+ nr_dirty_time,
!list_empty(&bdi->bdi_list), bdi->state);
#undef K
@@ -380,6 +385,7 @@ static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi)
INIT_LIST_HEAD(&wb->b_dirty);
INIT_LIST_HEAD(&wb->b_io);
INIT_LIST_HEAD(&wb->b_more_io);
+ INIT_LIST_HEAD(&wb->b_dirty_time);
spin_lock_init(&wb->list_lock);
INIT_DELAYED_WORK(&wb->dwork, bdi_writeback_workfn);
}
diff --git a/mm/fadvise.c b/mm/fadvise.c
index fac23ecf8d72..4a3907cf79f8 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -28,6 +28,7 @@
SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
{
struct fd f = fdget(fd);
+ struct inode *inode;
struct address_space *mapping;
struct backing_dev_info *bdi;
loff_t endbyte; /* inclusive */
@@ -39,7 +40,8 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
if (!f.file)
return -EBADF;
- if (S_ISFIFO(file_inode(f.file)->i_mode)) {
+ inode = file_inode(f.file);
+ if (S_ISFIFO(inode->i_mode)) {
ret = -ESPIPE;
goto out;
}
@@ -50,7 +52,7 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
goto out;
}
- if (mapping->a_ops->get_xip_mem) {
+ if (IS_DAX(inode)) {
switch (advice) {
case POSIX_FADV_NORMAL:
case POSIX_FADV_RANDOM:
diff --git a/mm/filemap.c b/mm/filemap.c
index d9f5336552d7..ad7242043bdb 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1695,8 +1695,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
loff_t *ppos = &iocb->ki_pos;
loff_t pos = *ppos;
- /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
- if (file->f_flags & O_DIRECT) {
+ if (io_is_direct(file)) {
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
size_t count = iov_iter_count(iter);
@@ -1723,9 +1722,11 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
* we've already read everything we wanted to, or if
* there was a short read because we hit EOF, go ahead
* and return. Otherwise fallthrough to buffered io for
- * the rest of the read.
+ * the rest of the read. Buffered reads will not work for
+ * DAX files, so don't bother trying.
*/
- if (retval < 0 || !iov_iter_count(iter) || *ppos >= size) {
+ if (retval < 0 || !iov_iter_count(iter) || *ppos >= size ||
+ IS_DAX(inode)) {
file_accessed(file);
goto out;
}
@@ -2582,18 +2583,20 @@ ssize_t __generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (err)
goto out;
- /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
- if (unlikely(file->f_flags & O_DIRECT)) {
+ if (io_is_direct(file)) {
loff_t endbyte;
written = generic_file_direct_write(iocb, from, pos);
- if (written < 0 || written == count)
- goto out;
-
/*
- * direct-io write to a hole: fall through to buffered I/O
- * for completing the rest of the request.
+ * If the write stopped short of completing, fall back to
+ * buffered writes. Some filesystems do this for writes to
+ * holes, for example. For DAX files, a buffered write will
+ * not succeed (even if it did, DAX does not handle dirty
+ * page-cache pages correctly).
*/
+ if (written < 0 || written == count || IS_DAX(inode))
+ goto out;
+
pos += written;
count -= written;
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
deleted file mode 100644
index c175f9f25210..000000000000
--- a/mm/filemap_xip.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * linux/mm/filemap_xip.c
- *
- * Copyright (C) 2005 IBM Corporation
- * Author: Carsten Otte <cotte@de.ibm.com>
- *
- * derived from linux/mm/filemap.c - Copyright (C) Linus Torvalds
- *
- */
-
-#include <linux/fs.h>
-#include <linux/backing-dev.h>
-#include <linux/pagemap.h>
-#include <linux/export.h>
-#include <linux/uio.h>
-#include <linux/rmap.h>
-#include <linux/mmu_notifier.h>
-#include <linux/sched.h>
-#include <linux/seqlock.h>
-#include <linux/mutex.h>
-#include <linux/gfp.h>
-#include <asm/tlbflush.h>
-#include <asm/io.h>
-
-/*
- * We do use our own empty page to avoid interference with other users
- * of ZERO_PAGE(), such as /dev/zero
- */
-static DEFINE_MUTEX(xip_sparse_mutex);
-static seqcount_t xip_sparse_seq = SEQCNT_ZERO(xip_sparse_seq);
-static struct page *__xip_sparse_page;
-
-/* called under xip_sparse_mutex */
-static struct page *xip_sparse_page(void)
-{
- if (!__xip_sparse_page) {
- struct page *page = alloc_page(GFP_HIGHUSER | __GFP_ZERO);
-
- if (page)
- __xip_sparse_page = page;
- }
- return __xip_sparse_page;
-}
-
-/*
- * This is a file read routine for execute in place files, and uses
- * the mapping->a_ops->get_xip_mem() function for the actual low-level
- * stuff.
- *
- * Note the struct file* is not used at all. It may be NULL.
- */
-static ssize_t
-do_xip_mapping_read(struct address_space *mapping,
- struct file_ra_state *_ra,
- struct file *filp,
- char __user *buf,
- size_t len,
- loff_t *ppos)
-{
- struct inode *inode = mapping->host;
- pgoff_t index, end_index;
- unsigned long offset;
- loff_t isize, pos;
- size_t copied = 0, error = 0;
-
- BUG_ON(!mapping->a_ops->get_xip_mem);
-
- pos = *ppos;
- index = pos >> PAGE_CACHE_SHIFT;
- offset = pos & ~PAGE_CACHE_MASK;
-
- isize = i_size_read(inode);
- if (!isize)
- goto out;
-
- end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
- do {
- unsigned long nr, left;
- void *xip_mem;
- unsigned long xip_pfn;
- int zero = 0;
-
- /* nr is the maximum number of bytes to copy from this page */
- nr = PAGE_CACHE_SIZE;
- if (index >= end_index) {
- if (index > end_index)
- goto out;
- nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
- if (nr <= offset) {
- goto out;
- }
- }
- nr = nr - offset;
- if (nr > len - copied)
- nr = len - copied;
-
- error = mapping->a_ops->get_xip_mem(mapping, index, 0,
- &xip_mem, &xip_pfn);
- if (unlikely(error)) {
- if (error == -ENODATA) {
- /* sparse */
- zero = 1;
- } else
- goto out;
- }
-
- /* If users can be writing to this page using arbitrary
- * virtual addresses, take care about potential aliasing
- * before reading the page on the kernel side.
- */
- if (mapping_writably_mapped(mapping))
- /* address based flush */ ;
-
- /*
- * Ok, we have the mem, so now we can copy it to user space...
- *
- * The actor routine returns how many bytes were actually used..
- * NOTE! This may not be the same as how much of a user buffer
- * we filled up (we may be padding etc), so we can only update
- * "pos" here (the actor routine has to update the user buffer
- * pointers and the remaining count).
- */
- if (!zero)
- left = __copy_to_user(buf+copied, xip_mem+offset, nr);
- else
- left = __clear_user(buf + copied, nr);
-
- if (left) {
- error = -EFAULT;
- goto out;
- }
-
- copied += (nr - left);
- offset += (nr - left);
- index += offset >> PAGE_CACHE_SHIFT;
- offset &= ~PAGE_CACHE_MASK;
- } while (copied < len);
-
-out:
- *ppos = pos + copied;
- if (filp)
- file_accessed(filp);
-
- return (copied ? copied : error);
-}
-
-ssize_t
-xip_file_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
-{
- if (!access_ok(VERIFY_WRITE, buf, len))
- return -EFAULT;
-
- return do_xip_mapping_read(filp->f_mapping, &filp->f_ra, filp,
- buf, len, ppos);
-}
-EXPORT_SYMBOL_GPL(xip_file_read);
-
-/*
- * __xip_unmap is invoked from xip_unmap and xip_write
- *
- * This function walks all vmas of the address_space and unmaps the
- * __xip_sparse_page when found at pgoff.
- */
-static void __xip_unmap(struct address_space * mapping, unsigned long pgoff)
-{
- struct vm_area_struct *vma;
- struct page *page;
- unsigned count;
- int locked = 0;
-
- count = read_seqcount_begin(&xip_sparse_seq);
-
- page = __xip_sparse_page;
- if (!page)
- return;
-
-retry:
- i_mmap_lock_read(mapping);
- vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
- pte_t *pte, pteval;
- spinlock_t *ptl;
- struct mm_struct *mm = vma->vm_mm;
- unsigned long address = vma->vm_start +
- ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
-
- BUG_ON(address < vma->vm_start || address >= vma->vm_end);
- pte = page_check_address(page, mm, address, &ptl, 1);
- if (pte) {
- /* Nuke the page table entry. */
- flush_cache_page(vma, address, pte_pfn(*pte));
- pteval = ptep_clear_flush(vma, address, pte);
- page_remove_rmap(page);
- dec_mm_counter(mm, MM_FILEPAGES);
- BUG_ON(pte_dirty(pteval));
- pte_unmap_unlock(pte, ptl);
- /* must invalidate_page _before_ freeing the page */
- mmu_notifier_invalidate_page(mm, address);
- page_cache_release(page);
- }
- }
- i_mmap_unlock_read(mapping);
-
- if (locked) {
- mutex_unlock(&xip_sparse_mutex);
- } else if (read_seqcount_retry(&xip_sparse_seq, count)) {
- mutex_lock(&xip_sparse_mutex);
- locked = 1;
- goto retry;
- }
-}
-
-/*
- * xip_fault() is invoked via the vma operations vector for a
- * mapped memory region to read in file data during a page fault.
- *
- * This function is derived from filemap_fault, but used for execute in place
- */
-static int xip_file_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- struct file *file = vma->vm_file;
- struct address_space *mapping = file->f_mapping;
- struct inode *inode = mapping->host;
- pgoff_t size;
- void *xip_mem;
- unsigned long xip_pfn;
- struct page *page;
- int error;
-
- /* XXX: are VM_FAULT_ codes OK? */
-again:
- size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- if (vmf->pgoff >= size)
- return VM_FAULT_SIGBUS;
-
- error = mapping->a_ops->get_xip_mem(mapping, vmf->pgoff, 0,
- &xip_mem, &xip_pfn);
- if (likely(!error))
- goto found;
- if (error != -ENODATA)
- return VM_FAULT_OOM;
-
- /* sparse block */
- if ((vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) &&
- (vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) &&
- (!(mapping->host->i_sb->s_flags & MS_RDONLY))) {
- int err;
-
- /* maybe shared writable, allocate new block */
- mutex_lock(&xip_sparse_mutex);
- error = mapping->a_ops->get_xip_mem(mapping, vmf->pgoff, 1,
- &xip_mem, &xip_pfn);
- mutex_unlock(&xip_sparse_mutex);
- if (error)
- return VM_FAULT_SIGBUS;
- /* unmap sparse mappings at pgoff from all other vmas */
- __xip_unmap(mapping, vmf->pgoff);
-
-found:
- err = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address,
- xip_pfn);
- if (err == -ENOMEM)
- return VM_FAULT_OOM;
- /*
- * err == -EBUSY is fine, we've raced against another thread
- * that faulted-in the same page
- */
- if (err != -EBUSY)
- BUG_ON(err);
- return VM_FAULT_NOPAGE;
- } else {
- int err, ret = VM_FAULT_OOM;
-
- mutex_lock(&xip_sparse_mutex);
- write_seqcount_begin(&xip_sparse_seq);
- error = mapping->a_ops->get_xip_mem(mapping, vmf->pgoff, 0,
- &xip_mem, &xip_pfn);
- if (unlikely(!error)) {
- write_seqcount_end(&xip_sparse_seq);
- mutex_unlock(&xip_sparse_mutex);
- goto again;
- }
- if (error != -ENODATA)
- goto out;
- /* not shared and writable, use xip_sparse_page() */
- page = xip_sparse_page();
- if (!page)
- goto out;
- err = vm_insert_page(vma, (unsigned long)vmf->virtual_address,
- page);
- if (err == -ENOMEM)
- goto out;
-
- ret = VM_FAULT_NOPAGE;
-out:
- write_seqcount_end(&xip_sparse_seq);
- mutex_unlock(&xip_sparse_mutex);
-
- return ret;
- }
-}
-
-static const struct vm_operations_struct xip_file_vm_ops = {
- .fault = xip_file_fault,
- .page_mkwrite = filemap_page_mkwrite,
-};
-
-int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
-{
- BUG_ON(!file->f_mapping->a_ops->get_xip_mem);
-
- file_accessed(file);
- vma->vm_ops = &xip_file_vm_ops;
- vma->vm_flags |= VM_MIXEDMAP;
- return 0;
-}
-EXPORT_SYMBOL_GPL(xip_file_mmap);
-
-static ssize_t
-__xip_file_write(struct file *filp, const char __user *buf,
- size_t count, loff_t pos, loff_t *ppos)
-{
- struct address_space * mapping = filp->f_mapping;
- const struct address_space_operations *a_ops = mapping->a_ops;
- struct inode *inode = mapping->host;
- long status = 0;
- size_t bytes;
- ssize_t written = 0;
-
- BUG_ON(!mapping->a_ops->get_xip_mem);
-
- do {
- unsigned long index;
- unsigned long offset;
- size_t copied;
- void *xip_mem;
- unsigned long xip_pfn;
-
- offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
- index = pos >> PAGE_CACHE_SHIFT;
- bytes = PAGE_CACHE_SIZE - offset;
- if (bytes > count)
- bytes = count;
-
- status = a_ops->get_xip_mem(mapping, index, 0,
- &xip_mem, &xip_pfn);
- if (status == -ENODATA) {
- /* we allocate a new page unmap it */
- mutex_lock(&xip_sparse_mutex);
- status = a_ops->get_xip_mem(mapping, index, 1,
- &xip_mem, &xip_pfn);
- mutex_unlock(&xip_sparse_mutex);
- if (!status)
- /* unmap page at pgoff from all other vmas */
- __xip_unmap(mapping, index);
- }
-
- if (status)
- break;
-
- copied = bytes -
- __copy_from_user_nocache(xip_mem + offset, buf, bytes);
-
- if (likely(copied > 0)) {
- status = copied;
-
- if (status >= 0) {
- written += status;
- count -= status;
- pos += status;
- buf += status;
- }
- }
- if (unlikely(copied != bytes))
- if (status >= 0)
- status = -EFAULT;
- if (status < 0)
- break;
- } while (count);
- *ppos = pos;
- /*
- * No need to use i_size_read() here, the i_size
- * cannot change under us because we hold i_mutex.
- */
- if (pos > inode->i_size) {
- i_size_write(inode, pos);
- mark_inode_dirty(inode);
- }
-
- return written ? written : status;
-}
-
-ssize_t
-xip_file_write(struct file *filp, const char __user *buf, size_t len,
- loff_t *ppos)
-{
- struct address_space *mapping = filp->f_mapping;
- struct inode *inode = mapping->host;
- size_t count;
- loff_t pos;
- ssize_t ret;
-
- mutex_lock(&inode->i_mutex);
-
- if (!access_ok(VERIFY_READ, buf, len)) {
- ret=-EFAULT;
- goto out_up;
- }
-
- pos = *ppos;
- count = len;
-
- /* We can write back this queue in page reclaim */
- current->backing_dev_info = inode_to_bdi(inode);
-
- ret = generic_write_checks(filp, &pos, &count, S_ISBLK(inode->i_mode));
- if (ret)
- goto out_backing;
- if (count == 0)
- goto out_backing;
-
- ret = file_remove_suid(filp);
- if (ret)
- goto out_backing;
-
- ret = file_update_time(filp);
- if (ret)
- goto out_backing;
-
- ret = __xip_file_write (filp, buf, count, pos, ppos);
-
- out_backing:
- current->backing_dev_info = NULL;
- out_up:
- mutex_unlock(&inode->i_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(xip_file_write);
-
-/*
- * truncate a page used for execute in place
- * functionality is analog to block_truncate_page but does use get_xip_mem
- * to get the page instead of page cache
- */
-int
-xip_truncate_page(struct address_space *mapping, loff_t from)
-{
- pgoff_t index = from >> PAGE_CACHE_SHIFT;
- unsigned offset = from & (PAGE_CACHE_SIZE-1);
- unsigned blocksize;
- unsigned length;
- void *xip_mem;
- unsigned long xip_pfn;
- int err;
-
- BUG_ON(!mapping->a_ops->get_xip_mem);
-
- blocksize = 1 << mapping->host->i_blkbits;
- length = offset & (blocksize - 1);
-
- /* Block boundary? Nothing to do */
- if (!length)
- return 0;
-
- length = blocksize - length;
-
- err = mapping->a_ops->get_xip_mem(mapping, index, 0,
- &xip_mem, &xip_pfn);
- if (unlikely(err)) {
- if (err == -ENODATA)
- /* Hole? No need to truncate */
- return 0;
- else
- return err;
- }
- memset(xip_mem + offset, 0, length);
- return 0;
-}
-EXPORT_SYMBOL_GPL(xip_truncate_page);
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index a1599ca4ab0e..827732047da1 100644
--- a/mm/iov_iter.c
+++ b/mm/iov_iter.c
@@ -501,18 +501,31 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i)
EXPORT_SYMBOL(iov_iter_single_seg_count);
void iov_iter_kvec(struct iov_iter *i, int direction,
- const struct kvec *iov, unsigned long nr_segs,
+ const struct kvec *kvec, unsigned long nr_segs,
size_t count)
{
BUG_ON(!(direction & ITER_KVEC));
i->type = direction;
- i->kvec = (struct kvec *)iov;
+ i->kvec = kvec;
i->nr_segs = nr_segs;
i->iov_offset = 0;
i->count = count;
}
EXPORT_SYMBOL(iov_iter_kvec);
+void iov_iter_bvec(struct iov_iter *i, int direction,
+ const struct bio_vec *bvec, unsigned long nr_segs,
+ size_t count)
+{
+ BUG_ON(!(direction & ITER_BVEC));
+ i->type = direction;
+ i->bvec = bvec;
+ i->nr_segs = nr_segs;
+ i->iov_offset = 0;
+ i->count = count;
+}
+EXPORT_SYMBOL(iov_iter_bvec);
+
unsigned long iov_iter_alignment(const struct iov_iter *i)
{
unsigned long res = 0;
diff --git a/mm/madvise.c b/mm/madvise.c
index 1077cbdc8b52..d551475517bf 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -239,7 +239,7 @@ static long madvise_willneed(struct vm_area_struct *vma,
return -EBADF;
#endif
- if (file->f_mapping->a_ops->get_xip_mem) {
+ if (IS_DAX(file_inode(file))) {
/* no bad return value, but ignore advice */
return 0;
}
diff --git a/mm/memory.c b/mm/memory.c
index 99275325f303..8068893697bb 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1965,6 +1965,7 @@ static int do_page_mkwrite(struct vm_area_struct *vma, struct page *page,
vmf.pgoff = page->index;
vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE;
vmf.page = page;
+ vmf.cow_page = NULL;
ret = vma->vm_ops->page_mkwrite(vma, &vmf);
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))
@@ -2329,6 +2330,7 @@ void unmap_mapping_range(struct address_space *mapping,
details.last_index = ULONG_MAX;
+ /* DAX uses i_mmap_lock to serialise file truncate vs page fault */
i_mmap_lock_write(mapping);
if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
unmap_mapping_range_tree(&mapping->i_mmap, &details);
@@ -2638,7 +2640,8 @@ oom:
* See filemap_fault() and __lock_page_retry().
*/
static int __do_fault(struct vm_area_struct *vma, unsigned long address,
- pgoff_t pgoff, unsigned int flags, struct page **page)
+ pgoff_t pgoff, unsigned int flags,
+ struct page *cow_page, struct page **page)
{
struct vm_fault vmf;
int ret;
@@ -2647,10 +2650,13 @@ static int __do_fault(struct vm_area_struct *vma, unsigned long address,
vmf.pgoff = pgoff;
vmf.flags = flags;
vmf.page = NULL;
+ vmf.cow_page = cow_page;
ret = vma->vm_ops->fault(vma, &vmf);
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
return ret;
+ if (!vmf.page)
+ goto out;
if (unlikely(PageHWPoison(vmf.page))) {
if (ret & VM_FAULT_LOCKED)
@@ -2664,6 +2670,7 @@ static int __do_fault(struct vm_area_struct *vma, unsigned long address,
else
VM_BUG_ON_PAGE(!PageLocked(vmf.page), vmf.page);
+ out:
*page = vmf.page;
return ret;
}
@@ -2834,7 +2841,7 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma,
pte_unmap_unlock(pte, ptl);
}
- ret = __do_fault(vma, address, pgoff, flags, &fault_page);
+ ret = __do_fault(vma, address, pgoff, flags, NULL, &fault_page);
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
return ret;
@@ -2874,26 +2881,43 @@ static int do_cow_fault(struct mm_struct *mm, struct vm_area_struct *vma,
return VM_FAULT_OOM;
}
- ret = __do_fault(vma, address, pgoff, flags, &fault_page);
+ ret = __do_fault(vma, address, pgoff, flags, new_page, &fault_page);
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
goto uncharge_out;
- copy_user_highpage(new_page, fault_page, address, vma);
+ if (fault_page)
+ copy_user_highpage(new_page, fault_page, address, vma);
__SetPageUptodate(new_page);
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
if (unlikely(!pte_same(*pte, orig_pte))) {
pte_unmap_unlock(pte, ptl);
- unlock_page(fault_page);
- page_cache_release(fault_page);
+ if (fault_page) {
+ unlock_page(fault_page);
+ page_cache_release(fault_page);
+ } else {
+ /*
+ * The fault handler has no page to lock, so it holds
+ * i_mmap_lock for read to protect against truncate.
+ */
+ i_mmap_unlock_read(vma->vm_file->f_mapping);
+ }
goto uncharge_out;
}
do_set_pte(vma, address, new_page, pte, true, true);
mem_cgroup_commit_charge(new_page, memcg, false);
lru_cache_add_active_or_unevictable(new_page, vma);
pte_unmap_unlock(pte, ptl);
- unlock_page(fault_page);
- page_cache_release(fault_page);
+ if (fault_page) {
+ unlock_page(fault_page);
+ page_cache_release(fault_page);
+ } else {
+ /*
+ * The fault handler has no page to lock, so it holds
+ * i_mmap_lock for read to protect against truncate.
+ */
+ i_mmap_unlock_read(vma->vm_file->f_mapping);
+ }
return ret;
uncharge_out:
mem_cgroup_cancel_charge(new_page, memcg);
@@ -2912,7 +2936,7 @@ static int do_shared_fault(struct mm_struct *mm, struct vm_area_struct *vma,
int dirtied = 0;
int ret, tmp;
- ret = __do_fault(vma, address, pgoff, flags, &fault_page);
+ ret = __do_fault(vma, address, pgoff, flags, NULL, &fault_page);
if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
return ret;
diff --git a/mm/page_io.c b/mm/page_io.c
index 955db8b0d497..e6045804c8d8 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -269,14 +269,9 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
.bv_len = PAGE_SIZE,
.bv_offset = 0
};
- struct iov_iter from = {
- .type = ITER_BVEC | WRITE,
- .count = PAGE_SIZE,
- .iov_offset = 0,
- .nr_segs = 1,
- };
- from.bvec = &bv; /* older gcc versions are broken */
+ struct iov_iter from;
+ iov_iter_bvec(&from, ITER_BVEC | WRITE, &bv, 1, PAGE_SIZE);
init_sync_kiocb(&kiocb, swap_file);
kiocb.ki_pos = page_file_offset(page);
kiocb.ki_nbytes = PAGE_SIZE;
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index daa749c8b3fb..d8e376a5f0f1 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -524,6 +524,12 @@ static int p9_virtio_probe(struct virtio_device *vdev)
int err;
struct virtio_chan *chan;
+ if (!vdev->config->get) {
+ dev_err(&vdev->dev, "%s failure: config access disabled\n",
+ __func__);
+ return -EINVAL;
+ }
+
chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL);
if (!chan) {
pr_err("Failed to allocate virtio 9P channel\n");
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 65728e0dc4ff..0ee453fad3de 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -987,15 +987,12 @@ static int __init br_netfilter_init(void)
if (brnf_sysctl_header == NULL) {
printk(KERN_WARNING
"br_netfilter: can't register to sysctl.\n");
- ret = -ENOMEM;
- goto err1;
+ nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+ return -ENOMEM;
}
#endif
printk(KERN_NOTICE "Bridge firewalling registered\n");
return 0;
-err1:
- nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
- return ret;
}
static void __exit br_netfilter_fini(void)
diff --git a/net/core/dev.c b/net/core/dev.c
index d030575532a2..8f9710c62e20 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4024,6 +4024,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
NAPI_GRO_CB(skb)->flush = 0;
NAPI_GRO_CB(skb)->free = 0;
NAPI_GRO_CB(skb)->udp_mark = 0;
+ NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
/* Setup for GRO checksum validation */
switch (skb->ip_summed) {
@@ -5335,7 +5336,7 @@ EXPORT_SYMBOL(netdev_upper_dev_unlink);
/**
* netdev_bonding_info_change - Dispatch event about slave change
* @dev: device
- * @netdev_bonding_info: info to dispatch
+ * @bonding_info: info to dispatch
*
* Send NETDEV_BONDING_INFO to netdev notifiers with info.
* The caller must hold the RTNL lock.
diff --git a/net/core/filter.c b/net/core/filter.c
index ec9baea10c16..f6bdc2b1ba01 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -531,7 +531,7 @@ do_pass:
*insn = BPF_LDX_MEM(BPF_W, BPF_REG_A, BPF_REG_CTX, fp->k);
break;
- /* Unkown instruction. */
+ /* Unknown instruction. */
default:
goto err;
}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 9fa25b0ea145..b4899f5b7388 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -97,7 +97,7 @@
* New xmit() return, do_div and misc clean up by Stephen Hemminger
* <shemminger@osdl.org> 040923
*
- * Randy Dunlap fixed u64 printk compiler waring
+ * Randy Dunlap fixed u64 printk compiler warning
*
* Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org>
* New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 5be499b6a2d2..ab293a3066b3 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2162,7 +2162,14 @@ replay:
}
err = rtnl_configure_link(dev, ifm);
if (err < 0) {
- unregister_netdevice(dev);
+ if (ops->newlink) {
+ LIST_HEAD(list_kill);
+
+ ops->dellink(dev, &list_kill);
+ unregister_netdevice_many(&list_kill);
+ } else {
+ unregister_netdevice(dev);
+ }
goto out;
}
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index d104ae15836f..f23deadf42a0 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -521,10 +521,13 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
struct device_node *phy_dn, *port_dn;
bool phy_is_fixed = false;
u32 phy_flags = 0;
- int ret;
+ int mode, ret;
port_dn = cd->port_dn[p->port];
- p->phy_interface = of_get_phy_mode(port_dn);
+ mode = of_get_phy_mode(port_dn);
+ if (mode < 0)
+ mode = PHY_INTERFACE_MODE_NA;
+ p->phy_interface = mode;
phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
if (of_phy_is_fixed_link(port_dn)) {
@@ -559,6 +562,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
if (!p->phy)
return -ENODEV;
+ /* Use already configured phy mode */
+ p->phy_interface = p->phy->interface;
phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
p->phy_interface);
} else {
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index f0b4a31d7bd6..3a8985c94581 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1186,7 +1186,7 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
no_in_dev:
/* Not loopback addresses on loopback should be preferred
- in this case. It is importnat that lo is the first interface
+ in this case. It is important that lo is the first interface
in dev_base list.
*/
for_each_netdev_rcu(net, dev) {
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 92ddea1e6457..ff069f6597ac 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -22,14 +22,18 @@ static LIST_HEAD(fou_list);
struct fou {
struct socket *sock;
u8 protocol;
+ u8 flags;
u16 port;
struct udp_offload udp_offloads;
struct list_head list;
};
+#define FOU_F_REMCSUM_NOPARTIAL BIT(0)
+
struct fou_cfg {
u16 type;
u8 protocol;
+ u8 flags;
struct udp_port_cfg udp_config;
};
@@ -64,24 +68,20 @@ static int fou_udp_recv(struct sock *sk, struct sk_buff *skb)
}
static struct guehdr *gue_remcsum(struct sk_buff *skb, struct guehdr *guehdr,
- void *data, size_t hdrlen, u8 ipproto)
+ void *data, size_t hdrlen, u8 ipproto,
+ bool nopartial)
{
__be16 *pd = data;
size_t start = ntohs(pd[0]);
size_t offset = ntohs(pd[1]);
size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
- if (skb->remcsum_offload) {
- /* Already processed in GRO path */
- skb->remcsum_offload = 0;
- return guehdr;
- }
-
if (!pskb_may_pull(skb, plen))
return NULL;
guehdr = (struct guehdr *)&udp_hdr(skb)[1];
- skb_remcsum_process(skb, (void *)guehdr + hdrlen, start, offset);
+ skb_remcsum_process(skb, (void *)guehdr + hdrlen,
+ start, offset, nopartial);
return guehdr;
}
@@ -142,7 +142,9 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
if (flags & GUE_PFLAG_REMCSUM) {
guehdr = gue_remcsum(skb, guehdr, data + doffset,
- hdrlen, guehdr->proto_ctype);
+ hdrlen, guehdr->proto_ctype,
+ !!(fou->flags &
+ FOU_F_REMCSUM_NOPARTIAL));
if (!guehdr)
goto drop;
@@ -214,7 +216,8 @@ out_unlock:
static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
struct guehdr *guehdr, void *data,
- size_t hdrlen, u8 ipproto)
+ size_t hdrlen, u8 ipproto,
+ struct gro_remcsum *grc, bool nopartial)
{
__be16 *pd = data;
size_t start = ntohs(pd[0]);
@@ -222,7 +225,7 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
size_t plen = hdrlen + max_t(size_t, offset + sizeof(u16), start);
if (skb->remcsum_offload)
- return guehdr;
+ return NULL;
if (!NAPI_GRO_CB(skb)->csum_valid)
return NULL;
@@ -234,7 +237,8 @@ static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
return NULL;
}
- skb_gro_remcsum_process(skb, (void *)guehdr + hdrlen, start, offset);
+ skb_gro_remcsum_process(skb, (void *)guehdr + hdrlen,
+ start, offset, grc, nopartial);
skb->remcsum_offload = 1;
@@ -254,6 +258,10 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head,
void *data;
u16 doffset = 0;
int flush = 1;
+ struct fou *fou = container_of(uoff, struct fou, udp_offloads);
+ struct gro_remcsum grc;
+
+ skb_gro_remcsum_init(&grc);
off = skb_gro_offset(skb);
len = off + sizeof(*guehdr);
@@ -295,7 +303,9 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head,
if (flags & GUE_PFLAG_REMCSUM) {
guehdr = gue_gro_remcsum(skb, off, guehdr,
data + doffset, hdrlen,
- guehdr->proto_ctype);
+ guehdr->proto_ctype, &grc,
+ !!(fou->flags &
+ FOU_F_REMCSUM_NOPARTIAL));
if (!guehdr)
goto out;
@@ -345,6 +355,7 @@ out_unlock:
rcu_read_unlock();
out:
NAPI_GRO_CB(skb)->flush |= flush;
+ skb_gro_remcsum_cleanup(skb, &grc);
return pp;
}
@@ -455,6 +466,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
sk = sock->sk;
+ fou->flags = cfg->flags;
fou->port = cfg->udp_config.local_udp_port;
/* Initial for fou type */
@@ -541,6 +553,7 @@ static struct nla_policy fou_nl_policy[FOU_ATTR_MAX + 1] = {
[FOU_ATTR_AF] = { .type = NLA_U8, },
[FOU_ATTR_IPPROTO] = { .type = NLA_U8, },
[FOU_ATTR_TYPE] = { .type = NLA_U8, },
+ [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG, },
};
static int parse_nl_config(struct genl_info *info,
@@ -571,6 +584,9 @@ static int parse_nl_config(struct genl_info *info,
if (info->attrs[FOU_ATTR_TYPE])
cfg->type = nla_get_u8(info->attrs[FOU_ATTR_TYPE]);
+ if (info->attrs[FOU_ATTR_REMCSUM_NOPARTIAL])
+ cfg->flags |= FOU_F_REMCSUM_NOPARTIAL;
+
return 0;
}
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 53db2c309572..ea82fd492c1b 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -134,6 +134,7 @@ static bool tcp_fastopen_create_child(struct sock *sk,
struct tcp_sock *tp;
struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
struct sock *child;
+ u32 end_seq;
req->num_retrans = 0;
req->num_timeout = 0;
@@ -185,20 +186,35 @@ static bool tcp_fastopen_create_child(struct sock *sk,
/* Queue the data carried in the SYN packet. We need to first
* bump skb's refcnt because the caller will attempt to free it.
+ * Note that IPv6 might also have used skb_get() trick
+ * in tcp_v6_conn_request() to keep this SYN around (treq->pktopts)
+ * So we need to eventually get a clone of the packet,
+ * before inserting it in sk_receive_queue.
*
* XXX (TFO) - we honor a zero-payload TFO request for now,
* (any reason not to?) but no need to queue the skb since
* there is no data. How about SYN+FIN?
*/
- if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1) {
- skb = skb_get(skb);
- skb_dst_drop(skb);
- __skb_pull(skb, tcp_hdr(skb)->doff * 4);
- skb_set_owner_r(skb, child);
- __skb_queue_tail(&child->sk_receive_queue, skb);
- tp->syn_data_acked = 1;
+ end_seq = TCP_SKB_CB(skb)->end_seq;
+ if (end_seq != TCP_SKB_CB(skb)->seq + 1) {
+ struct sk_buff *skb2;
+
+ if (unlikely(skb_shared(skb)))
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ else
+ skb2 = skb_get(skb);
+
+ if (likely(skb2)) {
+ skb_dst_drop(skb2);
+ __skb_pull(skb2, tcp_hdrlen(skb));
+ skb_set_owner_r(skb2, child);
+ __skb_queue_tail(&child->sk_receive_queue, skb2);
+ tp->syn_data_acked = 1;
+ } else {
+ end_seq = TCP_SKB_CB(skb)->seq + 1;
+ }
}
- tcp_rsk(req)->rcv_nxt = tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+ tcp_rsk(req)->rcv_nxt = tp->rcv_nxt = end_seq;
sk->sk_data_ready(sk);
bh_unlock_sock(child);
sock_put(child);
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index d10f6f4ead27..4915d8284a86 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -402,6 +402,13 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff)
}
rcu_read_unlock();
+
+ if (skb->remcsum_offload)
+ skb_shinfo(skb)->gso_type |= SKB_GSO_TUNNEL_REMCSUM;
+
+ skb->encapsulation = 1;
+ skb_set_inner_mac_header(skb, nhoff + sizeof(struct udphdr));
+
return err;
}
@@ -410,9 +417,13 @@ static int udp4_gro_complete(struct sk_buff *skb, int nhoff)
const struct iphdr *iph = ip_hdr(skb);
struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
- if (uh->check)
+ if (uh->check) {
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
uh->check = ~udp_v4_check(skb->len - nhoff, iph->saddr,
iph->daddr, 0);
+ } else {
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
+ }
return udp_gro_complete(skb, nhoff);
}
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 2f780cba6e12..f45d6db50a45 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -172,7 +172,7 @@ static void __net_exit ip6_fl_purge(struct net *net)
{
int i;
- spin_lock(&ip6_fl_lock);
+ spin_lock_bh(&ip6_fl_lock);
for (i = 0; i <= FL_HASH_MASK; i++) {
struct ip6_flowlabel *fl;
struct ip6_flowlabel __rcu **flp;
@@ -190,7 +190,7 @@ static void __net_exit ip6_fl_purge(struct net *net)
flp = &fl->next;
}
}
- spin_unlock(&ip6_fl_lock);
+ spin_unlock_bh(&ip6_fl_lock);
}
static struct ip6_flowlabel *fl_intern(struct net *net,
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index d33df4cbd872..7deebf102cba 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1273,7 +1273,7 @@ emsgsize:
/* If this is the first and only packet and device
* supports checksum offloading, let's use it.
*/
- if (!skb &&
+ if (!skb && sk->sk_protocol == IPPROTO_UDP &&
length + fragheaderlen < mtu &&
rt->dst.dev->features & NETIF_F_V6_CSUM &&
!exthdrlen)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 98565ce0ebcd..4688bd4d7f59 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -141,7 +141,7 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
u32 *p = NULL;
if (!(rt->dst.flags & DST_HOST))
- return NULL;
+ return dst_cow_metrics_generic(dst, old);
peer = rt6_get_peer_create(rt);
if (peer) {
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index a56276996b72..ab889bb16b3c 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -161,9 +161,13 @@ static int udp6_gro_complete(struct sk_buff *skb, int nhoff)
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
- if (uh->check)
+ if (uh->check) {
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
uh->check = ~udp_v6_check(skb->len - nhoff, &ipv6h->saddr,
&ipv6h->daddr, 0);
+ } else {
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
+ }
return udp_gro_complete(skb, nhoff);
}
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 265e190f2218..c598f74063a1 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -19,6 +19,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
#include <net/netfilter/nf_tables.h>
static int nft_compat_chain_validate_dependency(const char *tablename,
@@ -40,6 +41,7 @@ static int nft_compat_chain_validate_dependency(const char *tablename,
union nft_entry {
struct ipt_entry e4;
struct ip6t_entry e6;
+ struct ebt_entry ebt;
};
static inline void
@@ -50,9 +52,9 @@ nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
par->hotdrop = false;
}
-static void nft_target_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
- const struct nft_pktinfo *pkt)
+static void nft_target_eval_xt(const struct nft_expr *expr,
+ struct nft_data data[NFT_REG_MAX + 1],
+ const struct nft_pktinfo *pkt)
{
void *info = nft_expr_priv(expr);
struct xt_target *target = expr->ops->data;
@@ -66,7 +68,7 @@ static void nft_target_eval(const struct nft_expr *expr,
if (pkt->xt.hotdrop)
ret = NF_DROP;
- switch(ret) {
+ switch (ret) {
case XT_CONTINUE:
data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
break;
@@ -74,7 +76,41 @@ static void nft_target_eval(const struct nft_expr *expr,
data[NFT_REG_VERDICT].verdict = ret;
break;
}
- return;
+}
+
+static void nft_target_eval_bridge(const struct nft_expr *expr,
+ struct nft_data data[NFT_REG_MAX + 1],
+ const struct nft_pktinfo *pkt)
+{
+ void *info = nft_expr_priv(expr);
+ struct xt_target *target = expr->ops->data;
+ struct sk_buff *skb = pkt->skb;
+ int ret;
+
+ nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info);
+
+ ret = target->target(skb, &pkt->xt);
+
+ if (pkt->xt.hotdrop)
+ ret = NF_DROP;
+
+ switch (ret) {
+ case EBT_ACCEPT:
+ data[NFT_REG_VERDICT].verdict = NF_ACCEPT;
+ break;
+ case EBT_DROP:
+ data[NFT_REG_VERDICT].verdict = NF_DROP;
+ break;
+ case EBT_CONTINUE:
+ data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+ break;
+ case EBT_RETURN:
+ data[NFT_REG_VERDICT].verdict = NFT_RETURN;
+ break;
+ default:
+ data[NFT_REG_VERDICT].verdict = ret;
+ break;
+ }
}
static const struct nla_policy nft_target_policy[NFTA_TARGET_MAX + 1] = {
@@ -100,6 +136,10 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
entry->e6.ipv6.proto = proto;
entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
break;
+ case NFPROTO_BRIDGE:
+ entry->ebt.ethproto = proto;
+ entry->ebt.invflags = inv ? EBT_IPROTO : 0;
+ break;
}
par->entryinfo = entry;
par->target = target;
@@ -307,6 +347,10 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
entry->e6.ipv6.proto = proto;
entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
break;
+ case NFPROTO_BRIDGE:
+ entry->ebt.ethproto = proto;
+ entry->ebt.invflags = inv ? EBT_IPROTO : 0;
+ break;
}
par->entryinfo = entry;
par->match = match;
@@ -490,6 +534,9 @@ nfnl_compat_get(struct sock *nfnl, struct sk_buff *skb,
case AF_INET6:
fmt = "ip6t_%s";
break;
+ case NFPROTO_BRIDGE:
+ fmt = "ebt_%s";
+ break;
default:
pr_err("nft_compat: unsupported protocol %d\n",
nfmsg->nfgen_family);
@@ -663,13 +710,17 @@ nft_target_select_ops(const struct nft_ctx *ctx,
nft_target->ops.type = &nft_target_type;
nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
- nft_target->ops.eval = nft_target_eval;
nft_target->ops.init = nft_target_init;
nft_target->ops.destroy = nft_target_destroy;
nft_target->ops.dump = nft_target_dump;
nft_target->ops.validate = nft_target_validate;
nft_target->ops.data = target;
+ if (family == NFPROTO_BRIDGE)
+ nft_target->ops.eval = nft_target_eval_bridge;
+ else
+ nft_target->ops.eval = nft_target_eval_xt;
+
list_add(&nft_target->head, &nft_target_list);
return &nft_target->ops;
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 6404a726d17b..9615b8b9fb37 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -39,6 +39,7 @@ static void nft_lookup_eval(const struct nft_expr *expr,
static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
[NFTA_LOOKUP_SET] = { .type = NLA_STRING },
+ [NFTA_LOOKUP_SET_ID] = { .type = NLA_U32 },
[NFTA_LOOKUP_SREG] = { .type = NLA_U32 },
[NFTA_LOOKUP_DREG] = { .type = NLA_U32 },
};
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index e2c348b8baca..50ec42f170a0 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -717,6 +717,8 @@ int ovs_flow_key_extract_userspace(const struct nlattr *attr,
{
int err;
+ memset(key, 0, OVS_SW_FLOW_KEY_METADATA_SIZE);
+
/* Extract metadata from netlink attributes. */
err = ovs_nla_get_flow_metadata(attr, key, log);
if (err)
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 993281e6278d..216f20b90aa5 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1516,7 +1516,7 @@ int ovs_nla_put_identifier(const struct sw_flow *flow, struct sk_buff *skb)
/* Called with ovs_mutex or RCU read lock. */
int ovs_nla_put_masked_key(const struct sw_flow *flow, struct sk_buff *skb)
{
- return ovs_nla_put_key(&flow->mask->key, &flow->key,
+ return ovs_nla_put_key(&flow->key, &flow->key,
OVS_FLOW_ATTR_KEY, false, skb);
}
@@ -1746,7 +1746,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
struct sw_flow_key key;
struct ovs_tunnel_info *tun_info;
struct nlattr *a;
- int err, start, opts_type;
+ int err = 0, start, opts_type;
ovs_match_init(&match, &key, NULL);
opts_type = ipv4_tun_from_nlattr(nla_data(attr), &match, false, log);
diff --git a/net/rds/cong.c b/net/rds/cong.c
index e5b65acd650b..e6144b8246fd 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -221,7 +221,21 @@ void rds_cong_queue_updates(struct rds_cong_map *map)
list_for_each_entry(conn, &map->m_conn_list, c_map_item) {
if (!test_and_set_bit(0, &conn->c_map_queued)) {
rds_stats_inc(s_cong_update_queued);
- rds_send_xmit(conn);
+ /* We cannot inline the call to rds_send_xmit() here
+ * for two reasons (both pertaining to a TCP transport):
+ * 1. When we get here from the receive path, we
+ * are already holding the sock_lock (held by
+ * tcp_v4_rcv()). So inlining calls to
+ * tcp_setsockopt and/or tcp_sendmsg will deadlock
+ * when it tries to get the sock_lock())
+ * 2. Interrupts are masked so that we can mark the
+ * the port congested from both send and recv paths.
+ * (See comment around declaration of rdc_cong_lock).
+ * An attempt to get the sock_lock() here will
+ * therefore trigger warnings.
+ * Defer the xmit to rds_send_worker() instead.
+ */
+ queue_delayed_work(rds_wq, &conn->c_send_w, 0);
}
}
diff --git a/samples/seccomp/bpf-fancy.c b/samples/seccomp/bpf-fancy.c
index 8eb483aaec46..e8b24f443709 100644
--- a/samples/seccomp/bpf-fancy.c
+++ b/samples/seccomp/bpf-fancy.c
@@ -25,7 +25,9 @@
int main(int argc, char **argv)
{
- struct bpf_labels l;
+ struct bpf_labels l = {
+ .count = 0,
+ };
static const char msg1[] = "Please type something: ";
static const char msg2[] = "You typed: ";
char buf[256];
diff --git a/samples/seccomp/bpf-helper.c b/samples/seccomp/bpf-helper.c
index 579cfe331886..05cb4d5ff9f5 100644
--- a/samples/seccomp/bpf-helper.c
+++ b/samples/seccomp/bpf-helper.c
@@ -10,6 +10,7 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "bpf-helper.h"
@@ -63,6 +64,11 @@ __u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label)
{
struct __bpf_label *begin = labels->labels, *end;
int id;
+
+ if (labels->count == BPF_LABELS_MAX) {
+ fprintf(stderr, "Too many labels\n");
+ exit(1);
+ }
if (labels->count == 0) {
begin->label = label;
begin->location = 0xffffffff;
diff --git a/scripts/Makefile b/scripts/Makefile
index 72902b5f2721..2016a64497ab 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -36,6 +36,7 @@ subdir-$(CONFIG_MODVERSIONS) += genksyms
subdir-y += mod
subdir-$(CONFIG_SECURITY_SELINUX) += selinux
subdir-$(CONFIG_DTC) += dtc
+subdir-$(CONFIG_GDB_SCRIPTS) += gdb
# Let clean descend into subdirs
subdir- += basic kconfig package
diff --git a/scripts/diffconfig b/scripts/diffconfig
index 6d672836e187..0db267d0adc9 100755
--- a/scripts/diffconfig
+++ b/scripts/diffconfig
@@ -28,7 +28,6 @@ If no config files are specified, .config and .config.old are used.
Example usage:
$ diffconfig .config config-with-some-changes
-EXT2_FS_XATTR n
--EXT2_FS_XIP n
CRAMFS n -> y
EXT2_FS y -> n
LOG_BUF_SHIFT 14 -> 16
diff --git a/scripts/gdb/Makefile b/scripts/gdb/Makefile
new file mode 100644
index 000000000000..62f5f65becfd
--- /dev/null
+++ b/scripts/gdb/Makefile
@@ -0,0 +1 @@
+subdir-y := linux
diff --git a/scripts/gdb/linux/.gitignore b/scripts/gdb/linux/.gitignore
new file mode 100644
index 000000000000..52e4e61140d1
--- /dev/null
+++ b/scripts/gdb/linux/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+*.pyo
diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile
new file mode 100644
index 000000000000..6cf1ecf61057
--- /dev/null
+++ b/scripts/gdb/linux/Makefile
@@ -0,0 +1,11 @@
+always := gdb-scripts
+
+SRCTREE := $(shell cd $(srctree) && /bin/pwd)
+
+$(obj)/gdb-scripts:
+ifneq ($(KBUILD_SRC),)
+ $(Q)ln -fsn $(SRCTREE)/$(obj)/*.py $(objtree)/$(obj)
+endif
+ @:
+
+clean-files := *.pyc *.pyo $(if $(KBUILD_SRC),*.py)
diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py
new file mode 100644
index 000000000000..4297b83fedef
--- /dev/null
+++ b/scripts/gdb/linux/cpus.py
@@ -0,0 +1,135 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# per-cpu tools
+#
+# Copyright (c) Siemens AG, 2011-2013
+#
+# Authors:
+# Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+
+from linux import tasks, utils
+
+
+MAX_CPUS = 4096
+
+
+def get_current_cpu():
+ if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU:
+ return gdb.selected_thread().num - 1
+ elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB:
+ tid = gdb.selected_thread().ptid[2]
+ if tid > (0x100000000 - MAX_CPUS - 2):
+ return 0x100000000 - tid - 2
+ else:
+ return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu']
+ else:
+ raise gdb.GdbError("Sorry, obtaining the current CPU is not yet "
+ "supported with this gdb server.")
+
+
+def per_cpu(var_ptr, cpu):
+ if cpu == -1:
+ cpu = get_current_cpu()
+ if utils.is_target_arch("sparc:v9"):
+ offset = gdb.parse_and_eval(
+ "trap_block[{0}].__per_cpu_base".format(str(cpu)))
+ else:
+ try:
+ offset = gdb.parse_and_eval(
+ "__per_cpu_offset[{0}]".format(str(cpu)))
+ except gdb.error:
+ # !CONFIG_SMP case
+ offset = 0
+ pointer = var_ptr.cast(utils.get_long_type()) + offset
+ return pointer.cast(var_ptr.type).dereference()
+
+
+cpu_mask = {}
+
+
+def cpu_mask_invalidate(event):
+ global cpu_mask
+ cpu_mask = {}
+ gdb.events.stop.disconnect(cpu_mask_invalidate)
+ if hasattr(gdb.events, 'new_objfile'):
+ gdb.events.new_objfile.disconnect(cpu_mask_invalidate)
+
+
+def cpu_list(mask_name):
+ global cpu_mask
+ mask = None
+ if mask_name in cpu_mask:
+ mask = cpu_mask[mask_name]
+ if mask is None:
+ mask = gdb.parse_and_eval(mask_name + ".bits")
+ if hasattr(gdb, 'events'):
+ cpu_mask[mask_name] = mask
+ gdb.events.stop.connect(cpu_mask_invalidate)
+ if hasattr(gdb.events, 'new_objfile'):
+ gdb.events.new_objfile.connect(cpu_mask_invalidate)
+ bits_per_entry = mask[0].type.sizeof * 8
+ num_entries = mask.type.sizeof * 8 / bits_per_entry
+ entry = -1
+ bits = 0
+
+ while True:
+ while bits == 0:
+ entry += 1
+ if entry == num_entries:
+ return
+ bits = mask[entry]
+ if bits != 0:
+ bit = 0
+ break
+
+ while bits & 1 == 0:
+ bits >>= 1
+ bit += 1
+
+ cpu = entry * bits_per_entry + bit
+
+ bits >>= 1
+ bit += 1
+
+ yield cpu
+
+
+class PerCpu(gdb.Function):
+ """Return per-cpu variable.
+
+$lx_per_cpu("VAR"[, CPU]): Return the per-cpu variable called VAR for the
+given CPU number. If CPU is omitted, the CPU of the current context is used.
+Note that VAR has to be quoted as string."""
+
+ def __init__(self):
+ super(PerCpu, self).__init__("lx_per_cpu")
+
+ def invoke(self, var_name, cpu=-1):
+ var_ptr = gdb.parse_and_eval("&" + var_name.string())
+ return per_cpu(var_ptr, cpu)
+
+
+PerCpu()
+
+
+class LxCurrentFunc(gdb.Function):
+ """Return current task.
+
+$lx_current([CPU]): Return the per-cpu task variable for the given CPU
+number. If CPU is omitted, the CPU of the current context is used."""
+
+ def __init__(self):
+ super(LxCurrentFunc, self).__init__("lx_current")
+
+ def invoke(self, cpu=-1):
+ var_ptr = gdb.parse_and_eval("&current_task")
+ return per_cpu(var_ptr, cpu).dereference()
+
+
+LxCurrentFunc()
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
new file mode 100644
index 000000000000..3c947f0c5dad
--- /dev/null
+++ b/scripts/gdb/linux/dmesg.py
@@ -0,0 +1,65 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# kernel log buffer dump
+#
+# Copyright (c) Siemens AG, 2011, 2012
+#
+# Authors:
+# Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+import string
+
+from linux import utils
+
+
+class LxDmesg(gdb.Command):
+ """Print Linux kernel log buffer."""
+
+ def __init__(self):
+ super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA)
+
+ def invoke(self, arg, from_tty):
+ log_buf_addr = int(str(gdb.parse_and_eval("log_buf")).split()[0], 16)
+ log_first_idx = int(gdb.parse_and_eval("log_first_idx"))
+ log_next_idx = int(gdb.parse_and_eval("log_next_idx"))
+ log_buf_len = int(gdb.parse_and_eval("log_buf_len"))
+
+ inf = gdb.inferiors()[0]
+ start = log_buf_addr + log_first_idx
+ if log_first_idx < log_next_idx:
+ log_buf_2nd_half = -1
+ length = log_next_idx - log_first_idx
+ log_buf = inf.read_memory(start, length)
+ else:
+ log_buf_2nd_half = log_buf_len - log_first_idx
+ log_buf = inf.read_memory(start, log_buf_2nd_half) + \
+ inf.read_memory(log_buf_addr, log_next_idx)
+
+ pos = 0
+ while pos < log_buf.__len__():
+ length = utils.read_u16(log_buf[pos + 8:pos + 10])
+ if length == 0:
+ if log_buf_2nd_half == -1:
+ gdb.write("Corrupted log buffer!\n")
+ break
+ pos = log_buf_2nd_half
+ continue
+
+ text_len = utils.read_u16(log_buf[pos + 10:pos + 12])
+ text = log_buf[pos + 16:pos + 16 + text_len]
+ time_stamp = utils.read_u64(log_buf[pos:pos + 8])
+
+ for line in memoryview(text).tobytes().splitlines():
+ gdb.write("[{time:12.6f}] {line}\n".format(
+ time=time_stamp / 1000000000.0,
+ line=line))
+
+ pos += length
+
+
+LxDmesg()
diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py
new file mode 100644
index 000000000000..a1504c4f1900
--- /dev/null
+++ b/scripts/gdb/linux/modules.py
@@ -0,0 +1,103 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# module tools
+#
+# Copyright (c) Siemens AG, 2013
+#
+# Authors:
+# Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+
+from linux import cpus, utils
+
+
+module_type = utils.CachedType("struct module")
+
+
+def module_list():
+ global module_type
+ module_ptr_type = module_type.get_type().pointer()
+ modules = gdb.parse_and_eval("modules")
+ entry = modules['next']
+ end_of_list = modules.address
+
+ while entry != end_of_list:
+ yield utils.container_of(entry, module_ptr_type, "list")
+ entry = entry['next']
+
+
+def find_module_by_name(name):
+ for module in module_list():
+ if module['name'].string() == name:
+ return module
+ return None
+
+
+class LxModule(gdb.Function):
+ """Find module by name and return the module variable.
+
+$lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules
+of the target and return that module variable which MODULE matches."""
+
+ def __init__(self):
+ super(LxModule, self).__init__("lx_module")
+
+ def invoke(self, mod_name):
+ mod_name = mod_name.string()
+ module = find_module_by_name(mod_name)
+ if module:
+ return module.dereference()
+ else:
+ raise gdb.GdbError("Unable to find MODULE " + mod_name)
+
+
+LxModule()
+
+
+class LxLsmod(gdb.Command):
+ """List currently loaded modules."""
+
+ _module_use_type = utils.CachedType("struct module_use")
+
+ def __init__(self):
+ super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA)
+
+ def invoke(self, arg, from_tty):
+ gdb.write(
+ "Address{0} Module Size Used by\n".format(
+ " " if utils.get_long_type().sizeof == 8 else ""))
+
+ for module in module_list():
+ ref = 0
+ module_refptr = module['refptr']
+ for cpu in cpus.cpu_list("cpu_possible_mask"):
+ refptr = cpus.per_cpu(module_refptr, cpu)
+ ref += refptr['incs']
+ ref -= refptr['decs']
+
+ gdb.write("{address} {name:<19} {size:>8} {ref}".format(
+ address=str(module['module_core']).split()[0],
+ name=module['name'].string(),
+ size=str(module['core_size']),
+ ref=str(ref)))
+
+ source_list = module['source_list']
+ t = self._module_use_type.get_type().pointer()
+ entry = source_list['next']
+ first = True
+ while entry != source_list.address:
+ use = utils.container_of(entry, t, "source_list")
+ gdb.write("{separator}{name}".format(
+ separator=" " if first else ",",
+ name=use['source']['name'].string()))
+ first = False
+ entry = entry['next']
+ gdb.write("\n")
+
+
+LxLsmod()
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
new file mode 100644
index 000000000000..cd5bea965d4e
--- /dev/null
+++ b/scripts/gdb/linux/symbols.py
@@ -0,0 +1,177 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# load kernel and module symbols
+#
+# Copyright (c) Siemens AG, 2011-2013
+#
+# Authors:
+# Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+import os
+import re
+import string
+
+from linux import modules, utils
+
+
+if hasattr(gdb, 'Breakpoint'):
+ class LoadModuleBreakpoint(gdb.Breakpoint):
+ def __init__(self, spec, gdb_command):
+ super(LoadModuleBreakpoint, self).__init__(spec, internal=True)
+ self.silent = True
+ self.gdb_command = gdb_command
+
+ def stop(self):
+ module = gdb.parse_and_eval("mod")
+ module_name = module['name'].string()
+ cmd = self.gdb_command
+
+ # enforce update if object file is not found
+ cmd.module_files_updated = False
+
+ # Disable pagination while reporting symbol (re-)loading.
+ # The console input is blocked in this context so that we would
+ # get stuck waiting for the user to acknowledge paged output.
+ show_pagination = gdb.execute("show pagination", to_string=True)
+ pagination = show_pagination.endswith("on.\n")
+ gdb.execute("set pagination off")
+
+ if module_name in cmd.loaded_modules:
+ gdb.write("refreshing all symbols to reload module "
+ "'{0}'\n".format(module_name))
+ cmd.load_all_symbols()
+ else:
+ cmd.load_module_symbols(module)
+
+ # restore pagination state
+ gdb.execute("set pagination %s" % ("on" if pagination else "off"))
+
+ return False
+
+
+class LxSymbols(gdb.Command):
+ """(Re-)load symbols of Linux kernel and currently loaded modules.
+
+The kernel (vmlinux) is taken from the current working directly. Modules (.ko)
+are scanned recursively, starting in the same directory. Optionally, the module
+search path can be extended by a space separated list of paths passed to the
+lx-symbols command."""
+
+ module_paths = []
+ module_files = []
+ module_files_updated = False
+ loaded_modules = []
+ breakpoint = None
+
+ def __init__(self):
+ super(LxSymbols, self).__init__("lx-symbols", gdb.COMMAND_FILES,
+ gdb.COMPLETE_FILENAME)
+
+ def _update_module_files(self):
+ self.module_files = []
+ for path in self.module_paths:
+ gdb.write("scanning for modules in {0}\n".format(path))
+ for root, dirs, files in os.walk(path):
+ for name in files:
+ if name.endswith(".ko"):
+ self.module_files.append(root + "/" + name)
+ self.module_files_updated = True
+
+ def _get_module_file(self, module_name):
+ module_pattern = ".*/{0}\.ko$".format(
+ module_name.replace("_", r"[_\-]"))
+ for name in self.module_files:
+ if re.match(module_pattern, name) and os.path.exists(name):
+ return name
+ return None
+
+ def _section_arguments(self, module):
+ try:
+ sect_attrs = module['sect_attrs'].dereference()
+ except gdb.error:
+ return ""
+ attrs = sect_attrs['attrs']
+ section_name_to_address = {
+ attrs[n]['name'].string() : attrs[n]['address']
+ for n in range(int(sect_attrs['nsections']))}
+ args = []
+ for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]:
+ address = section_name_to_address.get(section_name)
+ if address:
+ args.append(" -s {name} {addr}".format(
+ name=section_name, addr=str(address)))
+ return "".join(args)
+
+ def load_module_symbols(self, module):
+ module_name = module['name'].string()
+ module_addr = str(module['module_core']).split()[0]
+
+ module_file = self._get_module_file(module_name)
+ if not module_file and not self.module_files_updated:
+ self._update_module_files()
+ module_file = self._get_module_file(module_name)
+
+ if module_file:
+ gdb.write("loading @{addr}: {filename}\n".format(
+ addr=module_addr, filename=module_file))
+ cmdline = "add-symbol-file {filename} {addr}{sections}".format(
+ filename=module_file,
+ addr=module_addr,
+ sections=self._section_arguments(module))
+ gdb.execute(cmdline, to_string=True)
+ if not module_name in self.loaded_modules:
+ self.loaded_modules.append(module_name)
+ else:
+ gdb.write("no module object found for '{0}'\n".format(module_name))
+
+ def load_all_symbols(self):
+ gdb.write("loading vmlinux\n")
+
+ # Dropping symbols will disable all breakpoints. So save their states
+ # and restore them afterward.
+ saved_states = []
+ if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None:
+ for bp in gdb.breakpoints():
+ saved_states.append({'breakpoint': bp, 'enabled': bp.enabled})
+
+ # drop all current symbols and reload vmlinux
+ gdb.execute("symbol-file", to_string=True)
+ gdb.execute("symbol-file vmlinux")
+
+ self.loaded_modules = []
+ module_list = modules.module_list()
+ if not module_list:
+ gdb.write("no modules found\n")
+ else:
+ [self.load_module_symbols(module) for module in module_list]
+
+ for saved_state in saved_states:
+ saved_state['breakpoint'].enabled = saved_state['enabled']
+
+ def invoke(self, arg, from_tty):
+ self.module_paths = arg.split()
+ self.module_paths.append(os.getcwd())
+
+ # enforce update
+ self.module_files = []
+ self.module_files_updated = False
+
+ self.load_all_symbols()
+
+ if hasattr(gdb, 'Breakpoint'):
+ if not self.breakpoint is None:
+ self.breakpoint.delete()
+ self.breakpoint = None
+ self.breakpoint = LoadModuleBreakpoint(
+ "kernel/module.c:do_init_module", self)
+ else:
+ gdb.write("Note: symbol update on module loading not supported "
+ "with this gdb version\n")
+
+
+LxSymbols()
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py
new file mode 100644
index 000000000000..e2037d9bb7eb
--- /dev/null
+++ b/scripts/gdb/linux/tasks.py
@@ -0,0 +1,100 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# task & thread tools
+#
+# Copyright (c) Siemens AG, 2011-2013
+#
+# Authors:
+# Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+
+from linux import utils
+
+
+task_type = utils.CachedType("struct task_struct")
+
+def task_lists():
+ global task_type
+ task_ptr_type = task_type.get_type().pointer()
+ init_task = gdb.parse_and_eval("init_task").address
+ t = g = init_task
+
+ while True:
+ while True:
+ yield t
+
+ t = utils.container_of(t['thread_group']['next'],
+ task_ptr_type, "thread_group")
+ if t == g:
+ break
+
+ t = g = utils.container_of(g['tasks']['next'],
+ task_ptr_type, "tasks")
+ if t == init_task:
+ return
+
+def get_task_by_pid(pid):
+ for task in task_lists():
+ if int(task['pid']) == pid:
+ return task
+ return None
+
+
+class LxTaskByPidFunc(gdb.Function):
+ """Find Linux task by PID and return the task_struct variable.
+
+$lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and
+return that task_struct variable which PID matches."""
+
+ def __init__(self):
+ super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")
+
+ def invoke(self, pid):
+ task = get_task_by_pid(pid)
+ if task:
+ return task.dereference()
+ else:
+ raise gdb.GdbError("No task of PID " + str(pid))
+
+
+LxTaskByPidFunc()
+
+
+thread_info_type = utils.CachedType("struct thread_info")
+
+ia64_task_size = None
+
+
+def get_thread_info(task):
+ global thread_info_type
+ thread_info_ptr_type = thread_info_type.get_type().pointer()
+ if utils.is_target_arch("ia64"):
+ global ia64_task_size
+ if ia64_task_size is None:
+ ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)")
+ thread_info_addr = task.address + ia64_task_size
+ thread_info = thread_info_addr.cast(thread_info_ptr_type)
+ else:
+ thread_info = task['stack'].cast(thread_info_ptr_type)
+ return thread_info.dereference()
+
+
+class LxThreadInfoFunc (gdb.Function):
+ """Calculate Linux thread_info from task variable.
+
+$lx_thread_info(TASK): Given TASK, return the corresponding thread_info
+variable."""
+
+ def __init__(self):
+ super(LxThreadInfoFunc, self).__init__("lx_thread_info")
+
+ def invoke(self, task):
+ return get_thread_info(task)
+
+
+LxThreadInfoFunc()
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
new file mode 100644
index 000000000000..128c306db3ee
--- /dev/null
+++ b/scripts/gdb/linux/utils.py
@@ -0,0 +1,156 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# common utilities
+#
+# Copyright (c) Siemens AG, 2011-2013
+#
+# Authors:
+# Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+
+
+class CachedType:
+ def __init__(self, name):
+ self._type = None
+ self._name = name
+
+ def _new_objfile_handler(self, event):
+ self._type = None
+ gdb.events.new_objfile.disconnect(self._new_objfile_handler)
+
+ def get_type(self):
+ if self._type is None:
+ self._type = gdb.lookup_type(self._name)
+ if self._type is None:
+ raise gdb.GdbError(
+ "cannot resolve type '{0}'".format(self._name))
+ if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'):
+ gdb.events.new_objfile.connect(self._new_objfile_handler)
+ return self._type
+
+
+long_type = CachedType("long")
+
+
+def get_long_type():
+ global long_type
+ return long_type.get_type()
+
+
+def offset_of(typeobj, field):
+ element = gdb.Value(0).cast(typeobj)
+ return int(str(element[field].address).split()[0], 16)
+
+
+def container_of(ptr, typeobj, member):
+ return (ptr.cast(get_long_type()) -
+ offset_of(typeobj, member)).cast(typeobj)
+
+
+class ContainerOf(gdb.Function):
+ """Return pointer to containing data structure.
+
+$container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the
+data structure of the type TYPE in which PTR is the address of ELEMENT.
+Note that TYPE and ELEMENT have to be quoted as strings."""
+
+ def __init__(self):
+ super(ContainerOf, self).__init__("container_of")
+
+ def invoke(self, ptr, typename, elementname):
+ return container_of(ptr, gdb.lookup_type(typename.string()).pointer(),
+ elementname.string())
+
+ContainerOf()
+
+
+BIG_ENDIAN = 0
+LITTLE_ENDIAN = 1
+target_endianness = None
+
+
+def get_target_endianness():
+ global target_endianness
+ if target_endianness is None:
+ endian = gdb.execute("show endian", to_string=True)
+ if "little endian" in endian:
+ target_endianness = LITTLE_ENDIAN
+ elif "big endian" in endian:
+ target_endianness = BIG_ENDIAN
+ else:
+ raise gdb.GdgError("unknown endianness '{0}'".format(str(endian)))
+ return target_endianness
+
+
+def read_u16(buffer):
+ if get_target_endianness() == LITTLE_ENDIAN:
+ return ord(buffer[0]) + (ord(buffer[1]) << 8)
+ else:
+ return ord(buffer[1]) + (ord(buffer[0]) << 8)
+
+
+def read_u32(buffer):
+ if get_target_endianness() == LITTLE_ENDIAN:
+ return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16)
+ else:
+ return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16)
+
+
+def read_u64(buffer):
+ if get_target_endianness() == LITTLE_ENDIAN:
+ return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32)
+ else:
+ return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32)
+
+
+target_arch = None
+
+
+def is_target_arch(arch):
+ if hasattr(gdb.Frame, 'architecture'):
+ return arch in gdb.newest_frame().architecture().name()
+ else:
+ global target_arch
+ if target_arch is None:
+ target_arch = gdb.execute("show architecture", to_string=True)
+ return arch in target_arch
+
+
+GDBSERVER_QEMU = 0
+GDBSERVER_KGDB = 1
+gdbserver_type = None
+
+
+def get_gdbserver_type():
+ def exit_handler(event):
+ global gdbserver_type
+ gdbserver_type = None
+ gdb.events.exited.disconnect(exit_handler)
+
+ def probe_qemu():
+ try:
+ return gdb.execute("monitor info version", to_string=True) != ""
+ except:
+ return False
+
+ def probe_kgdb():
+ try:
+ thread_info = gdb.execute("info thread 2", to_string=True)
+ return "shadowCPU0" in thread_info
+ except:
+ return False
+
+ global gdbserver_type
+ if gdbserver_type is None:
+ if probe_qemu():
+ gdbserver_type = GDBSERVER_QEMU
+ elif probe_kgdb():
+ gdbserver_type = GDBSERVER_KGDB
+ if not gdbserver_type is None and hasattr(gdb, 'events'):
+ gdb.events.exited.connect(exit_handler)
+ return gdbserver_type
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
new file mode 100644
index 000000000000..48489285f119
--- /dev/null
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -0,0 +1,30 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# loader module
+#
+# Copyright (c) Siemens AG, 2012, 2013
+#
+# Authors:
+# Jan Kiszka <jan.kiszka@siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import os
+
+sys.path.insert(0, os.path.dirname(__file__) + "/scripts/gdb")
+
+try:
+ gdb.parse_and_eval("0")
+ gdb.execute("", to_string=True)
+except:
+ gdb.write("NOTE: gdb 7.2 or later required for Linux helper scripts to "
+ "work.\n")
+else:
+ import linux.utils
+ import linux.symbols
+ import linux.modules
+ import linux.dmesg
+ import linux.tasks
+ import linux.cpus
diff --git a/security/commoncap.c b/security/commoncap.c
index 2915d8503054..f66713bd7450 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -434,7 +434,6 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
*/
static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap)
{
- struct dentry *dentry;
int rc = 0;
struct cpu_vfs_cap_data vcaps;
@@ -446,9 +445,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c
if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
return 0;
- dentry = dget(bprm->file->f_path.dentry);
-
- rc = get_vfs_caps_from_disk(dentry, &vcaps);
+ rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
if (rc < 0) {
if (rc == -EINVAL)
printk(KERN_NOTICE "%s: get_vfs_caps_from_disk returned %d for %s\n",
@@ -464,7 +461,6 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c
__func__, rc, bprm->filename);
out:
- dput(dentry);
if (rc)
bprm_clear_caps(bprm);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 0c7aea4dea54..486ef6fa393b 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -414,6 +414,7 @@ link_check_failed:
link_prealloc_failed:
mutex_unlock(&user->cons_lock);
+ key_put(key);
kleave(" = %d [prelink]", ret);
return ret;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 33db1ad4fd10..1684bcc78b34 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1195,30 +1195,8 @@ static const struct file_operations sel_commit_bools_ops = {
static void sel_remove_entries(struct dentry *de)
{
- struct list_head *node;
-
- spin_lock(&de->d_lock);
- node = de->d_subdirs.next;
- while (node != &de->d_subdirs) {
- struct dentry *d = list_entry(node, struct dentry, d_child);
-
- spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
- list_del_init(node);
-
- if (d->d_inode) {
- dget_dlock(d);
- spin_unlock(&de->d_lock);
- spin_unlock(&d->d_lock);
- d_delete(d);
- simple_unlink(de->d_inode, d);
- dput(d);
- spin_lock(&de->d_lock);
- } else
- spin_unlock(&d->d_lock);
- node = de->d_subdirs.next;
- }
-
- spin_unlock(&de->d_lock);
+ d_genocide(de);
+ shrink_dcache_parent(de);
}
#define BOOL_DIR_NAME "booleans"
@@ -1668,37 +1646,13 @@ static int sel_make_class_dir_entries(char *classname, int index,
return rc;
}
-static void sel_remove_classes(void)
-{
- struct list_head *class_node;
-
- list_for_each(class_node, &class_dir->d_subdirs) {
- struct dentry *class_subdir = list_entry(class_node,
- struct dentry, d_child);
- struct list_head *class_subdir_node;
-
- list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
- struct dentry *d = list_entry(class_subdir_node,
- struct dentry, d_child);
-
- if (d->d_inode)
- if (d->d_inode->i_mode & S_IFDIR)
- sel_remove_entries(d);
- }
-
- sel_remove_entries(class_subdir);
- }
-
- sel_remove_entries(class_dir);
-}
-
static int sel_make_classes(void)
{
int rc, nclasses, i;
char **classes;
/* delete any existing entries */
- sel_remove_classes();
+ sel_remove_entries(class_dir);
rc = security_get_classes(&classes, &nclasses);
if (rc)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index a0ccce4e46f8..ed94f6f836e7 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3818,6 +3818,18 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
}
#endif /* CONFIG_IPV6 */
+#ifdef CONFIG_SECURITY_SMACK_NETFILTER
+ /*
+ * If there is a secmark use it rather than the CIPSO label.
+ * If there is no secmark fall back to CIPSO.
+ * The secmark is assumed to reflect policy better.
+ */
+ if (skb && skb->secmark != 0) {
+ skp = smack_from_secid(skb->secmark);
+ goto access_check;
+ }
+#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
+
netlbl_secattr_init(&secattr);
rc = netlbl_skbuff_getattr(skb, family, &secattr);
if (rc == 0)
@@ -3826,6 +3838,10 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
skp = &smack_known_huh;
netlbl_secattr_destroy(&secattr);
+#ifdef CONFIG_SECURITY_SMACK_NETFILTER
+access_check:
+#endif
+
#ifdef CONFIG_AUDIT
smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net->family = family;
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 4864392bfcba..c9917ca5de1a 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -151,7 +151,7 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
hw.info |= SNDRV_PCM_INFO_BATCH;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- addr_widths = dma_caps.dstn_addr_widths;
+ addr_widths = dma_caps.dst_addr_widths;
else
addr_widths = dma_caps.src_addr_widths;
}
diff --git a/tools/lguest/Makefile b/tools/lguest/Makefile
index 97bca4871ea3..a107b5e4da13 100644
--- a/tools/lguest/Makefile
+++ b/tools/lguest/Makefile
@@ -1,7 +1,13 @@
# This creates the demonstration utility "lguest" which runs a Linux guest.
-CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE
+CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE -Iinclude
all: lguest
+include/linux/virtio_types.h: ../../include/uapi/linux/virtio_types.h
+ mkdir -p include/linux 2>&1 || true
+ ln -sf ../../../../include/uapi/linux/virtio_types.h $@
+
+lguest: include/linux/virtio_types.h
+
clean:
rm -f lguest
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index 32cf2ce15d69..e44052483ed9 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -41,6 +41,8 @@
#include <signal.h>
#include <pwd.h>
#include <grp.h>
+#include <sys/user.h>
+#include <linux/pci_regs.h>
#ifndef VIRTIO_F_ANY_LAYOUT
#define VIRTIO_F_ANY_LAYOUT 27
@@ -61,12 +63,19 @@ typedef uint16_t u16;
typedef uint8_t u8;
/*:*/
-#include <linux/virtio_config.h>
-#include <linux/virtio_net.h>
-#include <linux/virtio_blk.h>
-#include <linux/virtio_console.h>
-#include <linux/virtio_rng.h>
+#define VIRTIO_CONFIG_NO_LEGACY
+#define VIRTIO_PCI_NO_LEGACY
+#define VIRTIO_BLK_NO_LEGACY
+#define VIRTIO_NET_NO_LEGACY
+
+/* Use in-kernel ones, which defines VIRTIO_F_VERSION_1 */
+#include "../../include/uapi/linux/virtio_config.h"
+#include "../../include/uapi/linux/virtio_net.h"
+#include "../../include/uapi/linux/virtio_blk.h"
+#include "../../include/uapi/linux/virtio_console.h"
+#include "../../include/uapi/linux/virtio_rng.h"
#include <linux/virtio_ring.h>
+#include "../../include/uapi/linux/virtio_pci.h"
#include <asm/bootparam.h>
#include "../../include/linux/lguest_launcher.h"
@@ -91,13 +100,16 @@ static bool verbose;
/* The pointer to the start of guest memory. */
static void *guest_base;
/* The maximum guest physical address allowed, and maximum possible. */
-static unsigned long guest_limit, guest_max;
+static unsigned long guest_limit, guest_max, guest_mmio;
/* The /dev/lguest file descriptor. */
static int lguest_fd;
/* a per-cpu variable indicating whose vcpu is currently running */
static unsigned int __thread cpu_id;
+/* 5 bit device number in the PCI_CONFIG_ADDR => 32 only */
+#define MAX_PCI_DEVICES 32
+
/* This is our list of devices. */
struct device_list {
/* Counter to assign interrupt numbers. */
@@ -106,30 +118,50 @@ struct device_list {
/* Counter to print out convenient device numbers. */
unsigned int device_num;
- /* The descriptor page for the devices. */
- u8 *descpage;
-
- /* A single linked list of devices. */
- struct device *dev;
- /* And a pointer to the last device for easy append. */
- struct device *lastdev;
+ /* PCI devices. */
+ struct device *pci[MAX_PCI_DEVICES];
};
/* The list of Guest devices, based on command line arguments. */
static struct device_list devices;
-/* The device structure describes a single device. */
-struct device {
- /* The linked-list pointer. */
- struct device *next;
+struct virtio_pci_cfg_cap {
+ struct virtio_pci_cap cap;
+ u32 pci_cfg_data; /* Data for BAR access. */
+};
- /* The device's descriptor, as mapped into the Guest. */
- struct lguest_device_desc *desc;
+struct virtio_pci_mmio {
+ struct virtio_pci_common_cfg cfg;
+ u16 notify;
+ u8 isr;
+ u8 padding;
+ /* Device-specific configuration follows this. */
+};
- /* We can't trust desc values once Guest has booted: we use these. */
- unsigned int feature_len;
- unsigned int num_vq;
+/* This is the layout (little-endian) of the PCI config space. */
+struct pci_config {
+ u16 vendor_id, device_id;
+ u16 command, status;
+ u8 revid, prog_if, subclass, class;
+ u8 cacheline_size, lat_timer, header_type, bist;
+ u32 bar[6];
+ u32 cardbus_cis_ptr;
+ u16 subsystem_vendor_id, subsystem_device_id;
+ u32 expansion_rom_addr;
+ u8 capabilities, reserved1[3];
+ u32 reserved2;
+ u8 irq_line, irq_pin, min_grant, max_latency;
+
+ /* Now, this is the linked capability list. */
+ struct virtio_pci_cap common;
+ struct virtio_pci_notify_cap notify;
+ struct virtio_pci_cap isr;
+ struct virtio_pci_cap device;
+ struct virtio_pci_cfg_cap cfg_access;
+};
+/* The device structure describes a single device. */
+struct device {
/* The name of this device, for --verbose. */
const char *name;
@@ -139,6 +171,25 @@ struct device {
/* Is it operational */
bool running;
+ /* Has it written FEATURES_OK but not re-checked it? */
+ bool wrote_features_ok;
+
+ /* PCI configuration */
+ union {
+ struct pci_config config;
+ u32 config_words[sizeof(struct pci_config) / sizeof(u32)];
+ };
+
+ /* Features we offer, and those accepted. */
+ u64 features, features_accepted;
+
+ /* Device-specific config hangs off the end of this. */
+ struct virtio_pci_mmio *mmio;
+
+ /* PCI MMIO resources (all in BAR0) */
+ size_t mmio_size;
+ u32 mmio_addr;
+
/* Device-specific data. */
void *priv;
};
@@ -150,12 +201,15 @@ struct virtqueue {
/* Which device owns me. */
struct device *dev;
- /* The configuration for this queue. */
- struct lguest_vqconfig config;
+ /* Name for printing errors. */
+ const char *name;
/* The actual ring of buffers. */
struct vring vring;
+ /* The information about this virtqueue (we only use queue_size on) */
+ struct virtio_pci_common_cfg pci_config;
+
/* Last available index we saw. */
u16 last_avail_idx;
@@ -199,6 +253,16 @@ static struct termios orig_term;
#define le32_to_cpu(v32) (v32)
#define le64_to_cpu(v64) (v64)
+/*
+ * A real device would ignore weird/non-compliant driver behaviour. We
+ * stop and flag it, to help debugging Linux problems.
+ */
+#define bad_driver(d, fmt, ...) \
+ errx(1, "%s: bad driver: " fmt, (d)->name, ## __VA_ARGS__)
+#define bad_driver_vq(vq, fmt, ...) \
+ errx(1, "%s vq %s: bad driver: " fmt, (vq)->dev->name, \
+ vq->name, ## __VA_ARGS__)
+
/* Is this iovec empty? */
static bool iov_empty(const struct iovec iov[], unsigned int num_iov)
{
@@ -211,7 +275,8 @@ static bool iov_empty(const struct iovec iov[], unsigned int num_iov)
}
/* Take len bytes from the front of this iovec. */
-static void iov_consume(struct iovec iov[], unsigned num_iov,
+static void iov_consume(struct device *d,
+ struct iovec iov[], unsigned num_iov,
void *dest, unsigned len)
{
unsigned int i;
@@ -229,14 +294,7 @@ static void iov_consume(struct iovec iov[], unsigned num_iov,
len -= used;
}
if (len != 0)
- errx(1, "iovec too short!");
-}
-
-/* The device virtqueue descriptors are followed by feature bitmasks. */
-static u8 *get_feature_bits(struct device *dev)
-{
- return (u8 *)(dev->desc + 1)
- + dev->num_vq * sizeof(struct lguest_vqconfig);
+ bad_driver(d, "iovec too short!");
}
/*L:100
@@ -309,14 +367,20 @@ static void *map_zeroed_pages(unsigned int num)
return addr + getpagesize();
}
-/* Get some more pages for a device. */
-static void *get_pages(unsigned int num)
+/* Get some bytes which won't be mapped into the guest. */
+static unsigned long get_mmio_region(size_t size)
{
- void *addr = from_guest_phys(guest_limit);
+ unsigned long addr = guest_mmio;
+ size_t i;
+
+ if (!size)
+ return addr;
+
+ /* Size has to be a power of 2 (and multiple of 16) */
+ for (i = 1; i < size; i <<= 1);
+
+ guest_mmio += i;
- guest_limit += num * getpagesize();
- if (guest_limit > guest_max)
- errx(1, "Not enough memory for devices");
return addr;
}
@@ -547,9 +611,11 @@ static void tell_kernel(unsigned long start)
{
unsigned long args[] = { LHREQ_INITIALIZE,
(unsigned long)guest_base,
- guest_limit / getpagesize(), start };
- verbose("Guest: %p - %p (%#lx)\n",
- guest_base, guest_base + guest_limit, guest_limit);
+ guest_limit / getpagesize(), start,
+ (guest_mmio+getpagesize()-1) / getpagesize() };
+ verbose("Guest: %p - %p (%#lx, MMIO %#lx)\n",
+ guest_base, guest_base + guest_limit,
+ guest_limit, guest_mmio);
lguest_fd = open_or_die("/dev/lguest", O_RDWR);
if (write(lguest_fd, args, sizeof(args)) < 0)
err(1, "Writing to /dev/lguest");
@@ -564,7 +630,8 @@ static void tell_kernel(unsigned long start)
* we have a convenient routine which checks it and exits with an error message
* if something funny is going on:
*/
-static void *_check_pointer(unsigned long addr, unsigned int size,
+static void *_check_pointer(struct device *d,
+ unsigned long addr, unsigned int size,
unsigned int line)
{
/*
@@ -572,7 +639,8 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
* or addr + size wraps around.
*/
if ((addr + size) > guest_limit || (addr + size) < addr)
- errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);
+ bad_driver(d, "%s:%i: Invalid address %#lx",
+ __FILE__, line, addr);
/*
* We return a pointer for the caller's convenience, now we know it's
* safe to use.
@@ -580,14 +648,14 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
return from_guest_phys(addr);
}
/* A macro which transparently hands the line number to the real function. */
-#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
+#define check_pointer(d,addr,size) _check_pointer(d, addr, size, __LINE__)
/*
* Each buffer in the virtqueues is actually a chain of descriptors. This
* function returns the next descriptor in the chain, or vq->vring.num if we're
* at the end.
*/
-static unsigned next_desc(struct vring_desc *desc,
+static unsigned next_desc(struct device *d, struct vring_desc *desc,
unsigned int i, unsigned int max)
{
unsigned int next;
@@ -602,7 +670,7 @@ static unsigned next_desc(struct vring_desc *desc,
wmb();
if (next >= max)
- errx(1, "Desc next is %u", next);
+ bad_driver(d, "Desc next is %u", next);
return next;
}
@@ -613,21 +681,48 @@ static unsigned next_desc(struct vring_desc *desc,
*/
static void trigger_irq(struct virtqueue *vq)
{
- unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
+ unsigned long buf[] = { LHREQ_IRQ, vq->dev->config.irq_line };
/* Don't inform them if nothing used. */
if (!vq->pending_used)
return;
vq->pending_used = 0;
- /* If they don't want an interrupt, don't send one... */
+ /*
+ * 2.4.7.1:
+ *
+ * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated:
+ * The driver MUST set flags to 0 or 1.
+ */
+ if (vq->vring.avail->flags > 1)
+ bad_driver_vq(vq, "avail->flags = %u\n", vq->vring.avail->flags);
+
+ /*
+ * 2.4.7.2:
+ *
+ * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated:
+ *
+ * - The device MUST ignore the used_event value.
+ * - After the device writes a descriptor index into the used ring:
+ * - If flags is 1, the device SHOULD NOT send an interrupt.
+ * - If flags is 0, the device MUST send an interrupt.
+ */
if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) {
return;
}
+ /*
+ * 4.1.4.5.1:
+ *
+ * If MSI-X capability is disabled, the device MUST set the Queue
+ * Interrupt bit in ISR status before sending a virtqueue notification
+ * to the driver.
+ */
+ vq->dev->mmio->isr = 0x1;
+
/* Send the Guest an interrupt tell them we used something up. */
if (write(lguest_fd, buf, sizeof(buf)) != 0)
- err(1, "Triggering irq %i", vq->config.irq);
+ err(1, "Triggering irq %i", vq->dev->config.irq_line);
}
/*
@@ -646,6 +741,14 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
struct vring_desc *desc;
u16 last_avail = lg_last_avail(vq);
+ /*
+ * 2.4.7.1:
+ *
+ * The driver MUST handle spurious interrupts from the device.
+ *
+ * That's why this is a while loop.
+ */
+
/* There's nothing available? */
while (last_avail == vq->vring.avail->idx) {
u64 event;
@@ -679,8 +782,8 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
/* Check it isn't doing very strange things with descriptor numbers. */
if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num)
- errx(1, "Guest moved used index from %u to %u",
- last_avail, vq->vring.avail->idx);
+ bad_driver_vq(vq, "Guest moved used index from %u to %u",
+ last_avail, vq->vring.avail->idx);
/*
* Make sure we read the descriptor number *after* we read the ring
@@ -697,7 +800,7 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
/* If their number is silly, that's a fatal mistake. */
if (head >= vq->vring.num)
- errx(1, "Guest says index %u is available", head);
+ bad_driver_vq(vq, "Guest says index %u is available", head);
/* When we start there are none of either input nor output. */
*out_num = *in_num = 0;
@@ -712,24 +815,73 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
* that: no rmb() required.
*/
- /*
- * If this is an indirect entry, then this buffer contains a descriptor
- * table which we handle as if it's any normal descriptor chain.
- */
- if (desc[i].flags & VRING_DESC_F_INDIRECT) {
- if (desc[i].len % sizeof(struct vring_desc))
- errx(1, "Invalid size for indirect buffer table");
+ do {
+ /*
+ * If this is an indirect entry, then this buffer contains a
+ * descriptor table which we handle as if it's any normal
+ * descriptor chain.
+ */
+ if (desc[i].flags & VRING_DESC_F_INDIRECT) {
+ /* 2.4.5.3.1:
+ *
+ * The driver MUST NOT set the VIRTQ_DESC_F_INDIRECT
+ * flag unless the VIRTIO_F_INDIRECT_DESC feature was
+ * negotiated.
+ */
+ if (!(vq->dev->features_accepted &
+ (1<<VIRTIO_RING_F_INDIRECT_DESC)))
+ bad_driver_vq(vq, "vq indirect not negotiated");
- max = desc[i].len / sizeof(struct vring_desc);
- desc = check_pointer(desc[i].addr, desc[i].len);
- i = 0;
- }
+ /*
+ * 2.4.5.3.1:
+ *
+ * The driver MUST NOT set the VIRTQ_DESC_F_INDIRECT
+ * flag within an indirect descriptor (ie. only one
+ * table per descriptor).
+ */
+ if (desc != vq->vring.desc)
+ bad_driver_vq(vq, "Indirect within indirect");
+
+ /*
+ * Proposed update VIRTIO-134 spells this out:
+ *
+ * A driver MUST NOT set both VIRTQ_DESC_F_INDIRECT
+ * and VIRTQ_DESC_F_NEXT in flags.
+ */
+ if (desc[i].flags & VRING_DESC_F_NEXT)
+ bad_driver_vq(vq, "indirect and next together");
+
+ if (desc[i].len % sizeof(struct vring_desc))
+ bad_driver_vq(vq,
+ "Invalid size for indirect table");
+ /*
+ * 2.4.5.3.2:
+ *
+ * The device MUST ignore the write-only flag
+ * (flags&VIRTQ_DESC_F_WRITE) in the descriptor that
+ * refers to an indirect table.
+ *
+ * We ignore it here: :)
+ */
+
+ max = desc[i].len / sizeof(struct vring_desc);
+ desc = check_pointer(vq->dev, desc[i].addr, desc[i].len);
+ i = 0;
+
+ /* 2.4.5.3.1:
+ *
+ * A driver MUST NOT create a descriptor chain longer
+ * than the Queue Size of the device.
+ */
+ if (max > vq->pci_config.queue_size)
+ bad_driver_vq(vq,
+ "indirect has too many entries");
+ }
- do {
/* Grab the first descriptor, and check it's OK. */
iov[*out_num + *in_num].iov_len = desc[i].len;
iov[*out_num + *in_num].iov_base
- = check_pointer(desc[i].addr, desc[i].len);
+ = check_pointer(vq->dev, desc[i].addr, desc[i].len);
/* If this is an input descriptor, increment that count. */
if (desc[i].flags & VRING_DESC_F_WRITE)
(*in_num)++;
@@ -739,14 +891,15 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
* to come before any input descriptors.
*/
if (*in_num)
- errx(1, "Descriptor has out after in");
+ bad_driver_vq(vq,
+ "Descriptor has out after in");
(*out_num)++;
}
/* If we've got too many, that implies a descriptor loop. */
if (*out_num + *in_num > max)
- errx(1, "Looped descriptor");
- } while ((i = next_desc(desc, i, max)) != max);
+ bad_driver_vq(vq, "Looped descriptor");
+ } while ((i = next_desc(vq->dev, desc, i, max)) != max);
return head;
}
@@ -803,7 +956,7 @@ static void console_input(struct virtqueue *vq)
/* Make sure there's a descriptor available. */
head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
if (out_num)
- errx(1, "Output buffers in console in queue?");
+ bad_driver_vq(vq, "Output buffers in console in queue?");
/* Read into it. This is where we usually wait. */
len = readv(STDIN_FILENO, iov, in_num);
@@ -856,7 +1009,7 @@ static void console_output(struct virtqueue *vq)
/* We usually wait in here, for the Guest to give us something. */
head = wait_for_vq_desc(vq, iov, &out, &in);
if (in)
- errx(1, "Input buffers in console output queue?");
+ bad_driver_vq(vq, "Input buffers in console output queue?");
/* writev can return a partial write, so we loop here. */
while (!iov_empty(iov, out)) {
@@ -865,7 +1018,7 @@ static void console_output(struct virtqueue *vq)
warn("Write to stdout gave %i (%d)", len, errno);
break;
}
- iov_consume(iov, out, NULL, len);
+ iov_consume(vq->dev, iov, out, NULL, len);
}
/*
@@ -894,7 +1047,7 @@ static void net_output(struct virtqueue *vq)
/* We usually wait in here for the Guest to give us a packet. */
head = wait_for_vq_desc(vq, iov, &out, &in);
if (in)
- errx(1, "Input buffers in net output queue?");
+ bad_driver_vq(vq, "Input buffers in net output queue?");
/*
* Send the whole thing through to /dev/net/tun. It expects the exact
* same format: what a coincidence!
@@ -942,7 +1095,7 @@ static void net_input(struct virtqueue *vq)
*/
head = wait_for_vq_desc(vq, iov, &out, &in);
if (out)
- errx(1, "Output buffers in net input queue?");
+ bad_driver_vq(vq, "Output buffers in net input queue?");
/*
* If it looks like we'll block reading from the tun device, send them
@@ -986,6 +1139,12 @@ static void kill_launcher(int signal)
kill(0, SIGTERM);
}
+static void reset_vq_pci_config(struct virtqueue *vq)
+{
+ vq->pci_config.queue_size = VIRTQUEUE_NUM;
+ vq->pci_config.queue_enable = 0;
+}
+
static void reset_device(struct device *dev)
{
struct virtqueue *vq;
@@ -993,53 +1152,705 @@ static void reset_device(struct device *dev)
verbose("Resetting device %s\n", dev->name);
/* Clear any features they've acked. */
- memset(get_feature_bits(dev) + dev->feature_len, 0, dev->feature_len);
+ dev->features_accepted = 0;
/* We're going to be explicitly killing threads, so ignore them. */
signal(SIGCHLD, SIG_IGN);
- /* Zero out the virtqueues, get rid of their threads */
+ /*
+ * 4.1.4.3.1:
+ *
+ * The device MUST present a 0 in queue_enable on reset.
+ *
+ * This means we set it here, and reset the saved ones in every vq.
+ */
+ dev->mmio->cfg.queue_enable = 0;
+
+ /* Get rid of the virtqueue threads */
for (vq = dev->vq; vq; vq = vq->next) {
+ vq->last_avail_idx = 0;
+ reset_vq_pci_config(vq);
if (vq->thread != (pid_t)-1) {
kill(vq->thread, SIGTERM);
waitpid(vq->thread, NULL, 0);
vq->thread = (pid_t)-1;
}
- memset(vq->vring.desc, 0,
- vring_size(vq->config.num, LGUEST_VRING_ALIGN));
- lg_last_avail(vq) = 0;
}
dev->running = false;
+ dev->wrote_features_ok = false;
/* Now we care if threads die. */
signal(SIGCHLD, (void *)kill_launcher);
}
+static void cleanup_devices(void)
+{
+ unsigned int i;
+
+ for (i = 1; i < MAX_PCI_DEVICES; i++) {
+ struct device *d = devices.pci[i];
+ if (!d)
+ continue;
+ reset_device(d);
+ }
+
+ /* If we saved off the original terminal settings, restore them now. */
+ if (orig_term.c_lflag & (ISIG|ICANON|ECHO))
+ tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
+}
+
+/*L:217
+ * We do PCI. This is mainly done to let us test the kernel virtio PCI
+ * code.
+ */
+
+/* Linux expects a PCI host bridge: ours is a dummy, and first on the bus. */
+static struct device pci_host_bridge;
+
+static void init_pci_host_bridge(void)
+{
+ pci_host_bridge.name = "PCI Host Bridge";
+ pci_host_bridge.config.class = 0x06; /* bridge */
+ pci_host_bridge.config.subclass = 0; /* host bridge */
+ devices.pci[0] = &pci_host_bridge;
+}
+
+/* The IO ports used to read the PCI config space. */
+#define PCI_CONFIG_ADDR 0xCF8
+#define PCI_CONFIG_DATA 0xCFC
+
+/*
+ * Not really portable, but does help readability: this is what the Guest
+ * writes to the PCI_CONFIG_ADDR IO port.
+ */
+union pci_config_addr {
+ struct {
+ unsigned mbz: 2;
+ unsigned offset: 6;
+ unsigned funcnum: 3;
+ unsigned devnum: 5;
+ unsigned busnum: 8;
+ unsigned reserved: 7;
+ unsigned enabled : 1;
+ } bits;
+ u32 val;
+};
+
+/*
+ * We cache what they wrote to the address port, so we know what they're
+ * talking about when they access the data port.
+ */
+static union pci_config_addr pci_config_addr;
+
+static struct device *find_pci_device(unsigned int index)
+{
+ return devices.pci[index];
+}
+
+/* PCI can do 1, 2 and 4 byte reads; we handle that here. */
+static void ioread(u16 off, u32 v, u32 mask, u32 *val)
+{
+ assert(off < 4);
+ assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF);
+ *val = (v >> (off * 8)) & mask;
+}
+
+/* PCI can do 1, 2 and 4 byte writes; we handle that here. */
+static void iowrite(u16 off, u32 v, u32 mask, u32 *dst)
+{
+ assert(off < 4);
+ assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF);
+ *dst &= ~(mask << (off * 8));
+ *dst |= (v & mask) << (off * 8);
+}
+
+/*
+ * Where PCI_CONFIG_DATA accesses depends on the previous write to
+ * PCI_CONFIG_ADDR.
+ */
+static struct device *dev_and_reg(u32 *reg)
+{
+ if (!pci_config_addr.bits.enabled)
+ return NULL;
+
+ if (pci_config_addr.bits.funcnum != 0)
+ return NULL;
+
+ if (pci_config_addr.bits.busnum != 0)
+ return NULL;
+
+ if (pci_config_addr.bits.offset * 4 >= sizeof(struct pci_config))
+ return NULL;
+
+ *reg = pci_config_addr.bits.offset;
+ return find_pci_device(pci_config_addr.bits.devnum);
+}
+
+/*
+ * We can get invalid combinations of values while they're writing, so we
+ * only fault if they try to write with some invalid bar/offset/length.
+ */
+static bool valid_bar_access(struct device *d,
+ struct virtio_pci_cfg_cap *cfg_access)
+{
+ /* We only have 1 bar (BAR0) */
+ if (cfg_access->cap.bar != 0)
+ return false;
+
+ /* Check it's within BAR0. */
+ if (cfg_access->cap.offset >= d->mmio_size
+ || cfg_access->cap.offset + cfg_access->cap.length > d->mmio_size)
+ return false;
+
+ /* Check length is 1, 2 or 4. */
+ if (cfg_access->cap.length != 1
+ && cfg_access->cap.length != 2
+ && cfg_access->cap.length != 4)
+ return false;
+
+ /*
+ * 4.1.4.7.2:
+ *
+ * The driver MUST NOT write a cap.offset which is not a multiple of
+ * cap.length (ie. all accesses MUST be aligned).
+ */
+ if (cfg_access->cap.offset % cfg_access->cap.length != 0)
+ return false;
+
+ /* Return pointer into word in BAR0. */
+ return true;
+}
+
+/* Is this accessing the PCI config address port?. */
+static bool is_pci_addr_port(u16 port)
+{
+ return port >= PCI_CONFIG_ADDR && port < PCI_CONFIG_ADDR + 4;
+}
+
+static bool pci_addr_iowrite(u16 port, u32 mask, u32 val)
+{
+ iowrite(port - PCI_CONFIG_ADDR, val, mask,
+ &pci_config_addr.val);
+ verbose("PCI%s: %#x/%x: bus %u dev %u func %u reg %u\n",
+ pci_config_addr.bits.enabled ? "" : " DISABLED",
+ val, mask,
+ pci_config_addr.bits.busnum,
+ pci_config_addr.bits.devnum,
+ pci_config_addr.bits.funcnum,
+ pci_config_addr.bits.offset);
+ return true;
+}
+
+static void pci_addr_ioread(u16 port, u32 mask, u32 *val)
+{
+ ioread(port - PCI_CONFIG_ADDR, pci_config_addr.val, mask, val);
+}
+
+/* Is this accessing the PCI config data port?. */
+static bool is_pci_data_port(u16 port)
+{
+ return port >= PCI_CONFIG_DATA && port < PCI_CONFIG_DATA + 4;
+}
+
+static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask);
+
+static bool pci_data_iowrite(u16 port, u32 mask, u32 val)
+{
+ u32 reg, portoff;
+ struct device *d = dev_and_reg(&reg);
+
+ /* Complain if they don't belong to a device. */
+ if (!d)
+ return false;
+
+ /* They can do 1 byte writes, etc. */
+ portoff = port - PCI_CONFIG_DATA;
+
+ /*
+ * PCI uses a weird way to determine the BAR size: the OS
+ * writes all 1's, and sees which ones stick.
+ */
+ if (&d->config_words[reg] == &d->config.bar[0]) {
+ int i;
+
+ iowrite(portoff, val, mask, &d->config.bar[0]);
+ for (i = 0; (1 << i) < d->mmio_size; i++)
+ d->config.bar[0] &= ~(1 << i);
+ return true;
+ } else if ((&d->config_words[reg] > &d->config.bar[0]
+ && &d->config_words[reg] <= &d->config.bar[6])
+ || &d->config_words[reg] == &d->config.expansion_rom_addr) {
+ /* Allow writing to any other BAR, or expansion ROM */
+ iowrite(portoff, val, mask, &d->config_words[reg]);
+ return true;
+ /* We let them overide latency timer and cacheline size */
+ } else if (&d->config_words[reg] == (void *)&d->config.cacheline_size) {
+ /* Only let them change the first two fields. */
+ if (mask == 0xFFFFFFFF)
+ mask = 0xFFFF;
+ iowrite(portoff, val, mask, &d->config_words[reg]);
+ return true;
+ } else if (&d->config_words[reg] == (void *)&d->config.command
+ && mask == 0xFFFF) {
+ /* Ignore command writes. */
+ return true;
+ } else if (&d->config_words[reg]
+ == (void *)&d->config.cfg_access.cap.bar
+ || &d->config_words[reg]
+ == &d->config.cfg_access.cap.length
+ || &d->config_words[reg]
+ == &d->config.cfg_access.cap.offset) {
+
+ /*
+ * The VIRTIO_PCI_CAP_PCI_CFG capability
+ * provides a backdoor to access the MMIO
+ * regions without mapping them. Weird, but
+ * useful.
+ */
+ iowrite(portoff, val, mask, &d->config_words[reg]);
+ return true;
+ } else if (&d->config_words[reg] == &d->config.cfg_access.pci_cfg_data) {
+ u32 write_mask;
+
+ /*
+ * 4.1.4.7.1:
+ *
+ * Upon detecting driver write access to pci_cfg_data, the
+ * device MUST execute a write access at offset cap.offset at
+ * BAR selected by cap.bar using the first cap.length bytes
+ * from pci_cfg_data.
+ */
+
+ /* Must be bar 0 */
+ if (!valid_bar_access(d, &d->config.cfg_access))
+ return false;
+
+ iowrite(portoff, val, mask, &d->config.cfg_access.pci_cfg_data);
+
+ /*
+ * Now emulate a write. The mask we use is set by
+ * len, *not* this write!
+ */
+ write_mask = (1ULL<<(8*d->config.cfg_access.cap.length)) - 1;
+ verbose("Window writing %#x/%#x to bar %u, offset %u len %u\n",
+ d->config.cfg_access.pci_cfg_data, write_mask,
+ d->config.cfg_access.cap.bar,
+ d->config.cfg_access.cap.offset,
+ d->config.cfg_access.cap.length);
+
+ emulate_mmio_write(d, d->config.cfg_access.cap.offset,
+ d->config.cfg_access.pci_cfg_data,
+ write_mask);
+ return true;
+ }
+
+ /*
+ * 4.1.4.1:
+ *
+ * The driver MUST NOT write into any field of the capability
+ * structure, with the exception of those with cap_type
+ * VIRTIO_PCI_CAP_PCI_CFG...
+ */
+ return false;
+}
+
+static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask);
+
+static void pci_data_ioread(u16 port, u32 mask, u32 *val)
+{
+ u32 reg;
+ struct device *d = dev_and_reg(&reg);
+
+ if (!d)
+ return;
+
+ /* Read through the PCI MMIO access window is special */
+ if (&d->config_words[reg] == &d->config.cfg_access.pci_cfg_data) {
+ u32 read_mask;
+
+ /*
+ * 4.1.4.7.1:
+ *
+ * Upon detecting driver read access to pci_cfg_data, the
+ * device MUST execute a read access of length cap.length at
+ * offset cap.offset at BAR selected by cap.bar and store the
+ * first cap.length bytes in pci_cfg_data.
+ */
+ /* Must be bar 0 */
+ if (!valid_bar_access(d, &d->config.cfg_access))
+ bad_driver(d,
+ "Invalid cfg_access to bar%u, offset %u len %u",
+ d->config.cfg_access.cap.bar,
+ d->config.cfg_access.cap.offset,
+ d->config.cfg_access.cap.length);
+
+ /*
+ * Read into the window. The mask we use is set by
+ * len, *not* this read!
+ */
+ read_mask = (1ULL<<(8*d->config.cfg_access.cap.length))-1;
+ d->config.cfg_access.pci_cfg_data
+ = emulate_mmio_read(d,
+ d->config.cfg_access.cap.offset,
+ read_mask);
+ verbose("Window read %#x/%#x from bar %u, offset %u len %u\n",
+ d->config.cfg_access.pci_cfg_data, read_mask,
+ d->config.cfg_access.cap.bar,
+ d->config.cfg_access.cap.offset,
+ d->config.cfg_access.cap.length);
+ }
+ ioread(port - PCI_CONFIG_DATA, d->config_words[reg], mask, val);
+}
+
/*L:216
- * This actually creates the thread which services the virtqueue for a device.
+ * This is where we emulate a handful of Guest instructions. It's ugly
+ * and we used to do it in the kernel but it grew over time.
+ */
+
+/*
+ * We use the ptrace syscall's pt_regs struct to talk about registers
+ * to lguest: these macros convert the names to the offsets.
+ */
+#define getreg(name) getreg_off(offsetof(struct user_regs_struct, name))
+#define setreg(name, val) \
+ setreg_off(offsetof(struct user_regs_struct, name), (val))
+
+static u32 getreg_off(size_t offset)
+{
+ u32 r;
+ unsigned long args[] = { LHREQ_GETREG, offset };
+
+ if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0)
+ err(1, "Getting register %u", offset);
+ if (pread(lguest_fd, &r, sizeof(r), cpu_id) != sizeof(r))
+ err(1, "Reading register %u", offset);
+
+ return r;
+}
+
+static void setreg_off(size_t offset, u32 val)
+{
+ unsigned long args[] = { LHREQ_SETREG, offset, val };
+
+ if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0)
+ err(1, "Setting register %u", offset);
+}
+
+/* Get register by instruction encoding */
+static u32 getreg_num(unsigned regnum, u32 mask)
+{
+ /* 8 bit ops use regnums 4-7 for high parts of word */
+ if (mask == 0xFF && (regnum & 0x4))
+ return getreg_num(regnum & 0x3, 0xFFFF) >> 8;
+
+ switch (regnum) {
+ case 0: return getreg(eax) & mask;
+ case 1: return getreg(ecx) & mask;
+ case 2: return getreg(edx) & mask;
+ case 3: return getreg(ebx) & mask;
+ case 4: return getreg(esp) & mask;
+ case 5: return getreg(ebp) & mask;
+ case 6: return getreg(esi) & mask;
+ case 7: return getreg(edi) & mask;
+ }
+ abort();
+}
+
+/* Set register by instruction encoding */
+static void setreg_num(unsigned regnum, u32 val, u32 mask)
+{
+ /* Don't try to set bits out of range */
+ assert(~(val & ~mask));
+
+ /* 8 bit ops use regnums 4-7 for high parts of word */
+ if (mask == 0xFF && (regnum & 0x4)) {
+ /* Construct the 16 bits we want. */
+ val = (val << 8) | getreg_num(regnum & 0x3, 0xFF);
+ setreg_num(regnum & 0x3, val, 0xFFFF);
+ return;
+ }
+
+ switch (regnum) {
+ case 0: setreg(eax, val | (getreg(eax) & ~mask)); return;
+ case 1: setreg(ecx, val | (getreg(ecx) & ~mask)); return;
+ case 2: setreg(edx, val | (getreg(edx) & ~mask)); return;
+ case 3: setreg(ebx, val | (getreg(ebx) & ~mask)); return;
+ case 4: setreg(esp, val | (getreg(esp) & ~mask)); return;
+ case 5: setreg(ebp, val | (getreg(ebp) & ~mask)); return;
+ case 6: setreg(esi, val | (getreg(esi) & ~mask)); return;
+ case 7: setreg(edi, val | (getreg(edi) & ~mask)); return;
+ }
+ abort();
+}
+
+/* Get bytes of displacement appended to instruction, from r/m encoding */
+static u32 insn_displacement_len(u8 mod_reg_rm)
+{
+ /* Switch on the mod bits */
+ switch (mod_reg_rm >> 6) {
+ case 0:
+ /* If mod == 0, and r/m == 101, 16-bit displacement follows */
+ if ((mod_reg_rm & 0x7) == 0x5)
+ return 2;
+ /* Normally, mod == 0 means no literal displacement */
+ return 0;
+ case 1:
+ /* One byte displacement */
+ return 1;
+ case 2:
+ /* Four byte displacement */
+ return 4;
+ case 3:
+ /* Register mode */
+ return 0;
+ }
+ abort();
+}
+
+static void emulate_insn(const u8 insn[])
+{
+ unsigned long args[] = { LHREQ_TRAP, 13 };
+ unsigned int insnlen = 0, in = 0, small_operand = 0, byte_access;
+ unsigned int eax, port, mask;
+ /*
+ * Default is to return all-ones on IO port reads, which traditionally
+ * means "there's nothing there".
+ */
+ u32 val = 0xFFFFFFFF;
+
+ /*
+ * This must be the Guest kernel trying to do something, not userspace!
+ * The bottom two bits of the CS segment register are the privilege
+ * level.
+ */
+ if ((getreg(xcs) & 3) != 0x1)
+ goto no_emulate;
+
+ /* Decoding x86 instructions is icky. */
+
+ /*
+ * Around 2.6.33, the kernel started using an emulation for the
+ * cmpxchg8b instruction in early boot on many configurations. This
+ * code isn't paravirtualized, and it tries to disable interrupts.
+ * Ignore it, which will Mostly Work.
+ */
+ if (insn[insnlen] == 0xfa) {
+ /* "cli", or Clear Interrupt Enable instruction. Skip it. */
+ insnlen = 1;
+ goto skip_insn;
+ }
+
+ /*
+ * 0x66 is an "operand prefix". It means a 16, not 32 bit in/out.
+ */
+ if (insn[insnlen] == 0x66) {
+ small_operand = 1;
+ /* The instruction is 1 byte so far, read the next byte. */
+ insnlen = 1;
+ }
+
+ /* If the lower bit isn't set, it's a single byte access */
+ byte_access = !(insn[insnlen] & 1);
+
+ /*
+ * Now we can ignore the lower bit and decode the 4 opcodes
+ * we need to emulate.
+ */
+ switch (insn[insnlen] & 0xFE) {
+ case 0xE4: /* in <next byte>,%al */
+ port = insn[insnlen+1];
+ insnlen += 2;
+ in = 1;
+ break;
+ case 0xEC: /* in (%dx),%al */
+ port = getreg(edx) & 0xFFFF;
+ insnlen += 1;
+ in = 1;
+ break;
+ case 0xE6: /* out %al,<next byte> */
+ port = insn[insnlen+1];
+ insnlen += 2;
+ break;
+ case 0xEE: /* out %al,(%dx) */
+ port = getreg(edx) & 0xFFFF;
+ insnlen += 1;
+ break;
+ default:
+ /* OK, we don't know what this is, can't emulate. */
+ goto no_emulate;
+ }
+
+ /* Set a mask of the 1, 2 or 4 bytes, depending on size of IO */
+ if (byte_access)
+ mask = 0xFF;
+ else if (small_operand)
+ mask = 0xFFFF;
+ else
+ mask = 0xFFFFFFFF;
+
+ /*
+ * If it was an "IN" instruction, they expect the result to be read
+ * into %eax, so we change %eax.
+ */
+ eax = getreg(eax);
+
+ if (in) {
+ /* This is the PS/2 keyboard status; 1 means ready for output */
+ if (port == 0x64)
+ val = 1;
+ else if (is_pci_addr_port(port))
+ pci_addr_ioread(port, mask, &val);
+ else if (is_pci_data_port(port))
+ pci_data_ioread(port, mask, &val);
+
+ /* Clear the bits we're about to read */
+ eax &= ~mask;
+ /* Copy bits in from val. */
+ eax |= val & mask;
+ /* Now update the register. */
+ setreg(eax, eax);
+ } else {
+ if (is_pci_addr_port(port)) {
+ if (!pci_addr_iowrite(port, mask, eax))
+ goto bad_io;
+ } else if (is_pci_data_port(port)) {
+ if (!pci_data_iowrite(port, mask, eax))
+ goto bad_io;
+ }
+ /* There are many other ports, eg. CMOS clock, serial
+ * and parallel ports, so we ignore them all. */
+ }
+
+ verbose("IO %s of %x to %u: %#08x\n",
+ in ? "IN" : "OUT", mask, port, eax);
+skip_insn:
+ /* Finally, we've "done" the instruction, so move past it. */
+ setreg(eip, getreg(eip) + insnlen);
+ return;
+
+bad_io:
+ warnx("Attempt to %s port %u (%#x mask)",
+ in ? "read from" : "write to", port, mask);
+
+no_emulate:
+ /* Inject trap into Guest. */
+ if (write(lguest_fd, args, sizeof(args)) < 0)
+ err(1, "Reinjecting trap 13 for fault at %#x", getreg(eip));
+}
+
+static struct device *find_mmio_region(unsigned long paddr, u32 *off)
+{
+ unsigned int i;
+
+ for (i = 1; i < MAX_PCI_DEVICES; i++) {
+ struct device *d = devices.pci[i];
+
+ if (!d)
+ continue;
+ if (paddr < d->mmio_addr)
+ continue;
+ if (paddr >= d->mmio_addr + d->mmio_size)
+ continue;
+ *off = paddr - d->mmio_addr;
+ return d;
+ }
+ return NULL;
+}
+
+/* FIXME: Use vq array. */
+static struct virtqueue *vq_by_num(struct device *d, u32 num)
+{
+ struct virtqueue *vq = d->vq;
+
+ while (num-- && vq)
+ vq = vq->next;
+
+ return vq;
+}
+
+static void save_vq_config(const struct virtio_pci_common_cfg *cfg,
+ struct virtqueue *vq)
+{
+ vq->pci_config = *cfg;
+}
+
+static void restore_vq_config(struct virtio_pci_common_cfg *cfg,
+ struct virtqueue *vq)
+{
+ /* Only restore the per-vq part */
+ size_t off = offsetof(struct virtio_pci_common_cfg, queue_size);
+
+ memcpy((void *)cfg + off, (void *)&vq->pci_config + off,
+ sizeof(*cfg) - off);
+}
+
+/*
+ * 4.1.4.3.2:
+ *
+ * The driver MUST configure the other virtqueue fields before
+ * enabling the virtqueue with queue_enable.
+ *
+ * When they enable the virtqueue, we check that their setup is valid.
*/
-static void create_thread(struct virtqueue *vq)
+static void check_virtqueue(struct device *d, struct virtqueue *vq)
+{
+ /* Because lguest is 32 bit, all the descriptor high bits must be 0 */
+ if (vq->pci_config.queue_desc_hi
+ || vq->pci_config.queue_avail_hi
+ || vq->pci_config.queue_used_hi)
+ bad_driver_vq(vq, "invalid 64-bit queue address");
+
+ /*
+ * 2.4.1:
+ *
+ * The driver MUST ensure that the physical address of the first byte
+ * of each virtqueue part is a multiple of the specified alignment
+ * value in the above table.
+ */
+ if (vq->pci_config.queue_desc_lo % 16
+ || vq->pci_config.queue_avail_lo % 2
+ || vq->pci_config.queue_used_lo % 4)
+ bad_driver_vq(vq, "invalid alignment in queue addresses");
+
+ /* Initialize the virtqueue and check they're all in range. */
+ vq->vring.num = vq->pci_config.queue_size;
+ vq->vring.desc = check_pointer(vq->dev,
+ vq->pci_config.queue_desc_lo,
+ sizeof(*vq->vring.desc) * vq->vring.num);
+ vq->vring.avail = check_pointer(vq->dev,
+ vq->pci_config.queue_avail_lo,
+ sizeof(*vq->vring.avail)
+ + (sizeof(vq->vring.avail->ring[0])
+ * vq->vring.num));
+ vq->vring.used = check_pointer(vq->dev,
+ vq->pci_config.queue_used_lo,
+ sizeof(*vq->vring.used)
+ + (sizeof(vq->vring.used->ring[0])
+ * vq->vring.num));
+
+ /*
+ * 2.4.9.1:
+ *
+ * The driver MUST initialize flags in the used ring to 0
+ * when allocating the used ring.
+ */
+ if (vq->vring.used->flags != 0)
+ bad_driver_vq(vq, "invalid initial used.flags %#x",
+ vq->vring.used->flags);
+}
+
+static void start_virtqueue(struct virtqueue *vq)
{
/*
* Create stack for thread. Since the stack grows upwards, we point
* the stack pointer to the end of this region.
*/
char *stack = malloc(32768);
- unsigned long args[] = { LHREQ_EVENTFD,
- vq->config.pfn*getpagesize(), 0 };
/* Create a zero-initialized eventfd. */
vq->eventfd = eventfd(0, 0);
if (vq->eventfd < 0)
err(1, "Creating eventfd");
- args[2] = vq->eventfd;
-
- /*
- * Attach an eventfd to this virtqueue: it will go off when the Guest
- * does an LHCALL_NOTIFY for this vq.
- */
- if (write(lguest_fd, &args, sizeof(args)) != 0)
- err(1, "Attaching eventfd");
/*
* CLONE_VM: because it has to access the Guest memory, and SIGCHLD so
@@ -1048,167 +1859,531 @@ static void create_thread(struct virtqueue *vq)
vq->thread = clone(do_thread, stack + 32768, CLONE_VM | SIGCHLD, vq);
if (vq->thread == (pid_t)-1)
err(1, "Creating clone");
-
- /* We close our local copy now the child has it. */
- close(vq->eventfd);
}
-static void start_device(struct device *dev)
+static void start_virtqueues(struct device *d)
{
- unsigned int i;
struct virtqueue *vq;
- verbose("Device %s OK: offered", dev->name);
- for (i = 0; i < dev->feature_len; i++)
- verbose(" %02x", get_feature_bits(dev)[i]);
- verbose(", accepted");
- for (i = 0; i < dev->feature_len; i++)
- verbose(" %02x", get_feature_bits(dev)
- [dev->feature_len+i]);
-
- for (vq = dev->vq; vq; vq = vq->next) {
- if (vq->service)
- create_thread(vq);
+ for (vq = d->vq; vq; vq = vq->next) {
+ if (vq->pci_config.queue_enable)
+ start_virtqueue(vq);
}
- dev->running = true;
}
-static void cleanup_devices(void)
+static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask)
{
- struct device *dev;
+ struct virtqueue *vq;
- for (dev = devices.dev; dev; dev = dev->next)
- reset_device(dev);
+ switch (off) {
+ case offsetof(struct virtio_pci_mmio, cfg.device_feature_select):
+ /*
+ * 4.1.4.3.1:
+ *
+ * The device MUST present the feature bits it is offering in
+ * device_feature, starting at bit device_feature_select ∗ 32
+ * for any device_feature_select written by the driver
+ */
+ if (val == 0)
+ d->mmio->cfg.device_feature = d->features;
+ else if (val == 1)
+ d->mmio->cfg.device_feature = (d->features >> 32);
+ else
+ d->mmio->cfg.device_feature = 0;
+ goto feature_write_through32;
+ case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select):
+ if (val > 1)
+ bad_driver(d, "Unexpected driver select %u", val);
+ goto feature_write_through32;
+ case offsetof(struct virtio_pci_mmio, cfg.guest_feature):
+ if (d->mmio->cfg.guest_feature_select == 0) {
+ d->features_accepted &= ~((u64)0xFFFFFFFF);
+ d->features_accepted |= val;
+ } else {
+ assert(d->mmio->cfg.guest_feature_select == 1);
+ d->features_accepted &= 0xFFFFFFFF;
+ d->features_accepted |= ((u64)val) << 32;
+ }
+ /*
+ * 2.2.1:
+ *
+ * The driver MUST NOT accept a feature which the device did
+ * not offer
+ */
+ if (d->features_accepted & ~d->features)
+ bad_driver(d, "over-accepted features %#llx of %#llx",
+ d->features_accepted, d->features);
+ goto feature_write_through32;
+ case offsetof(struct virtio_pci_mmio, cfg.device_status): {
+ u8 prev;
+
+ verbose("%s: device status -> %#x\n", d->name, val);
+ /*
+ * 4.1.4.3.1:
+ *
+ * The device MUST reset when 0 is written to device_status,
+ * and present a 0 in device_status once that is done.
+ */
+ if (val == 0) {
+ reset_device(d);
+ goto write_through8;
+ }
- /* If we saved off the original terminal settings, restore them now. */
- if (orig_term.c_lflag & (ISIG|ICANON|ECHO))
- tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
-}
+ /* 2.1.1: The driver MUST NOT clear a device status bit. */
+ if (d->mmio->cfg.device_status & ~val)
+ bad_driver(d, "unset of device status bit %#x -> %#x",
+ d->mmio->cfg.device_status, val);
-/* When the Guest tells us they updated the status field, we handle it. */
-static void update_device_status(struct device *dev)
-{
- /* A zero status is a reset, otherwise it's a set of flags. */
- if (dev->desc->status == 0)
- reset_device(dev);
- else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) {
- warnx("Device %s configuration FAILED", dev->name);
- if (dev->running)
- reset_device(dev);
- } else {
- if (dev->running)
- err(1, "Device %s features finalized twice", dev->name);
- start_device(dev);
+ /*
+ * 2.1.2:
+ *
+ * The device MUST NOT consume buffers or notify the driver
+ * before DRIVER_OK.
+ */
+ if (val & VIRTIO_CONFIG_S_DRIVER_OK
+ && !(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK))
+ start_virtqueues(d);
+
+ /*
+ * 3.1.1:
+ *
+ * The driver MUST follow this sequence to initialize a device:
+ * - Reset the device.
+ * - Set the ACKNOWLEDGE status bit: the guest OS has
+ * notice the device.
+ * - Set the DRIVER status bit: the guest OS knows how
+ * to drive the device.
+ * - Read device feature bits, and write the subset
+ * of feature bits understood by the OS and driver
+ * to the device. During this step the driver MAY
+ * read (but MUST NOT write) the device-specific
+ * configuration fields to check that it can
+ * support the device before accepting it.
+ * - Set the FEATURES_OK status bit. The driver
+ * MUST not accept new feature bits after this
+ * step.
+ * - Re-read device status to ensure the FEATURES_OK
+ * bit is still set: otherwise, the device does
+ * not support our subset of features and the
+ * device is unusable.
+ * - Perform device-specific setup, including
+ * discovery of virtqueues for the device,
+ * optional per-bus setup, reading and possibly
+ * writing the device’s virtio configuration
+ * space, and population of virtqueues.
+ * - Set the DRIVER_OK status bit. At this point the
+ * device is “live”.
+ */
+ prev = 0;
+ switch (val & ~d->mmio->cfg.device_status) {
+ case VIRTIO_CONFIG_S_DRIVER_OK:
+ prev |= VIRTIO_CONFIG_S_FEATURES_OK; /* fall thru */
+ case VIRTIO_CONFIG_S_FEATURES_OK:
+ prev |= VIRTIO_CONFIG_S_DRIVER; /* fall thru */
+ case VIRTIO_CONFIG_S_DRIVER:
+ prev |= VIRTIO_CONFIG_S_ACKNOWLEDGE; /* fall thru */
+ case VIRTIO_CONFIG_S_ACKNOWLEDGE:
+ break;
+ default:
+ bad_driver(d, "unknown device status bit %#x -> %#x",
+ d->mmio->cfg.device_status, val);
+ }
+ if (d->mmio->cfg.device_status != prev)
+ bad_driver(d, "unexpected status transition %#x -> %#x",
+ d->mmio->cfg.device_status, val);
+
+ /* If they just wrote FEATURES_OK, we make sure they read */
+ switch (val & ~d->mmio->cfg.device_status) {
+ case VIRTIO_CONFIG_S_FEATURES_OK:
+ d->wrote_features_ok = true;
+ break;
+ case VIRTIO_CONFIG_S_DRIVER_OK:
+ if (d->wrote_features_ok)
+ bad_driver(d, "did not re-read FEATURES_OK");
+ break;
+ }
+ goto write_through8;
}
-}
+ case offsetof(struct virtio_pci_mmio, cfg.queue_select):
+ vq = vq_by_num(d, val);
+ /*
+ * 4.1.4.3.1:
+ *
+ * The device MUST present a 0 in queue_size if the virtqueue
+ * corresponding to the current queue_select is unavailable.
+ */
+ if (!vq) {
+ d->mmio->cfg.queue_size = 0;
+ goto write_through16;
+ }
+ /* Save registers for old vq, if it was a valid vq */
+ if (d->mmio->cfg.queue_size)
+ save_vq_config(&d->mmio->cfg,
+ vq_by_num(d, d->mmio->cfg.queue_select));
+ /* Restore the registers for the queue they asked for */
+ restore_vq_config(&d->mmio->cfg, vq);
+ goto write_through16;
+ case offsetof(struct virtio_pci_mmio, cfg.queue_size):
+ /*
+ * 4.1.4.3.2:
+ *
+ * The driver MUST NOT write a value which is not a power of 2
+ * to queue_size.
+ */
+ if (val & (val-1))
+ bad_driver(d, "invalid queue size %u", val);
+ if (d->mmio->cfg.queue_enable)
+ bad_driver(d, "changing queue size on live device");
+ goto write_through16;
+ case offsetof(struct virtio_pci_mmio, cfg.queue_msix_vector):
+ bad_driver(d, "attempt to set MSIX vector to %u", val);
+ case offsetof(struct virtio_pci_mmio, cfg.queue_enable): {
+ struct virtqueue *vq = vq_by_num(d, d->mmio->cfg.queue_select);
-/*L:215
- * This is the generic routine we call when the Guest uses LHCALL_NOTIFY. In
- * particular, it's used to notify us of device status changes during boot.
- */
-static void handle_output(unsigned long addr)
-{
- struct device *i;
+ /*
+ * 4.1.4.3.2:
+ *
+ * The driver MUST NOT write a 0 to queue_enable.
+ */
+ if (val != 1)
+ bad_driver(d, "setting queue_enable to %u", val);
- /* Check each device. */
- for (i = devices.dev; i; i = i->next) {
- struct virtqueue *vq;
+ /*
+ * 3.1.1:
+ *
+ * 7. Perform device-specific setup, including discovery of
+ * virtqueues for the device, optional per-bus setup,
+ * reading and possibly writing the device’s virtio
+ * configuration space, and population of virtqueues.
+ * 8. Set the DRIVER_OK status bit.
+ *
+ * All our devices require all virtqueues to be enabled, so
+ * they should have done that before setting DRIVER_OK.
+ */
+ if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)
+ bad_driver(d, "enabling vq after DRIVER_OK");
+ d->mmio->cfg.queue_enable = val;
+ save_vq_config(&d->mmio->cfg, vq);
+ check_virtqueue(d, vq);
+ goto write_through16;
+ }
+ case offsetof(struct virtio_pci_mmio, cfg.queue_notify_off):
+ bad_driver(d, "attempt to write to queue_notify_off");
+ case offsetof(struct virtio_pci_mmio, cfg.queue_desc_lo):
+ case offsetof(struct virtio_pci_mmio, cfg.queue_desc_hi):
+ case offsetof(struct virtio_pci_mmio, cfg.queue_avail_lo):
+ case offsetof(struct virtio_pci_mmio, cfg.queue_avail_hi):
+ case offsetof(struct virtio_pci_mmio, cfg.queue_used_lo):
+ case offsetof(struct virtio_pci_mmio, cfg.queue_used_hi):
/*
- * Notifications to device descriptors mean they updated the
- * device status.
+ * 4.1.4.3.2:
+ *
+ * The driver MUST configure the other virtqueue fields before
+ * enabling the virtqueue with queue_enable.
*/
- if (from_guest_phys(addr) == i->desc) {
- update_device_status(i);
- return;
- }
+ if (d->mmio->cfg.queue_enable)
+ bad_driver(d, "changing queue on live device");
+
+ /*
+ * 3.1.1:
+ *
+ * The driver MUST follow this sequence to initialize a device:
+ *...
+ * 5. Set the FEATURES_OK status bit. The driver MUST not
+ * accept new feature bits after this step.
+ */
+ if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK))
+ bad_driver(d, "setting up vq before FEATURES_OK");
- /* Devices should not be used before features are finalized. */
- for (vq = i->vq; vq; vq = vq->next) {
- if (addr != vq->config.pfn*getpagesize())
- continue;
- errx(1, "Notification on %s before setup!", i->name);
+ /*
+ * 6. Re-read device status to ensure the FEATURES_OK bit is
+ * still set...
+ */
+ if (d->wrote_features_ok)
+ bad_driver(d, "didn't re-read FEATURES_OK before setup");
+
+ goto write_through32;
+ case offsetof(struct virtio_pci_mmio, notify):
+ vq = vq_by_num(d, val);
+ if (!vq)
+ bad_driver(d, "Invalid vq notification on %u", val);
+ /* Notify the process handling this vq by adding 1 to eventfd */
+ write(vq->eventfd, "\1\0\0\0\0\0\0\0", 8);
+ goto write_through16;
+ case offsetof(struct virtio_pci_mmio, isr):
+ bad_driver(d, "Unexpected write to isr");
+ /* Weird corner case: write to emerg_wr of console */
+ case sizeof(struct virtio_pci_mmio)
+ + offsetof(struct virtio_console_config, emerg_wr):
+ if (strcmp(d->name, "console") == 0) {
+ char c = val;
+ write(STDOUT_FILENO, &c, 1);
+ goto write_through32;
}
+ /* Fall through... */
+ default:
+ /*
+ * 4.1.4.3.2:
+ *
+ * The driver MUST NOT write to device_feature, num_queues,
+ * config_generation or queue_notify_off.
+ */
+ bad_driver(d, "Unexpected write to offset %u", off);
}
+feature_write_through32:
/*
- * Early console write is done using notify on a nul-terminated string
- * in Guest memory. It's also great for hacking debugging messages
- * into a Guest.
+ * 3.1.1:
+ *
+ * The driver MUST follow this sequence to initialize a device:
+ *...
+ * - Set the DRIVER status bit: the guest OS knows how
+ * to drive the device.
+ * - Read device feature bits, and write the subset
+ * of feature bits understood by the OS and driver
+ * to the device.
+ *...
+ * - Set the FEATURES_OK status bit. The driver MUST not
+ * accept new feature bits after this step.
*/
- if (addr >= guest_limit)
- errx(1, "Bad NOTIFY %#lx", addr);
+ if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER))
+ bad_driver(d, "feature write before VIRTIO_CONFIG_S_DRIVER");
+ if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK)
+ bad_driver(d, "feature write after VIRTIO_CONFIG_S_FEATURES_OK");
- write(STDOUT_FILENO, from_guest_phys(addr),
- strnlen(from_guest_phys(addr), guest_limit - addr));
+ /*
+ * 4.1.3.1:
+ *
+ * The driver MUST access each field using the “natural” access
+ * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for
+ * 16-bit fields and 8-bit accesses for 8-bit fields.
+ */
+write_through32:
+ if (mask != 0xFFFFFFFF) {
+ bad_driver(d, "non-32-bit write to offset %u (%#x)",
+ off, getreg(eip));
+ return;
+ }
+ memcpy((char *)d->mmio + off, &val, 4);
+ return;
+
+write_through16:
+ if (mask != 0xFFFF)
+ bad_driver(d, "non-16-bit write to offset %u (%#x)",
+ off, getreg(eip));
+ memcpy((char *)d->mmio + off, &val, 2);
+ return;
+
+write_through8:
+ if (mask != 0xFF)
+ bad_driver(d, "non-8-bit write to offset %u (%#x)",
+ off, getreg(eip));
+ memcpy((char *)d->mmio + off, &val, 1);
+ return;
}
-/*L:190
- * Device Setup
- *
- * All devices need a descriptor so the Guest knows it exists, and a "struct
- * device" so the Launcher can keep track of it. We have common helper
- * routines to allocate and manage them.
- */
-
-/*
- * The layout of the device page is a "struct lguest_device_desc" followed by a
- * number of virtqueue descriptors, then two sets of feature bits, then an
- * array of configuration bytes. This routine returns the configuration
- * pointer.
- */
-static u8 *device_config(const struct device *dev)
+static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask)
{
- return (void *)(dev->desc + 1)
- + dev->num_vq * sizeof(struct lguest_vqconfig)
- + dev->feature_len * 2;
+ u8 isr;
+ u32 val = 0;
+
+ switch (off) {
+ case offsetof(struct virtio_pci_mmio, cfg.device_feature_select):
+ case offsetof(struct virtio_pci_mmio, cfg.device_feature):
+ case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select):
+ case offsetof(struct virtio_pci_mmio, cfg.guest_feature):
+ /*
+ * 3.1.1:
+ *
+ * The driver MUST follow this sequence to initialize a device:
+ *...
+ * - Set the DRIVER status bit: the guest OS knows how
+ * to drive the device.
+ * - Read device feature bits, and write the subset
+ * of feature bits understood by the OS and driver
+ * to the device.
+ */
+ if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER))
+ bad_driver(d,
+ "feature read before VIRTIO_CONFIG_S_DRIVER");
+ goto read_through32;
+ case offsetof(struct virtio_pci_mmio, cfg.msix_config):
+ bad_driver(d, "read of msix_config");
+ case offsetof(struct virtio_pci_mmio, cfg.num_queues):
+ goto read_through16;
+ case offsetof(struct virtio_pci_mmio, cfg.device_status):
+ /* As they did read, any write of FEATURES_OK is now fine. */
+ d->wrote_features_ok = false;
+ goto read_through8;
+ case offsetof(struct virtio_pci_mmio, cfg.config_generation):
+ /*
+ * 4.1.4.3.1:
+ *
+ * The device MUST present a changed config_generation after
+ * the driver has read a device-specific configuration value
+ * which has changed since any part of the device-specific
+ * configuration was last read.
+ *
+ * This is simple: none of our devices change config, so this
+ * is always 0.
+ */
+ goto read_through8;
+ case offsetof(struct virtio_pci_mmio, notify):
+ /*
+ * 3.1.1:
+ *
+ * The driver MUST NOT notify the device before setting
+ * DRIVER_OK.
+ */
+ if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK))
+ bad_driver(d, "notify before VIRTIO_CONFIG_S_DRIVER_OK");
+ goto read_through16;
+ case offsetof(struct virtio_pci_mmio, isr):
+ if (mask != 0xFF)
+ bad_driver(d, "non-8-bit read from offset %u (%#x)",
+ off, getreg(eip));
+ isr = d->mmio->isr;
+ /*
+ * 4.1.4.5.1:
+ *
+ * The device MUST reset ISR status to 0 on driver read.
+ */
+ d->mmio->isr = 0;
+ return isr;
+ case offsetof(struct virtio_pci_mmio, padding):
+ bad_driver(d, "read from padding (%#x)", getreg(eip));
+ default:
+ /* Read from device config space, beware unaligned overflow */
+ if (off > d->mmio_size - 4)
+ bad_driver(d, "read past end (%#x)", getreg(eip));
+
+ /*
+ * 3.1.1:
+ * The driver MUST follow this sequence to initialize a device:
+ *...
+ * 3. Set the DRIVER status bit: the guest OS knows how to
+ * drive the device.
+ * 4. Read device feature bits, and write the subset of
+ * feature bits understood by the OS and driver to the
+ * device. During this step the driver MAY read (but MUST NOT
+ * write) the device-specific configuration fields to check
+ * that it can support the device before accepting it.
+ */
+ if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER))
+ bad_driver(d,
+ "config read before VIRTIO_CONFIG_S_DRIVER");
+
+ if (mask == 0xFFFFFFFF)
+ goto read_through32;
+ else if (mask == 0xFFFF)
+ goto read_through16;
+ else
+ goto read_through8;
+ }
+
+ /*
+ * 4.1.3.1:
+ *
+ * The driver MUST access each field using the “natural” access
+ * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for
+ * 16-bit fields and 8-bit accesses for 8-bit fields.
+ */
+read_through32:
+ if (mask != 0xFFFFFFFF)
+ bad_driver(d, "non-32-bit read to offset %u (%#x)",
+ off, getreg(eip));
+ memcpy(&val, (char *)d->mmio + off, 4);
+ return val;
+
+read_through16:
+ if (mask != 0xFFFF)
+ bad_driver(d, "non-16-bit read to offset %u (%#x)",
+ off, getreg(eip));
+ memcpy(&val, (char *)d->mmio + off, 2);
+ return val;
+
+read_through8:
+ if (mask != 0xFF)
+ bad_driver(d, "non-8-bit read to offset %u (%#x)",
+ off, getreg(eip));
+ memcpy(&val, (char *)d->mmio + off, 1);
+ return val;
}
-/*
- * This routine allocates a new "struct lguest_device_desc" from descriptor
- * table page just above the Guest's normal memory. It returns a pointer to
- * that descriptor.
- */
-static struct lguest_device_desc *new_dev_desc(u16 type)
+static void emulate_mmio(unsigned long paddr, const u8 *insn)
{
- struct lguest_device_desc d = { .type = type };
- void *p;
+ u32 val, off, mask = 0xFFFFFFFF, insnlen = 0;
+ struct device *d = find_mmio_region(paddr, &off);
+ unsigned long args[] = { LHREQ_TRAP, 14 };
- /* Figure out where the next device config is, based on the last one. */
- if (devices.lastdev)
- p = device_config(devices.lastdev)
- + devices.lastdev->desc->config_len;
- else
- p = devices.descpage;
+ if (!d) {
+ warnx("MMIO touching %#08lx (not a device)", paddr);
+ goto reinject;
+ }
+
+ /* Prefix makes it a 16 bit op */
+ if (insn[0] == 0x66) {
+ mask = 0xFFFF;
+ insnlen++;
+ }
- /* We only have one page for all the descriptors. */
- if (p + sizeof(d) > (void *)devices.descpage + getpagesize())
- errx(1, "Too many devices");
+ /* iowrite */
+ if (insn[insnlen] == 0x89) {
+ /* Next byte is r/m byte: bits 3-5 are register. */
+ val = getreg_num((insn[insnlen+1] >> 3) & 0x7, mask);
+ emulate_mmio_write(d, off, val, mask);
+ insnlen += 2 + insn_displacement_len(insn[insnlen+1]);
+ } else if (insn[insnlen] == 0x8b) { /* ioread */
+ /* Next byte is r/m byte: bits 3-5 are register. */
+ val = emulate_mmio_read(d, off, mask);
+ setreg_num((insn[insnlen+1] >> 3) & 0x7, val, mask);
+ insnlen += 2 + insn_displacement_len(insn[insnlen+1]);
+ } else if (insn[0] == 0x88) { /* 8-bit iowrite */
+ mask = 0xff;
+ /* Next byte is r/m byte: bits 3-5 are register. */
+ val = getreg_num((insn[1] >> 3) & 0x7, mask);
+ emulate_mmio_write(d, off, val, mask);
+ insnlen = 2 + insn_displacement_len(insn[1]);
+ } else if (insn[0] == 0x8a) { /* 8-bit ioread */
+ mask = 0xff;
+ val = emulate_mmio_read(d, off, mask);
+ setreg_num((insn[1] >> 3) & 0x7, val, mask);
+ insnlen = 2 + insn_displacement_len(insn[1]);
+ } else {
+ warnx("Unknown MMIO instruction touching %#08lx:"
+ " %02x %02x %02x %02x at %u",
+ paddr, insn[0], insn[1], insn[2], insn[3], getreg(eip));
+ reinject:
+ /* Inject trap into Guest. */
+ if (write(lguest_fd, args, sizeof(args)) < 0)
+ err(1, "Reinjecting trap 14 for fault at %#x",
+ getreg(eip));
+ return;
+ }
- /* p might not be aligned, so we memcpy in. */
- return memcpy(p, &d, sizeof(d));
+ /* Finally, we've "done" the instruction, so move past it. */
+ setreg(eip, getreg(eip) + insnlen);
}
-/*
- * Each device descriptor is followed by the description of its virtqueues. We
- * specify how many descriptors the virtqueue is to have.
+/*L:190
+ * Device Setup
+ *
+ * All devices need a descriptor so the Guest knows it exists, and a "struct
+ * device" so the Launcher can keep track of it. We have common helper
+ * routines to allocate and manage them.
*/
-static void add_virtqueue(struct device *dev, unsigned int num_descs,
- void (*service)(struct virtqueue *))
+static void add_pci_virtqueue(struct device *dev,
+ void (*service)(struct virtqueue *),
+ const char *name)
{
- unsigned int pages;
struct virtqueue **i, *vq = malloc(sizeof(*vq));
- void *p;
-
- /* First we need some memory for this virtqueue. */
- pages = (vring_size(num_descs, LGUEST_VRING_ALIGN) + getpagesize() - 1)
- / getpagesize();
- p = get_pages(pages);
/* Initialize the virtqueue */
vq->next = NULL;
vq->last_avail_idx = 0;
vq->dev = dev;
+ vq->name = name;
/*
* This is the routine the service thread will run, and its Process ID
@@ -1218,25 +2393,11 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
vq->thread = (pid_t)-1;
/* Initialize the configuration. */
- vq->config.num = num_descs;
- vq->config.irq = devices.next_irq++;
- vq->config.pfn = to_guest_phys(p) / getpagesize();
-
- /* Initialize the vring. */
- vring_init(&vq->vring, num_descs, p, LGUEST_VRING_ALIGN);
-
- /*
- * Append virtqueue to this device's descriptor. We use
- * device_config() to get the end of the device's current virtqueues;
- * we check that we haven't added any config or feature information
- * yet, otherwise we'd be overwriting them.
- */
- assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0);
- memcpy(device_config(dev), &vq->config, sizeof(vq->config));
- dev->num_vq++;
- dev->desc->num_vq++;
+ reset_vq_pci_config(vq);
+ vq->pci_config.queue_notify_off = 0;
- verbose("Virtqueue page %#lx\n", to_guest_phys(p));
+ /* Add one to the number of queues */
+ vq->dev->mmio->cfg.num_queues++;
/*
* Add to tail of list, so dev->vq is first vq, dev->vq->next is
@@ -1246,73 +2407,239 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
*i = vq;
}
-/*
- * The first half of the feature bitmask is for us to advertise features. The
- * second half is for the Guest to accept features.
- */
-static void add_feature(struct device *dev, unsigned bit)
+/* The Guest accesses the feature bits via the PCI common config MMIO region */
+static void add_pci_feature(struct device *dev, unsigned bit)
{
- u8 *features = get_feature_bits(dev);
+ dev->features |= (1ULL << bit);
+}
- /* We can't extend the feature bits once we've added config bytes */
- if (dev->desc->feature_len <= bit / CHAR_BIT) {
- assert(dev->desc->config_len == 0);
- dev->feature_len = dev->desc->feature_len = (bit/CHAR_BIT) + 1;
- }
+/* For devices with no config. */
+static void no_device_config(struct device *dev)
+{
+ dev->mmio_addr = get_mmio_region(dev->mmio_size);
- features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT));
+ dev->config.bar[0] = dev->mmio_addr;
+ /* Bottom 4 bits must be zero */
+ assert(~(dev->config.bar[0] & 0xF));
+}
+
+/* This puts the device config into BAR0 */
+static void set_device_config(struct device *dev, const void *conf, size_t len)
+{
+ /* Set up BAR 0 */
+ dev->mmio_size += len;
+ dev->mmio = realloc(dev->mmio, dev->mmio_size);
+ memcpy(dev->mmio + 1, conf, len);
+
+ /*
+ * 4.1.4.6:
+ *
+ * The device MUST present at least one VIRTIO_PCI_CAP_DEVICE_CFG
+ * capability for any device type which has a device-specific
+ * configuration.
+ */
+ /* Hook up device cfg */
+ dev->config.cfg_access.cap.cap_next
+ = offsetof(struct pci_config, device);
+
+ /*
+ * 4.1.4.6.1:
+ *
+ * The offset for the device-specific configuration MUST be 4-byte
+ * aligned.
+ */
+ assert(dev->config.cfg_access.cap.cap_next % 4 == 0);
+
+ /* Fix up device cfg field length. */
+ dev->config.device.length = len;
+
+ /* The rest is the same as the no-config case */
+ no_device_config(dev);
+}
+
+static void init_cap(struct virtio_pci_cap *cap, size_t caplen, int type,
+ size_t bar_offset, size_t bar_bytes, u8 next)
+{
+ cap->cap_vndr = PCI_CAP_ID_VNDR;
+ cap->cap_next = next;
+ cap->cap_len = caplen;
+ cap->cfg_type = type;
+ cap->bar = 0;
+ memset(cap->padding, 0, sizeof(cap->padding));
+ cap->offset = bar_offset;
+ cap->length = bar_bytes;
}
/*
- * This routine sets the configuration fields for an existing device's
- * descriptor. It only works for the last device, but that's OK because that's
- * how we use it.
+ * This sets up the pci_config structure, as defined in the virtio 1.0
+ * standard (and PCI standard).
*/
-static void set_config(struct device *dev, unsigned len, const void *conf)
+static void init_pci_config(struct pci_config *pci, u16 type,
+ u8 class, u8 subclass)
{
- /* Check we haven't overflowed our single page. */
- if (device_config(dev) + len > devices.descpage + getpagesize())
- errx(1, "Too many devices");
+ size_t bar_offset, bar_len;
+
+ /*
+ * 4.1.4.4.1:
+ *
+ * The device MUST either present notify_off_multiplier as an even
+ * power of 2, or present notify_off_multiplier as 0.
+ *
+ * 2.1.2:
+ *
+ * The device MUST initialize device status to 0 upon reset.
+ */
+ memset(pci, 0, sizeof(*pci));
+
+ /* 4.1.2.1: Devices MUST have the PCI Vendor ID 0x1AF4 */
+ pci->vendor_id = 0x1AF4;
+ /* 4.1.2.1: ... PCI Device ID calculated by adding 0x1040 ... */
+ pci->device_id = 0x1040 + type;
+
+ /*
+ * PCI have specific codes for different types of devices.
+ * Linux doesn't care, but it's a good clue for people looking
+ * at the device.
+ */
+ pci->class = class;
+ pci->subclass = subclass;
+
+ /*
+ * 4.1.2.1:
+ *
+ * Non-transitional devices SHOULD have a PCI Revision ID of 1 or
+ * higher
+ */
+ pci->revid = 1;
+
+ /*
+ * 4.1.2.1:
+ *
+ * Non-transitional devices SHOULD have a PCI Subsystem Device ID of
+ * 0x40 or higher.
+ */
+ pci->subsystem_device_id = 0x40;
+
+ /* We use our dummy interrupt controller, and irq_line is the irq */
+ pci->irq_line = devices.next_irq++;
+ pci->irq_pin = 0;
+
+ /* Support for extended capabilities. */
+ pci->status = (1 << 4);
+
+ /* Link them in. */
+ /*
+ * 4.1.4.3.1:
+ *
+ * The device MUST present at least one common configuration
+ * capability.
+ */
+ pci->capabilities = offsetof(struct pci_config, common);
+
+ /* 4.1.4.3.1 ... offset MUST be 4-byte aligned. */
+ assert(pci->capabilities % 4 == 0);
+
+ bar_offset = offsetof(struct virtio_pci_mmio, cfg);
+ bar_len = sizeof(((struct virtio_pci_mmio *)0)->cfg);
+ init_cap(&pci->common, sizeof(pci->common), VIRTIO_PCI_CAP_COMMON_CFG,
+ bar_offset, bar_len,
+ offsetof(struct pci_config, notify));
+
+ /*
+ * 4.1.4.4.1:
+ *
+ * The device MUST present at least one notification capability.
+ */
+ bar_offset += bar_len;
+ bar_len = sizeof(((struct virtio_pci_mmio *)0)->notify);
+
+ /*
+ * 4.1.4.4.1:
+ *
+ * The cap.offset MUST be 2-byte aligned.
+ */
+ assert(pci->common.cap_next % 2 == 0);
+
+ /* FIXME: Use a non-zero notify_off, for per-queue notification? */
+ /*
+ * 4.1.4.4.1:
+ *
+ * The value cap.length presented by the device MUST be at least 2 and
+ * MUST be large enough to support queue notification offsets for all
+ * supported queues in all possible configurations.
+ */
+ assert(bar_len >= 2);
+
+ init_cap(&pci->notify.cap, sizeof(pci->notify),
+ VIRTIO_PCI_CAP_NOTIFY_CFG,
+ bar_offset, bar_len,
+ offsetof(struct pci_config, isr));
+
+ bar_offset += bar_len;
+ bar_len = sizeof(((struct virtio_pci_mmio *)0)->isr);
+ /*
+ * 4.1.4.5.1:
+ *
+ * The device MUST present at least one VIRTIO_PCI_CAP_ISR_CFG
+ * capability.
+ */
+ init_cap(&pci->isr, sizeof(pci->isr),
+ VIRTIO_PCI_CAP_ISR_CFG,
+ bar_offset, bar_len,
+ offsetof(struct pci_config, cfg_access));
+
+ /*
+ * 4.1.4.7.1:
+ *
+ * The device MUST present at least one VIRTIO_PCI_CAP_PCI_CFG
+ * capability.
+ */
+ /* This doesn't have any presence in the BAR */
+ init_cap(&pci->cfg_access.cap, sizeof(pci->cfg_access),
+ VIRTIO_PCI_CAP_PCI_CFG,
+ 0, 0, 0);
- /* Copy in the config information, and store the length. */
- memcpy(device_config(dev), conf, len);
- dev->desc->config_len = len;
+ bar_offset += bar_len + sizeof(((struct virtio_pci_mmio *)0)->padding);
+ assert(bar_offset == sizeof(struct virtio_pci_mmio));
- /* Size must fit in config_len field (8 bits)! */
- assert(dev->desc->config_len == len);
+ /*
+ * This gets sewn in and length set in set_device_config().
+ * Some devices don't have a device configuration interface, so
+ * we never expose this if we don't call set_device_config().
+ */
+ init_cap(&pci->device, sizeof(pci->device), VIRTIO_PCI_CAP_DEVICE_CFG,
+ bar_offset, 0, 0);
}
/*
- * This routine does all the creation and setup of a new device, including
- * calling new_dev_desc() to allocate the descriptor and device memory. We
- * don't actually start the service threads until later.
+ * This routine does all the creation and setup of a new device, but we don't
+ * actually place the MMIO region until we know the size (if any) of the
+ * device-specific config. And we don't actually start the service threads
+ * until later.
*
* See what I mean about userspace being boring?
*/
-static struct device *new_device(const char *name, u16 type)
+static struct device *new_pci_device(const char *name, u16 type,
+ u8 class, u8 subclass)
{
struct device *dev = malloc(sizeof(*dev));
/* Now we populate the fields one at a time. */
- dev->desc = new_dev_desc(type);
dev->name = name;
dev->vq = NULL;
- dev->feature_len = 0;
- dev->num_vq = 0;
dev->running = false;
- dev->next = NULL;
+ dev->wrote_features_ok = false;
+ dev->mmio_size = sizeof(struct virtio_pci_mmio);
+ dev->mmio = calloc(1, dev->mmio_size);
+ dev->features = (u64)1 << VIRTIO_F_VERSION_1;
+ dev->features_accepted = 0;
- /*
- * Append to device list. Prepending to a single-linked list is
- * easier, but the user expects the devices to be arranged on the bus
- * in command-line order. The first network device on the command line
- * is eth0, the first block device /dev/vda, etc.
- */
- if (devices.lastdev)
- devices.lastdev->next = dev;
- else
- devices.dev = dev;
- devices.lastdev = dev;
+ if (devices.device_num + 1 >= MAX_PCI_DEVICES)
+ errx(1, "Can only handle 31 PCI devices");
+
+ init_pci_config(&dev->config, type, class, subclass);
+ assert(!devices.pci[devices.device_num+1]);
+ devices.pci[++devices.device_num] = dev;
return dev;
}
@@ -1324,6 +2651,7 @@ static struct device *new_device(const char *name, u16 type)
static void setup_console(void)
{
struct device *dev;
+ struct virtio_console_config conf;
/* If we can save the initial standard input settings... */
if (tcgetattr(STDIN_FILENO, &orig_term) == 0) {
@@ -1336,7 +2664,7 @@ static void setup_console(void)
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
- dev = new_device("console", VIRTIO_ID_CONSOLE);
+ dev = new_pci_device("console", VIRTIO_ID_CONSOLE, 0x07, 0x00);
/* We store the console state in dev->priv, and initialize it. */
dev->priv = malloc(sizeof(struct console_abort));
@@ -1348,10 +2676,14 @@ static void setup_console(void)
* stdin. When they put something in the output queue, we write it to
* stdout.
*/
- add_virtqueue(dev, VIRTQUEUE_NUM, console_input);
- add_virtqueue(dev, VIRTQUEUE_NUM, console_output);
+ add_pci_virtqueue(dev, console_input, "input");
+ add_pci_virtqueue(dev, console_output, "output");
+
+ /* We need a configuration area for the emerg_wr early writes. */
+ add_pci_feature(dev, VIRTIO_CONSOLE_F_EMERG_WRITE);
+ set_device_config(dev, &conf, sizeof(conf));
- verbose("device %u: console\n", ++devices.device_num);
+ verbose("device %u: console\n", devices.device_num);
}
/*:*/
@@ -1449,6 +2781,7 @@ static void configure_device(int fd, const char *tapif, u32 ipaddr)
static int get_tun_device(char tapif[IFNAMSIZ])
{
struct ifreq ifr;
+ int vnet_hdr_sz;
int netfd;
/* Start with this zeroed. Messy but sure. */
@@ -1476,6 +2809,18 @@ static int get_tun_device(char tapif[IFNAMSIZ])
*/
ioctl(netfd, TUNSETNOCSUM, 1);
+ /*
+ * In virtio before 1.0 (aka legacy virtio), we added a 16-bit
+ * field at the end of the network header iff
+ * VIRTIO_NET_F_MRG_RXBUF was negotiated. For virtio 1.0,
+ * that became the norm, but we need to tell the tun device
+ * about our expanded header (which is called
+ * virtio_net_hdr_mrg_rxbuf in the legacy system).
+ */
+ vnet_hdr_sz = sizeof(struct virtio_net_hdr_v1);
+ if (ioctl(netfd, TUNSETVNETHDRSZ, &vnet_hdr_sz) != 0)
+ err(1, "Setting tun header size to %u", vnet_hdr_sz);
+
memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
return netfd;
}
@@ -1499,12 +2844,12 @@ static void setup_tun_net(char *arg)
net_info->tunfd = get_tun_device(tapif);
/* First we create a new network device. */
- dev = new_device("net", VIRTIO_ID_NET);
+ dev = new_pci_device("net", VIRTIO_ID_NET, 0x02, 0x00);
dev->priv = net_info;
/* Network devices need a recv and a send queue, just like console. */
- add_virtqueue(dev, VIRTQUEUE_NUM, net_input);
- add_virtqueue(dev, VIRTQUEUE_NUM, net_output);
+ add_pci_virtqueue(dev, net_input, "rx");
+ add_pci_virtqueue(dev, net_output, "tx");
/*
* We need a socket to perform the magic network ioctls to bring up the
@@ -1524,7 +2869,7 @@ static void setup_tun_net(char *arg)
p = strchr(arg, ':');
if (p) {
str2mac(p+1, conf.mac);
- add_feature(dev, VIRTIO_NET_F_MAC);
+ add_pci_feature(dev, VIRTIO_NET_F_MAC);
*p = '\0';
}
@@ -1538,25 +2883,21 @@ static void setup_tun_net(char *arg)
configure_device(ipfd, tapif, ip);
/* Expect Guest to handle everything except UFO */
- add_feature(dev, VIRTIO_NET_F_CSUM);
- add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
- add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
- add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
- add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
- add_feature(dev, VIRTIO_NET_F_HOST_TSO4);
- add_feature(dev, VIRTIO_NET_F_HOST_TSO6);
- add_feature(dev, VIRTIO_NET_F_HOST_ECN);
+ add_pci_feature(dev, VIRTIO_NET_F_CSUM);
+ add_pci_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
+ add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
+ add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
+ add_pci_feature(dev, VIRTIO_NET_F_GUEST_ECN);
+ add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO4);
+ add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO6);
+ add_pci_feature(dev, VIRTIO_NET_F_HOST_ECN);
/* We handle indirect ring entries */
- add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
- /* We're compliant with the damn spec. */
- add_feature(dev, VIRTIO_F_ANY_LAYOUT);
- set_config(dev, sizeof(conf), &conf);
+ add_pci_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
+ set_device_config(dev, &conf, sizeof(conf));
/* We don't need the socket any more; setup is done. */
close(ipfd);
- devices.device_num++;
-
if (bridging)
verbose("device %u: tun %s attached to bridge: %s\n",
devices.device_num, tapif, arg);
@@ -1607,7 +2948,7 @@ static void blk_request(struct virtqueue *vq)
head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
/* Copy the output header from the front of the iov (adjusts iov) */
- iov_consume(iov, out_num, &out, sizeof(out));
+ iov_consume(vq->dev, iov, out_num, &out, sizeof(out));
/* Find and trim end of iov input array, for our status byte. */
in = NULL;
@@ -1619,7 +2960,7 @@ static void blk_request(struct virtqueue *vq)
}
}
if (!in)
- errx(1, "Bad virtblk cmd with no room for status");
+ bad_driver_vq(vq, "Bad virtblk cmd with no room for status");
/*
* For historical reasons, block operations are expressed in 512 byte
@@ -1627,15 +2968,7 @@ static void blk_request(struct virtqueue *vq)
*/
off = out.sector * 512;
- /*
- * In general the virtio block driver is allowed to try SCSI commands.
- * It'd be nice if we supported eject, for example, but we don't.
- */
- if (out.type & VIRTIO_BLK_T_SCSI_CMD) {
- fprintf(stderr, "Scsi commands unsupported\n");
- *in = VIRTIO_BLK_S_UNSUPP;
- wlen = sizeof(*in);
- } else if (out.type & VIRTIO_BLK_T_OUT) {
+ if (out.type & VIRTIO_BLK_T_OUT) {
/*
* Write
*
@@ -1657,7 +2990,7 @@ static void blk_request(struct virtqueue *vq)
/* Trim it back to the correct length */
ftruncate64(vblk->fd, vblk->len);
/* Die, bad Guest, die. */
- errx(1, "Write past end %llu+%u", off, ret);
+ bad_driver_vq(vq, "Write past end %llu+%u", off, ret);
}
wlen = sizeof(*in);
@@ -1699,11 +3032,11 @@ static void setup_block_file(const char *filename)
struct vblk_info *vblk;
struct virtio_blk_config conf;
- /* Creat the device. */
- dev = new_device("block", VIRTIO_ID_BLOCK);
+ /* Create the device. */
+ dev = new_pci_device("block", VIRTIO_ID_BLOCK, 0x01, 0x80);
/* The device has one virtqueue, where the Guest places requests. */
- add_virtqueue(dev, VIRTQUEUE_NUM, blk_request);
+ add_pci_virtqueue(dev, blk_request, "request");
/* Allocate the room for our own bookkeeping */
vblk = dev->priv = malloc(sizeof(*vblk));
@@ -1712,9 +3045,6 @@ static void setup_block_file(const char *filename)
vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE);
vblk->len = lseek64(vblk->fd, 0, SEEK_END);
- /* We support FLUSH. */
- add_feature(dev, VIRTIO_BLK_F_FLUSH);
-
/* Tell Guest how many sectors this device has. */
conf.capacity = cpu_to_le64(vblk->len / 512);
@@ -1722,20 +3052,19 @@ static void setup_block_file(const char *filename)
* Tell Guest not to put in too many descriptors at once: two are used
* for the in and out elements.
*/
- add_feature(dev, VIRTIO_BLK_F_SEG_MAX);
+ add_pci_feature(dev, VIRTIO_BLK_F_SEG_MAX);
conf.seg_max = cpu_to_le32(VIRTQUEUE_NUM - 2);
- /* Don't try to put whole struct: we have 8 bit limit. */
- set_config(dev, offsetof(struct virtio_blk_config, geometry), &conf);
+ set_device_config(dev, &conf, sizeof(struct virtio_blk_config));
verbose("device %u: virtblock %llu sectors\n",
- ++devices.device_num, le64_to_cpu(conf.capacity));
+ devices.device_num, le64_to_cpu(conf.capacity));
}
/*L:211
- * Our random number generator device reads from /dev/random into the Guest's
+ * Our random number generator device reads from /dev/urandom into the Guest's
* input buffers. The usual case is that the Guest doesn't want random numbers
- * and so has no buffers although /dev/random is still readable, whereas
+ * and so has no buffers although /dev/urandom is still readable, whereas
* console is the reverse.
*
* The same logic applies, however.
@@ -1754,7 +3083,7 @@ static void rng_input(struct virtqueue *vq)
/* First we need a buffer from the Guests's virtqueue. */
head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
if (out_num)
- errx(1, "Output buffers in rng?");
+ bad_driver_vq(vq, "Output buffers in rng?");
/*
* Just like the console write, we loop to cover the whole iovec.
@@ -1763,8 +3092,8 @@ static void rng_input(struct virtqueue *vq)
while (!iov_empty(iov, in_num)) {
len = readv(rng_info->rfd, iov, in_num);
if (len <= 0)
- err(1, "Read from /dev/random gave %i", len);
- iov_consume(iov, in_num, NULL, len);
+ err(1, "Read from /dev/urandom gave %i", len);
+ iov_consume(vq->dev, iov, in_num, NULL, len);
totlen += len;
}
@@ -1780,17 +3109,20 @@ static void setup_rng(void)
struct device *dev;
struct rng_info *rng_info = malloc(sizeof(*rng_info));
- /* Our device's privat info simply contains the /dev/random fd. */
- rng_info->rfd = open_or_die("/dev/random", O_RDONLY);
+ /* Our device's private info simply contains the /dev/urandom fd. */
+ rng_info->rfd = open_or_die("/dev/urandom", O_RDONLY);
/* Create the new device. */
- dev = new_device("rng", VIRTIO_ID_RNG);
+ dev = new_pci_device("rng", VIRTIO_ID_RNG, 0xff, 0);
dev->priv = rng_info;
/* The device has one virtqueue, where the Guest places inbufs. */
- add_virtqueue(dev, VIRTQUEUE_NUM, rng_input);
+ add_pci_virtqueue(dev, rng_input, "input");
- verbose("device %u: rng\n", devices.device_num++);
+ /* We don't have any configuration space */
+ no_device_config(dev);
+
+ verbose("device %u: rng\n", devices.device_num);
}
/* That's the end of device setup. */
@@ -1820,17 +3152,23 @@ static void __attribute__((noreturn)) restart_guest(void)
static void __attribute__((noreturn)) run_guest(void)
{
for (;;) {
- unsigned long notify_addr;
+ struct lguest_pending notify;
int readval;
/* We read from the /dev/lguest device to run the Guest. */
- readval = pread(lguest_fd, &notify_addr,
- sizeof(notify_addr), cpu_id);
-
- /* One unsigned long means the Guest did HCALL_NOTIFY */
- if (readval == sizeof(notify_addr)) {
- verbose("Notify on address %#lx\n", notify_addr);
- handle_output(notify_addr);
+ readval = pread(lguest_fd, &notify, sizeof(notify), cpu_id);
+ if (readval == sizeof(notify)) {
+ if (notify.trap == 13) {
+ verbose("Emulating instruction at %#x\n",
+ getreg(eip));
+ emulate_insn(notify.insn);
+ } else if (notify.trap == 14) {
+ verbose("Emulating MMIO at %#x\n",
+ getreg(eip));
+ emulate_mmio(notify.addr, notify.insn);
+ } else
+ errx(1, "Unknown trap %i addr %#08x\n",
+ notify.trap, notify.addr);
/* ENOENT means the Guest died. Reading tells us why. */
} else if (errno == ENOENT) {
char reason[1024] = { 0 };
@@ -1893,11 +3231,9 @@ int main(int argc, char *argv[])
main_args = argv;
/*
- * First we initialize the device list. We keep a pointer to the last
- * device, and the next interrupt number to use for devices (1:
- * remember that 0 is used by the timer).
+ * First we initialize the device list. We remember next interrupt
+ * number to use for devices (1: remember that 0 is used by the timer).
*/
- devices.lastdev = NULL;
devices.next_irq = 1;
/* We're CPU 0. In fact, that's the only CPU possible right now. */
@@ -1921,12 +3257,14 @@ int main(int argc, char *argv[])
guest_base = map_zeroed_pages(mem / getpagesize()
+ DEVICE_PAGES);
guest_limit = mem;
- guest_max = mem + DEVICE_PAGES*getpagesize();
- devices.descpage = get_pages(1);
+ guest_max = guest_mmio = mem + DEVICE_PAGES*getpagesize();
break;
}
}
+ /* We always have a console device, and it's always device 1. */
+ setup_console();
+
/* The options are fairly straight-forward */
while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) {
switch (c) {
@@ -1967,8 +3305,8 @@ int main(int argc, char *argv[])
verbose("Guest base is at %p\n", guest_base);
- /* We always have a console device */
- setup_console();
+ /* Initialize the (fake) PCI host bridge device. */
+ init_pci_host_bridge();
/* Now we load the kernel */
start = load_kernel(open_or_die(argv[optind+1], O_RDONLY));